[英]d3.js scatterplot with different colors and symbols - issues encountered
我正在嘗試創建數百個數據點的散點圖,每個數據點有大約5個不同的屬性。 數據從.csv加載為對象數組,每個對象如下所示:
{hour: "02",yval: "63",foo: "33", goo:"0", bar:"1"},
我想顯示具有以下屬性的散點圖:
bar
:
-circle表示bar=0
所有點,而three-down表示bar=1
那些(這是一個虛擬變量)。
foo
和goo
顏色:
goo
是值[0,1,2]的分類,而foo
是定量的,范圍從0到50。 foo和goo是互斥的,因此只有其中一個具有值。 換句話說,對於每個數據點, foo=0
或goo=0
。 goo=1
點數應為橙色; goo=2
點數應為紅色。 foo
應該映射到從淺藍色到深藍色的線性色標,即d3.scale.linear().domain([0, 50]).range(["#87CEFF", "#0000FF"]);
我可以單獨完成這些,但是將所有內容組合在一起會為我創造問題。
我的代碼具有可重現的數據在這里: http : //jsfiddle.net/qy5ohw0x/3/
問題
.append("svg:path")
.attr("d", d3.svg.symbol())
這沒用。 我嘗試了一種不同的方法,但這沒有正確映射值:
var series = svg.selectAll("g.series")
.data(dataSet, function(d, i) { return d.bar; })
.enter()
.append("svg:g")
series.selectAll("g.point")
.data(dataSet)
.enter()
.append("svg:path")
.attr("transform", function(d, i) { return "translate(" + d.hour + "," + d.yval + ")"; })
.attr("d", function(d,i, j) { return d3.svg.symbol().type(symbolType[j])(); })
.attr("r", 2);
goo
顏色(灰色/橙色/紅色),我手動將值映射到3種顏色: 首先定義var colors = ["grey", "orange", "red"];
然后在繪制數據點鏈的同時
.style("fill", function (d) { return colors[d.type]; })
這單獨工作,但不是用不同的符號。
foo
鏈接第二種顏色.attr嗎? d3.scale.linear().domain([0, 50]).range(["#87CEFF", "#0000FF"]);
如果可能的話可能會有用。 再次,jsfiddle在這里: http : //jsfiddle.net/qy5ohw0x/3/
謝謝!!
只需對function(d)
中的每個屬性進行所有邏輯和比較。
首先設置一些助手:
// symbol generators
var symbolTypes = {
"triangleDown": d3.svg.symbol().type("triangle-down"),
"circle": d3.svg.symbol().type("circle")
};
// colors for foo
var fooColors = d3.scale
.linear()
.domain([0, 50])
.range(["#87CEFF", "#0000FF"]);
然后為每個符號附加一個路徑:
svg.selectAll("path")
.data(dataSet)
.enter().append("path")
.attr("class", "dot")
// position it, can't use x/y on path, so translate it
.attr("transform", function(d) {
return "translate(" + (x(d.hour) + (Math.random() * 12 - 6)) + "," + y(d.yval) + ")";
})
// assign d from our symbols
.attr("d", function(d,i){
if (d.bar === "0") // circle if bar === 0
return symbolTypes.circle();
else
return symbolTypes.triangleDown();
})
// fill based on goo and foo
.style("fill", function(d,i){
if (d.goo !== "0"){
if (d.goo === "1")
return "red";
else
return "orange";
}else{
return fooColors(d.foo);
}
});
更新了小提琴 。
另外,我認為在這種情況下,直接d3
比nvd3
更直觀。
nvd3.js簡化得多
function prepareData (data) {
return [{
key: 'Group 1',
values: data.map(function (item) {
item.shape = item.bar == "0" ? 'circle' : 'triangle-down';
item.x = Number(item.hour);
item.y = Number(item.yval);
item.size = 0.1;
item.disabled = Math.random() > 0.4;
return item;
})
}]
}
nv.addGraph(function() {
var chart = nv.models.scatterChart()
.showDistX(false)
.showDistY(true)
.showLegend(false)
//Axis settings
chart.xAxis.tickFormat(d3.format('3.0f'));
chart.yAxis.tickFormat(d3.format('3.0f'));
d3.select('#chart svg')
.datum(prepareData(dataSet))
.call(chart)
// A bit hacky but works
var fooscale = d3.scale.linear().domain([0, 50]).range(["#87CEFF", "#0000FF"]);
function colorer(d) {
if (d.goo == '1')
return 'orange';
else if (d.goo == '2')
return 'red';
else if (d.goo == '0')
return fooscale(d.foo);
return 'gray';
}
d3.selectAll('.nv-point')
.attr({
'stroke': colorer,
'fill': colorer
})
nv.utils.windowResize(chart.update);
return chart;
});
見https://jsfiddle.net/qy5ohw0x/4/
PS很遺憾Nvd3缺少文檔,所以請使用它的github代替
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.