prions prions - 1 year ago 163
Javascript Question

D3 Line with JSON Data, Not Rendering

I have a Flask webserver that takes a dict of Python data and uses the jsonify function to return a JSON object when a GET is called on

. The JSON object is not a nested list (see sample below) like most other examples on here.

I've been attempting to take that JSON data and pass it into my
function, but it appears that something is wrong with the data I'm passing into it. My webpage renders the axes, but no line appears.

Inspecting the elements shows that the x and y axes are populated with my data, (
<path class="domain" d="M0,6V0H890V6"></path>
) but my
<path class="line"></path>
is empty.

I'm running a map function to convert my dates and values into their correct formats and returning them as an array. Running
on this function shows an output of a valid JSON object.

Can anybody help me out with where I'm going wrong here? Should I reformat my jsonified object to be a nested list instead and then populate my data object with

Below is my code and JSON sample:

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

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;


<script src="//"></script>
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - - 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()

var yAxis = d3.svg.axis()

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

var svg ="body")
.attr("width", width + margin.left + margin.right)
.attr("height", height + + margin.bottom)
"translate (" + margin.left + "," + + ")");

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

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

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

.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")

.attr("class", "y axis")



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

Answer Source

Your data is in a strange format for d3ing. d3 prefers arrays of objects where each property of the object represents an x ory. So your data properly formatted should look something like this:

  "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

Further, my guess is that your type function is an attempt at re-formatting the data but you aren't even calling it...

Finally, if you want to just re-format your data with JavaScript, it would look something like this:

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

With that correction, here's your running code and plot.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download