i like to visualize my habits data that i track in my daily notes using time series heat maps. to display this right in obsidian, i use the heatmap tracker plugin. here’s part of what it looks like:

here’s the code snippet i use to create a heat map for all of my habits at once. while the heatmap tracker can be used alone, this snippet requires dataview to be installed in order to work.
performance
while you can put this plugin inside of any page, i recommend creating a separate note for it, especially if you want to display multiple habits like i have below. parsing so much data can be pretty resource intensive, so having it on its own note limits the performance hit occurring only when you want to see the heat maps.
```dataviewjs
const PATH_TO_YOUR_FOLDER = "010 daily notes";
 
// create an array of all the stats you want to visualize.
// each entry is an array where the first entry is the
// property name and the second entry is the title of the graph.
// if you want graphs to also have a subtitle, add it as the
// third entry of each array.
const stats = [
    ['thai', 'Thai Immersion'],
    ['thai-listening', 'Listening'],
    ['thai-reading', 'Reading'],
    ['thai-output', 'Output'],
    ['japanese', 'Japanese Immersion'],
    ['japanese-kanji', 'Kanji'],
    ['japanese-listening', 'Listening'],
    ['japanese-reading', 'Reading'],
    ['health-b12', 'B12'],
    ['health-multivitamin', 'Multivitamin'],
    ['health-exercise', 'Exercise']
];
 
// get all the pages with the stats
const pages = dv.pages(`"${PATH_TO_YOUR_FOLDER}"`);
 
// create an object with all the data.
// each element is an object corresponding to a day
// and each property is a stat
const habitData = {};
for (let page of pages) {
    const date = page.file.name;
    habitData[date] = {};
    for (let [habit] of stats) {
        if (page[habit] !== undefined) {
            habitData[date][habit] = page[habit];
        }
    }
}
 
// loop through all stats
stats.forEach(stat => {
    const [habit, title] = stat;
    let color;
 
    // i like each category to have the same color
    if (habit.startsWith('thai')) color = 'lavender';
    else if (habit.startsWith('japanese')) color = 'pink';
    else if (habit.startsWith('health')) color = 'green';
 
    // for binary data, i use an alternative color palette
    // whose only color is a mid to light tone in the
    // original palette. this is simply a personal preference
    // so that these heatmaps aren't so dark
    if (habit.endsWith('-listening') || habit.endsWith('-reading') || habit.endsWith('-output') || habit.endsWith('-kanji')) {
        color = color + '-light';
    }
 
    // build the object that will be used to render the heatmap
    const trackerData = {
        entries: [],
        separateMonths: false,
        heatmapTitle: title,
        //heatmapSubtitle: "stat[2]",
        colorScheme: { paletteName: color },
        basePath: PATH_TO_YOUR_FOLDER
    };
 
    // if data is binary, set the scale to only go from 0
	// (didn't do) to 1 (did). in addition, add an entry to
	// the insights tab to show how many times it's been done
	// the past week
    if (habit != 'thai' && habit != 'japanese') {
        trackerData.intensityScaleStart = 0;
        trackerData.intensityScaleEnd = 1;
        trackerData.insights = [{
            name: "Times done this week",
            calculate: ({ yearEntries }) => {
                let t = new Date();
                let d = new Date(Date.UTC(t.getFullYear(), t.getMonth(), t.getDate() - 7));
                const week = yearEntries.filter(e => new Date(e.date) >= d);
                const total = week.reduce((sum, e) => sum + (e.value || 0), 0);
                return total.toString();
            },
        }];
    } else {
	    // if the data is in minutes, this will show how
	    // many hours its been done for this year
        trackerData.insights = [{
            name: "Hours studied this year",
            calculate: ({ yearEntries }) => {
                const totalMinutes = yearEntries.reduce((sum, e) => sum + (e.value || 0), 0);
                return (totalMinutes / 60).toFixed(1).toString();
            },
        }];
    }
 
	// loops through the object we created with all the data
    // from the daily notes, adding new entries to the 
    // trackerData object for each time the given habit
	// was tracked
    for (let date in habitData) {
        if (habitData[date][habit] !== false && habitData[date][habit] !== undefined && habitData[date][habit] !== 0 && habitData[date][habit] !== null) {
            trackerData.entries.push({
                date: date,
                filePath: `${PATH_TO_YOUR_FOLDER}/${date}`,
                intensity: habitData[date][habit]
            });
        }
    }
 
    // render the heatmap
    renderHeatmapTracker(this.container, trackerData);
	// optional. render the statistics underneath the heatmap
	// renderHeatmapTrackerStatistics(this.container, trackerData)
});
```