Add metric display

This commit is contained in:
JUDIT GRESKOVITS 2017-01-23 15:05:51 +00:00
parent 9156526ce0
commit 1b42954bf2
12 changed files with 128 additions and 17 deletions

View File

@ -25,6 +25,9 @@
"added-label": "Added", "added-label": "Added",
"link-label": "Learn more" "link-label": "Learn more"
}, },
"metric": {
"settings-label": "Settings"
},
"cpu_agg_usage": { "cpu_agg_usage": {
"title": "Aggregated CPU usage", "title": "Aggregated CPU usage",
"description": "CPU usages accross all of the CPU cores." "description": "CPU usages accross all of the CPU cores."

View File

@ -51,6 +51,7 @@
"redux-thunk": "^2.1.0", "redux-thunk": "^2.1.0",
"reselect": "^2.5.4", "reselect": "^2.5.4",
"styled-components": "^1.3.0", "styled-components": "^1.3.0",
"svg-react-loader": "^0.3.7",
"understood": "^1.0.1", "understood": "^1.0.1",
"url-loader": "^0.5.7" "url-loader": "^0.5.7"
}, },

View File

@ -5,6 +5,7 @@ const actions = require('@state/actions');
const AddMetrics = require('./add-metrics'); const AddMetrics = require('./add-metrics');
const Button = require('@ui/components/button'); const Button = require('@ui/components/button');
const Column = require('@ui/components/column'); const Column = require('@ui/components/column');
const MetricCharts = require('./metric-charts');
const Monitors = require('./monitors'); const Monitors = require('./monitors');
const PropTypes = require('@root/prop-types'); const PropTypes = require('@root/prop-types');
const Row = require('@ui/components/row'); const Row = require('@ui/components/row');
@ -35,9 +36,13 @@ const Metrics = ({
</Column> </Column>
</Row> </Row>
<Monitors /> <Monitors />
<MetricCharts
datasets={metrics.datasets}
onSettingsClick={toggleMonitorView}
/>
<AddMetrics <AddMetrics
metricTypes={metricTypes} metricTypes={metricTypes}
metrics={metrics} metrics={metrics.types}
onAddMetric={addMetric} onAddMetric={addMetric}
/> />
</div> </div>

View File

@ -0,0 +1,89 @@
const React = require('react');
const moment = require('moment');
const PropTypes = require('@root/prop-types');
const Metric = require('@ui/components/metric');
const ReactIntl = require('react-intl');
const {
FormattedMessage
} = ReactIntl;
const {
MetricGraph,
MetricCloseButton,
MetricHeader,
MetricSelect,
MetricSettingsButton,
MetricTitle,
MetricView
} = Metric;
const MetricCharts = ({
// metricTypes,
// metrics,
// onAddMetric,
datasets,
duration = 360,
durations = [
360,
720,
1440,
2880
],
onDurationChange = () => {},
onSettingsClick = () => {},
onRemoveMetric = () => {}
// and another one here to come...
}) => {
const optionList = durations.map(duration => (
<option key={duration} value={duration}>
{moment.duration(duration, 'minutes').humanize()}
</option>
));
const metricList = datasets.map((dataset) => {
// TODO
// - yMeasurement '%' or not
// - yMin & yMax should all come from the metric type description
return (
<MetricView key={dataset.uuid + Math.random()}>
<MetricHeader>
<MetricTitle>{dataset.uuid}</MetricTitle>
<MetricSelect onChange={onDurationChange} value={durations[0]}>
{optionList}
</MetricSelect>
<MetricSettingsButton onClick={onSettingsClick}>
<FormattedMessage id={'metrics.metric.settings-label'} />
</MetricSettingsButton>
<MetricCloseButton onClick={onRemoveMetric} />
</MetricHeader>
<MetricGraph
data={dataset.data}
duration={duration}
yMax={100}
yMeasurement='%'
yMin={0}
/>
</MetricView>
);
});
return (
<div>
{metricList}
</div>
);
};
MetricCharts.propTypes = {
datasets: React.PropTypes.arrayOf(PropTypes.Dataset),
duration: React.PropTypes.number,
durations: React.PropTypes.arrayOf(React.PropTypes.number),
onDurationChange: React.PropTypes.func.isRequired,
onRemoveMetric: React.PropTypes.func.isRequired,
onSettingsClick: React.PropTypes.func.isRequired
};
module.exports = MetricCharts;

View File

@ -28,7 +28,7 @@ const mapStateToProps = (state, {
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
addMetric: (service) => (metric) => dispatch(addMetric({ addMetric: (service) => (metric) => dispatch(addMetric({
id: metric, id: metric,
service: service service: service.uuid
})) }))
}); });

View File

@ -48,7 +48,6 @@
}, },
"monitors": { "monitors": {
"ui": { "ui": {
"active": "dca08514-72e5-46ce-ad91-e68b3b0914d4",
"page": "create" "page": "create"
} }
}, },
@ -69,6 +68,12 @@
"net_agg_bytes_in", "net_agg_bytes_in",
"net_agg_bytes_out", "net_agg_bytes_out",
"time_of_day" "time_of_day"
],
"durations": [
360,
720,
1440,
2880
] ]
}, },
"data": { "data": {

View File

@ -89,9 +89,11 @@ const instancesByServiceId = (serviceId) => createSelector(
); );
const metricsByServiceId = (serviceId) => createSelector( const metricsByServiceId = (serviceId) => createSelector(
[metricTypes, serviceById(serviceId)], [metricTypes, serviceById(serviceId), metricDatasets],
(metricTypes, service) => (metricTypes, service, metrics) => ({
metricTypes.filter((i) => i.service === service.uuid) types: metricTypes.filter((i) => i.service === service.uuid),
datasets: datasets(metrics, service.metrics)
})
); );
const metricTypeByUuid = (metricTypeUuid) => createSelector( const metricTypeByUuid = (metricTypeUuid) => createSelector(

View File

@ -2,7 +2,10 @@ const React = require('react');
const Styled = require('styled-components'); 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 CloseIcon = require('!babel!svg-react!./close.svg?name=CloseIcon'); const CloseIcon =
require(
'!babel-loader!svg-react-loader!./close.svg?name=CloseIcon'
);
const { const {
default: styled default: styled

View File

@ -46,6 +46,7 @@ class Graph extends React.Component {
}] }]
}, },
options: { options: {
animation: false,
layout: { layout: {
padding: 10 padding: 10
}, },

View File

@ -4,7 +4,9 @@ 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 = const SettingsIcon =
require('!babel!svg-react!./icon-settings.svg?name=SettingsIcon'); require(
'!babel-loader!svg-react-loader!./icon-settings.svg?name=SettingsIcon'
);
const { const {
default: styled default: styled
@ -48,9 +50,10 @@ const StyledIcon = styled(SettingsIcon)`
const AddMetricButton = ({ const AddMetricButton = ({
children, children,
metric,
onClick onClick
}) => { }) => {
const onButtonClick = (e) => onClick(); const onButtonClick = (e) => onClick(metric);
return ( return (
<StyledButton <StyledButton
name='add-metric-button' name='add-metric-button'
@ -64,6 +67,7 @@ const AddMetricButton = ({
AddMetricButton.propTypes = { AddMetricButton.propTypes = {
children: React.PropTypes.node, children: React.PropTypes.node,
metric: React.PropTypes.string,
onClick: React.PropTypes.func, onClick: React.PropTypes.func,
}; };

View File

@ -19,6 +19,7 @@ const {
const Container = styled.div` const Container = styled.div`
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
margin: ${remcalc(24)} 0;
width: 100%; width: 100%;
max-width: ${remcalc(940)}; max-width: ${remcalc(940)};
box-shadow: ${boxes.bottomShaddow}; box-shadow: ${boxes.bottomShaddow};

View File

@ -1555,12 +1555,9 @@ chart.js@^2.4.0:
chartjs-color "^2.0.0" chartjs-color "^2.0.0"
moment "^2.10.6" moment "^2.10.6"
chartjs-chart-box-plot@^1.0.0-9: chartjs-chart-box-plot@prerelease:
version "1.0.0-9" version "1.0.0-18"
resolved "https://registry.yarnpkg.com/chartjs-chart-box-plot/-/chartjs-chart-box-plot-1.0.0-9.tgz#bd392c689301e71b13f602818629f5a0965eaddb" resolved "https://registry.yarnpkg.com/chartjs-chart-box-plot/-/chartjs-chart-box-plot-1.0.0-18.tgz#66a671af5ea37155b40d85e89dc6cbae38b90330"
dependencies:
react "^15.4.1"
react-dom "^15.4.1"
chartjs-color-string@^0.4.0: chartjs-color-string@^0.4.0:
version "0.4.0" version "0.4.0"
@ -5412,7 +5409,7 @@ react-docgen@^2.12.1:
node-dir "^0.1.10" node-dir "^0.1.10"
recast "^0.11.5" recast "^0.11.5"
react-dom@^15.4.1, react-dom@^15.4.2: react-dom@^15.4.2:
version "15.4.2" version "15.4.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f"
dependencies: dependencies:
@ -5487,7 +5484,7 @@ react-stubber@^1.0.0:
dependencies: dependencies:
babel-runtime "^6.5.0" babel-runtime "^6.5.0"
react@^15.4.1, react@^15.4.2: react@^15.4.2:
version "15.4.2" version "15.4.2"
resolved "https://registry.yarnpkg.com/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef" resolved "https://registry.yarnpkg.com/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef"
dependencies: dependencies: