Built with blockbuilder.org
This chart renders custom stacked row chart to represent bunch of servers, their up time and health level at different intervlas
Built with blockbuilder.org
This chart renders custom stacked row chart to represent bunch of servers, their up time and health level at different intervlas
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
svg { width:100%; height: 100% } | |
text { | |
font: 11px sans-serif; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
ul | |
{ | |
list-style-type: none; | |
} | |
</style> | |
</head> | |
<body> | |
<span><strong>Searver uptime and health</strong></span> | |
<ul> | |
<li><span style="background-color: #84CA50; padding-left: 15px;"></span> - good</li> | |
<li><span style="background-color: #F07D02; padding-left: 15px;"></span> - bad 1</li> | |
<li><span style="background-color: #E60000; padding-left: 15px;"></span> - bad 2</li> | |
<li><span style="background-color: #9E1313; padding-left: 15px;"></span> - bad 3</li> | |
</ul> | |
<script> | |
var chartData = [ | |
{ | |
TenantName: 'server 1', | |
BakeTimes: [ | |
{start: 0, end: 5, level: 0}, | |
{start: 5, end: 10, level: 1}, | |
{start: 10, end: 16, level: 2}, | |
{start: 19, end: 26, level: 4}, // 4 maps to level 3 color, anything grater than 3 = dark red | |
{start: 26, end: 35, level: 0} | |
] | |
}, | |
{ | |
TenantName: 'server 2', | |
BakeTimes: [ | |
{start: 10, end: 15, level: 0}, | |
{start: 15, end: 16, level: 1}, | |
{start: 16, end: 20, level: 2}, | |
{start: 20, end: 23, level: 4}, | |
{start: 23, end: 30, level: 0} | |
] | |
}, | |
{ | |
TenantName: 'server 3', | |
BakeTimes: [ | |
{start: 9, end: 15, level: 0}, | |
{start: 1, end: 6, level: 1}, //start,end not in any particular order | |
{start: 16, end: 20, level: 2}, | |
{start: 20, end: 21, level: 4}, | |
{start: 21, end: 22, level: 1}, | |
{start: 22, end: 33, level: 0} | |
] | |
}, | |
{ | |
TenantName: 'server 4', | |
BakeTimes: [ | |
{start: 2, end: 5, level: 0}, | |
{start: 7, end: 10, level: 1}, | |
{start: 13, end: 20, level: 0}, | |
{start: 20, end: 23, level: 4}, | |
{start: 23, end: 35, level: 0} | |
] | |
}, | |
{ | |
TenantName: 'server 5', | |
BakeTimes: [ | |
{start: 23, end: 35, level: 0} | |
] | |
} | |
]; | |
var maxVal = d3.max(chartData, function(data){ | |
return d3.max(data.BakeTimes, function(d){ | |
return d.end; | |
}); | |
}); | |
//console.log(maxVal); | |
//console.log(maxVal); | |
var id = 'body'; | |
var tenantRowColor = '#84CA50'; | |
var warningLevels = ['#84CA50', '#F07D02', '#E60000','#9E1313']; | |
var margin = { | |
top: 20, | |
right: 20, | |
bottom: 20, | |
left: 20 | |
}; | |
var chartWidth = 500, | |
width = chartWidth - margin.left - margin.right, | |
barHeight = 20, | |
height = ((barHeight * chartData.length)+25) - margin.top - margin.bottom; | |
var leftPadding = 180; | |
var xScale = d3.scale.linear() | |
.domain([0, d3.max(chartData, function(data){ | |
return d3.max(data.BakeTimes, function(d){ | |
return d.end; | |
}); | |
}) | |
]) | |
.range([0, width-(leftPadding+20)]); | |
var yScale = d3.scale.ordinal() | |
// SECOND PARAM IS PADDING | |
.rangeRoundBands([0, (barHeight * chartData.length)], 0) | |
.domain(chartData.map(function (d) { return d.TenantName; })); | |
var chart = d3.select(id).append('svg') | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom+40) | |
.append('g') | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
var lines = chart.append('g').selectAll('g') | |
.data(chartData) | |
.enter() | |
.append('g') | |
.attr("transform", | |
function(d, i) { return "translate(0," + i * barHeight + ")"; }); | |
lines.each(function(d){ | |
d3.select(this).append("line") | |
.attr("x1", leftPadding) | |
.attr("y1", 10) | |
.attr("x2", 300+leftPadding) | |
.attr("y2", 10) | |
.attr("stroke-width", 0.5) | |
.attr("stroke", "black") | |
.attr('stroke-dasharray', '3,3'); | |
}); | |
//render rectangle for each health level as bars | |
var newBar = chart.append('g').selectAll('g') | |
.data(chartData) | |
.enter() | |
.append('g') | |
.attr("transform", | |
function(d, i) { return "translate(0," + i * barHeight + ")"; }); | |
newBar | |
.each(function(d) { | |
var bakeTimes = d.BakeTimes; | |
d3.select(this).selectAll('rect').data(bakeTimes) | |
.enter() | |
.append('rect') | |
.attr('x', function(d) { return xScale(d.start) + leftPadding; }) | |
.attr('width', function(d) { return xScale(d.end) - xScale(d.start);}) | |
.attr('height', barHeight -3) | |
.attr('fill', function(d){ | |
var colorLevel = d.level; | |
if(colorLevel > 3) | |
{ | |
colorLevel = 3; | |
} | |
return warningLevels[colorLevel]; | |
}); | |
}); | |
//axis | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient('bottom') | |
.ticks(5); | |
chart.append('g') | |
.attr('class', 'x axis') | |
.attr('transform', 'translate('+ leftPadding +',' + (height+15) + ')') | |
.call(xAxis); | |
//y axis | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient('left'); | |
chart.append("g") | |
.attr("class", "y axis") | |
.attr('transform', 'translate('+leftPadding + ',' + 0 + ')') | |
.call(yAxis); | |
</script> | |
</body> |