0

I am using a simple d3.js line graph to display data from a MySQL database. It was working fine when I was pulling data from a static CSV, but now that I'm trying to connect it to the database the graph is not displaying correctly.

JS script:

// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;

// Parse the date / time
var parseDate = d3.time.format("%e-%b-%y %H:%M").parse;

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

// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom");

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

// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });

// Adds the svg canvas
var svg = d3.select("#air_temp_chart")
.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 + ")");

// Get the data
d3.csv("php/air_temperature_data.php", function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    }

    var tickValues = data.map(function(d) { return d.date; });

    xAxis
    .tickValues(tickValues)
    .tickFormat(d3.time.format('%H:%M'));

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) { return d.date; }));
    y.domain([0, d3.max(data, function(d) { return d.close; })]);

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

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

    // Add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);

);

});

PHP data file:

$server = mysql_connect($host, $username, $password);
$connection = mysql_select_db($database, $server);

$myquery = "SELECT  `date`, `close` FROM  `readings_air_temperature`";
$query = mysql_query($myquery);

if ( ! $query ) {
    echo mysql_error();
    die;
}

$data = array();

for ($x = 0; $x < mysql_num_rows($query); $x++) {
    $data[] = mysql_fetch_assoc($query);
}

echo json_encode($data);     

mysql_close($server);

?>

PHP output (JSON):

[{"date":"1-May-12 06:00","close":"58.13"},{"date":"1-May-12 06:30","close":"53.98"},{"date":"1-May-12 06:30","close":"88.00"},{"date":"1-May-12 06:30","close":"101.29"}]

The data file seems to be fine but the graph is not loading any data. Instead, the graph just shows the x and y axis without any labels or data.

When I look at the SVG output in Inspector in my browser, this is what I get:

<svg height="270" width="600"><g transform="translate(50,30)"><path class="line"></path><g transform="translate(0,210)" class="x axis"><path d="M0,6V0H530V6" class="domain"></path></g><g class="y axis"><path d="M-6,0H0V210H-6" class="domain"></path></g></g></svg>

Can someone point me to what is wrong?

4
  • Place this on top of your PHP data file. It might do the trick: header('Content-type: application/json'); Commented Apr 8, 2016 at 13:11
  • Thank you for your suggestion. I placed it as the first line but it didnt work :( Commented Apr 8, 2016 at 13:14
  • The live output of the graph can be seen at activetechnologies.us/garden . The graph in question is the "Air Temperature" graph which you will notice is blank. The other graphs are pulling data from csv files Commented Apr 8, 2016 at 13:15
  • Do you see any errors in the console? And where exactly are you decoding the encoded JSON - can you show us that part of your code? Commented Apr 8, 2016 at 14:31

1 Answer 1

1
// Get the data
d3.csv("php/air_temperature_data.php", function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    }
     //... SHOULD BE IN HERE
);

// ALL THIS STUFF...
var tickValues = data.map(function(d) { return d.date; });

xAxis
.tickValues(tickValues)
.tickFormat(d3.time.format('%H:%M'));

// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);

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

It's a sync issue. data will only be returned asynchronously within the d3.csv callback (the function(error,data) bit). The program however calls d3.csv and then continues on as if the data is available immediately. See the comments I added to your code ^^^


Edit2: It's a d3.csv call and we need d3.json as it's json getting returned!

Sign up to request clarification or add additional context in comments.

12 Comments

I updated the code based on your suggestion. The axes populate however the intervals on the axes are not correct based on the data and the line itself is not displaying...
You can see the output of the graph at: activetechnologies.us/garden It is the "Air Temperature" graph
you've included everything in the callback, but a lot of it also within the .each loop. Everything below d.close = +d.close; shouldn't be in the loop. Move it out of that loop, but still in the callback.
in fact, all of it is the each loop, keep it into the callback, but move it out the loop, and move the last 2 svg appends in your code into the callback - they depend on xaxis and yaxis which depend on data so need to be in there
Thank you for the continued help! I updated the code per your instructions (please see my original post) but unfortunately it is still not working. In fact, all graphs are now breaking so there must be an error in the code?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.