D3.js notes realtime chart

Posted on 週五 30 九月 2016 in Archive

http://bl.ocks.org/simenbrekken/6634070 https://bl.ocks.org/boeric/6a83de20f780b42fadb9

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <!-- Author: Bo Ericsson -->
  <title>Real Time Chart Multi</title>
  <link rel=stylesheet type=text/css href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" media="all">
  <!--<link rel=stylesheet type=text/css href="../_lib/bootstrap.min.css" media="all">-->
  <style>
  .axis text {
    font: 10px sans-serif;
  }
  .chartTitle {
    font-size: 18px;
    font-weight: bold;
    text-anchor: middle; 
  }
  .axis .title {
    font-size: 18px;
    font-weight: bold;
    text-anchor: middle;
  }
  .axis path,
  .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }
  .x.axis path {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }
  .nav .area {
    fill: lightgrey;
    stroke-width: 0px;
  }
  .nav .line {
    fill: none;
    stroke: darkgrey;
    stroke-width: 1px;
  }
  .viewport {
    stroke: grey;
    fill: black;
    fill-opacity: 0.3;
  }
  .viewport .extent {
    fill: orange;
  }
  .well {
    padding-top: 0px;
    padding-bottom: 0px;
  }
  </style>
<body>

<div style="max-width: 900px; max-height: 400px; padding: 10px">

  <div class="well">
    <h4>Energy Aware Scheduler Performance & Power Consumption
  </div>
  <input id="debug" type="checkbox" name="debug" value="debug" style="margin-bottom: 10px" /> Debug
  <input id="halt" type="checkbox" name="halt" value="halt" style="margin-bottom: 10px" /> Halt

  <div id="viewDiv1"></div>
  <div id="viewDiv2"></div>

</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<!--<script src="../_lib/d3.min.js"></script>-->
<script src="realTimeChartMulti.js"></script>
<script>
'use strict';

var cat1 = ["with EAS"];
var cat2 = ["with EAS", "lagacy"];

// create the real time chart
var chart1 = realTimeChartMulti()
    .title("Performance")
    .yTitle("FPS")
    .xTitle("Time")
    .yDomain(cat1) // initial y domain (note array)
    .border(true)
    .width(900)
    .height(350);

var chart2 = realTimeChartMulti()
    .title("Power Consumption")
    .yTitle("Current(mA)")
    .xTitle("Time")
    .yDomain(cat2) // initial y domain (note array)
    .border(true)
    .width(900)
    .height(350);

// invoke the chart
var chartDiv1 = d3.select("#viewDiv1").append("div")
    .attr("id", "chartDiv1")
    .call(chart1);

    // invoke the chart
var chartDiv2 = d3.select("#viewDiv2").append("div")
    .attr("id", "chartDiv2")
    .call(chart2);

// alternative and equivalent invocation
//chart(chartDiv); 

// event handler for debug checkbox
d3.select("#debug").on("change", function() {
  var state = d3.select(this).property("checked")
  chart1.debug(state);
  chart2.debug(state);
})

// event handler for halt checkbox
d3.select("#halt").on("change", function() {
  var state = d3.select(this).property("checked")
  chart1.halt(state);
  chart2.halt(state);
})


// configure the data generator

// mean and deviation for generation of time intervals
var tX = 5; // time constant, multiple of one second
var meanMs = 1000 * tX, // milliseconds
    dev = 200 * tX; // std dev

// define time scale
var timeScale = d3.scale.linear()
    .domain([300 * tX, 1700 * tX])
    .range([300 * tX, 1700 * tX])
    .clamp(true);

// define function that returns normally distributed random numbers
var normal = d3.random.normal(meanMs, dev);

// define color scale
var color = d3.scale.category10();

// in a normal use case, real time data would arrive through the network or some other mechanism
var d = -1;
var shapes = ["rect", "circle"];
var timeout = 0;

// define data generator
function dataGenerator() {

  setTimeout(function() {

    // output a sample for each category, each interval (five seconds)
    chart1.yDomain().forEach(function(cat, i) {

      // create randomized timestamp for this category data item
      var now = new Date(new Date().getTime() + i * (Math.random() - 0.5) * 1000);

      // create new data item
      var obj = {
        // complex data item; four attributes (type, color, opacity and size) are changing dynamically with each iteration (as an example)
        time: now,
        color: color(d % 10),
        opacity: Math.max(Math.random(), 0.3),
        category: cat1[i+1],
        //type: shapes[Math.round(Math.random() * (shapes.length - 1))], // the module currently doesn't support dynamically changed svg types (need to add key function to data, or method to dynamically replace svg object – tbd)
        type: "circle",
        size: Math.max(Math.round(Math.random() * 12), 4),
      };

      // send the datum to the chart
      chart1.datum(obj);      
    });

    // output a sample for each category, each interval (five seconds)
    chart2.yDomain().forEach(function(cat, i) {

      // create randomized timestamp for this category data item
      var now = new Date(new Date().getTime() + i * (Math.random() - 0.5) * 1000);

      // create new data item
      var obj = {
        // complex data item; four attributes (type, color, opacity and size) are changing dynamically with each iteration (as an example)
        time: now,
        color: color(d % 10),
        opacity: Math.max(Math.random(), 0.3),
        category: cat2[i+1],
        //type: shapes[Math.round(Math.random() * (shapes.length - 1))], // the module currently doesn't support dynamically changed svg types (need to add key function to data, or method to dynamically replace svg object – tbd)
        type: "circle",
        size: Math.max(Math.round(Math.random() * 12), 4),
      };

      // send the datum to the chart
      chart2.datum(obj);      
    });

    // drive data into the chart at average interval of five seconds
    // here, set the timeout to roughly five seconds
    timeout = Math.round(timeScale(normal()));

    // do forever
    dataGenerator();

  }, timeout);
}

// start the data generator
dataGenerator();

</script>