前言:本篇主要内容是svg的操控。使用D3获取、修改、删除节点(图元),比例尺,使用d3绘制简单柱状图,引入坐标轴。
d3.select('#red')
,即查询Id为‘red’的元素。de.select('.red')
,只会返回找到的第一个元素。
d3.selectAll('.green')
,即查询所有class是‘green’的元素d3.selectAll('rect')
,即查询所有标签是‘rect’的元素(rect为svg中的矩形标签)d3.select('#red rect')
,即查找id为red的标签,进一步查找id为red的子标签中是rect的。(结果通过父标签做了筛选)父节点的属性会影响子节点
子节点的属性会相对于父节点
id,class(特殊的属性,可以使用.attr设置)
x,y,cx,cy(cx,cy为圆的坐标轴)
fill(填充),stroke(边缘)
height,width,r(圆的半径)
transform -> translate ,rotate,scale
其余属性可查阅
https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute
屏幕空间的坐标轴与常见坐标轴不同
element.attr('attr_name','attr_value')
element.attr('attr_name')
不管是添加还是删除,在进行操作前都要先选择元素。
const myred = svg.append('rect') //添加矩形
const myred = d3.select('#mainsvg').append('rect')
const myred = d3.select('#mainsvg').append('rect').attr('x','100')
链式添加
以下代码为在选择了id为mainsvg的元素,为他添加组,并为这个组设置id值。
const myred =d3.select('#mainsvg').append('g').attr('id','maingroup')
opacity
'属性hack出移除的效果element.attr('opacity','0')
d3.select('myred').remove
通过d3.scaleLinear
或d3.scaleBand
得到的返回值本质上是函数
const xScale = d3.scaleLinear()
.domain([0,d3.max(data,datum=>datum.value)])
.range([0,innerWidth]);
const map = xScale(100)
一个栗子:
const myred = d3.scaleLinear().domain([0,10]).range([-1000,1000])
myred(5) //结果是0
myred(9) //结果是800
myred(2) //结果是-600
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用d3实现柱状图title>
<script src='https://d3js.org/d3.v5.min.js'>script>
head>
<body>
<svg width="1600" height="800" id="mainsvg" class="svgs">svg>
<script>
//定义数据
const data = [{
name:'红红',age:18},
{
name:'绿绿',age:20},{
name:'泡泡',age:9},{
name:'果果',age:1},
{
name:'红泡泡',age:9},{
name:'绿果果',age:6},{
name:'小明',age:3},
{
name:'小绿绿',age:4},{
name:'小果果',age:10},{
name:'花花',age:5},
{
name:'小张',age:12},{
name:'小结',age:16},{
name:'二狗子',age:9}];
//设置画布的宽高
const svg = d3.select('#mainsvg');
const width = +svg.attr('width');
const height = +svg.attr('height');
const margin = {
top:60,right:30,bottom:60,left:150};
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
//设置xy轴的最大最小值
const xScale = d3.scaleLinear()
.domain([0,d3.max(data,d=>d.age)]) //获取数据中的最大值,d=>d.age是一个回调函数
.range([0,innerWidth]); //映射的最大值和最小值
const yScale = d3.scaleBand()
.domain(data.map(d=>d.name)) //获取y轴的值,data.map
.range([0,innerHeight])
.padding(0.1); //调整条带柱状之间的间隔
//添加坐标轴画布
const g = svg.append('g').attr('id','maingroup')
.attr('transform',`translate(${
margin.left},${
margin.top})`);
//定义y轴
const y = d3.axisLeft(yScale);
g.append('g').call(y);
//定义x轴
const x = d3.axisBottom(xScale);
g.append('g').call(x).attr('transform',`translate(0,${
innerHeight})`);
//添加柱状条形图
data.forEach( d=>{
g.append('rect')
.attr('width',xScale(d.age)) //条形柱状的宽度
.attr('height',yScale.bandwidth())
.attr('fill','green')
.attr('y',yScale(d.name)) //映射位置
});
//修改坐标轴的字体大小
d3.selectAll('.tick text').attr('font-size','2rem'); //.tick是d3里给出的属性
//添加标题
g.append('text').text('绿泡泡绿泡泡绿绿绿')
.attr('font-size','3rem')
.attr('transform',`translate(${
innerWidth/2},0)`) //文字的左边居中
.attr('text-anchor','middle') //文字的中心点居中
script>
body>
html>
总结:
注意:
中添加了与坐标轴相关的元素