简体   繁体   中英

d3 - How to use values in counter from php script

When you use a counter in an sql query in a php script connecting a database to d3, how do you call that counter to use the values stored in it from d3? For instance I have the query

SELECT `ID_to`, count(*) as counter from `citations` group by `ID_to` ORDER BY counter desc

Now I want to call counter from d3 and use its values to scale my y axis on my scatterplot. It doesnt seem to work when I just use it as if it were a column in the table ie:

var yValue = function(d) { return d.counter;}, // data -> value
yScale = d3.scale.linear().range([height, 0]), // value -> display
yMap = function(d) { return yScale(yValue(d));}, // data -> display
yAxis = d3.svg.axis().scale(yScale).orient("left");

d3.json("connection2.php", function(error, data){
data.forEach(function(d) {
    d['ID_from'] =+d['ID_from']; 
    d['counter'] = +d['counter'];

     console.log(d);
    })      

How do I access these counter values and use them in d3?? Any help is much appreciated I am getting very frustrated with myself going around in circles. The error I'm getting is :

Error: Invalid value for <circle> attribute cy="NaN"

EDIT:: Here is my php script:

<?php
$username = "xxx"; 
$password = "xxx";   
$host = "xxx";
$database="xxx";

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

$myquery = "SELECT `ID_to`, count(*) as `counter` from `citations` group by `ID_to`";

$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);
?>

I have ran it in my browser and it returns correct results.

The reason for your cy="NaN" is that you've not assigned a domain to your scale . While the range is the pixel space of your chart, the domain is the value space (the range of values) in your data. You can use d3.extent , to get the min/max of your dataset:

yScale = d3.scale
  .linear()
  .range([height, 0])
  .domain(
    d3.extent(data, function(d){ return d.counter; })
  );

I suggest you take the time to create a small reproducible example of your problem. I attempted to do that below, but everything works fine.

Also, In this statement d3.json("connection2.php", function(error, data){ , you don't handle the error, are you sure your JSON's returning correctly:

d3.json("connection2.php", function(error, data){
   if (error) throw error;

   console.log(data);

What does that output?


 <!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .dot { stroke: #000; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var margin = { top: 20, right: 20, bottom: 30, left: 40 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var yValue = function(d) { return d.counter; }, // data -> value yScale = d3.scale.linear().range([height, 0]), // value -> display yMap = function(d) { return yScale(yValue(d)); }, // data -> display yAxis = d3.svg.axis().scale(yScale).orient("left"); var xValue = function(d){ return d.ID_from; }, xScale = d3.scale.linear().range([0, width]), // value -> display xMap = function(d) { return xScale(xValue(d)); }, // data -> display xAxis = d3.svg.axis().scale(xScale).orient("bottom"); 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 + ")"); var data = [{ 'ID_from': 1, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 2, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 3, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 4, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 5, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 6, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 7, 'counter': parseInt(Math.random() * 100) }, { 'ID_from': 8, 'counter': parseInt(Math.random() * 100) }]; data.forEach(function(d) { d.ID_from = +d.ID_from; d.counter = +d.counter; }); xScale.domain([d3.min(data, xValue) - 1, d3.max(data, xValue) + 1]); yScale.domain([d3.min(data, yValue) - 1, d3.max(data, yValue) + 1]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text"); svg.selectAll(".dot") .data(data) .enter().append("circle") .attr("class", "dot") .attr("r", 3.5) .attr("cx", xMap) .attr("cy", yMap); </script> 

Actually you are not assigning variable d to any global-scope variabile neither to a member of d3 object. In other words d is deallocated just after your console.log statements at every (forEach) loop iteration and its value get lost.

you should first check your service "connection2.php", we have no idea here, do you make some serialization and what's happen there - maybe you have a problem here. Just debug your service or execute it with "php connec....php" or use echo "<pre>";MY PHP STUFF HERE; echo"</pre>"; in your script and call your URL, to see your output in a browser, are you get any results. echo "<pre>";MY PHP STUFF HERE; echo"</pre>"; in your script and call your URL, to see your output in a browser, are you get any results.

Now you can try to use again your json-client-code, if every think is ok, then try "console.log(d)" before you try to use some keys of hashes. After that you can use console.log(d['SOME_KEY_WORD']) and "typeof" to see you get the write type, before make some math-operation, but at least, without your php-service you can not get a precise answer, just some debug steps and speculations. Cheers.

provide some more information. how do you assign the variable from the database query? if the sql query is called in the connection2.php and its result is assigned to some variable, let's call it $some_array , (like $some_array=$some_db_handler->someQuery(..your query..)) ; then you should write it to the output.

writing output with just echo in php will not help, since i assume the D3.json() that you are calling will expect a json. so do it like echo(json_encode($some_array));

then console.log(data) to verify the data that you have received

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM