Skip to content

Commit

Permalink
Graphs fully switched over
Browse files Browse the repository at this point in the history
  • Loading branch information
nkalupahana committed Dec 25, 2023
1 parent 2dc082d commit b879cac
Show file tree
Hide file tree
Showing 13 changed files with 425 additions and 252 deletions.
34 changes: 0 additions & 34 deletions src/components/Review/SurveyGraph.tsx

This file was deleted.

45 changes: 37 additions & 8 deletions src/components/Review/WeekInReviewReview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { IonIcon, IonSpinner } from "@ionic/react";
import { ref, serverTimestamp, set } from "firebase/database";
import { useEffect, useState } from "react";
import { auth, db } from "../../firebase";
import { AnyMap, PullDataStates, BASELINE_GRAPH_CONFIG, calculateBaseline, parseSurveyHistory, toast } from "../../helpers";
import { AnyMap, PullDataStates, calculateBaseline, parseSurveyHistory, toast } from "../../helpers";
import history from "../../history";
import Screener, { Priority } from "../../screeners/screener";
import SwiperType, { Pagination } from "swiper";
Expand All @@ -11,8 +11,9 @@ import "swiper/css";
import "swiper/css/pagination";
import { chevronBackOutline, chevronForwardOutline } from "ionicons/icons";
import { useAuthState } from "react-firebase-hooks/auth";
import SurveyGraph from "./SurveyGraph";
import BaselineDescription from "./BaselineDescription";
import BaselineGraph from "../graphs/BaselineGraph";
import useGraphConfig from "../graphs/useGraphConfig";

interface Props {
primary: Screener,
Expand All @@ -26,6 +27,9 @@ const WeekInReviewReview = ({ primary, secondary, update }: Props) => {
const [user] = useAuthState(auth);
const [surveyHistory, setSurveyHistory] = useState<AnyMap | PullDataStates>(PullDataStates.NOT_STARTED);
const [baselineGraph, setBaselineGraph] = useState<AnyMap[] | PullDataStates>(PullDataStates.NOT_STARTED);
const [swiperProgress, setSwiperProgress] = useState(0);

const { now, xZoomDomain, setXZoomDomain, zoomTo, pageWidthRef, pageWidth, tickCount, memoTickFormatter } = useGraphConfig();

useEffect(() => {
if (!user) return;
Expand Down Expand Up @@ -68,6 +72,9 @@ const WeekInReviewReview = ({ primary, secondary, update }: Props) => {
pagination={true}
onSwiper={swiper => setSwiper(swiper)}
className="swiper-container-mod"
onSlideChange={s => {
setSwiperProgress(s.progress);
}}
>
<SwiperSlide style={{"display": "flex", "alignItems": "center", "justifyContent": "center"}}>
<div>
Expand All @@ -79,9 +86,20 @@ const WeekInReviewReview = ({ primary, secondary, update }: Props) => {
return <SwiperSlide key={screener._key}>
<div className="title">Results</div>
<div className="text-center screener-slide">
{ screener.graphConfig && typeof surveyHistory === "object" &&
{ screener.graph && typeof surveyHistory === "object" &&
screener.processDataForGraph &&
<SurveyGraph data={screener.processDataForGraph(surveyHistory)} graphConfig={screener.graphConfig} /> }
<div className="swiper-no-swiping">
<screener.graph
data={screener.processDataForGraph(surveyHistory)}
xZoomDomain={xZoomDomain}
setXZoomDomain={setXZoomDomain}
now={now}
pageWidth={pageWidth}
tickCount={tickCount}
tickFormatter={memoTickFormatter}
zoomTo={zoomTo}
/>
</div>}
{ screener.getRecommendation() }
<p style={{"fontSize": "9px"}}>
If you want to discuss these results with a
Expand All @@ -93,9 +111,20 @@ const WeekInReviewReview = ({ primary, secondary, update }: Props) => {
}) }
<SwiperSlide>
<div className="title">Your baseline</div>
<div className="text-center screener-slide">
<div className="text-center screener-slide" ref={pageWidthRef}>
{ typeof baselineGraph === "object" && <>
<SurveyGraph data={baselineGraph} graphConfig={BASELINE_GRAPH_CONFIG} />
<div className="swiper-no-swiping">
<BaselineGraph
xZoomDomain={xZoomDomain}
setXZoomDomain={setXZoomDomain}
data={baselineGraph}
now={now}
pageWidth={pageWidth}
tickCount={tickCount}
tickFormatter={memoTickFormatter}
zoomTo={zoomTo}
/>
</div>
<BaselineDescription />
</> }
{ typeof baselineGraph === "number" && <p>
Expand All @@ -111,8 +140,8 @@ const WeekInReviewReview = ({ primary, secondary, update }: Props) => {
</SwiperSlide>
</Swiper>
<div className="swiper-pagniation-controls">
<IonIcon onClick={() => swiper?.slidePrev()} icon={chevronBackOutline} />
<IonIcon onClick={() => swiper?.slideNext()} icon={chevronForwardOutline} />
<IonIcon onClick={() => swiper?.slidePrev()} icon={chevronBackOutline} style={swiperProgress === 0 ? {color: "grey"} : {}} />
<IonIcon onClick={() => swiper?.slideNext()} icon={chevronForwardOutline} style={swiperProgress === 1 ? {color: "grey"} : {}}/>
</div>
</div>;
}
Expand Down
68 changes: 68 additions & 0 deletions src/components/graphs/BaselineGraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { VictoryScatter, VictoryChart, VictoryAxis, VictoryZoomContainer } from "victory";
import { BlockerRectangle, CustomLineSegment, ONE_DAY, GraphProps, GraphHeader, VictoryDateAxis, DefaultLine } from "./graph-helpers";
import theme from "./graph-theme";
import { AnyMap, COLORS } from "../../helpers";

const BaselineGraph = ({ xZoomDomain, setXZoomDomain, data, now, pageWidth, tickCount, tickFormatter, zoomTo }: GraphProps) => {
const lines: AnyMap[] = [
{
y: "value",
color: COLORS[0],
}
];

const keyMap: AnyMap = {
value: "baseline score"
};

return (
<div>
<GraphHeader lines={lines} keyMap={keyMap} zoomTo={zoomTo} />
<VictoryChart
theme={theme}
domainPadding={{ x: [25, 0], y: [0, 0] }}
containerComponent={<VictoryZoomContainer
zoomDimension="x"
onZoomDomainChange={(domain) => setXZoomDomain(domain.x as [number, number])}
minimumZoom={{ x: ONE_DAY * 60 }}
zoomDomain={{ x: xZoomDomain }}
/>}
maxDomain={{ x: now + ONE_DAY * 3 }}
width={pageWidth}
>
{/* Lines */}
{lines.map(line => <DefaultLine data={data} line={line} key={line.y} />)}

{/* Points on line */}
{lines.map((line) => (
<VictoryScatter
key={line.y}
data={data}
x="timestamp"
y={line.y}
style={{
data: { fill: line.color },
}}
/>
))}

<BlockerRectangle />
<VictoryDateAxis tickFormatter={tickFormatter} tickCount={tickCount} />

{/* Category axis (y) */}
<VictoryAxis
crossAxis
dependentAxis
style={{
grid: { stroke: "grey" },
tickLabels: { padding: 4 },
}}
offsetX={80}
gridComponent={<CustomLineSegment dx1={30} />}
/>
</VictoryChart>
</div>
);
};

export default BaselineGraph;
64 changes: 12 additions & 52 deletions src/components/graphs/DASSGraph.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { VictoryLine, VictoryScatter, VictoryChart, VictoryAxis, VictoryZoomContainer } from "victory";
import { BlockerRectangle, CustomLineSegment, CustomVictoryLabel, MultiCurve, ONE_DAY, GraphProps, GraphHeader } from "./graph-helpers";
import { VictoryScatter, VictoryChart, VictoryAxis, VictoryZoomContainer } from "victory";
import { BlockerRectangle, CustomLineSegment, CustomVictoryLabel, ONE_DAY, GraphProps, GraphHeader, VictoryDateAxis, DefaultLine } from "./graph-helpers";
import theme from "./graph-theme";
import { AnyMap } from "../../helpers";

const DASSGraph = ({ xZoomDomain, setXZoomDomain, data, now, pageWidth, tickCount, tickFormatter }: GraphProps) => {
const DASSGraph = ({ xZoomDomain, setXZoomDomain, data, now, pageWidth, tickCount, tickFormatter, zoomTo }: GraphProps) => {
const labels = ["Normal", "Mild", "Moderate", "Severe", "Extremely\nSevere", ""];
const lines: AnyMap[] = [
{
Expand Down Expand Up @@ -31,53 +31,25 @@ const DASSGraph = ({ xZoomDomain, setXZoomDomain, data, now, pageWidth, tickCoun
a: 0,
s: -0.03,
};

const zoomTo = (key: "3M" | "6M" | "1Y" | "All") => {
const lateTime = xZoomDomain ? xZoomDomain[1] : now;
if (key === "3M") {
setXZoomDomain([lateTime - ONE_DAY * 90, lateTime]);
} else if (key === "6M") {
setXZoomDomain([lateTime - ONE_DAY * 180, lateTime]);
} else if (key === "1Y") {
setXZoomDomain([lateTime - ONE_DAY * 365, lateTime]);
} else if (key === "All") {
setXZoomDomain(undefined);
}
}

return (
<div style={{ height: "400px", width: "100%" }}>
<div>
<GraphHeader lines={lines} keyMap={keyMap} zoomTo={zoomTo} />

<VictoryChart
theme={theme}
domainPadding={{ x: [25, 0], y: [0, 0] }}
containerComponent={
<VictoryZoomContainer
zoomDimension="x"
onZoomDomainChange={(domain) => setXZoomDomain(domain.x as [number, number])}
minimumZoom={{ x: ONE_DAY * 60 }}
zoomDomain={{ x: xZoomDomain }}
/>
}
containerComponent={<VictoryZoomContainer
zoomDimension="x"
onZoomDomainChange={(domain) => setXZoomDomain(domain.x as [number, number])}
minimumZoom={{ x: ONE_DAY * 60 }}
zoomDomain={{ x: xZoomDomain }}
/>}
maxDomain={{ x: now + ONE_DAY * 3 }}
width={pageWidth}
>
{/* Lines */}
{lines.map((line) => (
<VictoryLine
key={line.y}
data={data}
scale={{ x: "time", y: "linear" }}
x="timestamp"
y={line.y}
style={{
data: { stroke: line.color },
}}
interpolation="monotoneX"
dataComponent={<MultiCurve />}
/>
))}
{lines.map(line => <DefaultLine data={data} line={line} key={line.y} />)}

{/* Points on line */}
{lines.map((line) => (
Expand All @@ -104,19 +76,7 @@ const DASSGraph = ({ xZoomDomain, setXZoomDomain, data, now, pageWidth, tickCoun
))}

<BlockerRectangle />
{/* Date axis (x) */}
<VictoryAxis
crossAxis
tickFormat={tickFormatter}
style={{
grid: { stroke: "none" },
tickLabels: { padding: 20, angle: -45},
}}
axisComponent={<CustomLineSegment dx1={20} />}
tickComponent={<CustomLineSegment xcutoff={80} />}
tickLabelComponent={<CustomVictoryLabel xcutoff={80} dx1={-16} />}
tickCount={tickCount}
/>
<VictoryDateAxis tickFormatter={tickFormatter} tickCount={tickCount} />

{/* Category axis (y) */}
<VictoryAxis
Expand Down
77 changes: 77 additions & 0 deletions src/components/graphs/ResilienceGraph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { VictoryScatter, VictoryChart, VictoryAxis, VictoryZoomContainer } from "victory";
import { BlockerRectangle, CustomLineSegment, ONE_DAY, GraphProps, GraphHeader, VictoryDateAxis, DefaultLine, CustomVictoryLabel } from "./graph-helpers";
import theme from "./graph-theme";
import { AnyMap, COLORS } from "../../helpers";
import { useMemo } from "react";

const ResilienceGraph = ({ xZoomDomain, setXZoomDomain, data, now, pageWidth, tickCount, tickFormatter, zoomTo }: GraphProps) => {
const lines: AnyMap[] = [
{
y: "value",
color: COLORS[-3],
}
];

const keyMap: AnyMap = {
value: "Resilience Score"
};

const labels = useMemo(() => {
return ["Low", "Medium", "High"];
}, []);

return (
<div>
<GraphHeader lines={lines} keyMap={keyMap} zoomTo={zoomTo} />

<VictoryChart
theme={theme}
domainPadding={{ x: [25, 0], y: [0, 0] }}
containerComponent={<VictoryZoomContainer
zoomDimension="x"
onZoomDomainChange={(domain) => setXZoomDomain(domain.x as [number, number])}
minimumZoom={{ x: ONE_DAY * 60 }}
zoomDomain={{ x: xZoomDomain }}
/>}
maxDomain={{ x: now + ONE_DAY * 3 }}
width={pageWidth}
>
{/* Lines */}
{lines.map(line => <DefaultLine data={data} line={line} key={line.y} days={60} />)}

{/* Points on line */}
{lines.map((line) => (
<VictoryScatter
key={line.y}
data={data}
x="timestamp"
y={line.y}
style={{
data: { fill: line.color },
}}
/>
))}

<BlockerRectangle />
<VictoryDateAxis tickFormatter={tickFormatter} tickCount={tickCount} />

{/* Category axis (y) */}
<VictoryAxis
crossAxis
dependentAxis
tickValues={[0, 1, 2]}
tickFormat={(t) => labels[t]}
style={{
grid: { stroke: "grey" },
tickLabels: { padding: 4 },
}}
offsetX={80}
gridComponent={<CustomLineSegment dx1={30} />}
tickLabelComponent={<CustomVictoryLabel dy1={-50} />}
/>
</VictoryChart>
</div>
);
};

export default ResilienceGraph;
Loading

0 comments on commit b879cac

Please sign in to comment.