我需要創建一個可以具有負值的d3條形圖。理想情況下,應該根據數據的範圍來計算座標軸零點位置,但是我會找到一個解決方案,假定對稱的正面和負面的範圍,即它總是在圖表的中間。負值的條形圖
下面是我想達到的一個例子。
我需要創建一個可以具有負值的d3條形圖。理想情況下,應該根據數據的範圍來計算座標軸零點位置,但是我會找到一個解決方案,假定對稱的正面和負面的範圍,即它總是在圖表的中間。負值的條形圖
下面是我想達到的一個例子。
OK,讓我們假設你有一個數字爲您的數據集的數組,這包括一些積極和消極的價值觀:
var data = [-15, -20, -22, -18, 2, 6, -26, -18];
你會想要兩個尺度,構建柱狀圖。您需要一個定量標度(通常爲linear scale)來計算沿軸的軸位置,以及第二個軸向位置,以計算沿軸的軸位置。
對於定量範圍,通常需要計算基於最小值和最大值的數據域。一個簡單的方法就是通過d3.extent:
var x = d3.scale.linear()
.domain(d3.extent(data))
.range([0, width]);
您可能還需要nice規模略圓的程度。再舉一個例子,有時你想在畫布中央,在這種情況下,你要採取的最小值和最大值中的較大者爲中心的零值:
var x0 = Math.max(-d3.min(data), d3.max(data));
var x = d3.scale.linear()
.domain([-x0, x0])
.range([0, width])
.nice();
或者,您可以硬編碼任何你想要的域名。
var x = d3.scale.linear()
.domain([-30, 30])
.range([0, width]);
對於Ÿ軸,你需要使用rangeRoundBands的垂直空間劃分爲每個條帶。這也可以讓你指定條之間的填充量。對於一些識別數據通常使用序數標度 - 例如名稱或唯一標識。但是,您也可以結合使用順序尺度與數據的指數:
var y = d3.scale.ordinal()
.domain(d3.range(data.length))
.rangeRoundBands([0, height], .2);
現在,你有你的兩個尺度,你可以創建矩形元素,以顯示條。一個棘手的部分是在SVG中,根據其左上角定位了rects(x
和y
屬性)。因此,我們需要使用x和和 -scales來計算左上角的位置,這取決於關聯值是正值還是負值:如果值爲正數,則數據值確定條的右邊緣,如果爲負,則確定條的左邊。因此,這裏的條件如下:
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d, i) { return x(Math.min(0, d)); })
.attr("y", function(d, i) { return y(i); })
.attr("width", function(d, i) { return Math.abs(x(d) - x(0)); })
.attr("height", y.rangeBand());
最後,您可以添加一個座標軸在頂部顯示刻度標記。您也可以計算填充樣式(或甚至梯度)來改變區分正值和負值的外觀。全部放在一起: