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

问题描述 投票:1回答:1

我正在尝试使用JSON数据构建折线图。总价格随时间变化的图表。使用stock.json中提供的历史价格,需要计算每个日期的历史金额。我已经尝试了,但我无法特别为这种JSON格式做到这一点。

以下是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 }
                 ]
    }
  }
}

这是d3代码的plnkr

javascript json d3.js
1个回答
2
投票

你是正确的,因为你没有正确解析JSON。您可以在解析JSON数据时阅读this answer以更好地理解。然后努力了解它在D3函数中的工作原理。通常console.log是你的朋友,看你在哪里嵌套,并从那里调整。

图表上有多行 看看这个block builder

关键是将数据映射到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
        };
      })
    };
 });

下一个任务是将正在绘制的元素绑定到数据:

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)});

您可以使用新映射的数据为每个轴设置.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; }); 
  })] 
);

传递股票作为参数 我更新了笔以提供数据,就像您输入股票代码而不是在同一图表上绘制两者一样。

要使其动态化,您可以使用带有提交按钮的用户<input>字段。然后有一个.on('click')函数传递该值并在每次提交时运行d3.json调用

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

在D3调用中,您可以将var设置为等于data.historical[stock];,例如:

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.  

这样,当您调用访问该库存数据的函数时,您可以从该点开始,例如:

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); });

此外,plnkr中的代码中有相当多的缺失,以便“绘制”图表。我不确定你是否还没有到达那里或不确定,但这不在问题的范围内。

一些有用的链接:


初步回应 我认为您没有正确访问JSON属性。例如,你有d3.values(historical),但它应该是d3.values(data.historical)。

此外,d.KALE和d.BRGR不会返回任何内容,您需要d.historical.point.KALEd.historical.point.BRGR来访问每个项目d.historical.point.BRGR.price的日期和价格信息。

你可以做一些'预处理'并映射项目并存储它们,这样你就不必每次都写d.historical.point.KALE了。只是一些初步想法。这周末我会试着深入了解一下。

© www.soinside.com 2019 - 2024. All rights reserved.