- Chart Gallery
- Dashboards
- CIO Dashboard
CIO Dashboard
<html>
<head>
<script src="https://cdn.anychart.com/samples/dashboards/cio-dashboard/data.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-base.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-ui.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-sparkline.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-bullet.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-table.min.js"></script>
<link href="https://cdn.anychart.com/playground-css/dashboards/cio/style.css" type="text/css" rel="stylesheet">
<link href="https://cdn.anychart.com/releases/v8/css/anychart-ui.min.css" type="text/css" rel="stylesheet">
<link href="https://cdn.anychart.com/releases/v8/fonts/css/anychart-font.min.css" type="text/css" rel="stylesheet">
<style type="text/css">
html,
body,
#container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
anychart.onDocumentReady(function () {
// The data used in this sample can be obtained from the CDN
// https://cdn.anychart.com/samples/dashboards/cio-dashboard/data.js
var SARawData = getSARawData();
// System Availability accepted values. Columns are: ['System', 'Accepted Availability']
var SAAcceptedAvailability = [
['Network', 99],
['ERP', 98],
['Data Warehouse', 98],
['Web Site', 98],
['Email', 98],
['HR', 96],
['Problem Tracking', 93]
];
// CPU Capacity % for today. Columns are: ['DateTime', 'Capacity']
var HCCPUData = getHCCPUData();
// Storage Capacity % for last 12 month. Columns are: ['Month', 'Capacity']
var HCStorage = [
[Date.UTC(2013, 10), 61.2],
[Date.UTC(2013, 11), 64.1],
[Date.UTC(2014, 0), 65.8],
[Date.UTC(2014, 1), 67.5],
[Date.UTC(2014, 2), 69.0],
[Date.UTC(2014, 3), 70.3],
[Date.UTC(2014, 4), 71.6],
[Date.UTC(2014, 5), 71.4],
[Date.UTC(2014, 6), 73.0],
[Date.UTC(2014, 7), 73.2],
[Date.UTC(2014, 8), 73.8],
[Date.UTC(2014, 9), 74.6]
];
// Network Capacity % for last 12 month. Columns are: ['Month', 'Capacity']
var HCNetwork = [
[Date.UTC(2013, 10), 68.8],
[Date.UTC(2013, 11), 72.5],
[Date.UTC(2014, 0), 74.1],
[Date.UTC(2014, 1), 77.7],
[Date.UTC(2014, 2), 85.1],
[Date.UTC(2014, 3), 83.0],
[Date.UTC(2014, 4), 83.9],
[Date.UTC(2014, 5), 79.3],
[Date.UTC(2014, 6), 81.7],
[Date.UTC(2014, 7), 75.9],
[Date.UTC(2014, 8), 79.8],
[Date.UTC(2014, 9), 82.8]
];
var HCCPURanges = [0, 80, 90, 100];
var HCStorageRanges = [0, 60, 80, 100];
var HCNetworkRanges = [0, 60, 80, 100];
// The data used in this sample can be obtained from the CDN
// https://cdn.anychart.com/samples/dashboards/cio-dashboard/data.js
// Daily Network Traffic for different periods of time. Columns are ['Hour', 'Average Traffic'].
// These data are supposed to be pre-calculated by a server or something else.
// DNT for last six month.
var DNT6MonthAvgData = getDNT6MonthAvgData();
var DNTWeekAvgData = getDNTWeekAvgData();
var DNTYesterdayData = getDNTYesterdayData();
// Key Non-System Metrics report data:
// Summary expenses YTD. Columns are ['Month', 'Value'].
var KNSMExpensesData = [
[Date.UTC(2014, 0), 100000],
[Date.UTC(2014, 1), 97000],
[Date.UTC(2014, 2), 98000],
[Date.UTC(2014, 3), 98000],
[Date.UTC(2014, 4), 99000],
[Date.UTC(2014, 5), 100000],
[Date.UTC(2014, 6), 99000],
[Date.UTC(2014, 7), 98000],
[Date.UTC(2014, 8), 98000],
[Date.UTC(2014, 9), 97000]
];
// Customers satisfaction level YTD. Columns are ['Month', 'Satisfaction level'].
var KNSMSatisfactionData = [
[Date.UTC(2014, 0), 90],
[Date.UTC(2014, 1), 97],
[Date.UTC(2014, 2), 98],
[Date.UTC(2014, 3), 98],
[Date.UTC(2014, 4), 99],
[Date.UTC(2014, 5), 100],
[Date.UTC(2014, 6), 99],
[Date.UTC(2014, 7), 98],
[Date.UTC(2014, 8), 98],
[Date.UTC(2014, 9), 97]
];
// Level 1 Problems numbers YTD. Columns are ['Month', 'Number of Problems'].
var KNSMProblemsData = [
[Date.UTC(2014, 0), 45],
[Date.UTC(2014, 1), 97],
[Date.UTC(2014, 2), 95],
[Date.UTC(2014, 3), 87],
[Date.UTC(2014, 4), 99],
[Date.UTC(2014, 5), 78],
[Date.UTC(2014, 6), 99],
[Date.UTC(2014, 7), 86],
[Date.UTC(2014, 8), 98],
[Date.UTC(2014, 9), 97]
];
var KNSMBudgetTarget = 1175000;
var KNSMProblemsTarget = 100;
var KNSMExpensesRanges = [0, 90, 110, 150];
var KNSMSatisfactionRanges = [150, 100, 80, 0];
var KNSMProblemsRanges = [0, 90, 110, 150];
// Some Major Project Milestones for MPM report. Columns are ['Project', 'Milestone', 'Due date']
var MPMData = [
['ERP Upgrade', 'Full system test', Date.UTC(2014, 9, 24)],
['Add services data to DW', 'ETL coding', Date.UTC(2014, 9, 10)],
['Upgrade mainframe OS', 'Prepare plan', Date.UTC(2014, 9, 17)],
['Disaster recovery site', 'Install hardware', Date.UTC(2014, 9, 20)],
['Budgeting system', 'Hire team', Date.UTC(2014, 9, 2)],
['Web site face-lift', 'Move into production', Date.UTC(2014, 9, 22)]
];
// Some Projects for TPQ report. Columns are ['Project', 'Status', 'Funding approved', 'Schedule start']
var TPQData = [
[
'Professional service module',
'Pending available staff',
true,
Date.UTC(2014, 9, 22)
],
[
'Upgrade MS Office',
'Cost-benefit analysis',
false,
Date.UTC(2014, 11, 1)
],
[
'Failover for ERP',
'Preparing proposal',
false,
Date.UTC(2015, 0, 30)
],
[
'Upgrade data warehouse HW',
'Evaluating options',
true,
Date.UTC(2015, 1, 13)
],
[
'Executive dashboard',
'Vendor assessment',
false,
Date.UTC(2015, 4, 2)
]
];
// Utility functions for data ->
var Today = new Date(Date.UTC(2014, 9, 15));
var getDiffInDays = function (date1, date2) {
function isLeapYear(year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}
function getNumberOfDaysInMonth(year, month) {
switch (month) {
case 1:
return isLeapYear(year) ? 29 : 28;
case 3:
case 5:
case 8:
case 10:
return 30;
default:
}
return 31;
}
function getNumberOfDaysInYear(year) {
return isLeapYear(year) ? 366 : 365;
}
var sign = 1;
if (date1.getTime() > date2.getTime()) {
var tmp = date1;
date1 = date2;
date2 = tmp;
sign = -1;
}
var y1 = date1.getUTCFullYear();
var y2 = date2.getUTCFullYear();
var m1 = date1.getUTCMonth();
var m2 = date2.getUTCMonth();
var d1 = date1.getUTCDate();
var d2 = date2.getUTCDate();
var result = 0;
var i;
if (y1 < y2) {
for (i = y1 + 1; i < y2; i++) result += getNumberOfDaysInYear(i);
for (i = m1 + 1; i < 12; i++) { result += getNumberOfDaysInMonth(y1, i); }
for (i = 0; i < m2; i++) result += getNumberOfDaysInMonth(y2, i);
result += getNumberOfDaysInMonth(y1, m1) - d1;
result += d2;
} else if (m1 < m2) {
for (i = m1 + 1; i < m2; i++) { result += getNumberOfDaysInMonth(y1, i); }
result += getNumberOfDaysInMonth(y1, m1) - d1;
result += d2;
} else {
result += d2 - d1;
}
return result * sign;
};
function filterBySystem(fieldValue) {
return function (value) {
return fieldValue === value;
};
}
// Utility functions for data ->
// Colors to use
var title1FontColor = '#e65100';
var title2FontColor = '#e65100';
var markerColor = '#e65100';
var infoFontColor = '#212121';
var normalFontColor = '#7c868e';
var chartColor = '#64b5f6';
var chartBulletColor = '#1976d2';
var borderColor = '#CECECE';
var borderLightColor = '#EAEAEA';
var rangeColors = ['#E6E6E6', '#D6D6D6', '#B8B8B8'];
// Helpers functions
function applyTitleCellSettings(cell, fontSize) {
if (!fontSize) fontSize = '14px';
cell.fontSize(fontSize);
cell.fontColor(title2FontColor);
}
function formatDate(value) {
var m = value.getMonth() + 1;
if (m < 10) m = '0' + m;
var d = value.getDate();
if (d < 10) d = '0' + d;
var y = value.getFullYear() - 2000;
return m + '/' + d + '/' + y;
}
function hRect(path, size) {
var x = Math.round(size / 2);
var y = Math.round(size / 2);
var width = size * 0.6;
path
.clear()
.moveTo(x - width / 2, y - 2)
.lineTo(x + width / 2, y - 2)
.lineTo(x + width / 2, y + 1)
.lineTo(x - width / 2, y + 1)
.close();
}
function vRect(path, size) {
path.clear();
var x = Math.round(size / 2);
var y = Math.round(size / 2);
var height = size * 0.8;
path
.clear()
.moveTo(x - 2, y - height / 2)
.lineTo(x - 2, y + height / 2)
.lineTo(x + 3, y + height / 2)
.lineTo(x + 3, y - height / 2)
.close();
}
var getLegend = function (items) {
var legend = anychart.standalones.legend();
legend
.fontSize('11px')
.fontFamily('\'Verdana\', Helvetica, Arial, sans-serif')
.itemsLayout('horizontal')
.fontColor(normalFontColor)
.iconTextSpacing(0)
.align('right')
.position('center-bottom')
.padding(0)
.margin(0, 0, 7, 0)
.itemsSpacing(3)
.title(false)
.titleSeparator(false)
.paginator(false)
.background(false)
.items(items);
return legend;
};
var getBulletChart = function (value, scale, ranges) {
var bullet = anychart.bullet([
{
value: value,
type: 'bar',
fill: chartBulletColor,
gap: 0.7
}
]);
bullet.scale(scale).padding(0, 0, 0, 0).margin(0);
bullet.range(0).from(ranges[0]).to(ranges[1]).fill(rangeColors[0]);
bullet.range(1).from(ranges[1]).to(ranges[2]).fill(rangeColors[1]);
bullet.range(2).from(ranges[2]).to(ranges[3]).fill(rangeColors[2]);
bullet
.title(false)
.width('100%')
.height('100%')
.margin('30%', 0, '30%', 0)
.axis(false)
.background(false);
return bullet;
};
var getBulletLightChart = function (scale, value, rangeValue) {
var bullet = anychart.bullet([
{
value: value,
type: 'line',
fill: chartBulletColor,
gap: 0.4
}
]);
bullet.scale(scale).padding(0).margin(0);
bullet.range(0).from(rangeValue).to(100).fill(rangeColors[1]);
bullet
.axis(false)
.width('100%')
.height('100%')
.margin('30%', 0, '30%', 0);
bullet.background().enabled(true).stroke(rangeColors[1]);
return bullet;
};
var getLineChart = function (data, ranges) {
var sparkline = anychart.sparkline(data);
sparkline.seriesType('line');
sparkline.stroke('1.5 ' + chartColor);
sparkline.padding(0);
if (ranges) {
sparkline
.rangeMarker(0)
.from(ranges[0])
.to(ranges[1])
.fill(rangeColors[1]);
}
return sparkline;
};
var getBulletScale = function (min, max) {
var bulletScale = anychart.scales.linear();
bulletScale.minimum(min).maximum(max);
return bulletScale;
};
var getBulletAxis = function (min, max) {
var axis = anychart.standalones.axes.linear();
axis.orientation('bottom').stroke(borderColor).title(false);
axis.scale(getBulletScale(min, max));
axis.ticks().stroke(borderColor);
axis.minorTicks(false);
axis.labels().fontSize('9px').padding(0);
return axis;
};
var getNoticeMarkersFactory = function (size) {
var markersFactory = anychart.standalones.markersFactory();
markersFactory
.anchor('center')
.position('center')
.type('circle')
.fill(markerColor)
.stroke(null)
.size(size);
return markersFactory;
};
function calcSum(view, fieldName) {
var sum = 0;
var iter = view.getIterator();
while (iter.advance()) {
sum += iter.get(fieldName);
}
return sum;
}
function getLastFieldValue(view, fieldName) {
var iterator = view.getIterator();
if (iterator.select(iterator.getRowsCount() - 1)) { return iterator.get(fieldName); }
return undefined;
}
function calcAvg(view, fieldName) {
return calcSum(view, fieldName) / view.getIterator().getRowsCount();
}
function formatNumber(value, decimalDigits) {
return value
.toFixed(decimalDigits || 2)
.replace(/\d(?=(\d{3})+\.)/g, '$&,');
}
// Drawing parts of dashboard
var systemAvailabilityTable = function (
rawData,
acceptedAvailabilities
) {
var table = anychart.standalones.table();
table.cellBorder(null).fontColor(normalFontColor);
var bulletLegend = getLegend([
{
index: 0,
text: 'Actual',
iconType: vRect,
iconStroke: 'none',
iconFill: chartBulletColor
},
{
index: 1,
text: 'Acceptable',
iconType: vRect,
iconStroke: 'none',
iconFill: rangeColors[1]
}
]);
var contents = [
[
'System Availability <span style="color: ' +
infoFontColor +
'; font-size: 11px;">(last 30 days)</span>',
null,
null,
bulletLegend,
null
],
['Last 12 Month', null, 'System', 'Availability %', null]
];
var rawView = anychart.data.set(rawData).mapAs({
System: 0,
Availability: 2,
x: 1,
value: 2
});
var bulletScale = getBulletScale(85, 100);
for (var i = 0; i < acceptedAvailabilities.length; i++) {
var system = acceptedAvailabilities[i][0];
var availability = acceptedAvailabilities[i][1];
var systemData = rawView.filter('System', filterBySystem(system));
var avgAvailability = calcAvg(systemData, 'Availability');
var line = getLineChart(systemData, false);
var marker = null;
if (avgAvailability < availability) { marker = getNoticeMarkersFactory(5).add(null); }
var bullet = getBulletLightChart(
bulletScale,
avgAvailability,
availability
);
contents.push([
line,
marker,
system,
bullet,
avgAvailability.toFixed(1) + '%'
]);
}
contents.push([null, null, null, getBulletAxis(0, 100), null]);
table.contents(contents).vAlign('middle').fontSize(11);
var nameCell = table.getCell(0, 0);
nameCell.colSpan(3).useHtml(true);
applyTitleCellSettings(nameCell);
var legendCell = table.getCell(0, 3);
legendCell.colSpan(2);
applyTitleCellSettings(legendCell);
table.getRow(0).height(30);
table
.getRow(1)
.height(20)
.fontColor(infoFontColor)
.cellBorder()
.bottom('2 ' + borderLightColor);
table.getRow(9).height(20);
table.getCol(1).width(15).hAlign('center');
table.getCol(2).maxWidth(110);
table.getCol(4).width(50).hAlign('right');
table.getCell(1, 3).colSpan(2).hAlign('right');
return table;
};
var hardwareOfCapacityTable = function () {
var table = anychart.standalones.table();
table.cellBorder(null).fontColor(normalFontColor);
var bulletLegend = getLegend([
{
index: 0,
text: 'Actual',
iconType: hRect,
iconFill: chartBulletColor
},
{
index: 1,
text: 'Good',
iconType: vRect,
iconFill: rangeColors[0]
},
{
index: 2,
text: 'Excessive',
iconType: vRect,
iconFill: rangeColors[1]
},
{
index: 3,
text: 'Critical',
iconType: vRect,
iconFill: rangeColors[2]
}
]);
var lines = [];
var bullets = [];
var averages = [];
var bulletScale = getBulletScale(0, 100);
bulletScale.ticks().count(3);
bulletScale.minorTicks().count(3);
for (var i = 0; i < 3; i++) {
var data = anychart.data.set(arguments[i]).mapAs();
var avg = calcAvg(data, 'value');
var ranges = arguments[3 + i];
lines.push(getLineChart(data, false));
bullets.push(getBulletChart(avg, bulletScale, ranges));
averages.push(avg.toFixed() + '%');
}
lines[0].xScale(
anychart.scales.dateTime().minimumGap(0).maximumGap(0).ticks([])
);
var contents = [
['Hardware % of Capacity', null, null, bulletLegend, null, null],
['CPU', 'Today', lines[0], 'Overall', bullets[0], averages[0]],
[
'Storage',
'Last 12 Months',
lines[1],
'Today',
bullets[1],
averages[1]
],
[
'Network',
'Last 12 Months',
lines[2],
'Today',
bullets[2],
averages[2]
]
];
contents.push([null, null, null, null, getBulletAxis(0, 100), null]);
table.contents(contents).vAlign('middle').fontSize(11);
table
.getRow(0)
.cellBorder()
.bottom('2 ' + borderLightColor);
var nameCell = table.getCell(0, 0);
nameCell.colSpan(3);
applyTitleCellSettings(nameCell);
var legendCell = table.getCell(0, 3);
legendCell.colSpan(3);
applyTitleCellSettings(legendCell);
table.getRow(0).height(30).cellPadding(0);
table.getRow(4).height(20);
table.getCol(3).hAlign('center');
table.getCol(0).maxWidth(60);
table.getCol(1).maxWidth(100);
table.getCol(3).maxWidth(65);
table.getCol(5).width(40).hAlign('right');
return table;
};
var DailyOfNetworkTrafficTable = function (
sixMonthsData,
weekData,
yesterdayData
) {
var chart = anychart.cartesian();
chart.palette([rangeColors[1], rangeColors[2], chartColor]);
chart.padding(0);
chart.crosshair().enabled(true).yLabel().enabled(false);
chart.crosshair().yStroke(null).xLabel().enabled(false);
chart.tooltip().positionMode('point');
chart.interactivity().hoverMode('by-x');
chart.tooltip().displayMode('union');
var setupLine = function (data, name) {
var line = chart.line(data);
line.name(name);
line.markers(false);
line.hovered().markers(false);
};
setupLine(sixMonthsData, 'Daily mean for last 6 month');
setupLine(weekData, 'Daily mean for last 7 days');
setupLine(yesterdayData, 'Yesterday');
var xAxisScale = anychart.scales.dateTime();
xAxisScale.minimum(Date.UTC(0, 0, 1, 0));
xAxisScale.maximum(Date.UTC(0, 0, 2, 0));
xAxisScale.ticks().interval(0, 0, 0, 6);
xAxisScale.minorTicks().interval(0, 0, 0, 1);
var bottomAxis = chart.xAxis(0);
bottomAxis
.scale(xAxisScale)
.staggerMode(false)
.overlapMode('allow-overlap');
bottomAxis.title(false);
bottomAxis.ticks(false);
bottomAxis.minorTicks().enabled(false);
bottomAxis
.minorLabels()
.enabled(true)
.fontSize(10)
.format(function (value) {
var date = new Date(value.tickValue);
var h = date.getUTCHours() % 12;
return h || 12;
});
bottomAxis
.labels()
.enabled(true)
.fontSize(10)
.format(function (value) {
var date = new Date(value.tickValue);
var hour = date.getUTCHours();
var h = hour % 12 || 12;
if (hour === 0 && date.getUTCDay() === 1) return h + '\nAM';
if (hour === 12) return h + '\nPM';
return h;
});
var topAxis = chart.xAxis(1);
topAxis.orientation('top');
topAxis.ticks().enabled(false);
topAxis.minorTicks().enabled(false);
topAxis.title().enabled(false);
topAxis.labels().enabled(false);
topAxis.minorLabels().enabled(false);
chart.yScale().maximumGap(0).minimumGap(0);
var leftAxis = chart.yAxis();
leftAxis.title().enabled(false);
leftAxis.minorTicks().enabled(false);
leftAxis
.labels()
.fontSize(10)
.format(function (value) {
return (value.tickValue / 1000).toFixed(0) + 'K';
});
chart.xGrid().scale(xAxisScale);
var legend = chart.legend();
legend
.enabled(true)
.fontSize(10)
.fontColor(normalFontColor)
.tooltip(false)
.align('right')
.padding(0)
.margin(3, 0, 5);
legend.paginator().enabled(false);
var contents = [
[
'Daily Network Traffic <span style="color: ' +
infoFontColor +
'; font-size: 11px;">(kilobytes)</span>'
],
[chart]
];
var table = anychart.standalones.table();
table.cellBorder(null).fontColor(normalFontColor);
table.contents(contents);
var nameCell = table.getCell(0, 0);
nameCell.useHtml(true);
applyTitleCellSettings(nameCell);
table.getRow(0).height(30).cellPadding(0);
table
.getRow(0)
.cellBorder()
.bottom('2 ' + borderLightColor);
return table;
};
var keyNonSystemMetricTable = function () {
var table = anychart.standalones.table();
table.cellBorder(null).fontColor(normalFontColor);
var bulletLegend = getLegend([
{
index: 0,
text: 'Actual',
iconType: hRect,
iconFill: chartBulletColor
},
{
index: 1,
text: 'Good',
iconType: vRect,
iconFill: rangeColors[0]
},
{
index: 2,
text: 'Excessive',
iconType: vRect,
iconFill: rangeColors[1]
},
{
index: 3,
text: 'Critical',
iconType: vRect,
iconFill: rangeColors[2]
}
]);
var contents = [
['Key Non-System Metrics', null, null, bulletLegend, null],
['Year-to-Date', null, 'Metric', '% of Target', 'Actual']
];
var views = [
anychart.data.set(KNSMExpensesData).mapAs(),
anychart.data.set(KNSMSatisfactionData).mapAs(),
anychart.data.set(KNSMProblemsData).mapAs()
];
var actualExpenses = calcSum(views[0], 'value');
var actualSatisfaction = getLastFieldValue(views[1], 'value');
var actualProblems = calcAvg(views[2], 'value');
var actualValues = [
actualExpenses /
((KNSMBudgetTarget / (KNSMExpensesData.length * 12)) * 100),
actualSatisfaction,
actualProblems
];
var actualTexts = [
'$' + formatNumber(actualExpenses / 1000, 1) + 'K',
actualSatisfaction + '/100',
actualProblems.toFixed(0)
];
var rangesForLines = [
[0, KNSMBudgetTarget / 12],
[KNSMSatisfactionRanges[0], KNSMSatisfactionRanges[1]],
[
KNSMProblemsRanges[0] / (100 * KNSMProblemsTarget),
KNSMProblemsRanges[2] / (100 * KNSMProblemsTarget)
]
];
var metrics = [
'Expenses YTD',
'Customer Satisfaction',
'Level 1 Problems'
];
var rangesList = [
KNSMExpensesRanges,
KNSMSatisfactionRanges,
KNSMProblemsRanges,
KNSMBudgetTarget
];
for (var i = 0; i < 3; i++) {
var ranges = rangesList[i];
var marker = null;
if (
actualValues[i] > Math.max(ranges[0], ranges[1]) ||
actualValues[i] < Math.min(ranges[0], ranges[1])
) { marker = getNoticeMarkersFactory(5).add(null); }
contents.push([
getLineChart(views[i], rangesForLines[i]),
marker,
metrics[i],
getBulletChart(actualValues[i], getBulletScale(0, 150), ranges),
actualTexts[i]
]);
}
contents.push([null, null, null, getBulletAxis(0, 150), null]);
table.contents(contents).vAlign('middle').fontSize(11);
var nameCell = table.getCell(0, 0);
nameCell.colSpan(3);
applyTitleCellSettings(nameCell);
var legendCell = table.getCell(0, 3);
legendCell.colSpan(2);
table
.getRow(1)
.fontColor(infoFontColor)
.cellBorder()
.bottom('2 ' + borderLightColor);
table.getRow(5).height(20);
table.getCol(0).cellPadding(['20%', 0, '20%', 0]);
table.getRow(0).height(30).cellPadding(0);
table.getRow(1).height(20).cellPadding(0);
table.getCol(1).width(20).hAlign('center').cellPadding([0, 0, 0, 5]);
table.getCol(2).maxWidth(135);
table.getCol(4).width(60).hAlign('right');
return table;
};
var majorProjectMileStonesTable = function () {
var table = anychart.standalones.table();
table.cellBorder(null).fontColor(normalFontColor).fontSize(11);
var contents = [
[
'Major Project Milestones <span style="color: ' +
infoFontColor +
'; font-size: 11px;">(by priority)</span>',
null,
null,
null
],
[null, 'Project', 'Milestone', 'Days Until/Past Due', 'Due Date']
];
var view = anychart.data
.set(MPMData)
.mapAs({ Project: [0], Milestone: [1], Due: [2] });
var iterator = view.getIterator();
while (iterator.advance()) {
var dueDate = new Date(iterator.get('Due'));
var diff = getDiffInDays(Today, dueDate);
var bullet = anychart.bullet([
{
value: diff,
type: 'bar',
gap: 0.4,
fill: diff >= 0 ? rangeColors[1] : chartBulletColor
}
]);
bullet.scale(getBulletScale(-20, 20)).padding(0).margin(0);
bullet.title().enabled(false);
bullet.axis().enabled(false);
bullet.background().enabled(false);
var marker;
if (diff <= -10) marker = getNoticeMarkersFactory(5).add(null);
else marker = null;
contents.push([
marker,
iterator.get('Project'),
iterator.get('Milestone'),
bullet,
formatDate(dueDate)
]);
}
contents.push([null, null, null, getBulletAxis(-20, 20), null]);
table.contents(contents);
var nameCell = table.getCell(0, 0);
nameCell.colSpan(5).hAlign('left').useHtml(true);
applyTitleCellSettings(nameCell);
table.getRow(0).height(30);
table
.getRow(1)
.height(20)
.fontColor(infoFontColor)
.cellBorder()
.bottom('2 ' + borderLightColor);
table.getRow(8).height(20);
table.getCol(0).width(20);
table.getCol(2).maxWidth(140);
table.getCol(3).maxWidth(130);
table.getCol(4).width(70).hAlign('right');
return table;
};
var TopProjectInTheQueueTable = function () {
var table = anychart.standalones.table(7, 5);
table.cellBorder(null).fontColor(normalFontColor).fontSize(11);
var contents = [
['5 Top Projects in the Queue', null, null, null, null],
[null, 'Project', 'Status', 'Approved', 'Sched.Start']
];
var view = anychart.data.set(TPQData).mapAs({
Project: [0],
Status: [1],
Approved: [2],
Start: [3]
});
var iterator = view.getIterator();
for (var i = 0; iterator.advance(); i++) {
contents.push([
(i + 1).toString(),
iterator.get('Project'),
iterator.get('Status'),
iterator.get('Approved') ? 'X' : null,
formatDate(new Date(iterator.get('Start')))
]);
}
var nameCell = table.getCell(0, 0);
nameCell.colSpan(5);
applyTitleCellSettings(nameCell);
table
.getRow(1)
.height(20)
.fontColor(infoFontColor)
.cellBorder()
.bottom('2 ' + borderLightColor);
table.getCol(0).width(20).hAlign('center').cellPadding(0);
table.getCol(3).width(85).hAlign('center');
table.getCol(4).width(100).hAlign('right');
table.getRow(0).height(30).hAlign('left');
table.contents(contents);
return table;
};
// Drawing dashboard
var tableMain;
var leftDataTable;
var rightDataTable;
var wideContents;
var slimContents;
// Creates left inside layout table
var drawLeftDataTable = function () {
var table = anychart.standalones.table(3, 1);
table.contents([
[systemAvailabilityTable(SARawData, SAAcceptedAvailability)],
[
hardwareOfCapacityTable(
HCCPUData,
HCStorage,
HCNetwork,
HCCPURanges,
HCNetworkRanges,
HCStorageRanges
)
],
[
DailyOfNetworkTrafficTable(
DNT6MonthAvgData,
DNTWeekAvgData,
DNTYesterdayData
)
]
]);
table.cellBorder(null).fontColor(normalFontColor);
table.getRow(0).height('45%');
table.getRow(1).height('25%');
table.getRow(2).height('30%');
return table;
};
// Creates right inside layout table
var drawRightDataTable = function () {
var table = anychart.standalones.table(3, 1);
table.contents([
[keyNonSystemMetricTable()],
[majorProjectMileStonesTable()],
[TopProjectInTheQueueTable()]
]);
table.cellBorder(null).fontColor(normalFontColor);
table.getRow(0).height('30%');
table.getRow(1).height('37%');
table.getRow(2).height('33%');
return table;
};
// Draws general layout table in stage
var drawMainTable = function () {
var stage = acgraph.create('container');
tableMain = anychart.standalones.table();
tableMain.cellBorder(null).fontColor(normalFontColor);
tableMain.container(stage);
tableMain.bounds(0, 0, '100%', '100%');
tableMain.getCol(0).cellPadding(0, 20, 0, 0);
tableMain
.getCol(1)
.cellPadding(0, 0, 0, 20)
.hAlign('right')
.fontColor(infoFontColor);
tableMain.getRow(0).height(20).vAlign('middle');
tableMain
.getRow(1)
.height(30)
.vAlign('middle')
.cellBorder()
.bottom('4 ' + borderLightColor);
tableMain.getCell(1, 0).fontColor(title1FontColor).fontSize(16);
tableMain.container(stage).draw();
return tableMain;
};
// Creates general layout table with two inside layout tables
var fillInMainTable = function (flag, leftTable, rightTable) {
if (flag === 'wide') {
if (!wideContents) {
wideContents = [
[
'This sample is based on the dashboard sample in "Information Dashboard Design: Displaying Data for At-a-Glance Monitoring" by Stephen Few',
null
],
[
'CIO Dashboard',
'(As of ' +
Today.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
}) +
')'
],
[leftTable, rightTable]
];
}
tableMain.contents(wideContents);
var copyrightCell = tableMain.getCell(0, 0);
copyrightCell.colSpan(2);
} else {
if (!slimContents) {
slimContents = [
[
'This sample is based on the dashboard sample in "Information Dashboard Design: Displaying Data for At-a-Glance Monitoring" by Stephen Few'
],
[
'CIO Dashboard (As of ' +
Today.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
}) +
')'
],
[leftTable],
[rightTable]
];
}
tableMain.contents(slimContents);
}
};
// Creates general layout tables
tableMain = drawMainTable();
leftDataTable = drawLeftDataTable();
rightDataTable = drawRightDataTable();
if (window.innerWidth > 768) { fillInMainTable('wide', leftDataTable, rightDataTable); }
else {
fillInMainTable('slim', leftDataTable, rightDataTable);
}
// On resize changing layout to mobile version or conversely
window.onresize = function () {
if (tableMain.colsCount() === 1 && window.innerWidth > 767) {
fillInMainTable('wide', leftDataTable, rightDataTable);
} else if (tableMain.colsCount() === 2 && window.innerWidth <= 767) {
fillInMainTable('slim', leftDataTable, rightDataTable);
}
};
});
</script>
</body>
</html>
This dashboard and the description are taken from the “Information Dashboard Design. Displaying data for at-a-glance monitoring” by Stephen Few. The sample shows how AnyChart can be used to create complex visualizations, which are usually given as great examples of visualization by experts in datavis.
Here is what Stephen Few says about this dashboard:
A Chief Information Officer (CIO) must monitor many aspects of an organization’s information systems, including projects to implement new systems and update those that exist. My sample CIO dashboard includes information in the following categories:
- System availability (uptime)
- Expenses
- Customer satisfaction
- Severe problem count
- CPU usage relative to capacity
- Storage usage relative to capacity
- Network traffic
- Application response time
- Major project milestones
- Top projects in the queue
- Other critical events
This is a mixture of strategic and frequently updated operational information.
Only one section of this dashboard – the upper-left corner – displays near-real-time data. This section includes five alerts: one for each of the major systems to which the CIO might need to respond immediately when a problem arises. If no red icons could blink until clicked or even emit a sound that gradually increases in volume. The alert icons could also link to other screens that describe precisely what is wrong.
The rest of this dashboard provides the CIO with information that is more strategic in nature. Notice that a great deal of contextual information has been provided to complement the measures – especially comparisons to measures of acceptable performance. This is the kind of context that could help the CIO easily make sense of these measures.
There is a great deal of information on this dashboard, yet it doesn't seem cluttered. This is largely due to the fact that non-data pixels have been reduced to a minimum. For instance, white space alone has been used to separate the various sections of the display. A judicious use of color has also contributed to this effect. Besides gray-scale colors, the only other hues you see are a muted green for the name of each section and two intensities of red, which in every case serves as an alert. It is easy to scan the dashboard and quickly find everything that needs attention, because the red alert objects are unique, visually unlike anything else.
Including information about project milestones, pending projects, and other critical events on this dashboard not only locates all the most important information the CIO needs in one place, but also supports useful comparisons. Being reminded about coming events that might affect existing systems and being able to look immediately at the current performance of those systems could raise useful questions about their readiness.