From 31cfa881c7e8005e559bfd2635f192635f93504c Mon Sep 17 00:00:00 2001 From: Evan Fiordeliso Date: Fri, 4 Jul 2025 09:56:29 -0400 Subject: [PATCH] Use reading log for books and pages chart when filtering by month --- .../ReadingLogCodeBlockView.svelte | 2 +- .../ReadingStatsCodeBlockView.svelte | 23 +++- src/ui/components/charts/Bar.svelte | 2 +- src/ui/components/charts/BookAndPages.svelte | 101 ++++++++++++------ src/ui/components/charts/Pie.svelte | 2 +- src/ui/components/stats/AverageStat.svelte | 3 +- src/ui/components/stats/BookCountStat.svelte | 3 +- src/ui/components/stats/CountStat.svelte | 3 +- src/ui/components/stats/Stat.svelte | 5 +- src/ui/components/stats/TotalStat.svelte | 3 +- src/ui/directives/chart.ts | 3 + src/ui/stores/date-filter.svelte.ts | 2 +- 12 files changed, 99 insertions(+), 53 deletions(-) diff --git a/src/ui/code-blocks/ReadingLogCodeBlockView.svelte b/src/ui/code-blocks/ReadingLogCodeBlockView.svelte index e4d7a6a..e746c92 100644 --- a/src/ui/code-blocks/ReadingLogCodeBlockView.svelte +++ b/src/ui/code-blocks/ReadingLogCodeBlockView.svelte @@ -11,7 +11,7 @@ plugin: BookTrackerPlugin; } - let { plugin }: Props = $props(); + const { plugin }: Props = $props(); function bookUri(book: string) { const v = encodeURIComponent(plugin.app.vault.getName()); diff --git a/src/ui/code-blocks/ReadingStatsCodeBlockView.svelte b/src/ui/code-blocks/ReadingStatsCodeBlockView.svelte index a3daf04..92c00c1 100644 --- a/src/ui/code-blocks/ReadingStatsCodeBlockView.svelte +++ b/src/ui/code-blocks/ReadingStatsCodeBlockView.svelte @@ -23,20 +23,32 @@ import type BookTrackerPlugin from "@src/main"; import BookCountStat from "@ui/components/stats/BookCountStat.svelte"; import { ALL_TIME } from "@ui/stores/date-filter.svelte"; + import { + createReadingLog, + setReadingLogContext, + } from "@ui/stores/reading-log.svelte"; interface Props { plugin: BookTrackerPlugin; source: string; } - let { plugin, source }: Props = $props(); + const { plugin, source }: Props = $props(); - let settingsStore = createSettings(plugin); + const settingsStore = createSettings(plugin); setSettingsContext(settingsStore); - let metadataStore = createMetadata(plugin); + const metadataStore = createMetadata(plugin); setMetadataContext(metadataStore); + const readingLogStore = createReadingLog(plugin.readingLog); + setReadingLogContext(readingLogStore); + + $effect(() => { + readingLogStore.filterYear = metadataStore.filterYear; + readingLogStore.filterMonth = metadataStore.filterMonth; + }); + let sections = $state([]); let error = $state(null); @@ -68,7 +80,10 @@ } }); - onDestroy(() => metadataStore.destroy()); + onDestroy(() => { + metadataStore.destroy(); + readingLogStore.destroy(); + });
diff --git a/src/ui/components/charts/Bar.svelte b/src/ui/components/charts/Bar.svelte index 0991be5..c110bce 100644 --- a/src/ui/components/charts/Bar.svelte +++ b/src/ui/components/charts/Bar.svelte @@ -15,7 +15,7 @@ color?: "rainbow" | ColorName; }; - let { + const { property, horizontal, sortByLabel = false, diff --git a/src/ui/components/charts/BookAndPages.svelte b/src/ui/components/charts/BookAndPages.svelte index 051eed9..bf1a398 100644 --- a/src/ui/components/charts/BookAndPages.svelte +++ b/src/ui/components/charts/BookAndPages.svelte @@ -2,28 +2,46 @@ import { chart } from "@ui/directives/chart"; import { ALL_TIME } from "@ui/stores/date-filter.svelte"; import { getMetadataContext } from "@ui/stores/metadata.svelte"; + import { getReadingLogContext } from "@ui/stores/reading-log.svelte"; import { getSettingsContext } from "@ui/stores/settings.svelte"; import { Color } from "@utils/color"; import type { ChartConfiguration } from "chart.js"; - const settings = getSettingsContext().settings; + const settingsStore = getSettingsContext(); const store = getMetadataContext(); - const config = $derived.by(() => { - const items = store.metadata.map((f) => ({ - pageCount: f.frontmatter[settings.pageCountProperty], - date: f.frontmatter[settings.endDateProperty], - })); + const readingLog = getReadingLogContext(); + const isMonthly = $derived( + store.filterYear !== ALL_TIME && store.filterMonth !== ALL_TIME, + ); + + const items = $derived( + isMonthly + ? readingLog.entries.map((entry) => ({ + pageCount: entry.pagesRead, + date: entry.createdAt, + })) + : store.metadata.map((f) => ({ + pageCount: + f.frontmatter[settingsStore.settings.pageCountProperty], + // @ts-expect-error Moment is provided by Obsidian + date: moment( + f.frontmatter[settingsStore.settings.endDateProperty], + ), + })), + ); + + const config = $derived.by(() => { const books = new Map(); const pages = new Map(); for (const item of items) { - // @ts-expect-error Moment is provided by Obsidian - const date = moment(item.date); let key: number; if (store.filterYear === ALL_TIME) { - key = date.year(); + key = item.date.year(); + } else if (store.filterMonth === ALL_TIME) { + key = item.date.month(); } else { - key = date.month(); + key = item.date.date(); } const pageCount = pages.get(key) ?? 0; @@ -33,10 +51,26 @@ books.set(key, bookCount + 1); } + console.log(pages); + if (isMonthly && typeof store.filterMonth === "number") { + // @ts-expect-error Moment is provided by Obsidian + const daysInMonth = moment() + .month(store.filterMonth - 1) + .daysInMonth(); + + for (let i = 1; i <= daysInMonth; i++) { + if (!pages.has(i)) { + books.set(i, 0); + pages.set(i, 0); + } + } + } + console.log(pages); + const labels = Array.from(books.keys()) .sort((a, b) => a - b) .map((key) => - store.filterYear === ALL_TIME + store.filterYear === ALL_TIME || isMonthly ? key : // @ts-expect-error Moment is provided by Obsidian moment().month(key).format("MMM"), @@ -48,26 +82,30 @@ .sort((a, b) => a[0] - b[0]) .map((p) => p[1]); + let datasets = [ + { + label: "Pages", + data: sortedPages, + borderColor: Color.fromName("blue").hex, + backgroundColor: Color.fromName("blue").alpha(0.5).rgba, + yAxisID: isMonthly ? "y" : "y1", + }, + ]; + if (!isMonthly) { + datasets.push({ + label: "Books", + data: sortedBooks, + borderColor: Color.fromName("red").hex, + backgroundColor: Color.fromName("red").alpha(0.5).rgba, + yAxisID: "y", + }); + } + return { type: "line", data: { labels, - datasets: [ - { - label: "Books", - data: sortedBooks, - borderColor: Color.fromName("red").hex, - backgroundColor: Color.fromName("red").alpha(0.5).rgba, - yAxisID: "y", - }, - { - label: "Pages", - data: sortedPages, - borderColor: Color.fromName("blue").hex, - backgroundColor: Color.fromName("blue").alpha(0.5).rgba, - yAxisID: "y1", - }, - ], + datasets, }, options: { scales: { @@ -75,16 +113,13 @@ type: "linear", display: true, position: "left", + ticks: { beginAtZero: true }, }, y1: { type: "linear", - display: true, + display: !isMonthly, position: "right", - - // grid line settings - grid: { - drawOnChartArea: false, // only want the grid lines for one axis to show up - }, + grid: { drawOnChartArea: false }, }, }, }, diff --git a/src/ui/components/charts/Pie.svelte b/src/ui/components/charts/Pie.svelte index 55929d8..ed852e9 100644 --- a/src/ui/components/charts/Pie.svelte +++ b/src/ui/components/charts/Pie.svelte @@ -17,7 +17,7 @@ color?: PieChartColor; }; - let { property, groups, unit, unitPlural, responsive, color }: Props = + const { property, groups, unit, unitPlural, responsive, color }: Props = $props(); const store = createPropertyStore(property); diff --git a/src/ui/components/stats/AverageStat.svelte b/src/ui/components/stats/AverageStat.svelte index 1d805f2..23303e3 100644 --- a/src/ui/components/stats/AverageStat.svelte +++ b/src/ui/components/stats/AverageStat.svelte @@ -7,8 +7,7 @@ property: string; }; - let { label, property }: Props = $props(); - + const { label, property }: Props = $props(); const store = createPropertyStore(property); const avg = $derived.by(() => { if (store.propertyData.length === 0) { diff --git a/src/ui/components/stats/BookCountStat.svelte b/src/ui/components/stats/BookCountStat.svelte index dd65561..7fe3bb0 100644 --- a/src/ui/components/stats/BookCountStat.svelte +++ b/src/ui/components/stats/BookCountStat.svelte @@ -6,8 +6,7 @@ label: string; }; - let { label }: Props = $props(); - + const { label }: Props = $props(); const store = getMetadataContext(); const count = $derived(store.metadata.length); diff --git a/src/ui/components/stats/CountStat.svelte b/src/ui/components/stats/CountStat.svelte index fc0b9ba..b6c0729 100644 --- a/src/ui/components/stats/CountStat.svelte +++ b/src/ui/components/stats/CountStat.svelte @@ -7,8 +7,7 @@ property: string; }; - let { label, property }: Props = $props(); - + const { label, property }: Props = $props(); const store = createPropertyStore(property); const count = $derived(store.propertyData.length); diff --git a/src/ui/components/stats/Stat.svelte b/src/ui/components/stats/Stat.svelte index 3bf225a..1e220ec 100644 --- a/src/ui/components/stats/Stat.svelte +++ b/src/ui/components/stats/Stat.svelte @@ -1,13 +1,10 @@