1

D3.js Cubism.js ...漂亮的工作。

我尝试将 Cubism.js 与自己的数据源一起使用,需要同步显示多个水平线图。
更新间隔非常短(< 1s),这就是为什么我需要从数据源批量获取值 - 一次调用。
决定,如果在比较请求的 START,STOP 与存储的 lastSTART,lastSTOP 时加载最新数据。

它在我的代码中工作,但我不知道如何正确调用每个水平图的数据更新 CALLBACK 函数。
显示时仅更新最后一个图形。

有人可以帮我解决这个问题吗?

代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:lang="sk">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <meta charset="utf-8"/>
        <title>DRI_realtimeSeries</title>
        <link type="text/css" rel="stylesheet" href="./style.css"/>
<script src="./d3.v2.js"></script>
<!-- <script src="./d3.js"></script>   problem with d3.CSV !!!! -->
<script src="./cubism.v1.js"></script>
    </head>
<body>
<div id="view"></div>

<script id="JSON" type="text/javascript">//<![CDATA[
var context = cubism.context()
    .serverDelay(1 * 1000) 
    .clientDelay(1 * 1000)
    .step(1000) 
;
var horizon = context.horizon(); 
var metrics = [ "en", "es", "de", "fr"];
var lastStart = null, lastStop = null;
var callArr = {};

var horizon = context.horizon()
    .metric(function(d) { 
        return context.metric(
            function(start, stop, step, callback) {
    callArr[md] = callback;
                if ((+lastStart != +start) || (+lastStop != +stop)) {
                    lastStart = +start; lastStop = +stop;
                  d3.json("http://localhost/COMPONENTS/Cubism/DRI_data.php"
                      + "?expression=" + encodeURIComponent("sum(request.eq(language,'" + md + "'))")   
    + "&list=" + encodeURIComponent(JSON.stringify(metrics))
                      + "&start=" + d3.time.format.iso(start)       //cubism_cubeFormatDate(start)
                      + "&stop=" + d3.time.format.iso(stop)     //cubism_cubeFormatDate(stop)
                      + "&step=" + step, 
                      function(data) {
{"en":[ {"time":"2012-10-24T14:47:53.000Z","value":-37},
        {"time":"2012-10-24T14:47:54.000Z","value":115},
        {"time":"2012-10-24T14:47:55.000Z","value":100},
        ....
        {"time":"2012-10-24T14:48:00.000Z","value":94}
    ],
 "es":[ {"time":"2012-10-24T14:47:53.000Z","value":32},
        ....
        {"time":"2012-10-24T14:48:00.000Z","value":0}
    ],
 ....
}

                        for (var imd in callArr) {
                            if (callArr.hasOwnProperty(imd)) {
                                var callbackI = callArr[imd];
//HERE is something WRONG
                                if (!data) { return callbackI(new Error("unable to load data")); };
                                callbackI( null, data[imd].map( function(d) { return d.value; } ));
                            }
                        }
                      }
                    );
                }
            }, md=d );
        }
    );

d3.select("body").selectAll(".horizon")
  .data(metrics)
  .enter().append("div")
  .attr("class", "horizon")
  .call(horizon);
//]]></script> 
</body>
</html>

PHP 后端:
仅用于模拟目的 - 返回带有时间戳值的命名数组的 JSON 对象,
可能类似于 Cube.js

<?php
//default:
    $GP = array('list' => '["all"]');
    if (isset($_POST['expression']))    $GP['expression']   =$_POST['expression'];      elseif (isset($_GET['expression'])) $GP['expression']   =$_GET['expression'];
    if (isset($_POST['start']))         $GP['start']        =$_POST['start'];           elseif (isset($_GET['start']))      $GP['start']        =$_GET['start'];
    if (isset($_POST['stop']))          $GP['stop']         =$_POST['stop'];            elseif (isset($_GET['stop']))       $GP['stop']         =$_GET['stop'];
    if (isset($_POST['step']))          $GP['step']         =$_POST['step'];            elseif (isset($_GET['step']))       $GP['step']         =$_GET['step'];
    if (isset($_POST['list']))          $GP['list']         =$_POST['list'];            elseif (isset($_GET['list']))       $GP['list']         =$_GET['list'];

    if ( ! (    isset($GP['expression']) && isset($GP['start']) &&  isset($GP['stop'])  &&  isset($GP['step'])  )   )   {
        exit;
    }
    $iso_format = "%Y-%m-%dT%H:%M:%S.%LZ";
    $start = umktime(strptime($GP['start'], $iso_format));
    $stop  = umktime(strptime($GP['stop' ], $iso_format));
    $step =  $GP['step' ];  //milisecs

    $GP['list'] = json_decode($GP['list']);  if (! $GP['list']) { exit;}
    $cnt = count($GP['list']);
    $larray = array();

    for($i = 0; $i < $cnt; $i++) {
        $rarray = array();
        for ($dt = $start; $dt <= $stop; $dt+= ($step/1000.)) {
            $rarray[] = 
            array(
                "time"=> strftime("%Y-%m-%dT%H:%M:%S",$dt).sprintf(".%03dZ",($dt - (int)$dt)*1000),
                "value"=> rand(-50,150)
            );
        }
        $larray[$GP['list'][$i]] = $rarray;
    }
    echo json_encode($cnt == 1 ? $rarray : $larray);



function umktime($u_tm_arr) {
//int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )
    $mkt = mktime(  $u_tm_arr['tm_hour'],$u_tm_arr['tm_min'],$u_tm_arr['tm_sec'],$u_tm_arr['tm_mon']    + 1,$u_tm_arr['tm_mday'],($u_tm_arr['tm_year']  + 1900) - 2000  );
    $mkt = (float)$mkt;
    if (isset($u_tm_arr['tm_msec'])) {      $mkt += (((float)$u_tm_arr['tm_msec'])/1000) ;  }
    return $mkt;
}

//Windows strptime
function strptime($date, $format) { 
    $masks = array( '%d' => '(?P<d>[0-9]{2})',  '%m' => '(?P<m>[0-9]{2})',  '%Y' => '(?P<Y>[0-9]{4})',  
                    '%H' => '(?P<H>[0-9]{2})',  '%M' => '(?P<M>[0-9]{2})',  '%S' => '(?P<S>[0-9]{2})',      // usw.. 
                    '%L' => '(?P<L>[0-9]{3})',  '%u' => '(?P<u>[0-9]{3})', 
    ); 
    $rexep = "#".strtr(preg_quote($format), $masks)."#";
    if(!preg_match($rexep, $date, $out)) {
      return false; 
    }
    $ret = array(   "tm_sec"  => (int) $out['S'], "tm_min"  => (int) $out['M'], "tm_hour" => (int) $out['H'], 
                    "tm_mday" => (int) $out['d'], "tm_mon"  => $out['m']?$out['m']-1:0,  "tm_year" => $out['Y'] > 1900 ? $out['Y'] - 1900 : 0, 
                    "tm_msec" => (int) (isset($out['u']) ? $out['u'] : (isset($out['L']) ? $out['L'] : 0)     ), 
    ); 
    return $ret; 
  } 
?>
4

0 回答 0