简体   繁体   English

无法使用D3.js显示此JSON结构的折线图?

[英]Unable to display line chart for this JSON structure using D3.js?

I am trying to build a line chart using a JSON data. 我正在尝试使用JSON数据构建折线图。 The graph of the total price over time. 总价随时间变化的图表。 Using the historical prices provided in the stock.json, need to compute the historical amount per date. 使用stock.json中提供的历史价格,需要计算每个日期的历史金额。 I have tried but I am not able to do it for this JSON format in particular. 我已经尝试过,但是我无法对此JSON格式进行特别处理。

Below is the json format 下面是json格式

{
"historical": {
    "KALE": {
        "_id": "KALE",
        "point": [
            { "date": "2015-06-24T00:00:00.000Z", "price": 1043.55 },
            { "date": "2015-06-25T00:00:00.000Z", "price": 1014.75 },
            { "date": "2015-06-26T00:00:00.000Z", "price": 1019.85 },
            { "date": "2015-06-29T00:00:00.000Z", "price": 999.05 },
            { "date": "2015-06-30T00:00:00.000Z", "price": 999.5 }
                 ]
    },

    "BRGR": {
        "_id": "BRGR",
        "point": [
            { "date": "2015-06-24T00:00:00.000Z", "price": 193.47 },
            { "date": "2015-06-25T00:00:00.000Z", "price": 194.06 },
            { "date": "2015-06-26T00:00:00.000Z", "price": 195.06 },
            { "date": "2015-06-29T00:00:00.000Z", "price": 192.92 },
            { "date": "2015-06-30T00:00:00.000Z", "price": 194.76 }
                 ]
    }
  }
}

Here is the plnkr for d3 code 这是D3代码的plnkr

You are correct in that you are not parsing the JSON correctly. 您是正确的,因为您没有正确解析JSON。 You can read this answer on parsing JSON data to get a better understanding. 您可以阅读有关解析JSON数据的答案 ,以获得更好的理解。 And then work to get an understanding of how it works within D3 functions. 然后努力了解它在D3函数中的工作方式。 Often console.log is your friend to see where in the nesting you are and adjust from there. 通常, console.log是您的朋友,可以查看您在嵌套中的位置并从中进行调整。

Multiple lines on chart 图表上的多条线
Take a look at this block builder 看看这个积木建造者

The key was mapping the data to a more accessible format for D3 关键是将数据映射为D3的更易访问的格式

 var stocks = Object.keys(data).map(function(d){ ///map data to better fit our needs
    return {
      name: d,
      values: data[d].point.map(function(d){
        return {
          date: timeFormat(d.date), 
          price: d.price
        };
      })
    };
 });

The next task is to bind the elements being drawn to the data: 下一个任务是将绘制的元素绑定到数据:

var stock = chart.selectAll(".stocks") //This creates a <g> tag as I put circles on the lines. You don't need this if you just want the line
  .data(stocks)
  .enter().append("g")
  .attr("class", "stocks");

var paths = stock.selectAll(".line") //Bind the paths to the data we mapped earlier
  .data(stocks)
  .enter()
  .append("path")
  .attr("class", "line")
  .attr("d", function(d){return line(d.values)});

You can use the newly mapped data to set the .domain() for each axis. 您可以使用新映射的数据为每个轴设置.domain() In this case I updated the x-axis domain: 在这种情况下,我更新了x轴域:

x.domain(
  [d3.min(stocks, function(s){ 
      return d3.min(s.values, function(v){ return v.date; }); 
  }), d3.max(stocks, function(s){ 
      return d3.max(s.values, function(v){ return v.date; }); 
  })] 
);

Passing ticker as argument 将代码作为参数传递
I updated the pen to provide data as if you were entering the stock ticker rather than charting both on the same chart. 我更新了笔,以提供数据,就好像您正在输入股票报价器一样,而不是将两者都绘制在同一张图表上。

To make it dynamic you can have a user <input> field with a submit button. 要使其动态,您可以使用带有提交按钮的用户<input>字段。 Then have a .on('click') function that pass that value and runs the d3.json call each time you submit 然后有一个.on('click')函数,该函数传递该值并在每次提交时运行d3.json调用

$('#submit').on('click', function(){
  let stock = $('#stock-input').val().toUpperCase();
  paths(stock);
})

Within the D3 call you can set a var to equal data.historical[stock]; 在D3调用中,您可以将var设置为等于data.historical[stock]; for example: 例如:

var data = data.historical[stock] //This will now give access to KALE's or whatever other stock's data that was passed as an argument.  

This way when you call a function that access that stocks data you can begin from that point, such as: 这样,当您调用访问库存数据的函数时,您可以从这一点开始,例如:

var line = d3.svg.line()
.x(function(d) { return x(timeFormat.parse(d.date)); }) // Notice we didn't have to use data.historical['stock'].date
.y(function(d) { return y(d.price); });

In addition, there's quite a bit missing from your code in the plnkr in order to 'draw' the chart. 此外,为了“绘制”图表,plnkr中的代码中还缺少很多内容。 I'm not sure if you just haven't gotten there yet or are unsure, but that is outside the scope of the question. 我不确定您是否还没有到达那里或不确定,但这超出了问题的范围。

Some useful links: 一些有用的链接:


Initial Response 初步反应
I don't think you're accessing the JSON properties correctly. 我认为您无法正确访问JSON属性。 For example, you have d3.values(historical) , but it should be d3.values(data.historical ). 例如,您具有d3.values(historical) ,但应为d3.values(data.historical )。

Also, d.KALE and d.BRGR wouldn't return anything, you would need d.historical.point.KALE and d.historical.point.BRGR to access the date and price information for each item d.historical.point.BRGR.price. 另外,d.KALE和d.BRGR不会返回任何内容,您将需要d.historical.point.KALEd.historical.point.BRGR来访问每个项目d.historical.point.BRGR的日期和价格信息。价钱。

you can do some 'pre-processing' and map the items and store them so you don't have to write d.historical.point.KALE ... each time. 您可以进行一些“预处理”并映射项目并存储它们,因此您不必每次都编写d.historical.point.KALE ...。 Just some initial thoughts. 只是一些初步想法。 I'll try and take a deeper look this weekend. 这个周末我会尝试更深入的研究。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM