generated from tpl/obsidian-sample-plugin
Use reading log for books and pages chart when filtering by month
This commit is contained in:
parent
d9cfb3df36
commit
31cfa881c7
|
@ -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());
|
||||
|
|
|
@ -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<ReadingStatsSection[]>([]);
|
||||
let error = $state<string | null>(null);
|
||||
|
||||
|
@ -68,7 +80,10 @@
|
|||
}
|
||||
});
|
||||
|
||||
onDestroy(() => metadataStore.destroy());
|
||||
onDestroy(() => {
|
||||
metadataStore.destroy();
|
||||
readingLogStore.destroy();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="obt-reading-stats">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
color?: "rainbow" | ColorName;
|
||||
};
|
||||
|
||||
let {
|
||||
const {
|
||||
property,
|
||||
horizontal,
|
||||
sortByLabel = false,
|
||||
|
|
|
@ -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<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();
|
||||
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]);
|
||||
|
||||
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",
|
||||
},
|
||||
let datasets = [
|
||||
{
|
||||
label: "Pages",
|
||||
data: sortedPages,
|
||||
borderColor: Color.fromName("blue").hex,
|
||||
backgroundColor: Color.fromName("blue").alpha(0.5).rgba,
|
||||
yAxisID: "y1",
|
||||
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,
|
||||
},
|
||||
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 },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
label: string;
|
||||
};
|
||||
|
||||
let { label }: Props = $props();
|
||||
|
||||
const { label }: Props = $props();
|
||||
const store = getMetadataContext();
|
||||
const count = $derived(store.metadata.length);
|
||||
</script>
|
||||
|
|
|
@ -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);
|
||||
</script>
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
<script lang="ts">
|
||||
import type { Readable } from "svelte/store";
|
||||
|
||||
type Props = {
|
||||
label: string;
|
||||
value: number;
|
||||
};
|
||||
|
||||
let { label, value }: Props = $props();
|
||||
|
||||
const { label, value }: Props = $props();
|
||||
const numberFormatter = new Intl.NumberFormat("en-US", {
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
property: string;
|
||||
};
|
||||
|
||||
let { label, property }: Props = $props();
|
||||
|
||||
const { label, property }: Props = $props();
|
||||
const store = createPropertyStore(property);
|
||||
const total = $derived(
|
||||
store.propertyData.reduce((acc, f) => acc + f.value, 0),
|
||||
|
|
|
@ -63,6 +63,9 @@ export function chart<
|
|||
| ChartConfigurationCustomTypesPerDataset<Type, Data, Label>
|
||||
) => {
|
||||
chart.data = config.data;
|
||||
if (config.options) {
|
||||
chart.options = config.options;
|
||||
}
|
||||
chart.update();
|
||||
},
|
||||
destroy: () => {
|
||||
|
|
|
@ -44,7 +44,7 @@ export function createDateFilter<T>(
|
|||
data().forEach((item) => {
|
||||
years.add(selector(item).year());
|
||||
});
|
||||
return Array.from(years).sort((a, b) => a - b);
|
||||
return Array.from(years).sort((a, b) => b - a);
|
||||
});
|
||||
|
||||
const filterMonths = $derived.by(() => {
|
||||
|
|
Loading…
Reference in New Issue