forked from slowe/stuquery
-
Notifications
You must be signed in to change notification settings - Fork 0
/
barchart.html
433 lines (373 loc) · 18 KB
/
barchart.html
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/stuquery.barchart.css">
<script type="text/javascript" src="js/stuquery.js"></script>
<script type="text/javascript" src="js/stuquery.barchart.js"></script>
<script type="text/javascript" src="js/highlight.pack.js"></script>
<script type="text/javascript" src="js/formatexamples.js"></script>
<style>
.hljs { background: #111111; padding: 1em; display:block; overflow-x:auto; margin: 1em auto; background:#111; tab-size: 4; -moz-tab-size: 4; }
.hljs a { color: inherit; }
.hljs, .hljs-subst { color:#000; }
.hljs-name, .hljs-tag { color: #89bdff; }
.hljs-string { color: #65B042; }
.hljs-meta, .hljs-symbol, .hljs-template-tag, .hljs-template-variable, .hljs-addition { color:#0DBC37; }
.hljs-comment, .hljs-quote {color:#aaa; }
.hljs-number, .hljs-built_in { color: #3387CC; }
.hljs-regexp, .hljs-literal, .hljs-bullet, .hljs-link { color:#31a354; }
.hljs-deletion, .hljs-variable { color:#88f; }
.hljs-selector-tag, .hljs-title, .hljs-section, .hljs-doctag, .hljs-type, .hljs-selector-id, .hljs-selector-class, .hljs-strong { color:#2254F4; }
.hljs-keyword { color: #E28964; }
.hljs-emphasis { font-style:italic; }
.hljs-attribute { color:#D73058; }
.hljs-attr { color: #bdb76b; }
</style>
<style>
#barchartbasic,#barchart1,#barchart2,#barchart3,#barchart4,#barchart5,#barchart6,#barchartbasic {
height: 300px;
}
.key ul { list-style: none; margin: 0px; }
.key li { display: inline-block; line-height: 1em;}
.key .item { width: 1em; height: 1em; display: inline-block; top: 0.15em; position: relative; }
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>stuQuery barchart</title>
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@astronomyblog">
<meta name="twitter:url" property="og:url" content="https://slowe.github.io/stuquery/barchart">
<meta name="twitter:title" property="og:title" content="stuQuery Barchart">
<meta name="twitter:description" property="og:description" content="A simple HTML barchart library that makes use of stuQuery">
<meta name="twitter:image" property="og:image" content="https://slowe.github.io/stuquery/images/barchart.png">
<meta name="keywords" content="html,javascript,barchart">
</head>
<body>
<a href="https://github.com/slowe/stuquery" id="forkme_banner">Fork Me on GitHub</a>
<div id="content">
<section id="downloads">
<a href="js/stuquery.barchart.js">stuquery.barchart.js (13.1kB)</a>
<!--<a href="js/stuquery.barchart.min.js">minified (8.6kB)</a>-->
<a href="css/stuquery.barchart.css">css (2.1kB)</a>
</section>
<h1>stuQuery barchart<sup class="version"></sup></h1>
<p>This is a simple HTML barchart library that makes use of <a href="index.html">stuQuery</a>. Being created from simple HTML elements, it is easy to style the barcharts with CSS.</p>
<section class="example">
<h2>Basic example</h2>
<div id="barchartbasic" style="margin-bottom:1em;"></div>
<p>In the head of your page include the Javascript and CSS</p>
<pre class="prettyprint lang-js"><code><link rel="stylesheet" href="stuquery.barchart.css">
<script type="text/javascript" src="stuquery.js"></script>
<script type="text/javascript" src="stuquery.barchart.js"></script>
</code></pre>
<p>In the body include:</p>
<pre class="prettyprint lang-js"><code><div id="barchartbasic" style="margin-bottom:1em;"></div></code></pre>
<div class="example-code">
<script>
// Create your data array where each item is in the form [bin,value]
var data = [[-1.2,2],[-0.4,3],[-0.2,1],[0.2,4],[0.8,2.5],[1.2,2],[1.8,1],[2.2,1]]
// Build the barchart object attached to <div id="barchart">
var chart = new S.barchart('#barchartbasic');
// Set the data
// Set the bins - if no values are provided here, they will be automatically generated
// Draw the chart
chart.setData(data).setBins({'mintick':5}).draw();
</script>
</div>
</section>
<h2>Options</h2>
<p>A chart can be created with any of the following options:</p>
<pre class="prettyprint lang-js">
<code>// Build the barchart object with options set
var chart = new S.barchart('#barchart', {
'units': string, // Display a unit before the bin values
'formatKey': function, // A function that is called to format the key value
'formatBar': function, // A function that is called to add a class to a bar
'parent': node, // A value passed through to events as e.data.parent
'min': number, // The minimum bin value
'max': number, // The maximum bin value
'inc': number, // The numerical size of the bin
'mintick': number, // A minimum number of bins
'bin': function // A function that returns the bin number given an input value
});</code></pre>
<p>The <code>setBins</code> function can take the following options:</p>
<pre class="prettyprint lang-js">
<code>chart.setBins({
'min': number, // The minimum bin value
'max': number, // The maximum bin value
'inc': number, // The numerical size of the bin
'mintick': number, // A minimum number of bins
'update': true // Force a recalculation of the bins
});</code></pre>
<section class="example">
<h2 id="ex1">Example 1</h2>
<p>This chart shows year-based data binned by year and with labels only every decade.</p>
<div class="example-code">
<div id="barchart1" style="margin-bottom:1em;"></div>
<!--<button id="random">Randomise data</button>-->
<button id="year10">10 year bins</button>
<button id="year5">5 year bins</button>
<button id="year2">2 year bins</button>
<button id="year1">1 year bins</button>
<script>
// Create the barchart object attached to the element with id="barchart"
var chart1 = new S.barchart('#barchart1', {
// Only display an x-axis label every decade
'formatKey': function(key){
return (key%10==0 ? key.substr(0,4) : '');
}
});
// Add events
chart1.on('barclick',function(e){
// Get the bin
this.toggleBin(e.bin);
}).on('barover',function(e){
// Remove any existing information balloon
S('.balloon').remove();
// Get the key for this bin
var key = parseInt(this.bins[e.bin].key);
// Add a new information balloon - if the bin size is >1 we show the bin range in the label
S(e.event.currentTarget).find('.bar').append(
'<div class="balloon">'
+ (this.inc > 1 ? key+'&rarr;'+(key+this.inc) : key)
+ ': '+(this.bins[e.bin].value).toFixed(2).replace(/\.?0+$/,"")
+ '</div>');
});
// Remove the information balloon when we leave the chart
S('#barchart1').on('mouseleave',function(e){
S('.balloon').remove();
});
// Define data
var data1 = [[1950,1],[1951,0],[1952,0],[1953,0],[1954,0],[1955,0],[1956,0],[1957,0],[1958,0],[1959,1],[1960,0],[1961,0],[1962,0],[1963,1],[1964,1],[1965,1],[1966,0],[1967,0],[1968,0],[1969,0],[1970,0],[1971,1],[1972,0],[1973,1],[1974,2],[1975,1],[1976,1],[1977,0],[1978,0],[1979,1],[1980,0],[1981,0],[1982,1],[1983,3],[1984,3],[1985,1],[1986,3],[1987,2],[1988,0],[1989,5],[1990,7],[1991,1],[1992,5],[1993,3],[1994,2],[1995,5],[1996,4],[1997,9],[1998,5],[1999,7],[2000,13],[2001,10],[2002,11],[2003,14],[2004,19],[2005,13],[2006,18],[2007,14],[2008,18],[2009,14],[2010,20],[2011,22],[2012,28],[2013,33],[2014,50],[2015,52],[2016,72],[2017,1]];
// Force the bins to be 1 year wide, set the data, and draw the chart
chart1.setData(data1).setBins({'inc':1}).draw();
// Attach events to buttons
S('#year10').on('click',function(){ inc = 10; chart1.setBins({'inc':inc}).draw(); });
S('#year5').on('click',function(){ inc = 5; chart1.setBins({'inc':inc}).draw(); });
S('#year2').on('click',function(){ inc = 2; chart1.setBins({'inc':inc}).draw(); });
S('#year1').on('click',function(){ inc = 1; chart1.setBins({'inc':inc}).draw(); });
</script>
</div>
</section>
<section class="example">
<h2 id="ex2">Example 2</h2>
<p>This chart displays random data with an auto scaling to test negative values. Negative values are given a different bar style.</p>
<p>We'll add some CSS to change the colours of the bars to purple with a pink hover.</p>
<div class="example-code">
<div id="barchart2" style="margin-bottom:1em;"></div>
<button id="random">Randomise data</button>
<style>
#barchart2 .bar { background-color: #722EA5; }
#barchart2 td:hover .bar { background-color: #E6007C; }
#barchart2 td:hover .antibar { background-color: rgba(230,0,124,0.1); }
#barchart2 td.negative .bar {
background-color: #722EA5;
background-image: repeating-linear-gradient(45deg, transparent, transparent 35px, rgba(255,255,255,.5) 35px, rgba(255,255,255,.5) 70px);
}
#barchart2 td.negative:hover .bar { background-color: #E6007C; }
</style>
<script>
// Define some data
var data2 = [[-1.2,2],[-0.4,3],[-0.2,1],[0.2,4],[0.8,2.5],[1.2,2],[1.8,1],[2.2,1]];
// Create the barchart object. We'll add a function to
// customise the class of the bar depending on the key.
var chart2 = new S.barchart('#barchart2',{
formatBar: function(key){
return (key < 0 ? "negative":"");
}
});
// Send the data array and bin size then draw the chart
chart2.setData(data2).setBins({ 'mintick': 5 }).draw();
// Add an event
chart2.on('barover',function(e){
S('.balloon').remove();
S(e.event.currentTarget).find('.bar').append(
"<div class=\"balloon\">"
+(this.bins[e.bin].key
+" → "
+(parseFloat(this.bins[e.bin].key)+this.inc))
+" = "
+(this.bins[e.bin].value).toFixed(2).replace(/\.?0+$/,"")
+"</div>"
);
});
// Remove the information balloon when we leave the chart
S('#barchart2').on('mouseleave',function(e){
S('.balloon').remove();
});
// Add a button press event (id=random) which creates
// some new random data and updates the graph
S('#random').on('click',function(){
var mydata = [];
var maxy = 50;
var maxx = Math.pow(10,Math.random()*5);
var cen = Math.random()*maxx;
var n = 100;
for(var i = 0; i < n; i++) mydata[i] = [(Math.random()*maxx)-cen,1];
// We've created data with different bins so we will force a
// recalculation of the bins before redrawing
chart2.setData(mydata).setBins({'update':true}).draw();
});
</script>
</div>
</section>
<section class="example">
<h2 id="ex3">Example 3</h2>
<p>This chart shows category bins styled with CSS so that the tops of the bars look like water.</p>
<div class="example-code">
<div id="barchart3" style="margin-bottom:1em;"></div>
<script>
// Define the data
var data3 = [["Bradford Beck",0.2],["Lower Beck",0.4],["River Aire",0.5],["Flood alleviation",0.15]];
// Create the barchart object
var chart3 = new S.barchart('#barchart3');
// Add the data and draw the chart
chart3.setData(data3).setBins().draw();
// Display information on hover events
chart3.on('barover',function(e){
S('.balloon').remove();
S(e.event.currentTarget).find('.bar').append(
'<div class="balloon">'
+ (this.bins[e.bin].key)+': '
+ (this.bins[e.bin].value).toFixed(2).replace(/\.?0+$/,"")
+ '</div>'
);
}).on('mouseleave',function(e){
S('.balloon').remove();
});
</script>
<style>
#barchart3 .bar {
background: radial-gradient(circle closest-side, #f9f9fa 13px, rgba(255,255,255,0) 0) 0 -28px,
radial-gradient(circle closest-side, #f9f9fa 13px, rgba(255,255,255,0) 0) 25px -28px #178CFF;
background-size: 50px 50px;
background-repeat:repeat-x;
}
#barchart3 td:hover .bar {
background: radial-gradient(circle closest-side, #dfdfdf 13px, rgba(255,255,255,0) 0) 0 -28px,
radial-gradient(circle closest-side, #dfdfdf 13px, rgba(255,255,255,0) 0) 25px -28px #178CFF;
background-size: 50px 50px;
background-repeat:repeat-x;
}
</style>
</div>
</section>
<section class="example">
<h2 id="ex4">Example 4</h2>
<p>This chart shows monthly bins using categories. Note that the chart doesn't know that these are dates and the order is set by the data array.</p>
<div class="example-code">
<div id="barchart4" style="margin-bottom:1em;"></div>
<script>
// Define the data
var data4 = [["2014-04",1],["2014-05",9],["2014-06",4],["2014-07",10],["2014-08",1],["2014-09",6],["2014-10",9],["2014-11",7],["2014-12",12],["2015-01",13],["2015-02",14],["2015-03",17],["2015-04",20],["2015-05",16],["2015-06",23],["2015-07",14],["2015-08",4],["2015-09",20],["2015-10",15],["2015-11",24],["2015-12",9],["2016-01",16],["2016-02",20],["2016-03",11],["2016-04",16],["2016-05",19],["2016-06",19],["2016-07",21],["2016-08",3],["2016-09",15],["2016-10",17],["2016-11",14],["2016-12",7],["2017-01",8],["2017-02",12],["2017-03",1]];
// Make the chart
var chart4 = new S.barchart('#barchart4',{
// Only show x-axis labels when they are of the form YYYY-01
'formatKey': function(key){
return (key.indexOf('-01') > 0 ? key.substr(0,4) : '');
}
});
// Set the data and draw the chart
chart4.setData(data4).setBins().draw();
// Add events
chart4.on('barover',function(e){
S('.balloon').remove();
var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
S(e.event.currentTarget).find('.bar').append(
'<div class="balloon">'
+months[parseInt(this.bins[e.bin].key.substring(5))-1]
+' '
+this.bins[e.bin].key.substr(0,4)
+': '
+this.bins[e.bin].value
+'</div>'
)
});
// Remove the information balloon
S('#barchart4').on('mouseleave',function(e){
S('.balloon').remove();
});
</script>
</div>
</section>
<section class="example">
<h2 id="ex5">Example 5</h2>
<p>This chart shows time bins with negative values.</p>
<div class="example-code">
<div id="barchart5" style="margin-bottom:1em;"></div>
<script>
// Define the data
var data5 = [["00:00",0],["00:30",0],["01:00",0],["01:30",0],["02:00",0],["02:30",0],["03:00",0],["03:30",0],["04:00",0],["04:30",1.8],["05:00",0.8],["05:30",0.7],["06:00",8.1],["06:30",5.3],["07:00",0.3],["07:30",1.9],["08:00",0.5],["08:30",0.7],["09:00",4.1],["09:30",3.2],["10:00",-1],["10:30",-3],["11:00",-4],["11:30",-2],["12:00",0.3],["12:30",0.9],["13:00",3.3],["13:30",5.7],["14:00",-0.1],["14:30",-1.6],["15:00",-0.6],["15:30",0.9],["16:00",3],["16:30",3.5],["17:00",3.4],["17:30",2.6],["18:00",3.6],["18:30",2],["19:00",0.7],["19:30",0],["20:00",0],["20:30",0.6],["21:00",5.5],["21:30",16],["22:00",13.6],["22:30",2.8],["23:00",0.6],["23:30",0.2],["00:00",0]];
// Create the barchart object
var chart5 = new S.barchart('#barchart5', {
// Only display an x-axis label every decade
'formatKey': function (key) {
keyHours = Number(key.split(":")[0]);
keyMinutes = Number(key.split(":")[1]);
return (keyHours % 4 == 0 && keyMinutes == 0 ? key : '');
},
'formatBar':function(key,val){ return (val < 0 ? "negative":""); }
});
// Add events
chart5.on('barover', function (e) {
// Get the bin
var b = S(e.event.currentTarget).attr('data-index');
// Remove any existing information balloon
S('.balloon').remove();
// Add a new information balloon
S(e.event.currentTarget).find('.bar').append('<div class="balloon">' + this.bins[b].key + ': ' + (this.bins[b].value) + '</div>')
});
// draw the chart
chart5.setData(data5).setBins().draw();
</script>
<style>#barchart5 td.negative .bar { background-color: #F9BC26; }</style>
</div>
</section>
<section class="example">
<h2 id="ex6">Example 6</h2>
<p>This is an example of a stacked bar chart. The key is hardcoded separately.</p>
<div class="example-code">
<div id="barchart6" style="margin-bottom:1em;"></div>
<div id="barchart6-key" class="key">
<ul>
<li><span class="item series-0"></span> Coal</li>
<li><span class="item series-1"></span> Gas</li>
<li><span class="item series-2"></span> Wind</li>
<li><span class="item series-3"></span> Solar</li>
</ul>
</div>
<script>
// Define the data
var data6 = [["Big Gas Co.",[5,100,0,0]],["Friendly Energy Co.",[40,40,15,5]],["Energetique",[30,80,5,5]],["Helios Power",[0,0,0,20]]];
var chart6 = new S.barchart('#barchart6', {
'formatBar':function(key,val,series){ return (typeof series==="number" ? "series-"+series : ""); }
});
// Add events
chart6.on('barover', function (e) {
// Get the bin
var b = S(e.event.currentTarget).attr('data-index');
// Remove any existing information balloon
S('.balloon').remove();
// Add a new information balloon
S(S(e.event.currentTarget).find('.bar')[0]).append('<div class="balloon">' + this.bins[b].key + ': ' + (this.bins[b].value) + ' kWh</div>')
});
// draw the chart
chart6.setData(data6).setBins().draw();
</script>
<style>
#barchart6 .bar .series-0 { background-color: #999999!important; }
#barchart6 .bar .series-1 { background-color: #722EA5!important; }
#barchart6 .bar .series-2 { background-color: #1DD3A7!important; }
#barchart6 .bar .series-3 { background-color: #F9BC26!important; }
</style>
</section>
</div>
<script language="javascript" type="text/javascript" src="js/formatexamples.js"></script>
<script>
makeExamples({"order":["result","how"]});
S(document).ready(function(){
S('.version').html(chart.version());
});
</script>
</body>
</html>