2014-10-10 120 views
1

我已經有了從JSON有效載荷生成的多折線折線圖的基本演示。它按預期工作,但我覺得我沒有充分利用D3庫來正確解析或綁定數據。來自JSON的D3 Multiseries折線圖

什麼是嵌套數據的最佳格式?例如,對象的對象,數組的數組等?

http://jsfiddle.net/thinkin3d/nc2sgmcz/

的JSON有效載荷看起來是這樣的:

var data = { 
    "Series 1": { 
     "20141020": 3.5003987252672744, 
     "20141019": 2.505802351020492, 
     "20141018": 1.511804171940014}, 
    "Series 2": { 
     "20141008": 3.386547593121662, 
     "20141009": 2.1369256424188166, 
     "20141010": 0.88701610875722286}, 
    "Series 3": { 
     "20141024": 1.041445076319178, 
     "20141025": 1.1241181263211502, 
     "20141026": 1.38667149365412} 
} 

我打電話d3.entries將其改造成一個數組:

var entries = d3.entries(data); 

然後我再打電話d3.entries ,每次我想要訪問第二級中的特定鍵值對時:

var entry = d3.entries(d.value); 

我多次調用並重復自己,這就是爲什麼我覺得必須有更好的方式,我不知道。

我沒有使用D3庫的哪些部分?

理想情況下,我希望能夠保持JSON有效載荷格式,但如果在交付之前進行簡單的重新排列操作,D3會使事情變得容易許多,我全都是耳朵!

代碼:

var margin = {top: 20, right: 20, bottom: 30, left: 50}, 
     width = 600 - margin.left - margin.right, 
     height = 400 - margin.top - margin.bottom; 

var parseDate = d3.time.format("%Y%m%d").parse; 

var x = d3.time.scale() 
     .range([0, width]); 

var y = d3.scale.linear() 
     .range([0, height]); 

var color = d3.scale.category20(); 

var xAxis = d3.svg.axis() 
     .scale(x) 
     .orient("bottom"); 

var yAxis = d3.svg.axis() 
     .scale(y) 
     .orient("left"); 

var area = d3.svg.area() 
     .interpolate("basis") 
     .x(function (d) { 
      return x(parseDate(d.key)); 
     }) 
     .y0(height) 
     .y1(function (d) { 
      return y(d.value); 
     }); 

var svg = d3.select("body").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
     .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var entries = d3.entries(data); 

color.domain(entries.map(function (d) { 
    return d; 
})); 

var minX = d3.min(entries, function (kv) { 
    var entry = d3.entries(kv.value); 
    return d3.min(entry, function (d) { 
     return parseDate(d.key); 
    }) 
}); 
var maxX = d3.max(entries, function (kv) { 
    var entry = d3.entries(kv.value); 
    return d3.max(entry, function (d) { 
     return parseDate(d.key); 
    }) 
}); 
var minY = d3.min(entries, function (kv) { 
    var entry = d3.entries(kv.value); 
    return d3.min(entry, function (d) { 
     return d.value; 
    }) 
}); 
var maxY = d3.max(entries, function (kv) { 
    var entry = d3.entries(kv.value); 
    return d3.max(entry, function (d) { 
     return d.value; 
    }) 
}); 

x.domain([minX, maxX]); 
y.domain([minY, maxY]); 

var element = svg.selectAll(".element") 
     .data(entries) 
     .enter().append("g") 
     .attr("class", "element"); 

element.append("path") 
     .attr("class", "area") 
     .attr("d", function (d) { 
      var entry = d3.entries(d.value); 
      return area(entry); 
     }) 
     .style("fill", function (d) { 
      return color(d.key); 
     }); 

element.append("text") 
     .datum(function (d) { 
      var entry = d3.entries(d.value); 
      return { 
       name: d.key, 
       date: parseDate(entry[entry.length - 1].key), 
       value: entry[entry.length - 1].value 
      }; 
     }) 
     .attr("transform", function (d) { 
      return "translate(" + x(d.date) + "," + y(d.value) + ")"; 
     }) 
     .attr("x", -6) 
     .attr("dy", ".35em") 
     .text(function (d) { 
      return d.name; 
     }); 

svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis); 
+0

fddle it。更好,更好。 – 2014-10-10 15:46:25

+0

http://jsfiddle.net/thinkin3d/nc2sgmcz/ – 2014-10-19 10:44:41

回答

0

您可以簡化代碼相當,如果你第一次得到所有x和y的值,然後這些陣列的程度。這是相對簡單的,唯一要注意的是,你需要拼合嵌套數組:

var allX = d3.values(data).map(d3.keys) 
    .reduce(function(a,b) { return a.concat(b); }).map(parseDate); 
var allY = d3.values(data).map(d3.values) 
    .reduce(function(a,b) { return a.concat(b); }); 

x.domain(d3.extent(allX)); 
y.domain(d3.extent(allY)); 

這從您的初始數據結構得到的值,併爲每個無論是鍵或值,這取決於你是否希望的x或y。然後使用.reduce()將此嵌套數組展平。對於y,我們完成了,對於x,日期被解析。然後,您可以直接使用d3.extend()來獲取域的值。

完整演示here