2016-04-03 2 views
0

Я работаю над графиком, показывающим температуру, дату и время. До сих пор все работает неплохо, но для того, чтобы получить новые значения из моей базы данных MySQL, нужно полностью обновить мою страницу. Я хочу иметь возможность обновлять график без нажатия кнопки «Обновить». Это код:Как обновить график в D3.js при нажатии кнопки?

<?php require($_SERVER['DOCUMENT_ROOT'] . '/assets/php/getTemp.php'); ?> 

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

<head> 
    <title>RPi</title> 
</head> 

<style> 

div.tooltip { 
    position: absolute; 
    text-align: center; 
    width: 120px; 
    height: 28px; 
    padding: 3px; 
    font: 12px sans-serif; 
    background: lightgrey; 
    border: 0px; 
    border-radius: 8px; 
    pointer-events: none; 
} 


body { font: 14px Arial;} 

path { 
    stroke: #FF8C00; 
    stroke-width: 3; 
    fill: none; 
} 

.axis path, 
.axis line { 
    fill: none; 
    stroke: black; 
    stroke-width: 2; 
    shape-rendering: crispEdges; 
} 

.grid .tick { 
    stroke: grey; 
    stroke-opacity: 0.3; 
    shape-rendering: geometricPrecision; 
} 
.grid path { 
      stroke-width: 0; 
} 


</style> 
<body> 


<div id="option"> 
    <input name="updateButton" 
      type="button" 
      value="Update" 
      onclick="updateData()" 
    /> 
</div> 


<!-- load the d3.js library --> 
<script src="http://d3js.org/d3.v3.min.js"></script> 

<script> 


var margin = {top: 30, right: 20, bottom: 30, left: 50}, 
    width = 800 - margin.left - margin.right, 
    height = 270 - margin.top - margin.bottom; 

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

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").ticks(5); 

var valueline = d3.svg.line() 
    .interpolate("basis") 
    .x(function(d) { return x(d.datetime); }) 
    .y(function(d) { return y(d.temperature); }); 

var div = d3.select("body").append("div") 
    .attr("class", "tooltip") 
    .style("opacity", 0); 

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

function make_x_axis() { 
    return d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .ticks(5) 
} 

function make_y_axis() { 
    return d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(5) 
} 

<?php echo "data=".$json_data.";" ?> 
data.forEach(function(d) { 
d.datetime = parseDate(d.datetime); 
d.temperature = +d.temperature; 
}); 

x.domain(d3.extent(data, function(d) { return d.datetime; })); 
y.domain([0, d3.max(data, function(d) { return d.temperature; })]); 


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


svg.selectAll("dot") 
    .data(data) 
.enter().append("circle") 
    .attr("r", 4) 
    .attr("cx", function(d) { return x(d.datetime); }) 
    .attr("cy", function(d) { return y(d.temperature); }) 
    .on("mouseover", function(d) { 
     div.transition() 
      .duration(200) 
      .style("opacity", 1); 
     div.html(formatTime(d.datetime) + "<br/>" + d.temperature + " &#8451") 
      .style("left", (d3.event.pageX + 16) + "px") 
      .style("top", (d3.event.pageY + 16) + "px") 
     .style("position", "absolute"); 
     }) 
    .on("mouseout", function(d) { 
     div.transition() 
      .duration(50) 
      .style("opacity", 0); 
}); 

svg.append("g") 
    .attr("class", "grid") 
    .attr("transform", "translate(0," + height + ")") 
    .call(make_x_axis() 
     .tickSize(-height, 0, 0) 
     .tickFormat("") 
) 

svg.append("g") 
    .attr("class", "grid") 
    .call(make_y_axis() 
     .tickSize(-width, 0, 0) 
     .tickFormat("") 
) 

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> 

Я пытался сделать это:

function updateData() { 

//d3.json("/assets/php/getTemp.php", function(error, data) { 
     <?php echo "data=".$json_data.";" ?> 
     data.forEach(function(d) { 
     d3.select("body").selectAll("svg") 
     d.datetime = parseDate(d.datetime); 
     d.temperature = +d.temperature; 
}); 

x.domain(d3.extent(data, function(d) { return d.datetime; })); 
y.domain([0, d3.max(data, function(d) { return d.temperature; })]); 

var svg = d3.select("body").transition(); 

    svg.select(".line") 
     .duration(750) 
     .attr("d", valueline(data)); 
    svg.select(".x.axis") 
     .duration(750) 
     .call(xAxis); 
    svg.select(".y.axis") 
     .duration(750) 
     .call(yAxis); 
}; 

, но ничего не происходит, даже не ошибка.

Если это имеет значение это код PHP используется для получения температуры и формы времени MySQL:

<?php 
$hostname = 'localhost'; 
$username = 'root'; 
$password = 'admin'; 

try { 
    $dbh = new PDO("mysql:host=$hostname;dbname=temp_database", 
           $username, $password); 


    $sth = $dbh->prepare(" 
     SELECT `datetime`, `temperature` FROM `tempLog` 
    "); 
    $sth->execute(); 


    $result = $sth->fetchAll(PDO::FETCH_ASSOC); 


    $dbh = null; 

} 
catch(PDOException $e) 
    { 
     echo $e->getMessage(); 
    } 

$json_data = json_encode($result); 
?> 

Что мне нужно сделать?

+0

Выглядит прямо мне. Не могли бы вы поместить это в jsfiddle с примером того, какие данные вы используете? – BHouwens

+0

Конечно: https://jsfiddle.net/zzmoL7Le/4/ Я надеюсь, что ссылка в порядке. –

+0

Проблема заключается в том, что вы форматируете данные в функции 'updateData'. Если вы прокомментируете этот раздел, выполните код – BHouwens

ответ

0

Посмотрите на использование функции d3.json. Это позволяет вам запускать json из скриптов php без перезагрузки всей страницы с нуля. Это материал AJAX, но вспомогательные функции d3 скрывают детали.

https://github.com/mbostock/d3/wiki/Requests

PS. Помните, что это будет асинхронный вызов, поэтому увидеть принятый ответ здесь, а также: JSON output from PHP using d3.json


Как, почему он не работает в данный момент, моя догадка *, хотя там не хватает информации, чтобы подтвердить, является что нет никаких изменений, потому что это всегда те же данные, так что ничего не изменится

<?php echo "data=".$json_data.";" ?> 

Эта линия ^^^ в updateData вычисляется один раз в начале, а затем вся функция уронил в яваскрипта области. Однако много раз вы вызываете updateData, что ранее сгенерированная переменная javascript (data={some_json}) не изменится без перезагрузки php-страницы, которая сгенерировала updateData, даже если вы вызываете эту php, связанную с базой данных, которая генерирует переменную на стороне сервера.

* может быть вздор, но бит над линией по-прежнему прав

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