import * as plotly from "plotly.js-dist" import React, { FC, useEffect, useState } from "react" import { Grid, FormControl, FormLabel, MenuItem, Select, } from "@material-ui/core" import { createStyles, makeStyles, Theme } from "@material-ui/core/styles" const plotDomId = "graph-pareto-front" const useStyles = makeStyles((theme: Theme) => createStyles({ formControl: { marginBottom: theme.spacing(2), marginRight: theme.spacing(5), marginTop: theme.spacing(10), }, }) ) export const GraphParetoFront: FC<{ study: StudyDetail | null }> = ({ study = null }) => { const classes = useStyles() const [objectiveXId, setObjectiveXId] = useState(0) const [objectiveYId, setObjectiveYId] = useState(1) const handleObjectiveXChange = ( event: React.ChangeEvent<{ value: unknown }> ) => { setObjectiveXId(event.target.value as number) } const handleObjectiveYChange = ( event: React.ChangeEvent<{ value: unknown }> ) => { setObjectiveYId(event.target.value as number) } useEffect(() => { if (study != null) { plotParetoFront(study, objectiveXId, objectiveYId) } }, [study, objectiveXId, objectiveYId]) return ( {study !== null && study.directions.length !== 1 ? ( Objective X ID: Objective Y ID: ) : null}
) } const plotParetoFront = ( study: StudyDetail, objectiveXId: number, objectiveYId: number ) => { if (document.getElementById(plotDomId) === null) { return } const dim: number = study.directions.length if (dim != 2) { return } const layout: Partial = { title: "Pareto-front plot", margin: { l: 50, r: 50, b: 0, }, } const trials: Trial[] = study ? study.trials : [] const completedTrials = trials.filter((t) => t.state === "Complete") if (completedTrials.length === 0) { plotly.react(plotDomId, [], layout) return } const normalizedValues: number[][] = [] completedTrials.forEach((t) => { if (t.values && t.values.length == dim) { const trialValues = t.values.map((v: number, i: number) => { return study.directions[i] === "minimize" ? v : -v }) normalizedValues.push(trialValues) } }) const pointColors: string[] = [] normalizedValues.forEach((values0: number[], i: number) => { let dominated = false dominated = normalizedValues.some((values1: number[], j: number) => { if (i === j) { return false } return values0.every((value0: number, k: number) => { return values1[k] <= value0 }) }) if (dominated) { pointColors.push("blue") } else { pointColors.push("red") } }) const plotData: Partial[] = [ { type: "scatter", x: completedTrials.map((t: Trial): number => { return t.values![objectiveXId] }), y: completedTrials.map((t: Trial): number => { return t.values![objectiveYId] }), mode: "markers", xaxis: "Objective X", yaxis: "Objective Y", marker: { color: pointColors, }, text: completedTrials.map((t: Trial): string => { return JSON.stringify( { number: t.number, values: t.values, params: t.params, }, null, 2 ).replaceAll("\n", "
") }), hovertemplate: "%{text}", }, ] plotly.react(plotDomId, plotData, layout) }