Obsidianで使えるプラグインObsidian Charts
を使って、DailyNoteで記録した体調数値などの数値データをグラフ化し、時系列で変化が分かるようにした
これによって、振り返りの際に数値の変化がわかりやすくなり「このときこういう感じだったな」というのを思い出しやすくなった
Obsidian Charts
Obsidian上で数値データをグラフ化して表示するプラグイン
このプラグインを使うことで、何かしらのデータをもとにObsidian上でもグラフ表示ができる
中身でグラフ化する部分に関してはChart.jsを使っているので渡すオプションの値など詳しく知りたい場合はChart.jsのドキュメントも参考にできる
今回はこのプラグインとDataviewプラグインを組み合わせてDailyNoteで継続的に記録した数値データをグラフに変換した
なお、プラグインのインストール方法については公式読めば分かるので割愛する
Daily Noteの例
前提として、Daily Noteに以下のように記録をつけていく(必要な部分だけ抜き出している)
--- date: 2023-03-26 week: 2023-W12 score: 80 facilitate: 1 meeting: 2 ---
Dataviewプラグインとの連携
Dataview Integration - Obsidian Charts
dataviewjs
でwindow.renderChart(data, element);
と記述することでグラフをレンダリングできる
data
には渡すデータを、element
にはthis.container
を指定する
data
の中身を変えて複数のグラフを描画することも可能
Dataviewで集計してChartsでグラフ描画
Dataviewプラグインのdataviewjs
で、さまざまなページからデータを取得し集計が可能なのでごにょごにょやった結果をChartsに渡して可視化する
いきなりだが、自分が使っているコードを載せておく
1行目の日付部分に決め打ちが入ってしまっているがそれ以外は参考にはできると思う
const pages = dv.pages('#daily').filter(p => p.file.name != "daily_note" && p.file.name > "2023-01-02").sort(p => p.file.name); function extract(pages, key) { return pages.map(p => p[key]).values } const days = pages.map(p => p.file.name).values const scores = extract(pages, 'score') const facilitates = extract(pages, 'facilitate') const meetings = extract(pages, 'meeting') function scoreChart(terms, data) { return { type: 'line', data: { labels: terms, datasets: [{ label: 'Mark', data: data, backgroundColor: ['rgba(99, 255, 132, 0.2)'], borderColor: ['rgba(99, 255, 132, 1)'], borderWidth: 1, tension: 0.3 }] } } } function meetingChart(terms, meeting, facilitate) { return { type: 'bar', data: { labels: terms, datasets: [{ label: 'meeting', data: meeting, borderColor: ['rgba(99, 132, 255, 1)'], backgroundColor: ['rgba(99, 132, 255, 0.7)'] },{ label: 'facilitate', data: facilitate, borderColor: ['rgba(255, 99, 132, 1)'], backgroundColor: ['rgba(255, 99, 132, 0.7)'] }] } } } const dailyScore = scoreChart(days, scores) const dailyMeeting = meetingChart(days, meetings, facilitates) window.renderChart(dailyScore, this.container) window.renderChart(dailyMeeting, this.container)
Dailyの推移
余談だが、自分はscore以外にもfacilitate,meetingも数値を取っている
会議数よりファシリテーションする数によってその日の疲れが違うなーと思ったので記録している
Weeklyで集計した値をグラフ化する
dailyでは取ってきた値をそのままChartsへ渡すだけで良かったがWeeklyの場合は適切な集計をしてからChartsへ渡す必要がある
雑なコードだがこちらも以下に載せておく
const pages = dv.pages('#daily').filter(p => p.file.name != "daily_note" && p.file.name > "2023-01-02").sort(p => p.file.name); function extract(pages, key) { return pages.map(p => p[key]).values } function aggregate(pages, term, key) { const termValues = pages.values.reduce((acc, cur) => { acc[cur[term]] ||= []; acc[cur[term]] = [...acc[cur[term]], cur[key]] return acc }, {}) const metrics = Object.keys(termValues).map(t => { const sum = termValues[t].reduce((a, c) => a + c); return { avg: sum / termValues[t].length, sum: sum } }); return {terms: Object.keys(termValues), data: metrics}; } function aggregateKeys(pages, term, metric, keys) { const metrics = keys.map(key => { return aggregate(pages, term, key) }); const data = metrics.map(m => m.data.map(r => r[metric])); return [metrics[0].terms, ...data] } const days = pages.map(p => p.file.name).values const scores = extract(pages, 'score') const facilitates = extract(pages, 'facilitate') const meetings = extract(pages, 'meeting') function scoreChart(terms, data) { return { type: 'line', data: { labels: terms, datasets: [{ label: 'Mark', data: data, backgroundColor: ['rgba(99, 255, 132, 0.2)'], borderColor: ['rgba(99, 255, 132, 1)'], borderWidth: 1, tension: 0.3 }] } } } function meetingChart(terms, meeting, facilitate) { return { type: 'bar', data: { labels: terms, datasets: [{ label: 'meeting', data: meeting, borderColor: ['rgba(99, 132, 255, 1)'], backgroundColor: ['rgba(99, 132, 255, 0.7)'] },{ label: 'facilitate', data: facilitate, borderColor: ['rgba(255, 99, 132, 1)'], backgroundColor: ['rgba(255, 99, 132, 0.7)'] }] } } } const dailyScore = scoreChart(days, scores) const dailyMeeting = meetingChart(days, meetings, facilitates) const weeklyScore = scoreChart(...aggregateKeys(pages, 'week', 'avg', ['score'])) const weeklyMeeting = meetingChart(...aggregateKeys(pages, 'week', 'sum', ['meeting', 'facilitate'])) window.renderChart(dailyScore, this.container) window.renderChart(dailyMeeting, this.container) window.renderChart(weeklyScore, this.container) window.renderChart(weeklyMeeting, this.container)
このコードでは、いくつかまとめた処理を関数化しているが
- Daily Noteから数値データを取り出す
- 週単位で合計、平均などの計算をする
- 計算結果をChartsへ渡してレンダリングする
といった処理をしている
Weeklyの推移
まとめ
ObsidianChartsプラグインを使うことで、DailyNoteで記録した数値データを簡単に時系列でグラフ化できる
Dataviewプラグインと組み合わせることで集計をした結果を時系列でグラフ化できる
この結果を見ながら振り返りなどを行うことでより分析しやすくなる