obsidian-book-tracker/src/ui/components/charts/BookAndPages.svelte

93 lines
2.3 KiB
Svelte

<script lang="ts">
import { chart } from "@ui/directives/chart";
import { ALL_TIME, getMetadataContext } from "@ui/stores/metadata.svelte";
import { getSettingsContext } from "@ui/stores/settings.svelte";
import { Color } from "@utils/color";
import type { ChartConfiguration } from "chart.js";
const settings = getSettingsContext().settings;
const store = getMetadataContext();
const config = $derived.by(() => {
const items = store.metadata.map((f) => ({
pageCount: f.frontmatter[settings.pageCountProperty],
date: f.frontmatter[settings.endDateProperty],
}));
const books = new Map<number, number>();
const pages = new Map<number, number>();
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();
} else {
key = date.month();
}
const pageCount = pages.get(key) ?? 0;
pages.set(key, pageCount + item.pageCount);
const bookCount = books.get(key) ?? 0;
books.set(key, bookCount + 1);
}
const labels = Array.from(books.keys())
.sort((a, b) => a - b)
.map((m) =>
// @ts-expect-error Moment is provided by Obsidian
moment().month(m).format("MMM"),
);
const sortedBooks = Array.from(books.entries())
.sort((a, b) => a[0] - b[0])
.map((b) => b[1]);
const sortedPages = Array.from(pages.entries())
.sort((a, b) => a[0] - b[0])
.map((p) => p[1]);
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",
},
],
},
options: {
scales: {
y: {
type: "linear",
display: true,
position: "left",
},
y1: {
type: "linear",
display: true,
position: "right",
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
},
},
} as ChartConfiguration;
});
</script>
<canvas use:chart={config}></canvas>