DB and D3 connection via php. Unable to complete D3noob's tutorial

At first I want to thank the community a lot for everything I've learnt here. Now I feel like I can't find the answer.

I'm having problems following this guide http://www.d3noob.org/2013/02/using-mysql-database-as-source-of-data.html . I followed step by step (with updated WAMPSERVER version), and got this. I've been struggling and have not found my mistake. Any help would be appreciated.

This is my first question, please feel free to edit, improve, correct, ask. Thank you :)

data2.php file:

<?php
    $username = "homedbuser"; 
    $password = "homedbuser";   
    $host = "localhost";
    $database="homedb";

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

    $myquery = "
SELECT  `date`, `close` FROM  `data2`
";
    $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);
?>

simple-graph.html file:

<!DOCTYPE html>

<style>

</style>
<body>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>
var margin = {top: 30, right: 20, bottom: 30, left: 50},
    width = 600 - margin.left - margin.right,
    height = 270 - margin.top - margin.bottom;

var parseDate = d3.time.format("%d-%b-%y").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").ticks(5);

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

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

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

// Get the data
d3.json("data2.php", function(error, data) {
    data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    });
    // 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; })]);

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

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

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

});
    </script>

</body>

The Firefox inspector thew the following JS error:

NS_ERROR_DOM_BAD_URI: Access to restricted URI denied

I solved it by putting both simple-graph.html and data2.php in the same folder. And in the script that is edited now shows

d3.json("data2.php", function(error, data) 

Instead of what originally showed

 d3.json("php/data2.php", function(error, data) 

The last error I got has knocked me out:

TypeError: data is undefined

It points out line 37 of my script:

 data.forEach(function(d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    });

I am stuck there. Where is/are the mistakes?

Thanks in advance

Upvotes: 2

Views: 1021

Answers (1)

d3noob
d3noob

Reputation: 2151

The error presented Firefox (Access to restricted URI denied) is symptomatic of trying to load cross domain content. This means that (in the case you present here) the browser believed that it was trying to access the file data2.php while that file was registering as being 'out of bounds'. Ths is a security feature for modern browsers as it reasonably expects files that are coming from the same domain (as the current file it is loading) to be trusted and those outside the domain to be potentially harmful (http://en.wikipedia.org/wiki/Same-origin_policy) .

This was nicely confirmed by the test where you ran the same file in Chrome and received the error 'Cross origin requests are only supported for HTTP' in the developer console.

The most likely cause of the problem is that the local web server that you have to support your development environment is mis-configured in some way or that it isn't running.

Edit: PleaseTeachMeHowToDoIt has provided some great feedback in the comments below that assist in explaining why the problem was occurring. While the .html file being displayed was being served by the local web server correctly, the php file that was extracting the data from the MySQL database wasn't. Hence the disparity of errors from the different browsers.

Upvotes: 1

Related Questions