HTMLcopy
1
<div id="container"></div>
CSScopy
6
1
html, body, #container {
2
width: 100%;
3
height: 100%;
4
margin: 0;
5
padding: 0;
6
}
JavaScriptcopy
x
1
anychart.onDocumentReady(function () {
2
// The data used in this sample can be obtained from the CDN
3
// https://cdn.anychart.com/samples/dashboards/cio-dashboard/data.js
4
var SARawData = getSARawData();
5
6
// System Availability accepted values. Columns are: ['System', 'Accepted Availability']
7
var SAAcceptedAvailability = [
8
['Netw', 99],
9
['ERP', 98],
10
['Data Warehouse', 98],
11
['Web Site', 98],
12
['Email', 98],
13
['HR', 96],
14
['Problem Tracking', 93]
15
];
16
17
// CPU Capacity % for today. Columns are: ['DateTime', 'Capacity']
18
var HCCPUData = getHCCPUData();
19
20
// Storage Capacity % for last 12 month. Columns are: ['Month', 'Capacity']
21
var HCStorage = [
22
[Date.UTC(2013, 10), 61.2],
23
[Date.UTC(2013, 11), 64.1],
24
[Date.UTC(2014, 0), 65.8],
25
[Date.UTC(2014, 1), 67.5],
26
[Date.UTC(2014, 2), 69.0],
27
[Date.UTC(2014, 3), 70.3],
28
[Date.UTC(2014, 4), 71.6],
29
[Date.UTC(2014, 5), 71.4],
30
[Date.UTC(2014, 6), 73.0],
31
[Date.UTC(2014, 7), 73.2],
32
[Date.UTC(2014, 8), 73.8],
33
[Date.UTC(2014, 9), 74.6]
34
];
35
36
// Network Capacity % for last 12 month. Columns are: ['Month', 'Capacity']
37
var HCNetwork = [
38
[Date.UTC(2013, 10), 68.8],
39
[Date.UTC(2013, 11), 72.5],
40
[Date.UTC(2014, 0), 74.1],
41
[Date.UTC(2014, 1), 77.7],
42
[Date.UTC(2014, 2), 85.1],
43
[Date.UTC(2014, 3), 83.0],
44
[Date.UTC(2014, 4), 83.9],
45
[Date.UTC(2014, 5), 79.3],
46
[Date.UTC(2014, 6), 81.7],
47
[Date.UTC(2014, 7), 75.9],
48
[Date.UTC(2014, 8), 79.8],
49
[Date.UTC(2014, 9), 82.8]
50
];
51
52
var HCCPURanges = [0, 80, 90, 100];
53
var HCStorageRanges = [0, 60, 80, 100];
54
var HCNetworkRanges = [0, 60, 80, 100];
55
56
// The data used in this sample can be obtained from the CDN
57
// https://cdn.anychart.com/samples/dashboards/cio-dashboard/data.js
58
// Daily Network Traffic for different periods of time. Columns are ['Hour', 'Average Traffic'].
59
// These data are supposed to be pre-calculated by a server or something else.
60
// DNT for last six month.
61
var DNT6MonthAvgData = getDNT6MonthAvgData();
62
var DNTWeekAvgData = getDNTWeekAvgData();
63
var DNTYesterdayData = getDNTYesterdayData();
64
65
// Key Non-System Metrics report data:
66
// Summary expenses YTD. Columns are ['Month', 'Value'].
67
var KNSMExpensesData = [
68
[Date.UTC(2014, 0), 100000],
69
[Date.UTC(2014, 1), 97000],
70
[Date.UTC(2014, 2), 98000],
71
[Date.UTC(2014, 3), 98000],
72
[Date.UTC(2014, 4), 99000],
73
[Date.UTC(2014, 5), 100000],
74
[Date.UTC(2014, 6), 99000],
75
[Date.UTC(2014, 7), 98000],
76
[Date.UTC(2014, 8), 98000],
77
[Date.UTC(2014, 9), 97000]
78
];
79
80
// Customers satisfaction level YTD. Columns are ['Month', 'Satisfaction level'].
81
var KNSMSatisfactionData = [
82
[Date.UTC(2014, 0), 90],
83
[Date.UTC(2014, 1), 97],
84
[Date.UTC(2014, 2), 98],
85
[Date.UTC(2014, 3), 98],
86
[Date.UTC(2014, 4), 99],
87
[Date.UTC(2014, 5), 100],
88
[Date.UTC(2014, 6), 99],
89
[Date.UTC(2014, 7), 98],
90
[Date.UTC(2014, 8), 98],
91
[Date.UTC(2014, 9), 97]
92
];
93
94
// Level 1 Problems numbers YTD. Columns are ['Month', 'Number of Problems'].
95
var KNSMProblemsData = [
96
[Date.UTC(2014, 0), 45],
97
[Date.UTC(2014, 1), 97],
98
[Date.UTC(2014, 2), 95],
99
[Date.UTC(2014, 3), 87],
100
[Date.UTC(2014, 4), 99],
101
[Date.UTC(2014, 5), 78],
102
[Date.UTC(2014, 6), 99],
103
[Date.UTC(2014, 7), 86],
104
[Date.UTC(2014, 8), 98],
105
[Date.UTC(2014, 9), 97]
106
];
107
var KNSMBudgetTarget = 1175000;
108
var KNSMProblemsTarget = 100;
109
var KNSMExpensesRanges = [0, 90, 110, 150];
110
var KNSMSatisfactionRanges = [150, 100, 80, 0];
111
var KNSMProblemsRanges = [0, 90, 110, 150];
112
113
// Some Major Project Milestones for MPM report. Columns are ['Project', 'Milestone', 'Due date']
114
var MPMData = [
115
['ERP Upgrade', 'Full system test', Date.UTC(2014, 9, 24)],
116
['Add services data to DW', 'ETL coding', Date.UTC(2014, 9, 10)],
117
['Upgrade mainframe OS', 'Prepare plan', Date.UTC(2014, 9, 17)],
118
['Disaster recovery site', 'Install hardware', Date.UTC(2014, 9, 20)],
119
['Budgeting system', 'Hire team', Date.UTC(2014, 9, 2)],
120
['Web site face-lift', 'Move into production', Date.UTC(2014, 9, 22)]
121
];
122
123
// Some Projects for TPQ report. Columns are ['Project', 'Status', 'Funding approved', 'Schedule start']
124
var TPQData = [
125
['Professional service module', 'Pending available staff', true, Date.UTC(2014, 9, 22)],
126
['Upgrade MS Office', 'Cost-benefit analysis', false, Date.UTC(2014, 11, 1)],
127
['Failover for ERP', 'Preparing proposal', false, Date.UTC(2015, 0, 30)],
128
['Upgrade data warehouse HW', 'Evaluating options', true, Date.UTC(2015, 1, 13)],
129
['Executive dashboard', 'Vendor assessment', false, Date.UTC(2015, 4, 2)]
130
];
131
132
133
// Utility functions for data ->
134
var Today = new Date(Date.UTC(2014, 9, 15));
135
136
var getDiffInDays = function (date1, date2) {
137
function isLeapYear(year) {
138
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
139
}
140
141
function getNumberOfDaysInMonth(year, month) {
142
switch (month) {
143
case 1:
144
return isLeapYear(year) ? 29 : 28;
145
case 3:
146
case 5:
147
case 8:
148
case 10:
149
return 30;
150
}
151
return 31;
152
}
153
154
function getNumberOfDaysInYear(year) {
155
return isLeapYear(year) ? 366 : 365;
156
}
157
158
var sign = 1;
159
if (date1.getTime() > date2.getTime()) {
160
var tmp = date1;
161
date1 = date2;
162
date2 = tmp;
163
sign = -1;
164
}
165
var y1 = date1.getUTCFullYear();
166
var y2 = date2.getUTCFullYear();
167
var m1 = date1.getUTCMonth();
168
var m2 = date2.getUTCMonth();
169
var d1 = date1.getUTCDate();
170
var d2 = date2.getUTCDate();
171
var result = 0, i;
172
if (y1 < y2) {
173
for (i = y1 + 1; i < y2; i++) result += getNumberOfDaysInYear(i);
174
for (i = m1 + 1; i < 12; i++) result += getNumberOfDaysInMonth(y1, i);
175
for (i = 0; i < m2; i++) result += getNumberOfDaysInMonth(y2, i);
176
result += getNumberOfDaysInMonth(y1, m1) - d1;
177
result += d2;
178
} else if (m1 < m2) {
179
for (i = m1 + 1; i < m2; i++) result += getNumberOfDaysInMonth(y1, i);
180
result += getNumberOfDaysInMonth(y1, m1) - d1;
181
result += d2;
182
} else {
183
result += d2 - d1;
184
}
185
return result * sign;
186
};
187
188
function filterBySystem(fieldValue) {
189
return function (value) {
190
return fieldValue == value;
191
}
192
}
193
194
// Utility functions for data ->
195
196
// Colors to use
197
var title1FontColor = '#e65100';
198
var title2FontColor = '#e65100';
199
var markerColor = '#e65100';
200
201
var infoFontColor = '#212121';
202
var normalFontColor = '#7c868e';
203
204
var chartColor = '#64b5f6';
205
var chartBulletColor = '#1976d2';
206
var borderColor = '#CECECE';
207
var borderLightColor = '#EAEAEA';
208
var range_colors = ['#E6E6E6', '#D6D6D6', '#B8B8B8'];
209
210
// Helpers functions
211
function applyTitleCellSettings(cell, font_size) {
212
if (!font_size) font_size = '14px';
213
cell.fontSize(font_size);
214
cell.fontColor(title2FontColor);
215
}
216
217
function formatDate(value) {
218
var m = value.getMonth() + 1;
219
if (m < 10) m = '0' + m;
220
var d = value.getDate();
221
if (d < 10) d = '0' + d;
222
var y = value.getFullYear() - 2000;
223
return m + '/' + d + '/' + y;
224
}
225
226
function hRect(path, size) {
227
var x = Math.round(size / 2);
228
var y = Math.round(size / 2);
229
var width = size * 0.6;
230
path.clear()
231
.moveTo(x - width / 2, y - 2)
232
.lineTo(x + width / 2, y - 2)
233
.lineTo(x + width / 2, y + 1)
234
.lineTo(x - width / 2, y + 1)
235
.close();
236
}
237
238
function vRect(path, size) {
239
path.clear();
240
var x = Math.round(size / 2);
241
var y = Math.round(size / 2);
242
var height = size * 0.8;
243
path.clear()
244
.moveTo(x - 2, y - height / 2)
245
.lineTo(x - 2, y + height / 2)
246
.lineTo(x + 3, y + height / 2)
247
.lineTo(x + 3, y - height / 2)
248
.close();
249
}
250
251
var getLegend = function (items) {
252
var legend = anychart.standalones.legend();
253
legend.fontSize('11px')
254
.fontFamily("'Verdana', Helvetica, Arial, sans-serif")
255
.itemsLayout('horizontal')
256
.fontColor(normalFontColor)
257
.iconTextSpacing(0)
258
.align('right')
259
.position('center-bottom')
260
.padding(0)
261
.margin(0, 0, 7, 0)
262
.itemsSpacing(3)
263
.title(false)
264
.titleSeparator(false)
265
.paginator(false)
266
.background(false)
267
.items(items);
268
return legend
269
};
270
271
var getBulletChart = function (value, scale, ranges) {
272
var bullet = anychart.bullet([{'value': value, 'type': 'bar', fill: chartBulletColor, 'gap': 0.7}]);
273
bullet.scale(scale)
274
.padding(0, 0, 0, 0)
275
.margin(0);
276
bullet.range(0)
277
.from(ranges[0])
278
.to(ranges[1])
279
.fill(range_colors[0]);
280
bullet.range(1)
281
.from(ranges[1])
282
.to(ranges[2])
283
.fill(range_colors[1]);
284
bullet.range(2)
285
.from(ranges[2])
286
.to(ranges[3])
287
.fill(range_colors[2]);
288
bullet.title(false)
289
.width('100%')
290
.height('100%')
291
.margin('30%', 0, '30%', 0)
292
.axis(false)
293
.background(false);
294
return bullet
295
};
296
297
var getBulletLightChart = function (scale, value, rangeValue) {
298
var bullet = anychart.bullet([{'value': value, 'type': 'line', fill: chartBulletColor, 'gap': 0.4}]);
299
bullet.scale(scale)
300
.padding(0)
301
.margin(0);
302
bullet.range(0)
303
.from(rangeValue)
304
.to(100)
305
.fill(range_colors[1]);
306
bullet.axis(false)
307
.width('100%')
308
.height('100%')
309
.margin('30%', 0, '30%', 0);
310
bullet.background()
311
.enabled(true)
312
.stroke(range_colors[1]);
313
return bullet
314
};
315
316
var getLineChart = function (data, ranges) {
317
var sparkline = anychart.sparkline(data);
318
sparkline.seriesType('line');
319
sparkline.stroke('1.5 ' + chartColor);
320
sparkline.padding(0);
321
if (ranges) {
322
sparkline.rangeMarker(0)
323
.from(ranges[0])
324
.to(ranges[1])
325
.fill(range_colors[1]);
326
}
327
return sparkline;
328
};
329
330
var getBulletScale = function (min, max) {
331
var bulletScale = anychart.scales.linear();
332
bulletScale.minimum(min)
333
.maximum(max);
334
return bulletScale
335
};
336
337
var getBulletAxis = function (min, max) {
338
var axis = anychart.standalones.axes.linear();
339
axis.orientation('bottom')
340
.stroke(borderColor)
341
.title(false);
342
axis.scale(getBulletScale(min, max));
343
axis.ticks().stroke(borderColor);
344
axis.minorTicks(false);
345
axis.labels()
346
.fontSize('9px')
347
.padding(0);
348
return axis
349
};
350
351
var getNoticeMarkersFactory = function (size) {
352
var markersFactory = anychart.standalones.markersFactory();
353
markersFactory.anchor('center')
354
.position('center')
355
.type('circle')
356
.fill(markerColor)
357
.stroke(null)
358
.size(size);
359
return markersFactory
360
};
361
362
function calcSum(view, fieldName) {
363
var sum = 0;
364
var count = 0;
365
var iter = view.getIterator();
366
while (iter.advance()) {
367
count++;
368
sum += iter.get(fieldName);
369
}
370
return sum;
371
}
372
373
function getLastFieldValue(view, fieldName) {
374
var iterator = view.getIterator();
375
if (iterator.select(iterator.getRowsCount() - 1))
376
return iterator.get(fieldName);
377
else
378
return undefined;
379
}
380
381
function calcAvg(view, fieldName) {
382
return calcSum(view, fieldName) / view.getIterator().getRowsCount();
383
}
384
385
function formatNumber(value, opt_decimalDigits) {
386
return value.toFixed(opt_decimalDigits || 2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
387
}
388
389
// Drawing parts of dashboard
390
var systemAvailabilityTable = function (rawData, acceptedAvailabilities) {
391
var table = anychart.standalones.table();
392
table.cellBorder(null).fontColor(normalFontColor);
393
var bulletLegend = getLegend([
394
{
395
'index': 0,
396
'text': 'Actual',
397
'iconType': vRect,
398
'iconStroke': 'none',
399
'iconFill': chartBulletColor
400
},
401
{
402
'index': 1,
403
'text': 'Acceptable',
404
'iconType': vRect,
405
'iconStroke': 'none',
406
'iconFill': range_colors[1]
407
}
408
]);
409
var contents = [
410
['System Availability <span style="color: ' + infoFontColor + '; font-size: 11px;">(last 30 days)</span>', null, null, bulletLegend, null],
411
['Last 12 Month', null, 'System', 'Availability %', null]
412
];
413
414
var rawView = anychart.data.set(rawData).mapAs({'System': 0, 'Availability': 2, 'x': 1, 'value': 2});
415
var bulletScale = getBulletScale(85, 100);
416
417
for (var i = 0; i < acceptedAvailabilities.length; i++) {
418
var system = acceptedAvailabilities[i][0];
419
var availability = acceptedAvailabilities[i][1];
420
var systemData = rawView.filter('System', filterBySystem(system));
421
var avgAvailability = calcAvg(systemData, 'Availability');
422
var line = getLineChart(systemData, false);
423
var marker = null;
424
if (avgAvailability < availability) marker = getNoticeMarkersFactory(5).add(null);
425
var bullet = getBulletLightChart(bulletScale, avgAvailability, availability);
426
contents.push([line, marker, system, bullet, avgAvailability.toFixed(1) + '%']);
427
}
428
contents.push([null, null, null, getBulletAxis(0, 100), null]);
429
table.contents(contents).vAlign('middle').fontSize(11);
430
431
var name_cell = table.getCell(0, 0);
432
name_cell.colSpan(3).useHtml(true);
433
applyTitleCellSettings(name_cell);
434
435
var legend_cell = table.getCell(0, 3);
436
legend_cell.colSpan(2);
437
applyTitleCellSettings(legend_cell);
438
439
table.getRow(0).height(30);
440
table.getRow(1).height(20).fontColor(infoFontColor).cellBorder().bottom('2 ' + borderLightColor);
441
table.getRow(9).height(20);
442
table.getCol(1).width(15).hAlign('center');
443
table.getCol(2).maxWidth(110);
444
table.getCol(4).width(50).hAlign('right');
445
table.getCell(1, 3).colSpan(2).hAlign('right');
446
return table
447
};
448
449
var hardwareOfCapacityTable = function (CPUData, StorageData, NetworkData, CPURanges, StorageRanges, NetworkRanges) {
450
var table = anychart.standalones.table();
451
table.cellBorder(null).fontColor(normalFontColor);
452
var bulletLegend = getLegend([
453
{'index': 0, 'text': 'Actual', 'iconType': hRect, 'iconFill': chartBulletColor},
454
{'index': 1, 'text': 'Good', 'iconType': vRect, 'iconFill': range_colors[0]},
455
{'index': 2, 'text': 'Excessive', 'iconType': vRect, 'iconFill': range_colors[1]},
456
{'index': 3, 'text': 'Critical', 'iconType': vRect, 'iconFill': range_colors[2]}
457
]);
458
var lines = [], bullets = [], averages = [];
459
var bulletScale = getBulletScale(0, 100);
460
bulletScale.ticks().count(3);
461
bulletScale.minorTicks().count(3);
462
463
for (var i = 0; i < 3; i++) {
464
var data = anychart.data.set(arguments[i]).mapAs();
465
var avg = calcAvg(data, 'value');
466
var ranges = arguments[3 + i];
467
lines.push(getLineChart(data, false));
468
bullets.push(getBulletChart(avg, bulletScale, ranges));
469
averages.push(avg.toFixed() + '%');
470
}
471
472
lines[0].xScale(anychart.scales.dateTime().minimumGap(0).maximumGap(0).ticks([]));
473
var contents = [
474
['Hardware % of Capacity', null, null, bulletLegend, null, null],
475
['CPU', 'Today', lines[0], 'Overall', bullets[0], averages[0]],
476
['Storage', 'Last 12 Months', lines[1], 'Today', bullets[1], averages[1]],
477
['Network', 'Last 12 Months', lines[2], 'Today', bullets[2], averages[2]]
478
];
479
480
contents.push([null, null, null, null, getBulletAxis(0, 100), null]);
481
table.contents(contents).vAlign('middle').fontSize(11);
482
table.getRow(0).cellBorder().bottom('2 ' + borderLightColor);
483
484
var name_cell = table.getCell(0, 0);
485
name_cell.colSpan(3);
486
applyTitleCellSettings(name_cell);
487
var legend_cell = table.getCell(0, 3);
488
legend_cell.colSpan(3);
489
applyTitleCellSettings(legend_cell);
490
491
table.getRow(0).height(30).cellPadding(0);
492
table.getRow(4).height(20);
493
table.getCol(3).hAlign('center');
494
table.getCol(0).maxWidth(60);
495
table.getCol(1).maxWidth(100);
496
table.getCol(3).maxWidth(65);
497
table.getCol(5).width(40).hAlign('right');
498
return table
499
};
500
501
var DailyOfNetworkTrafficTable = function (sixMonthsData, weekData, yesterdayData) {
502
var chart = anychart.cartesian();
503
chart.palette([range_colors[1], range_colors[2], chartColor]);
504
chart.padding(0);
505
chart.crosshair().enabled(true).yLabel().enabled(false);
506
chart.crosshair().yStroke(null).xLabel().enabled(false);
507
chart.tooltip().positionMode('point');
508
chart.interactivity().hoverMode('by-x');
509
chart.tooltip().displayMode('union');
510
var setupLine = function (data, name) {
511
var line = chart.line(data);
512
line.name(name);
513
line.markers(false);
514
line.hovered().markers(false);
515
};
516
setupLine(sixMonthsData, 'Daily mean for last 6 month');
517
setupLine(weekData, 'Daily mean for last 7 days');
518
setupLine(yesterdayData, 'Yesterday');
519
520
var xAxisScale = anychart.scales.dateTime();
521
xAxisScale.minimum(Date.UTC(0, 0, 1, 0));
522
xAxisScale.maximum(Date.UTC(0, 0, 2, 0));
523
xAxisScale.ticks().interval(0, 0, 0, 6);
524
xAxisScale.minorTicks().interval(0, 0, 0, 1);
525
526
var bottomAxis = chart.xAxis(0);
527
bottomAxis.scale(xAxisScale).staggerMode(false).overlapMode('allow-overlap');
528
bottomAxis.title(false);
529
bottomAxis.ticks(false);
530
bottomAxis.minorTicks().enabled(false);
531
bottomAxis.minorLabels().enabled(true).fontSize(10).format(function (value) {
532
var date = new Date(value['tickValue']);
533
var h = date.getUTCHours() % 12;
534
return h || 12;
535
});
536
bottomAxis.labels().enabled(true).fontSize(10).format(function (value) {
537
var date = new Date(value['tickValue']);
538
var hour = date.getUTCHours();
539
var h = (hour % 12) || 12;
540
if (hour == 0 && date.getUTCDay() == 1) return h + '\nAM';
541
else if (hour == 12) return h + '\nPM';
542
else return h;
543
});
544
545
var topAxis = chart.xAxis(1);
546
topAxis.orientation('top');
547
topAxis.ticks().enabled(false);
548
topAxis.minorTicks().enabled(false);
549
topAxis.title().enabled(false);
550
topAxis.labels().enabled(false);
551
topAxis.minorLabels().enabled(false);
552
553
chart.yScale().maximumGap(0).minimumGap(0);
554
var leftAxis = chart.yAxis();
555
leftAxis.title().enabled(false);
556
leftAxis.minorTicks().enabled(false);
557
leftAxis.labels().fontSize(10).format(function (value) {
558
return (value['tickValue'] / 1000).toFixed(0) + 'K';
559
});
560
chart.xGrid().scale(xAxisScale);
561
var legend = chart.legend();
562
legend.enabled(true)
563
.fontSize(10)
564
.fontColor(normalFontColor)
565
.tooltip(false)
566
.align('right')
567
.padding(0)
568
.margin(3, 0, 5);
569
legend.paginator().enabled(false);
570
var contents = [
571
['Daily Network Traffic <span style="color: ' + infoFontColor + '; font-size: 11px;">(kilobytes)</span>'],
572
[chart]
573
];
574
var table = anychart.standalones.table();
575
table.cellBorder(null).fontColor(normalFontColor);
576
table.contents(contents);
577
var name_cell = table.getCell(0, 0);
578
name_cell.useHtml(true);
579
applyTitleCellSettings(name_cell);
580
table.getRow(0).height(30).cellPadding(0);
581
table.getRow(0).cellBorder().bottom('2 ' + borderLightColor);
582
return table;
583
};
584
585
var keyNonSystemMetricTable = function () {
586
var table = anychart.standalones.table();
587
table.cellBorder(null).fontColor(normalFontColor);
588
var bulletLegend = getLegend([
589
{'index': 0, 'text': 'Actual', 'iconType': hRect, 'iconFill': chartBulletColor},
590
{'index': 1, 'text': 'Good', 'iconType': vRect, 'iconFill': range_colors[0]},
591
{'index': 2, 'text': 'Excessive', 'iconType': vRect, 'iconFill': range_colors[1]},
592
{'index': 3, 'text': 'Critical', 'iconType': vRect, 'iconFill': range_colors[2]}
593
]);
594
var contents = [
595
['Key Non-System Metrics', null, null, bulletLegend, null],
596
['Year-to-Date', null, 'Metric', '% of Target', 'Actual']
597
];
598
var views = [
599
anychart.data.set(KNSMExpensesData).mapAs(),
600
anychart.data.set(KNSMSatisfactionData).mapAs(),
601
anychart.data.set(KNSMProblemsData).mapAs()
602
];
603
var actualExpenses = calcSum(views[0], 'value');
604
var actualSatisfaction = getLastFieldValue(views[1], 'value');
605
var actualProblems = calcAvg(views[2], 'value');
606
607
var actualValues = [
608
actualExpenses / (KNSMBudgetTarget / KNSMExpensesData.length * 12) * 100,
609
actualSatisfaction,
610
actualProblems
611
];
612
var actualTexts = [
613
'$' + formatNumber(actualExpenses / 1000, 1) + 'K',
614
actualSatisfaction + '/100',
615
actualProblems.toFixed(0)
616
];
617
var rangesForLines = [
618
[0, KNSMBudgetTarget / 12],
619
[KNSMSatisfactionRanges[0], KNSMSatisfactionRanges[1]],
620
[KNSMProblemsRanges[0] / 100 * KNSMProblemsTarget, KNSMProblemsRanges[2] / 100 * KNSMProblemsTarget]
621
];
622
var metrics = [
623
'Expenses YTD',
624
'Customer Satisfaction',
625
'Level 1 Problems'
626
];
627
var ranges_list = [KNSMExpensesRanges, KNSMSatisfactionRanges, KNSMProblemsRanges, KNSMBudgetTarget];
628
for (var i = 0; i < 3; i++) {
629
var ranges = ranges_list[i];
630
var marker = null;
631
if (actualValues[i] > Math.max(ranges[0], ranges[1]) || actualValues[i] < Math.min(ranges[0], ranges[1]))
632
marker = getNoticeMarkersFactory(5).add(null);
633
contents.push([
634
getLineChart(views[i], rangesForLines[i]),
635
marker,
636
metrics[i],
637
getBulletChart(actualValues[i], getBulletScale(0, 150), ranges),
638
actualTexts[i]]);
639
}
640
contents.push([null, null, null, getBulletAxis(0, 150), null]);
641
642
table.contents(contents).vAlign('middle').fontSize(11);
643
644
var name_cell = table.getCell(0, 0);
645
name_cell.colSpan(3);
646
applyTitleCellSettings(name_cell);
647
648
var legend_cell = table.getCell(0, 3);
649
legend_cell.colSpan(2);
650
table.getRow(1).fontColor(infoFontColor).cellBorder().bottom('2 ' + borderLightColor);
651
table.getRow(5).height(20);
652
table.getCol(0).cellPadding(['20%', 0, '20%', 0]);
653
table.getRow(0).height(30).cellPadding(0);
654
table.getRow(1).height(20).cellPadding(0);
655
table.getCol(1).width(20).hAlign('center').cellPadding([0, 0, 0, 5]);
656
table.getCol(2).maxWidth(135);
657
table.getCol(4).width(60).hAlign('right');
658
659
return table
660
};
661
662
var majorProjectMileStonesTable = function () {
663
var table = anychart.standalones.table();
664
table.cellBorder(null).fontColor(normalFontColor).fontSize(11);
665
var contents = [
666
['Major Project Milestones <span style="color: ' + infoFontColor + '; font-size: 11px;">(by priority)</span>', null, null, null],
667
[null, 'Project', 'Milestone', 'Days Until/Past Due', 'Due Date']
668
];
669
var view = anychart.data.set(MPMData).mapAs({'Project': [0], 'Milestone': [1], 'Due': [2]});
670
var iterator = view.getIterator();
671
672
while (iterator.advance()) {
673
var dueDate = new Date(iterator.get('Due'));
674
var diff = getDiffInDays(Today, dueDate);
675
var bullet = anychart.bullet([{
676
'value': diff,
677
'type': 'bar',
678
'gap': 0.4,
679
'fill': ((diff >= 0) ? range_colors[1] : chartBulletColor)
680
}]);
681
682
bullet.scale(getBulletScale(-20, 20)).padding(0).margin(0);
683
bullet.title().enabled(false);
684
bullet.axis().enabled(false);
685
bullet.background().enabled(false);
686
687
var marker;
688
if (diff <= -10)
689
marker = getNoticeMarkersFactory(5).add(null);
690
else
691
marker = null;
692
contents.push([marker, iterator.get('Project'), iterator.get('Milestone'), bullet, formatDate(dueDate)]);
693
}
694
contents.push([null, null, null, getBulletAxis(-20, 20), null]);
695
table.contents(contents);
696
697
var name_cell = table.getCell(0, 0);
698
name_cell.colSpan(5).hAlign('left').useHtml(true);
699
applyTitleCellSettings(name_cell);
700
701
table.getRow(0).height(30);
702
table.getRow(1).height(20).fontColor(infoFontColor).cellBorder().bottom('2 ' + borderLightColor);
703
table.getRow(8).height(20);
704
705
table.getCol(0).width(20);
706
table.getCol(2).maxWidth(140);
707
table.getCol(3).maxWidth(130);
708
table.getCol(4).width(70).hAlign('right');
709
return table
710
};
711
712
var TopProjectInTheQueueTable = function () {
713
var table = anychart.standalones.table(7, 5);
714
table.cellBorder(null).fontColor(normalFontColor).fontSize(11);
715
var contents = [
716
['5 Top Projects in the Queue', null, null, null, null],
717
[null, 'Project', 'Status', 'Approved', 'Sched.Start']
718
];
719
var view = anychart.data.set(TPQData).mapAs({
720
'Project': [0],
721
'Status': [1],
722
'Approved': [2],
723
'Start': [3]
724
});
725
var iterator = view.getIterator();
726
for (var i = 0; iterator.advance(); i++) {
727
contents.push([
728
(i + 1).toString(),
729
iterator.get('Project'),
730
iterator.get('Status'),
731
iterator.get('Approved') ? 'X' : null,
732
formatDate(new Date(iterator.get('Start')))
733
]);
734
}
735
var name_cell = table.getCell(0, 0);
736
name_cell.colSpan(5);
737
applyTitleCellSettings(name_cell);
738
table.getRow(1).height(20).fontColor(infoFontColor).cellBorder().bottom('2 ' + borderLightColor);
739
table.getCol(0).width(20).hAlign('center').cellPadding(0);
740
table.getCol(3).width(85).hAlign('center');
741
table.getCol(4).width(100).hAlign('right');
742
table.getRow(0).height(30).hAlign('left');
743
table.contents(contents);
744
return table;
745
};
746
747
748
// Drawing dashboard
749
var tableMain, leftDataTable, rightDataTable, wideContents, slimContents;
750
751
// Creates left inside layout table
752
var drawLeftDataTable = function () {
753
var table = anychart.standalones.table(3, 1);
754
table.contents([
755
[systemAvailabilityTable(SARawData, SAAcceptedAvailability)],
756
[hardwareOfCapacityTable(HCCPUData, HCStorage, HCNetwork, HCCPURanges, HCNetworkRanges, HCStorageRanges)],
757
[DailyOfNetworkTrafficTable(DNT6MonthAvgData, DNTWeekAvgData, DNTYesterdayData)]
758
]);
759
table.cellBorder(null).fontColor(normalFontColor);
760
table.getRow(0).height('45%');
761
table.getRow(1).height('25%');
762
table.getRow(2).height('30%');
763
return table
764
};
765
766
// Creates right inside layout table
767
var drawRightDataTable = function () {
768
var table = anychart.standalones.table(3, 1);
769
table.contents([
770
[keyNonSystemMetricTable()],
771
[majorProjectMileStonesTable()],
772
[TopProjectInTheQueueTable()]
773
]);
774
table.cellBorder(null).fontColor(normalFontColor);
775
table.getRow(0).height('30%');
776
table.getRow(1).height('37%');
777
table.getRow(2).height('33%');
778
return table
779
};
780
781
// Draws general layout table in stage
782
var drawMainTable = function () {
783
var stage = acgraph.create('container');
784
tableMain = anychart.standalones.table();
785
tableMain.cellBorder(null).fontColor(normalFontColor);
786
tableMain.container(stage);
787
tableMain.bounds(0, 0, '100%', '100%');
788
789
790
tableMain.getCol(0).cellPadding(0, 20, 0, 0);
791
tableMain.getCol(1).cellPadding(0, 0, 0, 20).hAlign('right').fontColor(infoFontColor);
792
tableMain.getRow(0).height(20).vAlign('middle');
793
tableMain.getRow(1).height(30).vAlign('middle').cellBorder().bottom('4 ' + borderLightColor);
794
tableMain.getCell(1, 0).fontColor(title1FontColor).fontSize(16);
795
796
tableMain.container(stage).draw();
797
return tableMain
798
799
};
800
801
// Creates general layout table with two inside layout tables
802
var fillInMainTable = function (flag, leftTable, rightTable) {
803
if (flag == 'wide') {
804
if (!wideContents) {
805
wideContents = [
806
['This sample is based on the dashboard sample in "Information Dashboard Design: Displaying Data for At-a-Glance Monitoring" by Stephen Few', null],
807
['CIO Dashboard', '(As of ' + Today.toLocaleDateString('en-US', {
808
year: 'numeric',
809
month: 'long',
810
day: 'numeric'
811
}) + ')'],
812
[leftTable, rightTable]
813
]
814
}
815
tableMain.contents(wideContents);
816
var copyright_cell = tableMain.getCell(0, 0);
817
copyright_cell.colSpan(2);
818
} else {
819
if (!slimContents) {
820
slimContents = [
821
['This sample is based on the dashboard sample in "Information Dashboard Design: Displaying Data for At-a-Glance Monitoring" by Stephen Few'],
822
['CIO Dashboard (As of ' + Today.toLocaleDateString('en-US', {
823
year: 'numeric',
824
month: 'long',
825
day: 'numeric'
826
}) + ')'],
827
[leftTable],
828
[rightTable]]
829
}
830
tableMain.contents(slimContents);
831
}
832
};
833
834
// Creates general layout tables
835
tableMain = drawMainTable();
836
leftDataTable = drawLeftDataTable();
837
rightDataTable = drawRightDataTable();
838
if (window.innerWidth > 768)
839
fillInMainTable('wide', leftDataTable, rightDataTable);
840
else {
841
fillInMainTable('slim', leftDataTable, rightDataTable);
842
}
843
844
// On resize changing layout to mobile version or conversely
845
window.onresize = function () {
846
if (tableMain.colsCount() == 1 && window.innerWidth > 767) {
847
fillInMainTable('wide', leftDataTable, rightDataTable);
848
} else if (tableMain.colsCount() == 2 && window.innerWidth <= 767) {
849
fillInMainTable('slim', leftDataTable, rightDataTable);
850
}
851
};
852
});