src/components/Chart/HistoricalChart.js
import React from 'react';
import moment from 'moment';
import { Icon } from 'antd';
import ChartEngine from './ChartEngine';
import ChartLegend from './ChartLegend';
import ChartTimeRange from './ChartTimeRange';
import ChartDeleteButton from './ChartDeleteButton';
const exportToCsv = (metric1, metric2, measurements1, measurements2) => {
let bySecond = Object.values(measurements1).reduce((c, d) => c.concat(d), []);
if (measurements2) {
bySecond = bySecond.concat(Object.values(measurements1).reduce((c, d) => c.concat(d), []));
}
bySecond = bySecond.map(d => moment(d.time).unix())
.filter((v, i, a) => a.indexOf(v) === i)
.sort();
let labels = [ 'time', ...Object.keys(measurements1).map(m => metric1 + ':' + m) ];
if (measurements2) {
labels = labels.concat(Object.keys(measurements2).map(m => metric2 + ':' + m));
}
const arr2d = bySecond.map(() => Array.from({ length: labels.length }));
const bySecondToIndex = bySecond.reduce((c, v, i) => Object.assign({ [v]: i }, c), {});
const labelsToIndex = labels.reduce((c, v, i) => Object.assign({ [v]: i }, c), {});
for (let i = 0; i < arr2d.length; ++i) {
arr2d[i][0] = moment.unix(bySecond[i]).toISOString();
}
for (const host of Object.keys(measurements1)) {
for (const point of Object.values(measurements1[host])) {
arr2d[bySecondToIndex[moment(point.time).unix()]][labelsToIndex[metric1 + ':' + host]] = point.value;
}
}
if (measurements2) {
for (const host of Object.keys(measurements2)) {
for (const point of Object.values(measurements2[host])) {
arr2d[bySecondToIndex[moment(point.time).unix()]][labelsToIndex[metric2 + ':' + host]] = point.value;
}
}
}
const toExport = [ labels, ...arr2d ];
const str = toExport.map(v => v.join(',')).join('\r\n');
const exportLink = document.createElement('a');
exportLink.setAttribute('href', 'data:text/csv;base64,' + window.btoa(str));
exportLink.setAttribute('download', 'historical_' + metric1 + (metric2 ? '_' + metric2 : '') + '.csv');
exportLink.appendChild(document.createTextNode('test.csv'));
document.getElementsByTagName('body')[0].appendChild(exportLink);
exportLink.click();
exportLink.remove();
};
const HistoricalChart = ({
metric1, measurements1, hosts1,
metric2, measurements2, hosts2,
metrics, indeterminate, start, end,
onMetric1Changed, onHostDismissedFromMetric1, onHostAddedToMetric1,
onMetric2Changed, onHostDismissedFromMetric2, onHostAddedToMetric2,
onRangeChanged, onChartClosed
}) => (
<div className="chart-container">
<div className="chart-container-main">
<div className="chart-corner">
<ChartTimeRange from={start} to={end} onChange={onRangeChanged} />
<a
className="chart-csv-button"
onClick={() => exportToCsv(metric1, metric2, measurements1, measurements2)}
>
<Icon type="export" />
</a>
<ChartDeleteButton onDelete={onChartClosed} />
</div>
<ChartEngine
metric1={metrics[metric1]}
metric1Measurements={measurements1}
metric2={metrics[metric2]}
metric2Measurements={measurements2}
indeterminate={indeterminate}
/>
</div>
<div className="chart-container-side">
<ChartLegend
necessary={true}
label="Metryka podstawowa"
metrics={metrics}
metric={metric1}
hosts={hosts1}
onMetricChanged={onMetric1Changed}
onHostAdded={onHostAddedToMetric1}
onHostDismissed={onHostDismissedFromMetric1}
/>
<ChartLegend
label="Metryka dodatkowa"
metrics={metrics}
metric={metric2}
hosts={hosts2}
onMetricChanged={onMetric2Changed}
onHostAdded={onHostAddedToMetric2}
onHostDismissed={onHostDismissedFromMetric2}
/>
</div>
</div>
);
export default HistoricalChart;