import { differenceInDays, format } from "date-fns"; import { VictoryAxis, VictoryChart, VictoryGroup, VictoryStack, VictoryLabel, VictoryLine, VictoryScatter, VictoryArea, VictoryTheme, VictoryTooltip, VictoryVoronoiContainer, } from "victory"; import { chartColors, ChartData, ChartSeries, goldenRatio } from "./utils"; const height = 200 const width = height * goldenRatio let dateFormat = "dd/MM/yy"; // "yyyy-MM-dd" // "MMM do yy" // can't be replaced with React component, VictoryChart requires VictoryGroup elements to be immediate children const getVictoryGroup = ({ data, i, highlight, isBinary, }: { data: ChartSeries; i: number; highlight?: boolean; isBinary?: boolean; }) => { return ( {isBinary ? ( ) : null} (active || highlight ? 0 : 0)} //(active || highlight ? 3.75 : 3)} /> ); }; export type Props = { data: ChartData; highlight: number | undefined; }; export const InnerChart: React.FC = ({ data: { maxProbability, seriesList, minDate, maxDate }, highlight, }) => { const domainMax = maxProbability < 0.5 ? Math.round(10 * (maxProbability + 0.05)) / 10 : 1; const padding = { top: 15, bottom: 50, left: 30, right: 17, }; const isBinary = seriesList.length == 1; console.log(isBinary); return ( "Not shown"} labelComponent={ } text={({ datum }) => `${datum.name}: ${Math.round(datum.y * 100)}%\n${format( datum.x, dateFormat )}` } style={{ fontSize: 10, // needs to be set here and not just in labelComponent for text size calculations fontFamily: '"Gill Sans", "Gill Sans MT", "SerĀ­avek", "Trebuchet MS", sans-serif', // default font family from Victory, need to be specified explicitly for some reason, otherwise text size gets miscalculated }} flyoutStyle={{ stroke: "#999", fill: "white", }} cornerRadius={4} flyoutPadding={{ top: 4, bottom: 4, left: 10, right: 10 }} /> } radius={20} voronoiBlacklist={ [...Array(seriesList.length).keys()].map((i) => `line-${i}`) // see: https://github.com/FormidableLabs/victory/issues/545 } /> } scale={{ x: "time", y: "linear", }} domain={{ x: [minDate, maxDate], y: [0, domainMax], }} > { // Note: axis is not in fact unaligned. Fetchers are at ~12:00 // whereas the date is at the beginning of the day // however, it still doesn't look very pretty. } } scale={{ x: "time" }} tickFormat={(t) => format(t, dateFormat)} /> } // tickFormat specifies how ticks should be displayed tickFormat={(x) => `${x * 100}%`} /> {[...Array(seriesList.length).keys()] .reverse() // affects svg render order, we want to render largest datasets on top of others //.filter((i) => i !== highlight) .map((i) => getVictoryGroup({ data: seriesList[i], i, highlight: i == highlight, // false isBinary: isBinary, }) )} { // note: this produces an annoying change of color effect /* highlight === undefined ? null : // render highlighted series on top of everything else getVictoryGroup({ data: seriesList[highlight], i: highlight, highlight: true, }) */ } ); };