7

我正在使用 PHP 来设置创建 Google 折线图的日期范围。对于范围内的每个日期,设置一个变量 ($running_balance) 以使用数据库中的数据在折线图上创建点。我希望能够设置变量 $end,它本质上动态地确定日期范围,但我不确定如何执行此操作,以便根据这个新范围重新绘制图表。我知道我可以创建一个包括drawChart();重绘图表的新函数,我将使用三个按钮将日期范围设置为 1 年、3 个月或 1 个月,但我不确定如何将所有这个一起。这是我目前拥有的代码:

$begin = new DateTime(date('Y-m-d', strtotime('+1 days')));
$end = new DateTime(date('Y-m-d', strtotime('+365 days')));
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($begin, $interval, $end);

foreach ( $period as $dt ) {

$date_display = $dt->format("D j M");

.....  code to generate $running_balance .....

$temp = array();

    $temp[] = array('v' => (string) $date_display); 
    $temp[] = array('v' => (string) $running_balance);
    $temp[] = array('v' => (string) $running_balance);
    $rows[] = array('c' => $temp);
}

$table['rows'] = $rows;
$jsonTable = json_encode($table);

<script type="text/javascript">

    // Load the Visualization API and the piechart package.
    google.load('visualization', '1', {'packages':['corechart']});

    // Set a callback to run when the Google Visualization API is loaded.
    google.setOnLoadCallback(drawChart);

    var table = <?php echo $jsonTable; ?>;

    function drawChart() {
    var data = new google.visualization.DataTable(table);

      // Create our data table out of JSON data loaded from server.
        //  var data = new google.visualization.DataTable(<?=$jsonTable?>);
      var formatter = new google.visualization.NumberFormat({fractionDigits:2,prefix:'\u00A3'});
      formatter.format(data, 1);
      var options = {
          pointSize: 5,
          legend: 'none',
          hAxis: { showTextEvery:31 },
          series: {0:{color:'2E838F',lineWidth:2}},
          chartArea: {left:50,width:"95%",height:"80%"},
          backgroundColor: '#F7FBFC',
          height: 400
        };
      // Instantiate and draw our chart, passing in some options.
      //do not forget to check ur div ID
      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }

</script>
4

1 回答 1

7

好的,如果我对您的理解正确,那么您在构思和设计这些操作的哪些部分是服务器端 (PHP) 以及哪些部分是客户端 (Javascript) 以及客户端-服务器通信策略时遇到了麻烦。这是一个常见的减速带。有几种方法可以处理它。

首先(不太推荐),您可以创建一个表单并使用新的日期范围重新加载整个页面:

// we're looking for '+1 year', '+3 months' or '+1 month'. if someone really
// wants to send another value here, it's not likely to be a security risk
// but know your own application and note that you might want to validate
$range = isset($_GET['range'])&&$_GET['range']?$_GET['range']:'+1 year';

$begin = new DateTime(date('Y-m-d', strtotime('+1 days')));
$end = new DateTime(date('Y-m-d', strtotime($range)));
// ... the rest of your code to build the chart.
?>
<form action="<?= $_SERVER['PHP_SELF']; ?>" method="get">
    <select name="range" size="1">
        <option value="+1 year">1 year</option>
        <option value="+3 months">3 months</option>
        <option value="+1 month">1 month</option>
    </select>
    <input type="submit" name="action" value="Redraw Chart">
</form>

...不太受欢迎的原因是因为它会导致整个页面刷新。

如果你想避免整个页面刷新,你正在做几乎相同的事情,但是用 ajax 来做。设置几乎相同,只有几个小改动:

// between building the data table and the javascript to build the chart...
$jsonTable = json_encode($table);
if (isset($_GET['ajax']) && $_GET['ajax']) {
    echo json_encode(array('table' => $table));
    exit;
}
// remainder of your code, then our new form from above
?>
<form id="redraw_chart_form" action="<?= $_SERVER['PHP_SELF']; ?>" data-ajaxaction="forecast.php" method="get">
    <? foreach ($_GET as $key => $val) { ?>
    <input type="hidden" name="<?= $key; ?>" value="<?= $val; ?>">
    <? } ?>
    <input type="hidden" name="ajax" id="redraw_chart_form_ajax" value="0">
    <select name="range" size="1">
        <option value="+1 year">1 year</option>
        <option value="+3 months">3 months</option>
        <option value="+1 month">1 month</option>
    </select>
    <input type="submit" name="action" value="Redraw Chart">
</form>
<script>
    // I'm assuming you've got jQuery installed, if not there are
    // endless tutorials on running your own ajax query
    $('#redraw_chart_form').submit(function(event) {
        event.preventDefault(); // this stops the form from processing normally
        $('#redraw_chart_form_ajax').val(1);
        $.ajax({
            url: $(this).attr('data-ajaxaction'),
            type: $(this).attr('method'),
            data: $(this).serialize(),
            complete: function() { $('#redraw_chart_form_ajax').val(0); },
            success: function(data) {
                // referring to the global table...
                table = data.table;
                drawChart();
            },
            error: function() {
                // left as an exercise for the reader, if ajax
                // fails, attempt to submit the form normally
                // with a full page refresh.
            }
        });
        return false; // if, for whatever reason, the preventDefault from above didn't prevent form processing, this will
    });
</script>

为清楚起见进行编辑:

  1. 不要忘记使用第一个(页面刷新)示例中的以下代码块,否则您根本没有使用该表单:

    $range = isset($_GET['range'])&&$_GET['range']?$_GET['range']:'+1 year';

    $begin = new DateTime(date('Y-m-d', strtotime('+1 days')));

    $end = new DateTime(date('Y-m-d', strtotime($range)));

  2. Ajax will only work if the only data you're sending back is the json encoded block, which means your chart building data needs to be at the top of the script before any HTML output is started, including your page template. If you can't put the chart building code at the top of the script, then you'll have to add it to a whole separate script that all it does is calculate the data for the chart, and then you can have it return the ajax data without all of the other HTML on the page. If you can't do either of those things, you'll just have to turn off the Ajax bit and do a whole page refresh.


Edit 2: I added the data-ajaxaction attribute to the <form> element, this is a user defined attribute that I made up to provide a different action just for ajax. I also changed the $.ajax() call to use this attribute rather than the action attribute.

于 2013-05-19T13:11:15.583 回答