Creating Dynamic Graphs in Obsidian

A decorative graph on paper, symbolizing graphs in Obsidian.

Obsidian has an incredible plugin ecosystem. Not only are the plugins individually impressive, but sometimes they integrate with each other in unexpected and wonderful ways. One of my favorites gives us the ability to create graphs in Obsidian.

This trick involves two community plugins: Dataview and Obsidian Charts. Dataview gives you ability to query almost anything you could want, and Charts allows you to plot that data on a graph. We can get into all kinds of trouble if we connect those two things.

What graphs in Obsidian look like

If you’re like me, you might not get how useful dynamic graphs are until you’re given some concrete examples. Fair enough!

There are all sorts of things you can track in Obsidian using these two plugins. In my own vault, here are a few of the things I use it for:

  • Visualizing writing projects
  • Tracking daily habits
  • Tracking task completions
  • Tracking the growth of my Zettelkasten

We’ll talk about each of these in more depth below. For the purposes of this article I’m not going to go into how to set up these individual graphs. I’d just like to show you some of what is possible using these two plugins.

Basic bar charts in Obsidian

In order to create a chart with these plugins, you need to be familiar with DataviewJS and chart.js.

DataviewJS is a JavaScript API provided by Dataview. It allows you to query your vault using JavaScript, which gives you a ton of power and flexibility. If you know JavaScript, then this should be pretty easy to pick up.

As for chart.js, that is the library that Obsidian Charts uses, you can see the full chart.js documentation here. You can do some incredibly complex things with this library, but we’re going to start simple.

In my experience, the easiest chart to start with is the basic bar chart. Here’s the code required to create a bar chart, and what it looks like in Obsidian:

```dataviewjs
const labels = ['One', 'Two', 'Three'];
const data = [1, 2, 3];

const chartData = {  
    type: 'bar',
    data: {
        labels: labels,
        datasets: [{
            label: 'Numbers',
            data: data
        }]
    }
}

window.renderChart(chartData, this.container);
```
A simple bar chart in Obsidian.

In order to create this type of chart, you need two pieces of data: labels and data. In the example above, those are stored in the variables called labels and data. They are both arrays that contain three items, and our chart represents that in the manner above.

The trick is creating those two variables dynamically instead of statically. I manually typed out the arrays above, but we can do better, and that is where DataviewJS comes in.

Visualizing writing projects with graphs

DataviewJS is the key to making dynamic graphs in Obsidian. The trick is formatting it so that Obsidian Charts can process it.

One way you can use a bar chart is to track the relative sizes of writing projects. This is a quick-and-dirty way to gauge how far along different projects are.

We’ll start by fetching notes with a certain tag in them:

const tagPages = dv.pages('#writing/idea');

Next we need to format the data for the chart. To do that, we create two different arrays and use a loop:

var labels = [],
    wordCount = [];

// Loop through every note and add data to the above arrays
tagPages.forEach(note => {
    // add the name of the note
    labels.push(note.file.name);
    // add the word count for the note
    wordCount.push(note.file.size);
});

Then we use that data in our chart:

const chartData = {  
    type: 'bar',
    data: {
        labels: labels,
        datasets: [{
            label: 'File Size',
            data: wordCount
        }]
    }
}

window.renderChart(chartData, this.container);

In my own vault, the results of that code look something like this:

A dynamic bar chart in Obsidian that shows the relative lengths of articles I've been writing.

Pretty neat, eh? You can use this same code to display any of the built in values that Dataview indexes.

Creating a daily habits graph in Obsidian

Another great use for graphs in Obsidian is tracking daily habits.

There are a few more prerequisites for this one:

  • You must be using the core Daily Notes plugin
  • You must add your own metadata to each note

I add the metadata to a template for my daily notes, which looks something like this:

## Daily Questions
Today did I...
- Read::0
- Workout::0
- Pray::0

## Journal Entries

Note: Dataview allows you to create metadata by adding two colons after any text. Examples above include “Read”, “Workout”, and “Pray”, all of which have the value “0”. To complete a habit, I change the 0 to a 1.

Once you have this metadata in your notes, you can start to pull it into graphs.

There are a couple of different ways you can visualize this information. If you have multiple habits you want to track, then perhaps the simplest method would be to use a bar chart:

An example bar chart showing habit completions.
Uh oh: looks like I better get back on my workout game.

I also like a line chart for habits. You can either design the chart to be cumulative, or you can do a “streak counter”, where your progress goes back to zero if you miss a day (I find this method is more motivating):

An example streak counter in Obsidian.
My longest streak this year is only eight days: another thing I should try to improve!

These two graphs are more complicated to set up, but it’s a great way to visualize how consistent you are at completing habits over time.

See Streamline Your Day: Enhance Focus and Productivity with RescueTime and Obsidian if you want to set up this kind of a graph.

An example of a RescueTime bar graph in Obsidian.

Tracking task completions with graphs

I’m a big fan of managing tasks in Obsidian. One reason why is the flexibility that Obsidian provides. You can fine-tune your task system to work exactly how you want it to work.

You can also create your own custom data visualizations. For task management, I’m a big fan of tracking task completions over time. This allows you to get a rough idea of whether your task system is working or not.

I like to track both daily task completions and monthly. I find both of these visualizations useful, and I reference them frequently:

An example graph that shows completed tasks in Obsidian.

Learn how to make this graph in Plotting Task Completions with DataviewJS and Obsidian Charts.

Tracking the growth of a Zettelkasten with graphs

A while back I wrote about Getting Started with Zettelkasten. When I started building a Zettelkasten, I wanted a concrete way to visualize how my atomic notes grew over time. To do that, I turned to charts.

I ended up with two charts: one is cumulative and the other is a daily report. Here’s what each looks like:

Zettelkasten analytics in Obsidian.

In this case I also added a table above the graphs that gives me more direct access to recently created notes. I find this useful, as there’s no way to explore notes within the graphs. They are strictly visualizations.

For more details, see A Graph for Zettelkasten: Measuring growth in Obsidian.

In conclusion

Dynamic graphs can be a little complex to set up, but they’re a great way to get extra value out of all the data you’re creating within your vault. Hopefully this article has given you some ideas for how graphs could help in your vault.

If you want more details about any of the above graphs, let me know, and we can provide a deeper dive into the details.

15 responses to “Creating Dynamic Graphs in Obsidian”

  1. Hi Tim, I found your plots of completed tasks and created notes plot interesting.

    Would you mind sharing the code to create the plots in section Tracking task completions with graphs and Tracking the growth of a Zettelkasten with graphs.

    Thanks

    1. Hi Meng! Thanks for letting me know. We’ve now written an article for task completions, you can see that here: https://obsidian.rocks/plotting-task-completions-with-dataviewjs-and-obsidian-charts/

      And I’m planning one on the Zettelkasten graph in the next week or two, so stay tuned!

  2. Superb article!

    Would you mind sharing the dataviewjs code on that? thanks in advance.
    because I tried it myself it kind of works but the dates are messed up. I followed the documentation on both dataview and charts.

    I’d like to understand this more better so Please would you mind sharing the code?

    1. Hi Kean! I’m happy to share. Which graph in particular are you interested in?

      Several of these are pretty complex, and I’m planning on writing more about how they work in the future. Dates in particular can be a little tricky, since Dataview isn’t always 100% reliable when it comes to dates.

      1. Hi Tim, I am extremely interested in the code on both the daily task completion as well as the monthly task completion. I have been trying to work through how to do this exactly to no avail. Thanks so much!

        1. Hey Josh! Thanks for letting me know. We just published an article on how to create those two graphs, you can see it here: https://obsidian.rocks/plotting-task-completions-with-dataviewjs-and-obsidian-charts/

          If you decide to try it, I’d love to hear how it works for you!

  3. I hurt my jaw as it hit the desk.

    I had no idea this functionality existed, let alone was so powerful.

    And esthetic.

    Thanks so much!

    1. Glad I could help Jon. It IS incredible how much you can do with Obsidian with a little creativity. We’ll be publishing more articles soon on how to build your own graphs, so keep an eye out for those!

  4. Hi there!
    That’s an awesome article. Thanks.

    I’m interested in creating a bullet chart – to mimic an “thermometer” – for taking the “temperature” of my team – by collecting in each of my 1:1 a “person temperature”: 1 low – bad and 10 high – good.
    So, I had something nice built with tracker plugin, but I had to reorganize my notes, and can’t make the tracker chart work again. That’s why I’mlooking into replacing it with ObIdian Charts.

    Can you help?
    Thanks
    Ovi

  5. Hello Tim,
    your article is really inspiring and I think it might hold the solution to a problem I am trying to solve.
    I want to have a line graph that displays the daily word count from a folder or file.
    At first I thought that your first solution could be what I was looking for, but with this one can only see the progress over all projects.

    I would like to have a daily word count like you did with the habit tracking. Could you share your scripts for this part of the article? I think I might be able to tweak it from this point 🙂

    That would be really great.
    Thank you nonetheless, your article is a really great start for me.

    Bye 🙂

    1. Hey MJ! Glad you found this article inspiring 🙂

      Just for fun, I took a shot at creating the view you’re talking about. Here is the code. Copy the whole thing (including yaml) into a new note in your vault.

      It includes a daily and month graph of your progress, and a table which shows file size for your recently created notes. You can limit which folder it uses by changing the location property.

      The one caveat: Dataview doesn’t store word count for files, so I was forced to use file.size, which is closer to a character count than a word count. You could do word count, but you would need to use another plugin to add the word count to your properties, so that Dataview can access it. Hopefully that gets you close!

      1. Thank you very much, that looks amazing.
        I experimented a little bit and came up with this solution here: https://github.com/KamoD-a/wordcount, but one has to type in everything manually, so your approach comes in handy to find a more automated solution. Thank you very much again 🙂

        1. Very cool MJ, glad you were able to make it work 🙂 your script looks great!

  6. Riley Stolberg Avatar
    Riley Stolberg

    Hello Tim,

    Just curious if I could get the code you used to make that streak counter for multiple habits. I’ve been trying and failing to recreate it.

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *