D3js来自json文件的多个折线图

时间:2017-09-26 10:30:53

标签: json d3.js charts

我是javascript的新手,所以需要一些。 我使用d3js库在我的页面上呈现图表。 上周我遇到了一个名为responsive chat visualization的概念或类似的东西。现在,我试图找到一种方式,以便它们以更好的方式一起工作。我希望有人可以帮我找到解决方案。 我有一个简单的HTML页面

<div id="chart"></div><script src="js/chart2.js"></script>

脚本:

var Chart = (function(window,d3) {
var svg,div, data, x, y, xAxis, yAxis, dim, chartWrapper, line, path,fh,fw, dots, margin = {}, width, height, locator,formatTime;
var timeFormat = d3.time.format('%Y-%m-%d %H:%M:%S.%L');
var wbreakPoint = 768;
var hbreakPoint = 200;
d3.json('data2.json', init); 
function init(json) {
data = json;    
xExtent = d3.extent(data, function(d,i) { return new Date(d.date) });
yExtent = d3.extent(data, function(d,i) { return parseInt(d["lux"]); }); 
x = d3.time.scale().domain(xExtent);
y = d3.scale.linear().domain(yExtent).range([0, height]);
xAxis = d3.svg.axis().orient('bottom').tickFormat(d3.time.format('%d %H:%M:%S'));
yAxis = d3.svg.axis();

line = d3.svg.line()
  .x(function(d) { return x(new Date(d.date)) })
  .y(function(d) { return y(d.lux) })
  .interpolate("basis");
svg = d3.select('#chart')
  .append('svg')
  .style('pointer-events', 'none'); 
svg.append("rect")
    .attr("fill", "rgba(0, 128, 0, 0.2)");      

chartWrapper = svg
    .append('g')
    .style('pointer-events', 'all');

var defs = chartWrapper.append("defs");
var gradient = defs.append("linearGradient")
   .attr("id", "svgGradient")
   .attr("x1", "0%")
   .attr("x2", "100%")
   .attr("y1", "0%")
   .attr("y2", "100%");
gradient.append("stop")
   .attr('class', 'start')
   .attr("offset", "0%")
   .attr("stop-color", "red")
   .attr("stop-opacity", 1);
gradient.append("stop")
   .attr('class', 'end')
   .attr("offset", "100%")
   .attr("stop-color", "blue")
   .attr("stop-opacity", 1);


path = chartWrapper.append('path').data([data]).classed('line', true);  


chartWrapper.append('g').classed('x axis', true);
chartWrapper.append('g').classed('y axis', true);   

touchScale = d3.scale.linear(); 
render();}
function render() {
updateDimensions(window.innerWidth);   
x.range([0, width]);
y.range([height, 0]);
touchScale.domain([0,width]).range([0,data.length-1]).clamp(true);
svg
  .attr('width', '100%')
  .attr('height', height + margin.top + margin.bottom);
fh = svg.style("height").replace("px", "");
fw = svg.style("width").replace("px", "");
chartWrapper
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
xAxis.scale(x);
yAxis.scale(y).orient(window.innerWidth < wbreakPoint ? 'right' : 'left');
if(window.innerWidth < wbreakPoint) {
  xAxis.ticks(d3.time.minutes, 4)
}
else {
  xAxis.ticks(d3.time.minutes, 1)
}
if(window.innerinnerHeight < hbreakPoint) {   
  yAxis.ticks(Math.max(height/50, 2))
}
else {
  yAxis.ticks(Math.max(height/50, 1));
} 
svg.select('.x.axis')
    .attr('transform', 'translate(0,' + height + ')')
    .transition()
    .duration(500)
    .delay(200)
    .call(xAxis)
    .selectAll("text")  
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform", "rotate(-50)" );
svg.select("rect")
    .attr("width", "100%")
    .attr("height", "100%");
svg.select('.y.axis')
    .transition()
    .duration(500)
    .delay(200)
    .call(yAxis);
chartWrapper.select("text")
    .attr("x", (fw / 2))             
    .attr("y", 0 - (margin.top / 2))
    .attr("text-anchor", "middle");     
path
    .transition()
    .duration(1000)
    .attr('d', line(data))
    .attr("stroke-width", 3)
          .attr("stroke", "url(#svgGradient)")
          .attr("fill", "none");}
function updateDimensions(winWidth) {
margin.top = 40;
margin.right = winWidth < wbreakPoint ? 50 : 80;
margin.left = winWidth < wbreakPoint ? 0 : 50;
margin.bottom = 80;
width = winWidth - margin.left - margin.right;
height = .1 * width;}   
return {render : render}
})(window,d3);
window.addEventListener('resize', Chart.render);

它完美运行,而JSON文件如下所示:

[{"lux":"0","date":"2017-08-11 15:10:34.363"},
{"lux":"32","date":"2017-08-11 15:19:34.363"},
{"lux":"90","date":"2017-08-11 15:19:40.225"},
{"lux":"176","date":"2017-08-11 15:20:06.360"},
{"lux":"116","date":"2017-08-11 15:28:14.115"},
{"lux":"50","date":"2017-08-11 15:28:19.225"},
{"lux":"32","date":"2017-08-11 15:29:00.100"}]

但我需要一个多线图,我无法理解如何处理如下所示的json文件:

[{"symbol":"ar1","lux":"20","date":"2017-08-12 15:40:34.363"},
{"symbol":"aw1","lux":"25","date":"2017-08-12 15:40:35.363"},
{"symbol":"ar1","lux":"2","date":"2017-08-12 15:49:34.363"},
{"symbol":"ar1","lux":"50","date":"2017-08-12 15:49:40.225"},
{"symbol":"aw1","lux":"20","date":"2017-08-12 15:49:48.363"},
{"symbol":"ar1","lux":"76","date":"2017-08-12 15:50:06.360"},
{"symbol":"ar1","lux":"116","date":"2017-08-12 15:58:14.115"},
{"symbol":"ar1","lux":"50","date":"2017-08-12 15:58:19.225"},
{"symbol":"ar1","lux":"132","date":"2017-08-12 15:59:00.100"}]

P.S。:对于大量的代码字符串和我的英语感到抱歉;)

1 个答案:

答案 0 :(得分:0)

我犯了一个可怕的错误。我试过的所有例子都是为d3.v4 libary编写的,你可以猜到我使用的是d3.v3库... soo这里是代码:

var Chart = (function(window,d3) {
var svg,div, data, xScale, yScale, xAxis, yAxis, dim, chartWrapper,parse, line,lineGen, colors,path,fh,fw, dots, margin = {}, width, height, locator,formatTime;
var wbreakPoint = 768;
var hbreakPoint = 200;
d3.json('data3.json', init); 
function init(json) {
    data = {
"Model": "Model A",
"Data": [{
        "city": "Datchik2",
        "Data": [{
                    "Date":"2017-08-11 15:10:34.363",
                    "Value":"0" 
                },{
                    "Date":"2017-08-12 21:12:34.363",
                    "Value":"32"
                },{
                    "Date":"2017-08-15 21:55:34.363",
                    "Value":"200"
                }]
        },{
        "city": "Rele1",
        "Data": [{
                    "Date":"2017-08-11 17:11:34.363",
                    "Value":"1"
                },{
                    "Date":"2017-08-15 18:11:34.363",
                    "Value":"1"
                },{
                    "Date":"2017-08-16 19:12:34.363",
                    "Value":"2"
                }]
        },{
        "city": "Datchik22",
        "Data": [{
                    "Date":"2017-08-12 21:10:34.363",
                    "Value":"10"
                },{
                    "Date":"2017-08-13 22:10:34.363",
                    "Value":"20"
                },{
                    "Date":"2017-08-14 23:10:34.363",
                    "Value":"30"
                }]
        }]};    
    colors = d3.scaleOrdinal(d3.schemeCategory10);
    parse = d3.timeParse("%Y-%m-%d %H:%M:%S.%L");
    xExtent = d3.extent(data.Data[0].Data, function(d,i) { return parse(d.Date) });
    yExtent = d3.extent(data.Data[0].Data, function(d,i) { return (d.Value) });
    x = d3.scaleTime().domain(xExtent);
    y = d3.scaleLinear().domain(yExtent);
    xAxis = d3.axisBottom(xScale);
    yAxis = d3.axisLeft(yScale);
    svg = d3.select('#chart').append('svg').style('pointer-events', 'none');        
    groups = svg.selectAll("foo").data(data.Data).enter().append("g");
    chartWrapper = groups.append('g').style('pointer-events', 'all');  
    lineGen = d3.line().x(d => x(parse(d.Date))).y(d => y(d.Value));
    path = chartWrapper.append('path').classed('line', true).attr("d", d => lineGen(d.Data));   
    chartWrapper.append('g').classed('x axis', true);
    chartWrapper.append('g').classed('y axis', true);       
    touchScale = d3.scaleLinear();  
    render();}
function render() {
    updateDimensions(window.innerWidth);   
    x.range([0, width]);
    y.range([height, 0]);
    touchScale.domain([0,width]).range([0,data.length-1]).clamp(true);
    svg.attr('width', '100%').attr('height', height + margin.top + margin.bottom);
    fh = svg.style("height").replace("px", "");
    fw = svg.style("width").replace("px", "");
    chartWrapper.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');    
    xAxis.scale(x);
    yAxis.scale(y);
    svg.select('.x.axis')
        .attr('transform', 'translate(0,' + height + ')')
        .transition()
        .duration(500)
        .delay(200)
        .call(xAxis)
        .selectAll("text")  
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", ".15em")
            .attr("transform", "rotate(-50)" ); 
    svg.select('.y.axis')
        .transition()
        .duration(500)
        .delay(200)
        .call(yAxis);
    chartWrapper.select("text")
        .attr("x", (fw / 2))             
        .attr("y", 0 - (margin.top / 2))
        .attr("text-anchor", "middle");     
    path
        .transition()
        .duration(1000)
        .attr('d',  d => lineGen(d.Data))
        .attr("stroke-width", 3)
              .attr("fill", "none")
    .attr("stroke", (d, i) => colors(i));} 
function updateDimensions(winWidth) {
    margin.top = 40;
    margin.right = winWidth < wbreakPoint ? 50 : 80;
    margin.left = winWidth < wbreakPoint ? 0 : 50;
    margin.bottom = 80;
    width = winWidth - margin.left - margin.right;
    height = .1 * width;}
return {render : render}
})(window,d3);
window.addEventListener('resize', Chart.render);

正如您所看到的,我更改了json文件结构。现在看起来像:

[
"Model": "Model A",
"Data": [{
        "city": "Datchik2",
        "Data": [{
                    "Date":"2017-08-11 21:10:34.363",
                    "Value":"15"    
                },{
                    "Date":"2017-08-12 21:12:34.363",
                    ....]
        },{
        ....]

渲染功能运行良好,但现在我有一点问题(xExtent和yExtent)并使用本地文件(在工作项目中没有本地文件,我使用服务器的响应字符串将json直接放在数据变量中)。但我想我会找到一个解决方案。如果发生这种情况我可以把解决方案放在这里感谢大家观看和编辑问题文本! P.S。:对于大量的代码字符串和我的英语感到抱歉;)