Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript d3js-如何为多组可更新的项目绘制多折线图?_Javascript_Html_Css_D3.js_Svg - Fatal编程技术网

Javascript d3js-如何为多组可更新的项目绘制多折线图?

Javascript d3js-如何为多组可更新的项目绘制多折线图?,javascript,html,css,d3.js,svg,Javascript,Html,Css,D3.js,Svg,我是d3的新手,目前有一个简单的折线图,显示了一组数据的两条线。我想做的是能够以灵活的方式为多个组创建多行。每个组都会有几行,它们会为组母公司进行颜色编码——在我的数据中,在本例中是资产或股票代码 目前,您可以在我的代码中看到,我正在为每个路径手动创建一个数组,但我想如果我开始有100个路径,这可能会变得非常混乱。有更好的方法吗 我曾尝试使用d3.nest,但我始终无法确定数据应该是什么样的,这样就可以为每组行应用更新/进入/退出模式 这是我的WIP代码: <!DOCTYPE html&

我是d3的新手,目前有一个简单的折线图,显示了一组数据的两条线。我想做的是能够以灵活的方式为多个组创建多行。每个组都会有几行,它们会为组母公司进行颜色编码——在我的数据中,在本例中是资产或股票代码

目前,您可以在我的代码中看到,我正在为每个路径手动创建一个数组,但我想如果我开始有100个路径,这可能会变得非常混乱。有更好的方法吗

我曾尝试使用d3.nest,但我始终无法确定数据应该是什么样的,这样就可以为每组行应用更新/进入/退出模式

这是我的WIP代码:


<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */

body { font: 12px Arial;}

path { 
    stroke: steelblue;
    stroke-width: 2;
    fill: none;
}

.axis path,
.axis line {
    fill: none;
    stroke: grey;
    stroke-width: 1;
    shape-rendering: crispEdges;
}

</style>
<body>
<div id="graphDiv"></div>

<!-- load the d3.js library -->    
<script src="https://d3js.org/d3.v5.min.js"></script>

<script>
    var data_set = [{
    'Date': '2009-03-23',
    'Raw': 25,
    'Raw2': 25,
    'Asset': 'A'
  },
  {
    'Date': '2009-03-24',
    'Raw': 28,
    'Raw2': 25.4,
    'Asset': 'A'
  },
  {
    'Date': '2009-03-25',
    'Raw': 26,
    'Raw2': 25.37,
    'Asset': 'B'
  },
  {
    'Date': '2009-03-26',
    'Raw': 22,
    'Raw2': 25.03,
    'Asset': 'B'
  },
  {
    'Date': '2009-03-27',
    'Raw': 19,
    'Raw2': 24.42,
    'Asset': 'C'
  },
  {
    'Date': '2009-03-28',
    'Raw': 23,
    'Raw2': 24.28,
    'Asset': 'D'
  }
]

var margin = {
  top: 30,
  right: 50,
  bottom: 30,
  left: 50
};
var svgWidth = 600;
var svgHeight = 1000;
var graphWidth = svgWidth - margin.left - margin.right;
var graphHeight = svgHeight - margin.top - margin.bottom;
// var parseDate = d3.timeParse("%d/%m/%Y");
var parseDate = d3.timeParse("%Y-%m-%d");

var x = d3.scaleTime().range([0, graphWidth]);
var y = d3.scaleLinear().range([graphHeight, 0]);
var z = d3.scaleOrdinal(d3.schemeCategory10); // for colours
var xAxis = d3.axisBottom().scale(x).ticks(10);
var yAxis = d3.axisLeft().scale(y).ticks(10);

// Need to create the lines manually for each bit of data
var line = d3.line()
  .x(function(d) {
    return x(d.date);
  })
  .y(function(d) {
    return y(d.y);
  });

// Creates the SVG area within the div on the dom 
// Just doing this once 
var svg = d3.select("#graphDiv")
  .append("svg")
  .attr("width", svgWidth)
  .attr("height", svgHeight)
var g = svg.append("g")
  .attr("transform",
    "translate(" + margin.left + "," + margin.top + ")")
  .call(d3.zoom().on("zoom", function() {
    svg.attr("transform", d3.event.transform)
  }));

// Add the X Axis
g.append("g").attr("class", "x axis")
  .attr("transform", "translate(0," + graphHeight + ")")
  .call(xAxis);
// Text label for x axis 
g.append("text")
  .style("text-anchor", "middle")
  .text("timeseries dates")
  .attr("transform", "translate(" + (graphWidth / 2) + " ," + (graphHeight + margin.top) + ")");

// Add the Y Axis
g.append("g")
  .attr("class", "y axis")
  .call(yAxis);
// text label for the y axis
g.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", 0 - margin.left)
  .attr("x", 0 - (graphHeight / 2))
  .attr("dy", "1em")
  .style("text-anchor", "middle")
  .text("price points");


function drawGraph(data_set) {

  let pathData = []
  //assume 2 paths
  pathData.push([])
  pathData.push([])

  // Pass in the data here 
  data_set.forEach(function(d) {

    let path0 = {}
    let path1 = {}

    path0.date = parseDate(d.Date)
    path1.date = parseDate(d.Date)

    path0.y = +d.Raw
    path1.y = +d.Raw2

    pathData[0].push(path0)
    pathData[1].push(path1)

  });

  x.domain(d3.extent(data_set, function(d) {
    return parseDate(d.Date);
  }));
  y.domain([
    d3.min(data_set, function(d) {
      return Math.min(d.Raw, d.Raw2)
    }),
    d3.max(data_set, function(d) {
      return Math.max(d.Raw, d.Raw2)
    })
  ]);

  var lines = g.selectAll(".path")
    .data(pathData)

  lines.exit().remove()

  var enter = lines.enter()
    .append("path")
    .attr("class", "path")
    .style("stroke", (d, i) => z(i))

  var merge = enter.merge(lines)
    .attr("d", line)

}

// display initial chart
window.onload = drawGraph(data_set)
// Push new data every 5 seconds for a specific date
var h = setInterval(function() {
  data_set.push({
    'Date': '2009-03-29',
    'Raw': Math.floor(Math.random() * 50),
    'Raw2': Math.floor(Math.random() * 25),
    'Asset': 'A'
  }, {
    'Date': '2009-03-30',
    'Raw': Math.floor(Math.random() * 50),
    'Raw2': Math.floor(Math.random() * 25),
    'Asset': 'A'
  }, {
    'Date': '2009-03-31',
    'Raw': Math.floor(Math.random() * 50),
    'Raw2': Math.floor(Math.random() * 25),
    'Asset': 'A'
  }, {
    'Date': '2009-04-01',
    'Raw': Math.floor(Math.random() * 50),
    'Raw2': Math.floor(Math.random() * 25),
    'Asset': 'A'
  }, {
    'Date': '2009-04-02',
    'Raw': Math.floor(Math.random() * 50),
    'Raw2': Math.floor(Math.random() * 25),
    'Asset': 'A'
  }, {
    'Date': '2009-04-03',
    'Raw': Math.floor(Math.random() * 50),
    'Raw2': Math.floor(Math.random() * 25),
    'Asset': 'A'
  });
  drawGraph(data_set);
}, 5000);
</script>
</body>```




/*设置CSS*/
正文{font:12px Arial;}
路径{
笔画:钢蓝;
笔画宽度:2;
填充:无;
}
.轴线路径,
.轴线{
填充:无;
笔画:灰色;
笔画宽度:1;
形状渲染:边缘清晰;
}
变量数据集=[{
“日期”:“2009-03-23”,
“原始”:25,
“Raw2”:25,
“资产”:“A”
},
{
‘日期’:‘2009-03-24’,
“原始”:28,
“Raw2”:25.4,
“资产”:“A”
},
{
“日期”:“2009-03-25”,
“原始”:26,
“Raw2”:25.37,
“资产”:“B”
},
{
“日期”:“2009-03-26”,
“原始”:22,
“Raw2”:25.03,
“资产”:“B”
},
{
‘日期’:‘2009-03-27’,
“原始”:19,
“Raw2”:24.42,
“资产”:“C”
},
{
‘日期’:‘2009-03-28’,
“原始”:23,
“Raw2”:24.28,
“资产”:“D”
}
]
var保证金={
前30名,
右:50,,
底数:30,
左:50
};
var svgWidth=600;
var svgHeight=1000;
var graphWidth=svgWidth-margin.left-margin.right;
var graphHeight=svghight-margin.top-margin.bottom;
//var parseDate=d3.timeParse(“%d/%m/%Y”);
var parseDate=d3.timeParse(“%Y-%m-%d”);
var x=d3.scaleTime().range([0,graphWidth]);
var y=d3.scaleLinear().range([graphHeight,0]);
var z=d3.scaleOrdinal(d3.schemeCategory 10);//颜色
var xAxis=d3.axisBottom().scale(x)、ticks(10);
var yAxis=d3.axisLeft().scale(y)、ticks(10);
//需要为每个数据位手动创建行
var line=d3.line()
.x(功能(d){
返回x(d.日期);
})
.y(功能(d){
返回y(d.y);
});
//在dom上的div内创建SVG区域
//就这么一次
var svg=d3。选择(#graphDiv)
.append(“svg”)
.attr(“宽度”,svgWidth)
.attr(“高度”,svgHeight)
var g=svg.append(“g”)
.attr(“转换”,
“翻译(“+margin.left+”,“+margin.top+”)
.call(d3.zoom().on(“zoom”,function()){
attr(“transform”,d3.event.transform)
}));
//添加X轴
g、 附加(“g”).attr(“类”、“x轴”)
.attr(“转换”、“转换(0,+graphHeight+)”)
.呼叫(xAxis);
//x轴的文本标签
g、 附加(“文本”)
.style(“文本锚定”、“中间”)
.text(“时间序列日期”)
.attr(“transform”、“translate”(+(graphWidth/2)+)、“+(graphHeight+margin.top)+”);
//添加Y轴
g、 附加(“g”)
.attr(“类”、“y轴”)
.呼叫(yAxis);
//y轴的文本标签
g、 附加(“文本”)
.attr(“变换”、“旋转(-90)”)
.attr(“y”,0-页边距。左)
.attr(“x”,0-(图形高度/2))
.attr(“dy”、“1em”)
.style(“文本锚定”、“中间”)
.文本(“价格点”);
函数绘图图(数据集){
让pathData=[]
//假设有两条路径
pathData.push([])
pathData.push([])
//在这里传递数据
数据集forEach(函数(d){
设path0={}
设path1={}
path0.date=parseDate(d.date)
path1.date=parseDate(d.date)
路径0.y=+d.Raw
路径1.y=+d.Raw2
路径数据[0]。推送(路径0)
路径数据[1]。推送(路径1)
});
x、 域(d3.范围(数据集,函数(d)){
返回日期(d.Date);
}));
y、 领域([
d3.min(数据集,功能(d){
返回Math.min(d.Raw,d.Raw2)
}),
d3.最大值(数据集,功能(d){
返回Math.max(d.Raw,d.Raw2)
})
]);
变量行=g.selectAll(“.path”)
.data(路径数据)
lines.exit().remove()
var enter=lines.enter()
.append(“路径”)
.attr(“类”、“路径”)
.style(“笔划”,(d,i)=>z(i))
var merge=enter.merge(行)
.attr(“d”,行)
}
//显示初始图表
window.onload=drawGraph(数据集)
//针对特定日期,每5秒推送一次新数据
var h=setInterval(函数(){
数据推送({
“日期”:“2009-03-29”,
“Raw”:Math.floor(Math.random()*50),
“Raw2”:Math.floor(Math.random()*25),
“资产”:“A”
}, {
‘日期’:‘2009-03-30’,
“Raw”:Math.floor(Math.random()*50),
“Raw2”:Math.floor(Math.random()*25),
“资产”:“A”
}, {
‘日期’:‘2009-03-31’,
“Raw”:Math.floor(Math.random()*50),
“Raw2”:Math.floor(Math.random()*25),
“资产”:“A”
}, {
“日期”:“2009-04-01”,
“Raw”:Math.floor(Math.random()*50),
“Raw2”:Math.floor(Math.random()*25),
“资产”:“A”
}, {
“日期”:“2009-04-02”,
“Raw”:Math.floor(Math.random()*50),
“Raw2”:Math.floor(Math.random()*25),
“资产”:“A”
}, {
“日期”:“2009-04-03”,
“Raw”:Math.floor(Math.random()*50),
“Raw2”:Math.floor(Math.random()*25),
“资产”:“A”
});
绘图(数据集);
}, 5000);
```

您的代码中有几个问题:

  • 你没有更新你的轴。因此,x轴显示的日期是2000年1月,而不是2009年3月/4月。要解决此问题,您必须将
    drawGraph
    函数中的轴更新为:

    svg.selectAll('.x.axis').call(xAxis);
    svg.selectAll('.y.axis').call(yAxis);
    
  • 使用
    setInterval
    的测试会在循环的第一次迭代后反复发送相同日期的数据。因此,您的
    数据集
    将相同日期的数据传递到
    路径数据
    。要解决此问题,最好将测试构建为:

    let newdata = [{
      'Date': '2009-03-29',
      'Raw': Math.floor(Math.random() * 50),
      'Raw2': Math.floor(Math.random() * 25),
      'Asset': 'A'
    }, {
      'Date': '2009-03-30',
      'Raw': Math.floor(Math.random() * 50),
      'Raw2': Math.floor(Math.random() * 25),
      'Asset': 'A'
    }, {
      'Date': '2009-03-31',
      'Raw': Math.floor(Math.random() * 50),
      'Raw2': Math.floor(Math.random() * 25),
      'Asset': 'A'
    }, {
      'Date': '2009-04-01',
      'Raw': Math.floor(Math.random() * 50),
      'Raw2': Math.floor(Math.random() * 25),
      'Asset': 'A'
    }, {
      'Date': '2009-04-02',
      'Raw': Math.floor(Math.random() * 50),
      'Raw2': Math.floor(Math.random() * 25),
      'Asset': 'A'
    }, {
      'Date': '2009-04-03',
      'Raw': Math.floor(Math.random() * 50),
      'Raw2': Math.floor(Math.random() * 25),
      'Asset': 'A'
    }
    ]
    
    let counter = 0;
    // Push new data every 5 seconds for a specific date
    var h = setInterval(function () {
      if (counter < newdata.length) { // this limits the steps to only the length of the newdata
       data_set.push(newdata[counter]);
       counter++;
       drawGraph(data_set);
      }
    }, 3000);
    
    。注意:在本例中,
    newdata
    的末尾还包含了一些更多的ol数据
        // Push new data every 5 seconds for a specific date
        var h = setInterval(function () {
          //obtain the index from the data_set for the same date
          let index = data_set.findIndex((f) => f.Date === newdata[counter].Date);
          if (index === -1) { // if data with same date not found push the new data
            data_set.push(newdata[counter]);
          } else { //else if it is found replace the old data
            data_set[index] = newdata[counter];
          }
          counter++;
          drawGraph(data_set);
        }, 3000);