坐标轴,是可视化图表中经常出现的一种图形,由一些列线段和刻度组成。坐标轴在 SVG 中是没有现成的图形元素的,需要用其他的元素组合构成。D3 提供了坐标轴的组件,如此在 SVG 画布中绘制坐标轴变得像添加一个普通元素一样简单。
坐标轴的构成
坐标轴在可视化图形中是很重要的一部分,很多图表的展示都需要使用坐标轴,例如:柱形图、折线图。
SVG 画布的预定义元素里,有六种基本图形:
- 矩形
- 圆形
- 椭圆
- 线段
- 折线
- 多边形
还有一种比较特殊的存在,也是最强的元素:
- 路径
所以说,在D3种是没有现成的坐标轴组件的,需要我们使用别的方式使用坐标轴。
<g>
<!-- 第一个刻度 -->
<g>
<line></line> <!-- 第一个刻度的直线 -->
<text></text> <!-- 第一个刻度的文字 -->
</g>
<!-- 第二个刻度 -->
<g>
<line></line> <!-- 第二个刻度的直线 -->
<text></text> <!-- 第二个刻度的文字 -->
</g>
...
<!-- 坐标轴的轴线 -->
<path></path>
</g>
分组元素 ,是 SVG 画布中的元素,意思是 group。此元素是将其他元素进行组合的容器,在这里是用于将坐标轴的其他元素分组存放。
如果需要手动添加这些元素就太麻烦了,为此,D3 提供了一个组件:d3.axisBottom(xScale)。它为我们完成了以上工作。
使用坐标轴
- 定义坐标轴
坐标轴通常需要和比例尺一起使用:
// 为坐标轴定义一个线性比例尺
var xScale = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
// 定义一个坐标轴
var axis = d3.axisBottom(xScale) //定义一个axis,由bottom可知,是朝下的
.ticks(7); //设置刻度数目
- 定义坐标轴相关的函数:
3.svgAxis():D3 中坐标轴的组件,能够在 SVG 中生成组成坐标轴的元素。
axisBottom:中的Bottom|Top|Left|Right为坐标轴的方向。
scale():指定比例尺。
ticks():指定刻度的数量。
- 添加坐标轴
上面我们定义好了坐标轴,接下来就是将其添加到画布中去。call()的参数是一个函数,其参数是前面定义的坐标轴 axis。
svg.append("g").call(axis);
设定坐标轴的样式和位置
默认的坐标轴样式不太美观,下面提供一个常见的样式:
.axis path,
.axis line{
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
分别定义了类 axis 下的 path、line、text 元素的样式。接下来,只需要将坐标轴的类设定为 axis 即可。
坐标轴的位置,可以通过 transform 属性来设定。
通常在添加元素的时候就一并设定,写成如下形式:
svg.append("g")
.attr("class","axis")
.attr("transform","translate(20,130)")
.call(axis)
- 在比例尺的基础上添加坐标轴
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 14px;
}
<div id="test-svg">
</div>
var svg = d3.select("#test-svg")
.append('svg')
var dataset = [2.5, 2.1, 1.7, 1.3, 0.9];
var linear = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
var rectHeight = 25;
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", 20)
.attr("y", function (d, i) {
return i * rectHeight;
})
.attr("width", function (d) {
return linear(d); //在这里用比例尺
})
.attr("height", rectHeight - 2)
.attr("fill", function (d, i) {
return '#' + Math.random().toString(16).substr(-6);
});
// 在比例尺的基础上,添加坐标轴
var linear = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
// 定义一个坐标轴
var axis = d3.axisBottom(linear) //定义一个axis,由bottom可知,是朝下的
.ticks(7); //设置刻度数目
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(20,130)")
.call(axis)