Skip to content

Commit

Permalink
use NjspPlot on homepage
Browse files Browse the repository at this point in the history
  • Loading branch information
ryan-williams committed Feb 3, 2024
1 parent 82e68ed commit 1f03fda
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 33 deletions.
19 changes: 12 additions & 7 deletions www/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,26 @@ import { HasTotals, Plot, plotSpecs, ProjectedTotals } from "@/src/plotSpecs";
import { loadSync } from "@rdub/base/load";
import { buildPlot, buildPlots, PlotsDict } from "@rdub/next-plotly/plot";
import { loadPlots } from "@rdub/next-plotly/plot-load";
import { NjspPlot } from "@/src/njsp/plot";
import * as Njsp from "@/src/njsp/plot";
import { loadProps } from "@/server/njsp/plot";

type Props = { plotsDict: PlotsDict, rundate: string, } & HasTotals
type Props = {
plotsDict: PlotsDict
njspProps: Njsp.Props
}

export const getStaticProps: GetStaticProps = async () => {
const { rundate } = loadSync<{ rundate: string }>(`public/rundate.json`)
console.log(`rundate: ${rundate}`)
const plotsDict: PlotsDict = loadPlots(plotSpecs)
const projectedTotals = loadSync<ProjectedTotals>(`public/plots/projected_totals.json`)
return { props: { plotsDict, projectedTotals, rundate, }, }
const njspProps = await loadProps()
return { props: { plotsDict, njspProps }, }
}

const Home = ({ plotsDict, projectedTotals, rundate, }: Props) => {
const Home = ({ plotsDict, njspProps, }: Props) => {
// console.log("Home plots:", plotsDict)
const basePath = getBasePath()

const { rundate, projectedTotals } = njspProps
const data = { rundate, projectedTotals }
const [ njspPlotSpec, ...plotSpecs2 ] = plotSpecs
const njspPlot = buildPlot(njspPlotSpec, plotsDict[njspPlotSpec.id], data)
Expand Down Expand Up @@ -86,7 +91,7 @@ const Home = ({ plotsDict, projectedTotals, rundate, }: Props) => {
<li>Click / double-click legend entries below to toggle traces on/off.</li>
</ul>
<div key={njspPlotSpec.id} className={css["plot-container"]}>
<Plot basePath={basePath} {...njspPlot} margin={{b: 30,}} data={{rundate, projectedTotals}}/>
<NjspPlot {...njspProps} />
<hr/>
</div>
{
Expand Down
24 changes: 22 additions & 2 deletions www/server/njsp/plot.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { loadPlot } from "@rdub/next-plotly/plot-load";
import { njspPlotSpec } from "@/src/plotSpecs";
import { curYear, njspPlotSpec, ProjectedTotals, prvYear } from "@/src/plotSpecs";
import { initDuckDb, runQuery } from "@rdub/duckdb/duckdb";
import { registerTableData, TableData } from "@/src/tableData";
import { loadTableData } from "@/server/tableData";
import { getPlotData, PlotParams, Props } from "@/src/njsp/plot";
import { AsyncDuckDB } from "@duckdb/duckdb-wasm";
import path, { dirname } from "path";
import fs from "fs";
import { loadSync } from "@rdub/base/load";
import { fromEntries } from "@rdub/base/objs";

export async function getProjectedTotal(db: AsyncDuckDB) {
const projectedCsvPath = path.join(dirname(process.cwd()), "data/njsp/projected.csv")
Expand All @@ -33,16 +35,34 @@ export async function loadProps(): Promise<Props> {
// const crashesBase64 = loadParquetBase64("data/crashes.pqt")
const tableData: TableData = loadTableData({ fmt: 'csv', stem: "data/njsp/year-type-county" })
const target = await registerTableData({ db, tableData, stem: "ytc", })
const { data, annotations } = await getPlotData({
const { data, rows, annotations } = await getPlotData({
db,
target,
projectedTotal,
initialPlotData,
})

const ytcMap = fromEntries(
rows.map(
({ year, total, projected }) =>
[ year, { total, projected } ]
)
)

const { rundate } = loadSync<{ rundate: string }>(`public/rundate.json`)
console.log(`rundate: ${rundate}`)
const projectedTotals: ProjectedTotals = {
2021: ytcMap[2021].total,
2022: ytcMap[2022].total,
}
projectedTotals[prvYear] = ytcMap[prvYear].total
projectedTotals[curYear] = projectedTotal

return {
params: { data, layout: { ...layout, annotations }, ...plotRest },
tableData,
projectedTotal,
rundate,
projectedTotals,
}
}
24 changes: 12 additions & 12 deletions www/src/njsp/plot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import * as Plotly from "react-plotly.js";
import { registerTableData, TableData } from "@/src/tableData";
import { AsyncDuckDB } from "@duckdb/duckdb-wasm";
import { initDuckDb, runQuery } from "@rdub/duckdb/duckdb";
import { njspPlotSpec } from "@/src/plotSpecs";
import PlotWrapper from "@rdub/next-plotly/plot-wrapper";
import { Data, njspPlotSpec, Plot } from "@/src/plotSpecs";
import React, { useEffect, useState } from "react";

export type PlotParams = { data: PlotData[] } & Omit<Plotly.PlotParams, "data">
Expand All @@ -14,9 +13,9 @@ export type Props = {
params: PlotParams
tableData: TableData
projectedTotal: number
}
} & Data

export type YtcRow = {
export type YtRow = {
year: number
driver: number
pedestrian: number
Expand All @@ -32,7 +31,7 @@ export async function getPlotData({ db, target, projectedTotal, initialPlotData
projectedTotal: number
initialPlotData: PlotData[]
}): Promise<{
rows: YtcRow[]
rows: YtRow[]
data: PlotData[]
annotations: Annotation[]
}> {
Expand All @@ -49,11 +48,11 @@ export async function getPlotData({ db, target, projectedTotal, initialPlotData
FROM ${target}
GROUP BY year
`
const rows = await runQuery<YtcRow>(db, query)
const rows = await runQuery<YtRow>(db, query)
const last = rows[rows.length - 1]
last.projected = projectedTotal - last.total
console.log("got ytc data:", rows)
const typesMap: { [k: string]: keyof YtcRow } = {
const typesMap: { [k: string]: keyof YtRow } = {
"Drivers": "driver",
"Pedestrians": "pedestrian",
"Cyclists": "cyclist",
Expand Down Expand Up @@ -82,7 +81,7 @@ export async function getPlotData({ db, target, projectedTotal, initialPlotData

export const title = "New Jersey Car Crash Deaths"

export function NjspPlot({ params, tableData, projectedTotal, }: Props) {
export function NjspPlot({ params, tableData, projectedTotal, rundate, projectedTotals, }: Props) {
const spec = njspPlotSpec
let { src, name } = spec
src = src ?? `plots/${name}.png`
Expand Down Expand Up @@ -117,11 +116,12 @@ export function NjspPlot({ params, tableData, projectedTotal, }: Props) {
)

return (
<PlotWrapper
params={{ data: data, layout: { ...layout, annotations }, ...plotRest }}
<Plot
{...spec}
params={{ data, layout: { ...layout, annotations }, ...plotRest }}
src={src}
alt={title}
// margin={{b: 30,}}
title={title}
data={{ rundate, projectedTotals }}
/>
)
}
25 changes: 13 additions & 12 deletions www/src/plotSpecs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ const { HalfRoundWiden, filterIdxs, filterValues } = Plots
export const curYear = (new Date().getFullYear())
export const prvYear = curYear - 1
export type Year = "2021" | "2022" | typeof prvYear | typeof curYear
export type YearTotals = { "Projected Total": number }
export type ProjectedTotals = { [k in Year]: YearTotals }
export type ProjectedTotals = { [k in Year]: number }
export type HasTotals = { projectedTotals: ProjectedTotals }

export type T = { rundate: string } & HasTotals
export type PlotSpec = Plots.PlotSpec<T>
export type Plot = Plots.Plot<T>
export const Plot = (args: Plot) => Plots.Plot<T>(args)
export type Data = { rundate: string } & HasTotals
export type PlotSpec = Plots.PlotSpec<Data>
export type Plot = Plots.Plot<Data>
export const Plot = (args: Plot) => Plots.Plot<Data>(args)

export const EMPTY: PlotSpec[] = []
export const YM_SC_PID_SPECS: PlotSpec[] =
Expand All @@ -40,19 +39,21 @@ export const YM_SC_PID_SPECS: PlotSpec[] =
))
))

export const estimationHref = 'https://nbviewer.org/github/neighbor-ryan/nj-crashes/blob/main/njsp/update-projections.ipynb'

export const njspPlotSpec: PlotSpec = {
title: "NJ Traffic Deaths per Year", id: "per-year", name: "fatalities_per_year_by_type",
menuName: "Traffic Deaths / Year", dropdownSection: "NJSP",
filter: filterValues({ mapRange: HalfRoundWiden }),
children: ({ rundate, projectedTotals }: { rundate: string, } & HasTotals) => {
const total2021 = projectedTotals["2021"]["Projected Total"]
const total2022 = projectedTotals["2022"]["Projected Total"]
const prvYearTotal = projectedTotals[prvYear]["Projected Total"]
const curYearTotal = projectedTotals[curYear]["Projected Total"]
children: ({ rundate, projectedTotals }: Data) => {
const total2021 = projectedTotals["2021"]
const total2022 = projectedTotals["2022"]
const prvYearTotal = projectedTotals[prvYear]
const curYearTotal = projectedTotals[curYear]
const shortDate = new Date(rundate).toLocaleDateString("en-US", { month: "short", day: "numeric", timeZone: 'UTC' })
return <>
<p>2021 and 2022 were the worst years in the NJSP record (since 2008), with {total2021} and {total2022} deaths, resp.</p>
<p><A href={`${GitHub.href}/commits/main`}>As of {shortDate}</A>, {curYear} is on pace {curYearTotal > prvYearTotal ? `to exceed ${prvYear}, with` : `for`} {curYearTotal} deaths (<A href={"https://nbviewer.org/github/neighbor-ryan/nj-crashes/blob/main/njsp-plots.ipynb#Estimate-end-of-year-death-toll"}>estimated</A>).</p>
<p><A href={`${GitHub.href}/commits/main`}>As of {shortDate}</A>, {curYear} is on pace {curYearTotal > prvYearTotal ? `to exceed ${prvYear}, with` : `for`} {curYearTotal} deaths (<A href={estimationHref}>estimated</A>).</p>
</>
},
}
Expand Down

0 comments on commit 1f03fda

Please sign in to comment.