From 912e1b96bfa7d6c022d854fa744f719b49ca98d0 Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Tue, 21 Jul 2020 15:33:37 +0200 Subject: Add first plotting attempts for portfolios --- .../components/app/results/MetricChartComponent.js | 67 +++++++++++++++++++ .../app/results/PortfolioResultsComponent.js | 78 ++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 frontend/src/components/app/results/MetricChartComponent.js create mode 100644 frontend/src/components/app/results/PortfolioResultsComponent.js (limited to 'frontend/src/components/app/results') diff --git a/frontend/src/components/app/results/MetricChartComponent.js b/frontend/src/components/app/results/MetricChartComponent.js new file mode 100644 index 00000000..29a4676a --- /dev/null +++ b/frontend/src/components/app/results/MetricChartComponent.js @@ -0,0 +1,67 @@ +import React from 'react' +import ReactDOM from 'react-dom/server' +import SvgSaver from 'svgsaver' +import { VictoryAxis, VictoryChart, VictoryLabel, VictoryLine, VictoryScatter } from 'victory' +import { convertSecondsToFormattedTime } from '../../../util/date-time' + +const MetricChartComponent = ({ data, currentTick }) => { + const onExport = () => { + const div = document.createElement('div') + div.innerHTML = ReactDOM.renderToString( + + ) + div.firstChild.style = 'font-family: Roboto, Arial, sans-serif; font-size: 10pt;' + const svgSaver = new SvgSaver() + svgSaver.asSvg(div.firstChild, 'opendc-chart-export-' + Date.now() + '.svg') + } + + return ( +
+ Load over time + + +
+ ) +} + +const VictoryChartComponent = ({ data, currentTick, showCurrentTick }) => ( + + convertSecondsToFormattedTime(tick)} + fixLabelOverlap={true} + label="Simulated Time" + /> + + + + {showCurrentTick ? ( + } + data={[ + { x: currentTick + 1, y: 0 }, + { x: currentTick + 1, y: 1 }, + ]} + labels={(point) => + point.y === 1 ? 'Current tick : ' + convertSecondsToFormattedTime(currentTick) : '' + } + style={{ + data: { stroke: '#00A6D6', strokeWidth: 4 }, + labels: { fill: '#00A6D6' }, + }} + /> + ) : undefined} + +) + +const ExportChartComponent = ({ onExport }) => ( + +) + +export default MetricChartComponent diff --git a/frontend/src/components/app/results/PortfolioResultsComponent.js b/frontend/src/components/app/results/PortfolioResultsComponent.js new file mode 100644 index 00000000..8c778098 --- /dev/null +++ b/frontend/src/components/app/results/PortfolioResultsComponent.js @@ -0,0 +1,78 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Bar, BarChart, CartesianGrid, ErrorBar, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts' +import { AVAILABLE_METRICS, METRIC_NAMES } from '../../../util/available-metrics' +import { mean, std } from 'mathjs' +import Shapes from '../../../shapes/index' +import approx from 'approximate-number' + +const PortfolioResultsComponent = ({ portfolio, scenarios }) => { + if (!portfolio) { + return
Loading...
+ } + + const nonFinishedScenarios = scenarios.filter((s) => s.simulation.state !== 'FINISHED') + + if (nonFinishedScenarios.length > 0) { + if (nonFinishedScenarios.every((s) => s.simulation.state === 'QUEUED' || s.simulation.state === 'RUNNING')) { + return ( +
+

Simulation running...

+

{nonFinishedScenarios.length} of the scenarios are still being simulated

+
+ ) + } + if (nonFinishedScenarios.some((s) => s.simulation.state === 'FAILED')) { + return ( +
+

Simulation failed.

+

+ Try again by creating a new scenario. Please contact the OpenDC team for support, if issues + persist. +

+
+ ) + } + } + + const dataPerMetric = {} + + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios.map((scenario) => ({ + name: scenario.name, + value: mean(scenario.results[metric]), + std: std(scenario.results[metric]), + })) + }) + + return ( +
+

Portfolio: {portfolio.name}

+

Repeats per Scenario: {portfolio.targets.repeatsPerScenario}

+
+ {AVAILABLE_METRICS.map(metric => ( +
+

{METRIC_NAMES[metric]}

+ + + + + approx(tick)}/> + + + + + +
+ ))} +
+
+ ) +} + +PortfolioResultsComponent.propTypes = { + portfolio: Shapes.Portfolio, + scenarios: PropTypes.arrayOf(Shapes.Scenario), +} + +export default PortfolioResultsComponent -- cgit v1.2.3