我是d3js的新手,我正在构建一个如下所示的多线图:
下面列出的数据集样本。
{
"cognitive": [{
"score": 18296.129,
"timestamp": 1444795200000,
"count": 152
}, {
"score": 17413.408,
"timestamp": 1444881600000,
"count": 146
}, {
"score": 13893.5,
"timestamp": 1444968000000,
"count": 87
}, {
"score": 11139.98,
"timestamp": 1445054400000,
"count": 71
}, {
"score": 8268.798,
"timestamp": 1445140800000,
"count": 44
}, {
"score": 11507.722,
"timestamp": 1445227200000,
"count": 85
}, {
"score": 12146.143,
"timestamp": 1445313600000,
"count": 107
}],
"blumix": [{
"score": 8232.498,
"timestamp": 1444795200000,
"count": 62
}, {
"score": 7778.5425,
"timestamp": 1444881600000,
"count": 58
}, {
"score": 6566.0786,
"timestamp": 1444968000000,
"count": 52
}, {
"score": 4971.932,
"timestamp": 1445054400000,
"count": 39
}, {
"score": 4448.755,
"timestamp": 1445140800000,
"count": 20
}, {
"score": 6997.92,
"timestamp": 1445227200000,
"count": 59
}, {
"score": 7539.2417,
"timestamp": 1445313600000,
"count": 62
}]
}
我正在使用jQuery Ajax请求获取此Object并将其传递给我的buildGraph函数。
Graph.utility.loadJson = function(){
var url = "../../App/assets/JSON/data.json",
dfd = new $.Deferred();
d3.json(url, function(error, json){
var err = !!error;
if (err) {
dfd.reject(error);
}else {
dfd.resolve(json.cognitive);
}
});
return dfd.promise();
};
这是我用来构建图形的buildGraph函数的片段。
var x = d3
.time
.scale()
.range([margin.left, W - margin.right]);
var y = d3.scale
.linear()
.range([H - margin.top - 30, 10]);
var xAxis = d3.svg
.axis()
.scale(x)
// .tickSize(H)
.orient("bottom")
.ticks(d3.time.days)
.tickFormat(d3.time.format("%a %d"))
.ticks(8);
var yAxis = d3.svg
.axis()
.scale(y)
.orient("left");
// Build Lines
var line = d3.svg.line()
.x(function(d) { return x(d.timestamp); })
.y(function(d) { return y(d.score); }); // .interpolate("basis");
var svg = d3.select("#d3-graph-js")
.append("svg")
.attr("id", "chart")
.attr("width", W)
.attr("height", H)
.attr("transform", "translate(0," + (H - margin.bottom) + ")")
.attr("viewBox", "0 0 " + W + " " + H)
.attr("preserveAspectRatio", "xMidYMid")
.append("g")
.attr("id", "g-chart");
// data.forEach(function(d, i){
// d.timestamp = new Date(d.timestamp);
// });
// x.domain([data[0].timestamp, data[data.length - 1].timestamp]);
// y.domain(d3.extent(data, function(d) { return d.score; }));
x.domain(d3.extent(data, function(d) { return d.timestamp;}));
y.domain(d3.extent(data, function(d) { return d.score; }));
当前代码在图中只生成了一行,因为我已经将json.cognitive传递给了buildGraph方法。如果我尝试在我的dfd.resolve(json)中传递Object并尝试使用
迭代Objectfor (key in data) {
var obj = key;
for (newObj in obj) {
// Insert the above snippet here
}
}
这会创建多行,但yAxis的范围从“cognotive”和“bluemix”
如何重写此代码,使其占据Object中所有节点的范围,并在图形上构建多行。
答案 0 :(得分:0)
您不能只在循环中插入所有图表代码。您的图表代码可以完成所有操作 - 包括域确定和轴创建。您需要做的是修改代码以接受行对象列表。
例如,如果您的数据对象需要两个维度数组:
data = [
[{score:10,timestamp:x},{...}....],
[{score:10,timestamp:x},{...}....]
]
然后你可以修改绘制这样的行的代码:
var lines = svg.selectAll(".lines")
.data(data)
.enter()
.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d);
})
.style("fill", "none");
你可以看到你仍然会使用你的行函数告诉d3 x和y坐标的值在哪里。
此外,如果您的代码段使用行列表,则需要修改指定域的代码,此行:
x.domain(d3.extent(data, function(d) { return d.timestamp;}));
必须替换为:
x.domain(d3.extent(data[0], function(d) { return d.timestamp;}));
但请注意,如果您的所有行都具有相同的最小值和最大值(位于同一域中),则您的图表可能会起作用。否则你将不得不修改代码。
我花了一些时间为我的需求创建一个图表库(https://github.com/hoonzis/KoExtensions),最后它几乎总是更容易占用现有的库,除非你想在将来调整它。 / p>