From 340d99b4852cd48c15a6b3c375358fcbccb157df Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Thu, 28 Apr 2022 15:22:22 -0400 Subject: [PATCH] tweak: Charts Add line, reorganize display Also fix nasty bug where probabilities are inverted in frontpage --- .eslintrc | 6 + src/web/questions/components/HistoryChart.tsx | 249 ++++++++++-------- .../questions/components/QuestionOptions.tsx | 11 +- src/web/questions/pages/QuestionPage.tsx | 24 +- 4 files changed, 174 insertions(+), 116 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..8def063 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,6 @@ +{ + "extends": ["next", "prettier"], + "rules": { + "next/no-document-import-in-page": "off" + } +} diff --git a/src/web/questions/components/HistoryChart.tsx b/src/web/questions/components/HistoryChart.tsx index fa33703..cd6a404 100644 --- a/src/web/questions/components/HistoryChart.tsx +++ b/src/web/questions/components/HistoryChart.tsx @@ -1,7 +1,15 @@ import React from "react"; import { - VictoryAxis, VictoryChart, VictoryGroup, VictoryLabel, VictoryLegend, VictoryScatter, - VictoryTheme, VictoryTooltip, VictoryVoronoiContainer + VictoryAxis, + VictoryChart, + VictoryGroup, + VictoryLabel, + VictoryLegend, + VictoryScatter, + VictoryLine, + VictoryTheme, + VictoryTooltip, + VictoryVoronoiContainer, } from "victory"; import { QuestionWithHistoryFragment } from "../../fragments.generated"; @@ -48,26 +56,25 @@ const getVictoryGroup = (data, i) => { return ( (active ? 3.75 : 3)} //labels={() => null} //labelComponent={} /> - {/* Doesn't work well with tooltips - null} - //labelComponent={} - /> - */} + null} + //labelComponent={} + /> ); }; export const HistoryChart: React.FC = ({ question }) => { - let height = 400; + let height = 300; let width = 500; let padding = { top: 20, bottom: 50, left: 50, right: 100 }; // let dataSetsNames = ["Yes", "No", "Maybe", "Perhaps", "Possibly"]; @@ -78,6 +85,7 @@ export const HistoryChart: React.FC = ({ question }) => { }); dataSetsNames = [...new Set(dataSetsNames)].slice(0, 5); // take the first 5 let dataSets = []; + /* dataSetsNames.forEach((name) => { let newDataset = []; question.history.forEach((item) => { @@ -96,112 +104,145 @@ export const HistoryChart: React.FC = ({ question }) => { }); dataSets.push(newDataset); }); + */ + + dataSetsNames.forEach((name) => { + let newDataset = []; + let previousDate = -Infinity; + for (let item of question.history) { + let relevantItemsArray = item.options.filter((x) => x.name == name); + let date = new Date(item.timestamp * 1000); + if ( + relevantItemsArray.length == 1 && + item.timestamp - previousDate > 12 * 60 * 60 + ) { + let relevantItem = relevantItemsArray[0]; + // if (relevantItem.type == "PROBABILITY") { + let result = { + date, + probability: relevantItem.probability, + }; + newDataset.push(result); + // } + previousDate = item.timestamp; + } + } + dataSets.push(newDataset); + }); let dataSetsLength = dataSets.length; return ( -
- +
+
+ + {/*

{question.title}

-
- `${datum.x}: ${Math.round(datum.y * 100)}%`} - labelComponent={ - - } - voronoiBlacklist={ - ["line0", "line1", "line2", "line3", "line4"] + */} + + + `${datum.x}: ${Math.round(datum.y * 100)}%` + } + labelComponent={ + + } + voronoiBlacklist={ + ["line-0", "line-1", "line-2", "line-3", "line-4"] - //Array.from(Array(5).keys()).map((x, i) => `line${i}`) - // see: https://github.com/FormidableLabs/victory/issues/545 - } - /> - } - domain={{ - y: [0, 1], - }} - > - ({ - name: dataSetsNames[i], - symbol: { fill: colors[i] }, - })) - /*[ + //Array.from(Array(5).keys()).map((x, i) => `line${i}`) + // see: https://github.com/FormidableLabs/victory/issues/545 + } + /> + } + domain={{ + y: [0, 1], + }} + > + ({ + name: dataSetsNames[i], + symbol: { fill: colors[i] }, + })) + /*[ { name: "One", symbol: { fill: "tomato", type: "star" } }, { name: "Two", symbol: { fill: "orange" } }, { name: "Three", symbol: { fill: "gold" } }, ]*/ - } - /> + } + /> - {dataSets.slice(0, 5).map((dataset, i) => getVictoryGroup(dataset, i))} - datum.x)} - // tickFormat={dataAsXy.map((datum) => datum.x)} - tickCount={7} - style={{ - grid: { stroke: null, strokeWidth: 0.5 }, - }} - //axisLabelComponent={ - // - //} - // label="Date (dd/mm/yy)" - tickLabelComponent={ - - } - /> - `${x * 100}%`} - style={{ - grid: { stroke: "#D3D3D3", strokeWidth: 0.5 }, - }} - tickLabelComponent={ - - } - /> - + {dataSets + .slice(0, 5) + .map((dataset, i) => getVictoryGroup(dataset, i))} + datum.x)} + // tickFormat={dataAsXy.map((datum) => datum.x)} + tickCount={7} + style={{ + grid: { stroke: null, strokeWidth: 0.5 }, + }} + //axisLabelComponent={ + // + //} + // label="Date (dd/mm/yy)" + tickLabelComponent={ + + } + /> + `${x * 100}%`} + style={{ + grid: { stroke: "#D3D3D3", strokeWidth: 0.5 }, + }} + tickLabelComponent={ + + } + /> + +
); }; diff --git a/src/web/questions/components/QuestionOptions.tsx b/src/web/questions/components/QuestionOptions.tsx index d984747..4a5ff9b 100644 --- a/src/web/questions/components/QuestionOptions.tsx +++ b/src/web/questions/components/QuestionOptions.tsx @@ -112,7 +112,8 @@ export const QuestionOptions: React.FC<{ options: Option[] }> = ({ const isBinary = options.length === 2 && (options[0].name === "Yes" || options[0].name === "No"); - + const getYesOption = (options) => + options.find((option) => option.name == "Yes"); const optionsSorted = options.sort((a, b) => b.probability - a.probability); const optionsMax5 = !!optionsSorted.slice ? optionsSorted.slice(0, 5) : []; // display max 5 options. @@ -121,17 +122,17 @@ export const QuestionOptions: React.FC<{ options: Option[] }> = ({
- {formatProbability(options[0].probability)} + {formatProbability(getYesOption(options).probability)} - {primaryEstimateAsText(options[0].probability)} + {primaryEstimateAsText(getYesOption(options).probability)}
); diff --git a/src/web/questions/pages/QuestionPage.tsx b/src/web/questions/pages/QuestionPage.tsx index 4b2b926..739c251 100644 --- a/src/web/questions/pages/QuestionPage.tsx +++ b/src/web/questions/pages/QuestionPage.tsx @@ -40,8 +40,8 @@ export const getServerSideProps: GetServerSideProps = async ( const QuestionCardContents: React.FC<{ question: QuestionWithHistoryFragment; }> = ({ question }) => ( -