diff options
| author | jc0b <j@jc0b.computer> | 2020-07-22 16:28:47 +0200 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2020-08-24 19:48:21 +0200 |
| commit | d7469b9ebb01cf36a78cc98aab31fa8f307c4f65 (patch) | |
| tree | d0535fa0cfe95001302fbd2b0d046d51caab6ffd /frontend/src/components/app/results/PortfolioResultsComponent.js | |
| parent | 67b6ec800df8e023efadb60ae5f7919030b19789 (diff) | |
| parent | 9e7cb3bd367607b32e102c3a87b68b33c53dec46 (diff) | |
Merge branch 'master' onto working copy
Diffstat (limited to 'frontend/src/components/app/results/PortfolioResultsComponent.js')
| -rw-r--r-- | frontend/src/components/app/results/PortfolioResultsComponent.js | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/frontend/src/components/app/results/PortfolioResultsComponent.js b/frontend/src/components/app/results/PortfolioResultsComponent.js new file mode 100644 index 00000000..35dba603 --- /dev/null +++ b/frontend/src/components/app/results/PortfolioResultsComponent.js @@ -0,0 +1,89 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' +import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_UNITS } 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 <div>Loading...</div> + } + + 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 ( + <div> + <h1>Simulation running...</h1> + <p>{nonFinishedScenarios.length} of the scenarios are still being simulated</p> + </div> + ) + } + if (nonFinishedScenarios.some((s) => s.simulation.state === 'FAILED')) { + return ( + <div> + <h1>Simulation failed.</h1> + <p> + Try again by creating a new scenario. Please contact the OpenDC team for support, if issues + persist. + </p> + </div> + ) + } + } + + const dataPerMetric = {} + + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios.map((scenario) => ({ + name: scenario.name, + value: mean(scenario.results[metric]), + errorX: std(scenario.results[metric]), + })) + }) + + return ( + <div className="full-height" style={{ overflowY: 'scroll', overflowX: 'hidden' }}> + <h2>Portfolio: {portfolio.name}</h2> + <p>Repeats per Scenario: {portfolio.targets.repeatsPerScenario}</p> + <div className="row"> + {AVAILABLE_METRICS.map((metric) => ( + <div className="col-6 mb-2" key={metric}> + <h4>{METRIC_NAMES[metric]}</h4> + <ResponsiveContainer aspect={16 / 9} width="100%"> + <ComposedChart data={dataPerMetric[metric]} margin={{ left: 35, bottom: 15 }} layout="vertical"> + <CartesianGrid strokeDasharray="3 3" /> + <XAxis + tickFormatter={(tick) => approx(tick)} + label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} + type="number" + /> + <YAxis dataKey="name" type="category" /> + <Bar dataKey="value" fill="#3399FF" isAnimationActive={false} /> + <Scatter dataKey="value" opacity={0} isAnimationActive={false}> + <ErrorBar + dataKey="errorX" + width={10} + strokeWidth={3} + stroke="#FF6600" + direction="x" + /> + </Scatter> + </ComposedChart> + </ResponsiveContainer> + </div> + ))} + </div> + </div> + ) +} + +PortfolioResultsComponent.propTypes = { + portfolio: Shapes.Portfolio, + scenarios: PropTypes.arrayOf(Shapes.Scenario), +} + +export default PortfolioResultsComponent |
