1
0
Fork 0

Basic box plot for task processing duration

This commit is contained in:
Gregory Eremin 2015-10-29 02:22:21 +03:00
parent d0a9829002
commit 5462985a40
2 changed files with 134 additions and 54 deletions

View File

@ -6,38 +6,28 @@ body {
#app { #app {
width: 1000px; width: 1000px;
margin: 0 auto; margin: 0 auto;
/*background-color: #eee;*/ /*background-color: #ccc;*/
} }
.daemon { .daemon {
margin-top: 40px; margin-top: 40px;
height: 150px;
} }
.daemon .left-block {
.daemon h1 { float: left;
width: 300px;
height: 150px;
/*background-color: #cfc;*/
}
.daemon .left-block h1 {
padding: 0; padding: 0;
margin: 0; margin: 0;
font-weight: 400; font-weight: 400;
} }
.daemon .stats { .daemon .boxplot {
width: 305px;
height: 60px;
}
.daemon dt, .daemon dd {
margin: 0;
float: left; float: left;
line-height: 20px; height: 150px;
} /*background-color: #fcc;*/
.daemon dt { border: #ccc 1px solid;
width: 75px;
color: #aaa;
}
.daemon dt.narrow {
width: 50px;
}
.daemon dd {
width: 80px;
margin-right: 10px;
font-family: monospace;
text-align: right;
} }

View File

@ -9,8 +9,25 @@ var Dashboard = React.createClass({
reload: function() { reload: function() {
getURL("http://127.0.0.1:6464/stats.json", {}, function(resp) { getURL("http://127.0.0.1:6464/stats.json", {}, function(resp) {
this.setState(resp); var newState = {};
setTimeout(this.reload, 5000); var decode = function(point) {
return {
timestamp: point[0],
processed: point[1],
errors: point[2],
min: point[3],
p25: point[4],
mean: point[5],
median: point[6],
p75: point[7],
max: point[8],
}
};
for (name in resp) {
newState[name] = resp[name].map(decode);
}
this.setState(newState);
setTimeout(this.reload, 3000);
}.bind(this)); }.bind(this));
}, },
@ -31,32 +48,105 @@ var Dashboard = React.createClass({
}); });
var Daemon = React.createClass({ var Daemon = React.createClass({
decode: function(point) {
return {
timestamp: point[0],
processed: point[1],
errors: point[2],
min: point[3],
mean: point[4],
p95: point[5],
max: point[6],
stddev: point[7],
}
},
render: function() { render: function() {
var last = this.decode(this.props.points[this.props.points.length - 1]); var last = this.props.points[this.props.points.length - 1];
return ( return (
<div className="daemon"> <div className="daemon">
<div className="left-block">
<h1>{this.props.name}</h1> <h1>{this.props.name}</h1>
<dl className="stats"> </div>
<dt>processed:</dt><dd>{last.processed}</dd> <BoxPlot points={this.props.points} />
<dt className="narrow">errors:</dt><dd>{last.errors} </dd> </div>
<dt>min:</dt><dd>{formatDuration(last.min)}</dd> );
<dt className="narrow">max:</dt><dd>{formatDuration(last.max)}</dd> }
<dt>mean:</dt><dd>{formatDuration(last.mean)}</dd> });
<dt className="narrow">95%:</dt><dd>{formatDuration(last.p95)}</dd>
</dl> var BoxPlot = React.createClass({
render: function(){
var points = this.props.points,
maxHeight = 140,
padding = 5;
var min, max;
points.map(function(point) {
if (min === undefined || point.min < min) {
min = point.min;
}
if (max === undefined || point.max > max) {
max = point.max;
}
});
var renderBox = function(point, i) {
var relativeY = function(val) {
return maxHeight - Math.round((val-min)/(max-min) * maxHeight) + padding;
};
var width = 10;
var padding = 5;
var x1 = (width + padding) * i + padding;
var x2 = x1 + width;
var minY = relativeY(point.min);
var p25Y = relativeY(point.p25);
var medianY = relativeY(point.median);
var p75Y = relativeY(point.p75);
var maxY = relativeY(point.max);
return (
<g key={i}>
<line key="max"
x1={x1}
x2={x2}
y1={maxY}
y2={maxY}
strokeWidth={1}
style={{stroke: "#444"}} />
<line key="max-bar"
x1={x1+width/2}
x2={x1+width/2}
y1={maxY}
y2={p75Y}
strokeDasharray="4,2"
strokeWidth={1}
style={{stroke: "#444"}} />
<rect key="iqr"
x={x1}
y={p75Y}
width={width}
height={p25Y - p75Y}
strokeWidth={1}
style={{fill: "transparent", stroke: "#444"}} />
<line key="median"
x1={x1}
x2={x2}
y1={medianY}
y2={medianY}
strokeWidth={1}
style={{stroke: "#444"}} />
<line key="min-bar"
x1={x1+width/2}
x2={x1+width/2}
y1={minY}
y2={p25Y}
strokeDasharray="4,2"
strokeWidth={1}
style={{stroke: "#444"}} />
<line key="min"
x1={x1}
x2={x2}
y1={minY}
y2={minY}
strokeWidth={1}
style={{stroke: "#444"}} />
</g>
);
};
return (
<div className="boxplot">
<svg width="455" height="150">
{this.props.points.map(renderBox)}
</svg>
</div> </div>
); );
} }