画一个横的柱状图
(我也是一个新学者,如果我写的有错,还请指出)
需要: 画布,比例尺,坐标轴,图元属性
1.设置画布的相关属性
svg标签,用来容纳柱状图
//这一部分写在body标签中
<svg width="1600" height="800" id="mainsvg" class="svgs"></svg>
然后选中它进行一些初始化
//这部分代码写在script标签内
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 innerHeight = height-margin.top-margin.bottom;
const innerWidth = width-margin.left-margin.right;
const g = svg.append('g')
.attr('id','maingroup')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
2.设置比例尺
首先需要知道domain(),range()
domain是定义域,就是坐标系下的值
range是值域,就是映射到svg画布上的值
下面是我已经用过的比例尺
d3.scaleLinear()线性比例尺
const xScale=d3.scaleLinear()
.domain([0,10])
.range([0,100]);
//domain和range都是连续的区域
d3.scaleBand()序数比例尺
const yScale=d3.scaleBand()
.domain([1,2,3,4])
.range([1,100]);
//domain是离散的区域,range是连续的区域
//就像是把range平均分割为domain中的个数
d3.scaleTime()时间比例尺
const xScale = d3.scaleTime()
.domain([new Date(2017, 0, 1, 0), new Date(2017, 0, 1, 2)])
.range([0,100]);
//domain和range都是连续的区域,但是domain中换成了时间
其他还有一些,没有用过,也不是很熟悉
d3.scaleIdentity() // 恒等比例尺
d3.scaleSqrt() // 乘方比例尺
d3.scalePow() // 类似scaleSqrt的乘方比例尺
d3.scaleLog() // 对数比例尺
d3.scaleQuantile() // 分位数比例尺
d3.scaleOrdinal() 序数比例尺
scaleQuantize() 量化比例尺
在具体运用中,domain和range往往不是直接给出数据,
而是根据相关函数或者变量的值来给出。
下面继续我们的代码书写。
const xScale = d3.scaleLinear()
.domain([0,d3.max(data,datum=>datum.value)])
.range([0,innerWidth]);
const yScale = d3.scaleBand()
.domain(data.map(datum=>datum.name))
.range([0,innerHeight]);
3.设置坐标轴
const xAxis = d3.axisBottom(xScale);
const yAxis =d3.axisLeft(yScale);
g.append('g').call(xAxis)
.attr('transform',`translate(0,${innerHeight})`);
g.append('g').call(yAxis);
d3.selectAll('.tick text').attr('font-size','2em');
4.对每个图元设置属性
我设置的是矩形,如果愿意,也可以尝试其他形状
data.forEach(datum=>{
g.append('rect')
.attr('width',xScale(datum.value))
.attr('height',yScale.bandwidth())
.attr('y',yScale(datum.name))
.attr('fill','orangered')
.attr('opacity','0.8');
})
-------------------------------------------------------------------------
以上就是我认为比较重要的步骤吧
下面放上完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../js/d3.min.js"></script>
<title>barchart</title>
</head>
<body>
<svg width="1600" height="800" id="mainsvg" class="svgs"></svg>
<script>
const data = [{name: 'Shao', value:6},
{name:'w', value:15}, {name:'Cai', value:16}, {name:'Li', value: 9},
{name:'Yuann', value:6}, {name:'Rug', value:10}, {name:'Xin', value:13},
{name:'He', value:14}, {name:'Xia', value:12}, {name:'G', value:20},
{name:'Wei-Y', value:15}, {name:'Cheng', value:14},
{name:'Yug', value:15}, {name:'Liw', value:18}];
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;
const g = svg.append('g').attr('id','maingroup')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const xscale = d3.scaleLinear()
.domain([0,d3.max(data,datum => datum.value)])
.range([0,innerwidth]);
const yscale = d3.scaleBand()
.domain(data.map(datum => datum.name))
.range([0,innerheight])
.padding(0.1);
data.forEach(datum =>{
g.append('rect')
.attr('width',xscale(datum.value))
.attr('height',yscale.bandwidth())
.attr('y',yscale(datum.name))
.attr('fill','orangered')
.attr('opacity','0.8')
})
const yAxis = d3.axisLeft(yscale);
const xAxis = d3.axisBottom(xscale);
g.append('g').call(yAxis);
g.append('g').call(xAxis).attr('transform', `translate(0, ${innerheight})`);
d3.selectAll('.tick text').attr('font-size', '2em');
//下面的代码可用于添加文字
// g.append('text').text('Value of CSFR').attr('font-size', '3em')
// .attr('x', innerwidth / 2 - 200).attr('y', -10)
</script>
</body>
</html>
目前学习的是b站上小魁少爷所发布的
数据可视化编程-使用D3.js
他是一个挺不错的老师,有问题私信也会回复