2016-09-20 2 views
1

У меня есть веб-сервер Flask, который берет на себя данные Python и использует функцию jsonify для возврата объекта JSON при вызове GET на /data. Объект JSON не является вложенным списком (см. Пример ниже), как и большинство других примеров здесь.D3 Линия с данными JSON, не рендеринг

Я пытаюсь взять данные JSON и передать его в мою функцию d3.svg.line(), но, похоже, что что-то не так с данными, которые я передаю. На моей веб-странице отображаются оси, но строка не отображается.

Осмотр элементов показывает, что оси x и y заполнены моими данными, (<path class="domain" d="M0,6V0H890V6"></path>), но мой <path class="line"></path> пуст.

Я запускаю функцию карты, чтобы преобразовать даты и значения в их правильные форматы и вернуть их в виде массива. Запуск console.log в этой функции показывает вывод действительного объекта JSON.

Может кто-нибудь помочь мне с тем, где я ошибаюсь? Должен ли я переформатировать свой jsonified-объект вместо вложенного списка, а затем заполнить свой объект данных forEach?

Ниже мой код и JSON образец:

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

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> 
<script src="//d3js.org/d3.v3.min.js"></script> 
    <script> 
     var margin = {top: 20, right: 20, bottom: 30, left: 50}, 
     width = 960 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 

     var formatDate = d3.time.format("%Y-%m-%d %H:%M:%S").parse; 

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

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

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

     var valueline = d3.svg.line() 
      .x(function(d) {return x(d.timeStamps); }) 
      .y(function(d) {return y(d.outTemps); }); 

     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 + ")"); 

     d3.json("/data",function(error, data) { 
      function type(d) { 
      d.timeStamps = 
      d.timeStamps.map(function (time) {return formatDate(time) }); 
      d.outTemps = d.outTemps.map(function (temp) {return parseFloat(temp)}); 
     }; 
    x.domain(d3.extent(data, function (d) {return d.timeStamps})); 
    y.domain(d3.extent(data, function(d) { return d.outTemps; })); 


     svg.append("path") 
      .datum(data) 
      .append("path") 
      .attr("class", "line") 
      .attr("d", valueline(data)); 

     svg.append("path") 
      .attr("class", "line") 
      .attr("d", valueline(data)); 

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

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

     }); 



</script> 
</body> 


{ 
    "outTemps": [ 
    "79.7", 
    "79.7", 
    "79.8", 
    ], 
    "timeStamps": [ 
    "2016-09-20 19:15:07", 
    "2016-09-20 19:10:07", 
    "2016-09-20 19:05:11", 
    ] 

ответ

0

Ваши данные в странном формате d3 Инг. d3 предпочитает массивы объектов, где каждое свойство объекта представляет x или y. Так что ваши данные правильно отформатированы должен выглядеть следующим образом:

[{ 
    "timeStamps": "2016-09-20T23:15:07.000Z", 
    "outTemps": 79.7 
}, { 
    "timeStamps": "2016-09-20T23:10:07.000Z", 
    "outTemps": 79.7 
}, { 
    "timeStamps": "2016-09-20T23:05:11.000Z", 
    "outTemps": 79.8 
}] 

Кроме того, я думаю, что ваша type функции является попыткой переформатирования данных, но вы даже не называя его ...

Наконец, если вы хотите просто переформатировать данные с JavaScript, это будет выглядеть примерно так:

data = data.timeStamps.map(function(d, i) { 
    return { 
     timeStamps: formatDate(d), 
     outTemps: parseFloat(data.outTemps[i]) 
    } 
    }); 

с этой коррекции, here's your running code and plot.

+0

Большое спасибо! Является ли мой формат данных неприемлемым вообще, или это было больше в моей обработке? Ваша функция работает отлично, но я верю, что могу переформатировать функцию Flask, чтобы вернуть правильные значения. Кроме того, насколько далекой базой была моя функция type(), и где я должен ее называть (для будущей справки). – prions

+0

Также, почему вы назовете карту на отметках времени, а не outTemps? data = data.timeStamps.map (function (d, i) – prions

+0

@prions, 1.) вы могли бы назвать 'type (data);', это оставило бы данные в ** той же структуре **, но принуждало ' timeStamps' до дат и 'outTemps', чтобы плавать. 2.) IMHO, чище иметь флягу, вернуть данные, правильно отформатированные. 3.) Я мог бы «.map» либо «timeStamps», либо «outTemps», если они были массивами одинаковой длины, это не имело значения. – Mark

Смежные вопросы