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.isstring": "^4.0.1",
|
||||
"lodash.isundefined": "^3.0.1",
|
||||
"moment": "^2.17.1",
|
||||
"param-case": "^2.1.0",
|
||||
"random-natural": "^1.0.3",
|
||||
"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 = {
|
||||
MetricBody: require('./body'),
|
||||
MetricGraph: require('./graph'),
|
||||
MetricCloseButton: require('./close-button'),
|
||||
MetricHeader: require('./header'),
|
||||
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,
|
||||
id = rndId(),
|
||||
name,
|
||||
onChange,
|
||||
required,
|
||||
selected
|
||||
selected,
|
||||
value
|
||||
}) => {
|
||||
return (
|
||||
<SelectWrapper>
|
||||
@ -70,8 +72,10 @@ const Select = ({
|
||||
form={form}
|
||||
id={id}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
required={required}
|
||||
selected={selected}
|
||||
value={value}
|
||||
>
|
||||
{children}
|
||||
</StyledSelect>
|
||||
@ -86,8 +90,10 @@ Select.propTypes = {
|
||||
form: React.PropTypes.string,
|
||||
id: React.PropTypes.string,
|
||||
name: React.PropTypes.string,
|
||||
onChange: React.PropTypes.func,
|
||||
required: React.PropTypes.bool,
|
||||
selected: React.PropTypes.bool
|
||||
selected: React.PropTypes.bool,
|
||||
value: React.PropTypes.string
|
||||
};
|
||||
|
||||
module.exports = Select;
|
||||
|
@ -3,7 +3,8 @@ const Styled = require('styled-components');
|
||||
const fns = require('../../shared/functions');
|
||||
const constants = require('../../shared/constants');
|
||||
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 {
|
||||
default: styled
|
||||
|
@ -6,7 +6,7 @@ const {
|
||||
} = require('@kadira/storybook');
|
||||
|
||||
const {
|
||||
MetricBody,
|
||||
MetricGraph,
|
||||
MetricCloseButton,
|
||||
MetricHeader,
|
||||
MetricSelect,
|
||||
@ -15,7 +15,42 @@ const {
|
||||
MetricView
|
||||
} = require('./');
|
||||
|
||||
const MetricData = require('./metric-data');
|
||||
|
||||
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)
|
||||
.add('Metric', () => (
|
||||
@ -23,16 +58,46 @@ storiesOf('Metric', module)
|
||||
<MetricView>
|
||||
<MetricHeader>
|
||||
<MetricTitle>Aggregated CPU usage</MetricTitle>
|
||||
<MetricSelect>
|
||||
<option selected>6 hours</option>
|
||||
<option>12 hours</option>
|
||||
<option>24 hours</option>
|
||||
<option>Two days</option>
|
||||
<MetricSelect onChange={onMetricSelect} value={sixHours}>
|
||||
<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>Settings</MetricSettingsButton>
|
||||
<MetricSettingsButton onClick={onButtonClick}>
|
||||
Settings
|
||||
</MetricSettingsButton>
|
||||
<MetricCloseButton onClick={onButtonClick} />
|
||||
</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>
|
||||
</Base>
|
||||
));
|
||||
|
@ -1,4 +1,5 @@
|
||||
const constants = require('../../shared/constants');
|
||||
const fns = require('../../shared/functions');
|
||||
const React = require('react');
|
||||
const Styled = require('styled-components');
|
||||
|
||||
@ -7,6 +8,10 @@ const {
|
||||
colors
|
||||
} = constants;
|
||||
|
||||
const {
|
||||
remcalc
|
||||
} = fns;
|
||||
|
||||
const {
|
||||
default: styled
|
||||
} = Styled;
|
||||
@ -15,6 +20,7 @@ const Container = styled.div`
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-width: ${remcalc(940)};
|
||||
box-shadow: ${boxes.bottomShaddow};
|
||||
border: 1px solid ${colors.borderSecondary};
|
||||
`;
|
||||
|
@ -4343,7 +4343,7 @@ mobx@^2.3.4:
|
||||
version "2.7.0"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.17.1.tgz#fed9506063f36b10f066c8b59a144d7faebe1d82"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user