Add functional metric chart with customisable time scale
This commit is contained in:
parent
97fced5728
commit
2c7d751204
@ -24,6 +24,7 @@
|
|||||||
"lodash.isfunction": "^3.0.8",
|
"lodash.isfunction": "^3.0.8",
|
||||||
"lodash.isstring": "^4.0.1",
|
"lodash.isstring": "^4.0.1",
|
||||||
"lodash.isundefined": "^3.0.1",
|
"lodash.isundefined": "^3.0.1",
|
||||||
|
"moment": "^2.17.1",
|
||||||
"param-case": "^2.1.0",
|
"param-case": "^2.1.0",
|
||||||
"random-natural": "^1.0.3",
|
"random-natural": "^1.0.3",
|
||||||
"react": "^15.4.1",
|
"react": "^15.4.1",
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
const React = require('react');
|
|
||||||
const Styled = require('styled-components');
|
|
||||||
const fns = require('../../shared/functions');
|
|
||||||
|
|
||||||
const {
|
|
||||||
remcalc
|
|
||||||
} = fns;
|
|
||||||
|
|
||||||
const {
|
|
||||||
default: styled
|
|
||||||
} = Styled;
|
|
||||||
|
|
||||||
const StyledBody = styled.div`
|
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: ${remcalc(264)};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Body = ({
|
|
||||||
children
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<StyledBody name='metric-body'>
|
|
||||||
{children}
|
|
||||||
</StyledBody>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Body.propTypes = {
|
|
||||||
children: React.PropTypes.node
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = Body;
|
|
174
ui/src/components/metric/graph.js
Normal file
174
ui/src/components/metric/graph.js
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
const React = require('react');
|
||||||
|
const Styled = require('styled-components');
|
||||||
|
const moment = require('moment');
|
||||||
|
const Chart = require('chart.js');
|
||||||
|
const whisker = require('chartjs-chart-box-plot');
|
||||||
|
|
||||||
|
whisker(Chart);
|
||||||
|
|
||||||
|
const {
|
||||||
|
default: styled
|
||||||
|
} = Styled;
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Canvas = styled.canvas`
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
class Graph extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const {
|
||||||
|
yMax = 100,
|
||||||
|
yMin = 0,
|
||||||
|
yMeasurement = '%'
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
xMax,
|
||||||
|
xMin,
|
||||||
|
xUnitStepSize
|
||||||
|
} = this.processData(this.props);
|
||||||
|
|
||||||
|
this._chart = new Chart(this._refs.component, {
|
||||||
|
type: 'whisker',
|
||||||
|
responsive: true,
|
||||||
|
maintainAspectRatio: true,
|
||||||
|
data: {
|
||||||
|
datasets: [{
|
||||||
|
data: data
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
layout: {
|
||||||
|
padding: 10
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
xAxes: [{
|
||||||
|
display: true,
|
||||||
|
type: 'time',
|
||||||
|
time: {
|
||||||
|
unit: 'minute',
|
||||||
|
unitStepSize: xUnitStepSize,
|
||||||
|
max: xMax,
|
||||||
|
min: xMin,
|
||||||
|
/*displayFormats: {
|
||||||
|
hour: 'MMM D, hA'
|
||||||
|
}*/
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
yAxes: [{
|
||||||
|
display: true,
|
||||||
|
ticks: {
|
||||||
|
min: yMin,
|
||||||
|
max: yMax,
|
||||||
|
callback: (value, index, values) => {
|
||||||
|
return `${value.toFixed(2)}${yMeasurement}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
xMax,
|
||||||
|
xMin,
|
||||||
|
xUnitStepSize
|
||||||
|
} = this.processData(nextProps);
|
||||||
|
|
||||||
|
this._chart.data.datasets = [{
|
||||||
|
data
|
||||||
|
}];
|
||||||
|
this._chart.options.scales.xAxes[0].time.max = xMax;
|
||||||
|
this._chart.options.scales.xAxes[0].time.min = xMin;
|
||||||
|
this._chart.options.scales.xAxes[0].time.unitStepSize = xUnitStepSize;
|
||||||
|
this._chart.update(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
processData(props) {
|
||||||
|
const {
|
||||||
|
data = [],
|
||||||
|
duration = 360
|
||||||
|
} = this.props;
|
||||||
|
// I'm going to assume that data will be structured in 10min intervals...
|
||||||
|
// And that newest data will be at the end...
|
||||||
|
// Let's rock and roll!
|
||||||
|
// All this shizzle below needs to be recalculated on new props, yay!
|
||||||
|
const now = moment();
|
||||||
|
// first time on scale x
|
||||||
|
const before = moment().subtract(duration, 'minutes');
|
||||||
|
// remove leading data before first time on scale x
|
||||||
|
const totalData = data.slice(data.length - 1 - duration/10);
|
||||||
|
// adjust time of first data, if there's less data than would fill the chart
|
||||||
|
const start = moment(before)
|
||||||
|
.add(duration - (totalData.length-1)*10, 'minutes');
|
||||||
|
// add times to data
|
||||||
|
const dataWithTime = totalData.map((d, i) => {
|
||||||
|
const add = i*10;
|
||||||
|
return Object.assign(
|
||||||
|
{},
|
||||||
|
d,
|
||||||
|
{
|
||||||
|
x: moment(start).add(add, 'minutes').toDate()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// set min and max
|
||||||
|
const xMax = now.toDate();
|
||||||
|
const xMin = before.toDate();
|
||||||
|
// calculate stepsize
|
||||||
|
const xUnitStepSize = duration/6;
|
||||||
|
|
||||||
|
return {
|
||||||
|
data: dataWithTime,
|
||||||
|
xMax,
|
||||||
|
xMin,
|
||||||
|
xUnitStepSize
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ref(name) {
|
||||||
|
this._refs = this._refs || {};
|
||||||
|
|
||||||
|
return (el) => {
|
||||||
|
this._refs[name] = el;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container name='metric-body'>
|
||||||
|
<Canvas
|
||||||
|
height={262}
|
||||||
|
innerRef={this.ref('component')}
|
||||||
|
width={940}
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph.propTypes = {
|
||||||
|
data: React.PropTypes.array,
|
||||||
|
duration: React.PropTypes.number,
|
||||||
|
yMax: React.PropTypes.number,
|
||||||
|
yMeasurement: React.PropTypes.string,
|
||||||
|
yMin: React.PropTypes.number
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Graph;
|
18
ui/src/components/metric/icon-settings.svg
Normal file
18
ui/src/components/metric/icon-settings.svg
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>icon: settings </title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="project:-adding-metrics-1.4" transform="translate(-979.000000, -413.000000)" fill="#FFFFFF">
|
||||||
|
<g id="metric:-cpu" transform="translate(208.000000, 391.000000)">
|
||||||
|
<g id="metric-head" transform="translate(5.000000, 0.000000)">
|
||||||
|
<g id="button:-settinga" transform="translate(742.000000, 0.000000)">
|
||||||
|
<path d="M33,34 C31.3425,34 30,32.6575 30,31 C30,29.3425 31.3425,28 33,28 C34.6575,28 36,29.3425 36,31 C36,32.6575 34.6575,34 33,34 L33,34 Z M42,32.5 L42,29.5 L40.3485,29.5 C40.155,28.543 39.774,27.655 39.252,26.869 L40.425,25.696 L38.304,23.575 L37.131,24.748 C36.345,24.226 35.457,23.845 34.5,23.6515 L34.5,22 L31.5,22 L31.5,23.6515 C30.543,23.845 29.655,24.226 28.869,24.748 L27.696,23.575 L25.575,25.696 L26.748,26.869 C26.226,27.655 25.845,28.543 25.6515,29.5 L24,29.5 L24,32.5 L25.6515,32.5 C25.845,33.457 26.226,34.345 26.748,35.131 L25.575,36.304 L27.696,38.425 L28.869,37.252 C29.655,37.774 30.543,38.155 31.5,38.3485 L31.5,40 L34.5,40 L34.5,38.3485 C35.457,38.155 36.345,37.774 37.131,37.252 L38.304,38.425 L40.425,36.304 L39.252,35.131 C39.774,34.345 40.155,33.457 40.3485,32.5 L42,32.5 Z" id="icon:-settings-"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
MetricBody: require('./body'),
|
MetricGraph: require('./graph'),
|
||||||
MetricCloseButton: require('./close-button'),
|
MetricCloseButton: require('./close-button'),
|
||||||
MetricHeader: require('./header'),
|
MetricHeader: require('./header'),
|
||||||
MetricSelect: require('./select'),
|
MetricSelect: require('./select'),
|
||||||
|
307
ui/src/components/metric/metric-data.js
Normal file
307
ui/src/components/metric/metric-data.js
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
module.exports = [{
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 15,
|
||||||
|
median: 15,
|
||||||
|
max: 15,
|
||||||
|
min: 15,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 26,
|
||||||
|
thirdQuartile: 26,
|
||||||
|
median: 26,
|
||||||
|
max: 26,
|
||||||
|
min: 26,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 17,
|
||||||
|
thirdQuartile: 17,
|
||||||
|
median: 17,
|
||||||
|
max: 17,
|
||||||
|
min: 17,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 19,
|
||||||
|
max: 19,
|
||||||
|
min: 20,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 19,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 21,
|
||||||
|
max: 20,
|
||||||
|
min: 25,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 24,
|
||||||
|
thirdQuartile: 30,
|
||||||
|
median: 25,
|
||||||
|
max: 26,
|
||||||
|
min: 27,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 28,
|
||||||
|
thirdQuartile: 34,
|
||||||
|
median: 30,
|
||||||
|
max: 30,
|
||||||
|
min: 30,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 30,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 35,
|
||||||
|
max: 40,
|
||||||
|
min: 40,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 45,
|
||||||
|
max: 44,
|
||||||
|
min: 44,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 55,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 57,
|
||||||
|
max: 58,
|
||||||
|
min: 57,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 56,
|
||||||
|
max: 56,
|
||||||
|
min: 56,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 60,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 60,
|
||||||
|
max: 60,
|
||||||
|
min: 60,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 57,
|
||||||
|
median: 57,
|
||||||
|
max: 57,
|
||||||
|
min: 57,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 45,
|
||||||
|
max: 45,
|
||||||
|
min: 45,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 40,
|
||||||
|
median: 30,
|
||||||
|
max: 49,
|
||||||
|
min: 30,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 15,
|
||||||
|
median: 15,
|
||||||
|
max: 15,
|
||||||
|
min: 15,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 26,
|
||||||
|
thirdQuartile: 26,
|
||||||
|
median: 26,
|
||||||
|
max: 26,
|
||||||
|
min: 26,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 17,
|
||||||
|
thirdQuartile: 17,
|
||||||
|
median: 17,
|
||||||
|
max: 17,
|
||||||
|
min: 17,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 19,
|
||||||
|
max: 19,
|
||||||
|
min: 20,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 19,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 21,
|
||||||
|
max: 20,
|
||||||
|
min: 25,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 24,
|
||||||
|
thirdQuartile: 30,
|
||||||
|
median: 25,
|
||||||
|
max: 26,
|
||||||
|
min: 10,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 28,
|
||||||
|
thirdQuartile: 34,
|
||||||
|
median: 30,
|
||||||
|
max: 30,
|
||||||
|
min: 30,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 30,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 35,
|
||||||
|
max: 40,
|
||||||
|
min: 40,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 45,
|
||||||
|
max: 44,
|
||||||
|
min: 44,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 55,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 57,
|
||||||
|
max: 58,
|
||||||
|
min: 57,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 56,
|
||||||
|
max: 56,
|
||||||
|
min: 56,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 60,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 60,
|
||||||
|
max: 60,
|
||||||
|
min: 60,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 57,
|
||||||
|
median: 57,
|
||||||
|
max: 57,
|
||||||
|
min: 57,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 45,
|
||||||
|
max: 45,
|
||||||
|
min: 45,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 40,
|
||||||
|
median: 30,
|
||||||
|
max: 49,
|
||||||
|
min: 30,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 15,
|
||||||
|
median: 15,
|
||||||
|
max: 15,
|
||||||
|
min: 15,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 26,
|
||||||
|
thirdQuartile: 26,
|
||||||
|
median: 26,
|
||||||
|
max: 26,
|
||||||
|
min: 26,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 17,
|
||||||
|
thirdQuartile: 17,
|
||||||
|
median: 17,
|
||||||
|
max: 17,
|
||||||
|
min: 17,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 19,
|
||||||
|
max: 19,
|
||||||
|
min: 20,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 19,
|
||||||
|
thirdQuartile: 25,
|
||||||
|
median: 21,
|
||||||
|
max: 20,
|
||||||
|
min: 25,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 24,
|
||||||
|
thirdQuartile: 30,
|
||||||
|
median: 25,
|
||||||
|
max: 26,
|
||||||
|
min: 27,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 28,
|
||||||
|
thirdQuartile: 34,
|
||||||
|
median: 30,
|
||||||
|
max: 30,
|
||||||
|
min: 30,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 30,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 35,
|
||||||
|
max: 40,
|
||||||
|
min: 40,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 45,
|
||||||
|
max: 44,
|
||||||
|
min: 44,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 55,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 57,
|
||||||
|
max: 58,
|
||||||
|
min: 57,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 56,
|
||||||
|
max: 56,
|
||||||
|
min: 56,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 60,
|
||||||
|
thirdQuartile: 56,
|
||||||
|
median: 60,
|
||||||
|
max: 60,
|
||||||
|
min: 60,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 57,
|
||||||
|
median: 57,
|
||||||
|
max: 57,
|
||||||
|
min: 57,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 57,
|
||||||
|
thirdQuartile: 55,
|
||||||
|
median: 55,
|
||||||
|
max: 55,
|
||||||
|
min: 55,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 20,
|
||||||
|
thirdQuartile: 45,
|
||||||
|
median: 45,
|
||||||
|
max: 45,
|
||||||
|
min: 45,
|
||||||
|
}, {
|
||||||
|
firstQuartile: 15,
|
||||||
|
thirdQuartile: 40,
|
||||||
|
median: 30,
|
||||||
|
max: 49,
|
||||||
|
min: 30,
|
||||||
|
}];
|
@ -59,8 +59,10 @@ const Select = ({
|
|||||||
form,
|
form,
|
||||||
id = rndId(),
|
id = rndId(),
|
||||||
name,
|
name,
|
||||||
|
onChange,
|
||||||
required,
|
required,
|
||||||
selected
|
selected,
|
||||||
|
value
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<SelectWrapper>
|
<SelectWrapper>
|
||||||
@ -70,8 +72,10 @@ const Select = ({
|
|||||||
form={form}
|
form={form}
|
||||||
id={id}
|
id={id}
|
||||||
name={name}
|
name={name}
|
||||||
|
onChange={onChange}
|
||||||
required={required}
|
required={required}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
|
value={value}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</StyledSelect>
|
</StyledSelect>
|
||||||
@ -86,8 +90,10 @@ Select.propTypes = {
|
|||||||
form: React.PropTypes.string,
|
form: React.PropTypes.string,
|
||||||
id: React.PropTypes.string,
|
id: React.PropTypes.string,
|
||||||
name: React.PropTypes.string,
|
name: React.PropTypes.string,
|
||||||
|
onChange: React.PropTypes.func,
|
||||||
required: React.PropTypes.bool,
|
required: React.PropTypes.bool,
|
||||||
selected: React.PropTypes.bool
|
selected: React.PropTypes.bool,
|
||||||
|
value: React.PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Select;
|
module.exports = Select;
|
||||||
|
@ -3,7 +3,8 @@ const Styled = require('styled-components');
|
|||||||
const fns = require('../../shared/functions');
|
const fns = require('../../shared/functions');
|
||||||
const constants = require('../../shared/constants');
|
const constants = require('../../shared/constants');
|
||||||
const Button = require('../button');
|
const Button = require('../button');
|
||||||
const SettingsIcon = require('!babel!svg-react!./close.svg?name=SettingsIcon');
|
const SettingsIcon =
|
||||||
|
require('!babel!svg-react!./icon-settings.svg?name=SettingsIcon');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
default: styled
|
default: styled
|
||||||
|
@ -6,7 +6,7 @@ const {
|
|||||||
} = require('@kadira/storybook');
|
} = require('@kadira/storybook');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
MetricBody,
|
MetricGraph,
|
||||||
MetricCloseButton,
|
MetricCloseButton,
|
||||||
MetricHeader,
|
MetricHeader,
|
||||||
MetricSelect,
|
MetricSelect,
|
||||||
@ -15,7 +15,42 @@ const {
|
|||||||
MetricView
|
MetricView
|
||||||
} = require('./');
|
} = require('./');
|
||||||
|
|
||||||
|
const MetricData = require('./metric-data');
|
||||||
|
|
||||||
const onButtonClick = () => {};
|
const onButtonClick = () => {};
|
||||||
|
const onMetricSelect = () => {};
|
||||||
|
|
||||||
|
const hour = 60; // in minutes - for moment
|
||||||
|
const sixHours = 6*hour;
|
||||||
|
const twelveHours = 12*hour;
|
||||||
|
const oneDay = 24*hour;
|
||||||
|
const twoDays = 48*hour;
|
||||||
|
|
||||||
|
const withinRange = (
|
||||||
|
value,
|
||||||
|
newMin,
|
||||||
|
newMax,
|
||||||
|
precision = 2,
|
||||||
|
oldMin = 0,
|
||||||
|
oldMax = 100
|
||||||
|
) => {
|
||||||
|
const normalisedValue = value-oldMin;
|
||||||
|
const newRange = newMax-newMin;
|
||||||
|
const oldRange = oldMax-oldMin;
|
||||||
|
const newValue = newMin + normalisedValue*newRange/oldRange;
|
||||||
|
return newValue.toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
const percentageMetricData = MetricData;
|
||||||
|
const kbMetricData = MetricData.map(m => {
|
||||||
|
return {
|
||||||
|
firstQuartile: withinRange(m.firstQuartile, 1.55, 2.0),
|
||||||
|
thirdQuartile: withinRange(m.thirdQuartile, 1.55, 2.0),
|
||||||
|
median: withinRange(m.median, 1.55, 2.0),
|
||||||
|
max: withinRange(m.max, 1.55, 2.0),
|
||||||
|
min: withinRange(m.min, 1.55, 2.0),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
storiesOf('Metric', module)
|
storiesOf('Metric', module)
|
||||||
.add('Metric', () => (
|
.add('Metric', () => (
|
||||||
@ -23,16 +58,46 @@ storiesOf('Metric', module)
|
|||||||
<MetricView>
|
<MetricView>
|
||||||
<MetricHeader>
|
<MetricHeader>
|
||||||
<MetricTitle>Aggregated CPU usage</MetricTitle>
|
<MetricTitle>Aggregated CPU usage</MetricTitle>
|
||||||
<MetricSelect>
|
<MetricSelect onChange={onMetricSelect} value={sixHours}>
|
||||||
<option selected>6 hours</option>
|
<option value={sixHours}>6 hours</option>
|
||||||
<option>12 hours</option>
|
<option value={twelveHours}>12 hours</option>
|
||||||
<option>24 hours</option>
|
<option value={oneDay}>24 hours</option>
|
||||||
<option>Two days</option>
|
<option value={twoDays}>Two days</option>
|
||||||
</MetricSelect>
|
</MetricSelect>
|
||||||
<MetricSettingsButton>Settings</MetricSettingsButton>
|
<MetricSettingsButton onClick={onButtonClick}>
|
||||||
|
Settings
|
||||||
|
</MetricSettingsButton>
|
||||||
<MetricCloseButton onClick={onButtonClick} />
|
<MetricCloseButton onClick={onButtonClick} />
|
||||||
</MetricHeader>
|
</MetricHeader>
|
||||||
<MetricBody />
|
<MetricGraph
|
||||||
|
data={percentageMetricData}
|
||||||
|
duration={sixHours}
|
||||||
|
yMax={100}
|
||||||
|
yMeasurement='%'
|
||||||
|
yMin={0}
|
||||||
|
/>
|
||||||
|
</MetricView>
|
||||||
|
<MetricView>
|
||||||
|
<MetricHeader>
|
||||||
|
<MetricTitle>Aggregated CPU usage</MetricTitle>
|
||||||
|
<MetricSelect onChange={onMetricSelect} value={twoDays}>
|
||||||
|
<option value={sixHours}>6 hours</option>
|
||||||
|
<option value={twelveHours}>12 hours</option>
|
||||||
|
<option value={oneDay}>24 hours</option>
|
||||||
|
<option value={twoDays}>Two days</option>
|
||||||
|
</MetricSelect>
|
||||||
|
<MetricSettingsButton onClick={onButtonClick}>
|
||||||
|
Settings
|
||||||
|
</MetricSettingsButton>
|
||||||
|
<MetricCloseButton onClick={onButtonClick} />
|
||||||
|
</MetricHeader>
|
||||||
|
<MetricGraph
|
||||||
|
data={kbMetricData}
|
||||||
|
duration={oneDay}
|
||||||
|
yMax={2.0}
|
||||||
|
yMeasurement='kb'
|
||||||
|
yMin={1.55}
|
||||||
|
/>
|
||||||
</MetricView>
|
</MetricView>
|
||||||
</Base>
|
</Base>
|
||||||
));
|
));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const constants = require('../../shared/constants');
|
const constants = require('../../shared/constants');
|
||||||
|
const fns = require('../../shared/functions');
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const Styled = require('styled-components');
|
const Styled = require('styled-components');
|
||||||
|
|
||||||
@ -7,6 +8,10 @@ const {
|
|||||||
colors
|
colors
|
||||||
} = constants;
|
} = constants;
|
||||||
|
|
||||||
|
const {
|
||||||
|
remcalc
|
||||||
|
} = fns;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
default: styled
|
default: styled
|
||||||
} = Styled;
|
} = Styled;
|
||||||
@ -15,6 +20,7 @@ const Container = styled.div`
|
|||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: ${remcalc(940)};
|
||||||
box-shadow: ${boxes.bottomShaddow};
|
box-shadow: ${boxes.bottomShaddow};
|
||||||
border: 1px solid ${colors.borderSecondary};
|
border: 1px solid ${colors.borderSecondary};
|
||||||
`;
|
`;
|
||||||
|
@ -4343,7 +4343,7 @@ mobx@^2.3.4:
|
|||||||
version "2.7.0"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-2.7.0.tgz#cf3d82d18c0ca7f458d8f2a240817b3dc7e54a01"
|
resolved "https://registry.yarnpkg.com/mobx/-/mobx-2.7.0.tgz#cf3d82d18c0ca7f458d8f2a240817b3dc7e54a01"
|
||||||
|
|
||||||
moment@^2.10.6:
|
moment@^2.10.6, moment@^2.17.1:
|
||||||
version "2.17.1"
|
version "2.17.1"
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.1.tgz#fed9506063f36b10f066c8b59a144d7faebe1d82"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.1.tgz#fed9506063f36b10f066c8b59a144d7faebe1d82"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user