-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathindex.html
More file actions
197 lines (167 loc) · 4.98 KB
/
Copy pathindex.html
File metadata and controls
197 lines (167 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<!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: 12px;
font-weight: bold;
text-anchor: middle;
}
.axis .title {
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: green;
}
.well {
padding-top: 0px;
padding-bottom: 0px;
}
</style>
<body>
<div style="max-width: 900px; max-height: 400px; padding: 10px">
<div class="well">
<h4>D3 Based Real Time Chart with Multiple Data Streams
</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="viewDiv"></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';
// create the real time chart
var chart = realTimeChartMulti()
.title("Chart Title")
.yTitle("Categories")
.xTitle("Time")
.yDomain(["Category1"]) // initial y domain (note array)
.border(true)
.width(900)
.height(350);
// invoke the chart
var chartDiv = d3.select("#viewDiv").append("div")
.attr("id", "chartDiv")
.call(chart);
// alternative and equivalent invocation
//chart(chartDiv);
// event handler for debug checkbox
d3.select("#debug").on("change", function() {
var state = d3.select(this).property("checked")
chart.debug(state);
})
// event handler for halt checkbox
d3.select("#halt").on("change", function() {
var state = d3.select(this).property("checked")
chart.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() {
// add categories dynamically
d++;
switch (d) {
case 5:
chart.yDomain(["Category1", "Category2"]);
break;
case 10:
chart.yDomain(["Category1", "Category2", "Category3"]);
break;
default:
}
// output a sample for each category, each interval (five seconds)
chart.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;
var doSimple = false;
if (doSimple) {
obj = {
// simple data item (simple black circle of constant size)
time: now,
color: "black",
opacity: 1,
category: "Category" + (i + 1),
type: "circle",
size: 5,
};
} else {
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: "Category" + (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
chart.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>