Created
August 15, 2022 02:06
-
-
Save Azurewren/bbfa1347135788733a8a0c05970173fa to your computer and use it in GitHub Desktop.
This is from @mulfok but with the renderMonthlyChart at the end of the file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Class for rendering charts in Obsidian. | |
* To be used with DataviewJS, Obsidian Charts and CustomJS plugins | |
* @author Olivier C <[email protected]> | |
*/ | |
class DvCharts { | |
/** | |
* Render a chart on a daily basis with a custom attribute extracted from dailies pages | |
* @param {object} args - object to pass containing properties used | |
* @param {object} args.dv - dataview object to perform queries | |
* @param {object} args.context - context to be set to **this**, used to render chart in place | |
* @param {string} args.daysPath - path to Daily notes | |
* @param {string} args.dayFormat - format of daily pages in Moment format | |
* @param {string} args.attr - attribute to query and render the value | |
* @param {string} args.label - label to display in chart for corresponding attr | |
* @param {number} args.limit - numbers of last pages containing values to display | |
*/ | |
renderSingleAttrChart(args) { | |
const { | |
dv, | |
context, | |
daysPath = '"Personal/Journal"', | |
dayFormat = 'YYYY-MM-DD', | |
attr, | |
label, | |
limit = 10 | |
} = args; | |
let days = dv.pages(daysPath) | |
.where(p => p[attr] && moment(p.file.name, dayFormat).isValid()) | |
.sort(p => p.file.name) | |
.filter((p, i, arr) => i >= arr.length - limit); | |
let dates = [], attrData = []; | |
days.forEach(p => { | |
dates.push(p.file.name); | |
attrData.push(p[attr]); | |
}); | |
const chartData = { | |
type: 'line', | |
data: { | |
labels: dates, | |
datasets: [{ | |
label, | |
data: attrData, | |
// backgroundColor: 'rgba(85, 174, 229, 0.2)', | |
// borderColor: 'rgba(85, 174, 229, 1)', | |
// borderWidth: 1, | |
fill: true, | |
tension: 0.2 | |
}], | |
} | |
} | |
window.renderChart(chartData, context.container); | |
} | |
/** | |
* Render a chart on a weekly basis from the specified date | |
* @param {object} args - object to pass containing properties used | |
* @param {object} args.dv - dataview object to perform queries | |
* @param {object} args.context - context to be set to **this**, used to render chart in place | |
* @param {string} args.daysPath - path to Daily notes | |
* @param {string} args.dayFormat - format of daily pages in Luxon format | |
* @param {string} args.attributes - object with keys as attributes to query and values as metadatas | |
* @param {object} args.template - default template for completing datasets metadatas | |
* @param {string} args.type - set it to **'average'** to display average data in chart | |
* @param {string} args.date - date in YYYY-MM-DD format from which weekly days will be retrieved | |
*/ | |
renderWeeklyChart(args) { | |
const { | |
dv, | |
context, | |
daysPath = '""', | |
dayFormat = 'yyyy-MM-dd', | |
template = { | |
label: "Default", | |
// backgroundColor: 'rgba(255, 99, 132, 0.2)', | |
// borderColor: 'rgba(255, 99, 132, 1)', | |
// borderWidth: 1, | |
fill: true, | |
tension: 0.2 | |
}, | |
attributes, | |
type, | |
date | |
} = args; | |
const datasets = (() => { | |
const startOfWeek = dv.date(date).startOf('week'); | |
const getWeeklyDay = dayNum => dv.pages(`"${daysPath}"`).find( | |
p => p.file.name == startOfWeek.plus({ days: dayNum }).toFormat(dayFormat)); | |
const weeklydays = Array.from({ length: 7 }, (c, i) => getWeeklyDay(i) || 0); | |
const getData = (attr, props) => weeklydays.map(p => | |
(type == 'average') ? (p[attr] / props.average * 100) || 0 : p[attr]); | |
let datasets = {}; | |
for (let [attr, props] of Object.entries(attributes)) { | |
datasets[attr] = Object.assign({}, template, props, {data: getData(attr, props)}); | |
} | |
return Object.values(datasets); | |
})(); | |
const chartData = { | |
type: 'line', | |
beginAtZero: false, | |
data: { | |
labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], | |
datasets, | |
} | |
} | |
window.renderChart(chartData, context.container); | |
} | |
/** | |
* Render a chart on a monthly basis from the specified date | |
* @param {object} args - object to pass containing properties used | |
* @param {object} args.dv - dataview object to perform queries | |
* @param {object} args.context - context to be set to **this**, used to render chart in place | |
* @param {string} args.daysPath - path to Daily notes | |
* @param {string} args.dayFormat - format of daily pages in Luxon format | |
* @param {string} args.attributes - object with keys as attributes to query and values as metadatas | |
* @param {object} args.template - default template for completing datasets metadatas | |
* @param {string} args.type - set it to **'average'** to display average data in chart | |
* @param {string} args.date - date in YYYY-MM-DD format from which monthly days will be retrieved | |
*/ | |
renderMonthlyChart(args) { | |
const { | |
dv, | |
context, | |
daysPath = '""', | |
dayFormat = 'yyyy-MM-dd', | |
template = { | |
label: "Default", | |
// backgroundColor: 'rgba(255, 99, 132, 0.2)', | |
// borderColor: 'rgba(255, 99, 132, 1)', | |
// borderWidth: 1, | |
fill: true, | |
tension: 0.2 | |
}, | |
attributes, | |
type, | |
date | |
} = args; | |
const datasets = (() => { | |
const startOfMonth = dv.date(date).startOf('month');; | |
const getMonthlyDay = dayNum => dv.pages(`"${daysPath}"`).find( | |
p => p.file.name == startOfMonth.plus({ days: dayNum }).toFormat(dayFormat)); | |
const monthlydays = Array.from({ length: moment(date).daysInMonth() }, (c, i) => getMonthlyDay(i) || 0); | |
const getData = (attr, props) => monthlydays.map(p => | |
(type == 'average') ? (p[attr] / props.average * 100) || 0 : p[attr]); | |
let datasets = {}; | |
for (let [attr, props] of Object.entries(attributes)) { | |
datasets[attr] = Object.assign({}, template, props, {data: getData(attr, props)}); | |
} | |
return Object.values(datasets); | |
})(); | |
let labels = [] | |
for (var i=1; i<=moment(date).daysInMonth(); i++) { | |
labels.push(i) | |
} | |
const chartData = { | |
type: 'line', | |
beginAtZero: false, | |
data: { | |
labels, | |
datasets, | |
} | |
} | |
window.renderChart(chartData, context.container); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment