feat: scale and domain in charts, fixes a few bugs
This commit is contained in:
parent
9973c25054
commit
e155781fcb
|
@ -1,4 +1,6 @@
|
||||||
import { format } from "date-fns";
|
import {
|
||||||
|
addDays, differenceInDays, format, startOfDay, startOfToday, startOfTomorrow
|
||||||
|
} from "date-fns";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
VictoryAxis, VictoryChart, VictoryGroup, VictoryLabel, VictoryLegend, VictoryLine,
|
VictoryAxis, VictoryChart, VictoryGroup, VictoryLabel, VictoryLegend, VictoryLine,
|
||||||
|
@ -35,12 +37,13 @@ type DataSet = { date: Date; probability: number; name: string }[];
|
||||||
|
|
||||||
const dataAsXy = (data: DataSet) =>
|
const dataAsXy = (data: DataSet) =>
|
||||||
data.map((datum) => ({
|
data.map((datum) => ({
|
||||||
x: format(datum.date, "yyyy-MM-dd"),
|
x: datum.date,
|
||||||
y: datum.probability,
|
y: datum.probability,
|
||||||
name: datum.name,
|
name: datum.name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const colors = ["dodgerblue", "crimson", "seagreen", "darkviolet", "turquoise"];
|
const colors = ["dodgerblue", "crimson", "seagreen", "darkviolet", "turquoise"];
|
||||||
|
|
||||||
// can't be replaced with React component, VictoryChart requires VictoryGroup elements to be immediate children
|
// can't be replaced with React component, VictoryChart requires VictoryGroup elements to be immediate children
|
||||||
const getVictoryGroup = ({ data, i }: { data: DataSet; i: number }) => {
|
const getVictoryGroup = ({ data, i }: { data: DataSet; i: number }) => {
|
||||||
return (
|
return (
|
||||||
|
@ -67,14 +70,19 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
if (isBinary) {
|
if (isBinary) {
|
||||||
dataSetsNames = ["Yes"];
|
dataSetsNames = ["Yes"];
|
||||||
}
|
}
|
||||||
|
|
||||||
let dataSets: DataSet[] = [];
|
let dataSets: DataSet[] = [];
|
||||||
let maxProbability = 0;
|
let maxProbability = 0;
|
||||||
let longestNameLength = 0;
|
let longestNameLength = 0;
|
||||||
|
|
||||||
|
const sortedHistory = question.history.sort((a, b) =>
|
||||||
|
a.timestamp < b.timestamp ? -1 : 1
|
||||||
|
);
|
||||||
|
|
||||||
for (const name of dataSetsNames) {
|
for (const name of dataSetsNames) {
|
||||||
let newDataset: DataSet = [];
|
let newDataset: DataSet = [];
|
||||||
let previousDate = -Infinity;
|
let previousDate = -Infinity;
|
||||||
for (let item of question.history) {
|
for (let item of sortedHistory) {
|
||||||
const relevantItemsArray = item.options.filter((x) => x.name === name);
|
const relevantItemsArray = item.options.filter((x) => x.name === name);
|
||||||
const date = new Date(item.timestamp * 1000);
|
const date = new Date(item.timestamp * 1000);
|
||||||
if (
|
if (
|
||||||
|
@ -122,6 +130,18 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
symbol: { fill: colors[i] },
|
symbol: { fill: colors[i] },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const minDate = sortedHistory.length
|
||||||
|
? startOfDay(new Date(sortedHistory[0].timestamp * 1000))
|
||||||
|
: startOfToday();
|
||||||
|
const maxDate = sortedHistory.length
|
||||||
|
? addDays(
|
||||||
|
startOfDay(
|
||||||
|
new Date(sortedHistory[sortedHistory.length - 1].timestamp * 1000)
|
||||||
|
),
|
||||||
|
1
|
||||||
|
)
|
||||||
|
: startOfTomorrow();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VictoryChart
|
<VictoryChart
|
||||||
domainPadding={20}
|
domainPadding={20}
|
||||||
|
@ -131,7 +151,7 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
width={width}
|
width={width}
|
||||||
containerComponent={
|
containerComponent={
|
||||||
<VictoryVoronoiContainer
|
<VictoryVoronoiContainer
|
||||||
labels={({ datum }) => `Not shown`}
|
labels={() => "Not shown"}
|
||||||
labelComponent={
|
labelComponent={
|
||||||
<VictoryTooltip
|
<VictoryTooltip
|
||||||
constrainToVisibleArea
|
constrainToVisibleArea
|
||||||
|
@ -154,13 +174,17 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
voronoiBlacklist={
|
voronoiBlacklist={
|
||||||
["line-0", "line-1", "line-2", "line-3", "line-4"]
|
[...Array(5).keys()].map((i) => `line-${i}`)
|
||||||
//Array.from(Array(5).keys()).map((x, i) => `line${i}`)
|
|
||||||
// see: https://github.com/FormidableLabs/victory/issues/545
|
// see: https://github.com/FormidableLabs/victory/issues/545
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
scale={{
|
||||||
|
x: "time",
|
||||||
|
y: "linear",
|
||||||
|
}}
|
||||||
domain={{
|
domain={{
|
||||||
|
x: [minDate, maxDate],
|
||||||
y: [0, domainMax],
|
y: [0, domainMax],
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -177,17 +201,10 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
.slice(0, 5)
|
.slice(0, 5)
|
||||||
.map((dataset, i) => getVictoryGroup({ data: dataset, i }))}
|
.map((dataset, i) => getVictoryGroup({ data: dataset, i }))}
|
||||||
<VictoryAxis
|
<VictoryAxis
|
||||||
// tickValues specifies both the number of ticks and where
|
tickCount={Math.min(7, differenceInDays(maxDate, minDate) + 1)}
|
||||||
// they are placed on the axis
|
|
||||||
// tickValues={dataAsXy.map((datum) => datum.x)}
|
|
||||||
// tickFormat={dataAsXy.map((datum) => datum.x)}
|
|
||||||
tickCount={7}
|
|
||||||
style={{
|
style={{
|
||||||
grid: { stroke: null, strokeWidth: 0.5 },
|
grid: { stroke: null, strokeWidth: 0.5 },
|
||||||
}}
|
}}
|
||||||
//axisLabelComponent={
|
|
||||||
// <VictoryLabel dy={40} style={{ fontSize: 10, fill: "gray" }} />
|
|
||||||
//}
|
|
||||||
tickLabelComponent={
|
tickLabelComponent={
|
||||||
<VictoryLabel
|
<VictoryLabel
|
||||||
dy={10}
|
dy={10}
|
||||||
|
@ -195,17 +212,19 @@ export const HistoryChart: React.FC<Props> = ({ question }) => {
|
||||||
style={{ fontSize: 15, fill: "gray" }}
|
style={{ fontSize: 15, fill: "gray" }}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
scale={{ x: "time" }}
|
||||||
|
tickFormat={(t) => format(t, "yyyy-MM-dd")}
|
||||||
/>
|
/>
|
||||||
<VictoryAxis
|
<VictoryAxis
|
||||||
dependentAxis
|
dependentAxis
|
||||||
// tickFormat specifies how ticks should be displayed
|
|
||||||
tickFormat={(x) => `${x * 100}%`}
|
|
||||||
style={{
|
style={{
|
||||||
grid: { stroke: "#D3D3D3", strokeWidth: 0.5 },
|
grid: { stroke: "#D3D3D3", strokeWidth: 0.5 },
|
||||||
}}
|
}}
|
||||||
tickLabelComponent={
|
tickLabelComponent={
|
||||||
<VictoryLabel dy={0} style={{ fontSize: 15, fill: "gray" }} />
|
<VictoryLabel dy={0} style={{ fontSize: 15, fill: "gray" }} />
|
||||||
}
|
}
|
||||||
|
// tickFormat specifies how ticks should be displayed
|
||||||
|
tickFormat={(x) => `${x * 100}%`}
|
||||||
/>
|
/>
|
||||||
</VictoryChart>
|
</VictoryChart>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user