坐標(biāo)軸,是可視化圖表中經(jīng)常出現(xiàn)的一種圖形承二,由一些列線段和刻度組成。坐標(biāo)軸在 SVG 中是沒有現(xiàn)成的圖形元素的纲爸,需要用其他的元素組合構(gòu)成亥鸠。D3 提供了坐標(biāo)軸的組件,如此在 SVG 畫布中繪制坐標(biāo)軸變得像添加一個普通元素一樣簡單缩焦。
坐標(biāo)軸的構(gòu)成
坐標(biāo)軸在可視化圖形中是很重要的一部分读虏,很多圖表的展示都需要使用坐標(biāo)軸,例如:柱形圖袁滥、折線圖盖桥。
SVG 畫布的預(yù)定義元素里,有六種基本圖形:
- 矩形
- 圓形
- 橢圓
- 線段
- 折線
- 多邊形
還有一種比較特殊的存在题翻,也是最強(qiáng)的元素:
- 路徑
所以說揩徊,在D3種是沒有現(xiàn)成的坐標(biāo)軸組件的,需要我們使用別的方式使用坐標(biāo)軸嵌赠。
<g>
<!-- 第一個刻度 -->
<g>
<line></line> <!-- 第一個刻度的直線 -->
<text></text> <!-- 第一個刻度的文字 -->
</g>
<!-- 第二個刻度 -->
<g>
<line></line> <!-- 第二個刻度的直線 -->
<text></text> <!-- 第二個刻度的文字 -->
</g>
...
<!-- 坐標(biāo)軸的軸線 -->
<path></path>
</g>
分組元素 塑荒,是 SVG 畫布中的元素,意思是 group姜挺。此元素是將其他元素進(jìn)行組合的容器齿税,在這里是用于將坐標(biāo)軸的其他元素分組存放。
如果需要手動添加這些元素就太麻煩了炊豪,為此凌箕,D3 提供了一個組件:d3.axisBottom(xScale)。它為我們完成了以上工作词渤。
使用坐標(biāo)軸
- 定義坐標(biāo)軸
坐標(biāo)軸通常需要和比例尺一起使用:
// 為坐標(biāo)軸定義一個線性比例尺
var xScale = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
// 定義一個坐標(biāo)軸
var axis = d3.axisBottom(xScale) //定義一個axis牵舱,由bottom可知,是朝下的
.ticks(7); //設(shè)置刻度數(shù)目
- 定義坐標(biāo)軸相關(guān)的函數(shù):
3.svgAxis():D3 中坐標(biāo)軸的組件缺虐,能夠在 SVG 中生成組成坐標(biāo)軸的元素芜壁。
axisBottom:中的Bottom|Top|Left|Right為坐標(biāo)軸的方向。
scale():指定比例尺高氮。
ticks():指定刻度的數(shù)量慧妄。
- 添加坐標(biāo)軸
上面我們定義好了坐標(biāo)軸,接下來就是將其添加到畫布中去剪芍。call()的參數(shù)是一個函數(shù)腰涧,其參數(shù)是前面定義的坐標(biāo)軸 axis。
svg.append("g").call(axis);
設(shè)定坐標(biāo)軸的樣式和位置
默認(rèn)的坐標(biāo)軸樣式不太美觀紊浩,下面提供一個常見的樣式:
.axis path,
.axis line{
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
分別定義了類 axis 下的 path、line、text 元素的樣式坊谁。接下來费彼,只需要將坐標(biāo)軸的類設(shè)定為 axis 即可。
坐標(biāo)軸的位置口芍,可以通過 transform 屬性來設(shè)定箍铲。
通常在添加元素的時候就一并設(shè)定,寫成如下形式:
svg.append("g")
.attr("class","axis")
.attr("transform","translate(20,130)")
.call(axis)
- 在比例尺的基礎(chǔ)上添加坐標(biāo)軸
.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);
});
// 在比例尺的基礎(chǔ)上鬓椭,添加坐標(biāo)軸
var linear = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
// 定義一個坐標(biāo)軸
var axis = d3.axisBottom(linear) //定義一個axis颠猴,由bottom可知,是朝下的
.ticks(7); //設(shè)置刻度數(shù)目
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(20,130)")
.call(axis)