Contribution Graph - generate heatmap charts to track your activity

Hi guys,

I wrote a plugin named contribution graph, which could generate interactive GitHub-style contribution graphs, month track graphs, and calendar track graphs.

talks is cheap, show images directly

  • default view

  • Month track view

  • Calendar track view

More case you can see at Github Project Site.

Many thanks to the plug-in authors of heatmap calendar and activity history, the inspiration comes from them

More

9 Likes

Case 1 - render latest days & add click action

a sample show how to render graph

  • find pages which container project tag
  • render latest 365 days range
  • search by date keyword when click cell

code


// pages 
const data = dv.pages('#project')
	.map(p => {
		return {
			date: p.file.ctime.toFormat('yyyy-MM-dd'),
			value: p
		}
	})
	.groupBy(p => p.date) // group by date
	.map(entry =>{ 
		// convert to contribution graph data
		return {
			date: entry.key,
			value: entry.rows.length
		}
	})
const options = {
    days: 365,
    title: 'Contributions in the last 365 days ', // graph title
    data: data,
    onCellClick: (item) => {
        // call global-search by cell's date
	    const key = `["tags":project] ["createTime":${item.date}]`
		app.internalPlugins.plugins['global-search'].instance.openGlobalSearch(key)
    },
}

// render graph by  data
renderContributionGraph(this.container, options )

images

Hi everyone, I have released a new version 0.4.0 today

Release 0.4.0 · vran-dev/obsidian-contribution-graph · GitHub

  • create and modify graphs without writing code
  • it’s not necessary need to integrate with dataview

life is becoming better

Create graph by command

contribution-graph-create

Modify graph

contribution-graph-edit

Hi everyone, I have released a new version 0.5.0 today

Release 0.5.0 · vran-dev/obsidian-contribution-graph · GitHub

  • support customized cell styles from UI
  • Add Create contribution graph to the context menu
  • supports specifying the format of dateField
  • Fixed tooltip may not hidden when graph re-rendered
  • support file.ctime and mtime as datefield
  • add datefield suggest
1 Like

Just what I was looking for.

However, I dropped using the filesystem’s date and time for created and modification of notes. It breaks quite easily and is therefore not reliable.

Basically, I use a combination of obsidian-linter and obsidian-frontmatter-modified-date as described in this Obsidian forum post.

sorry for response so late.

for your situation, you can switch Date Field to Specific Page Property in the form, then input your customized date property name

1 Like

Hello.

I’m currently using a plugin call “Better word count” and it stores my daily word count in a .json file.

However, i couldn’t work out how to make the plugin read data in that .json file, can you help me with that?

Many thanks.

This requires the use of dvjs code

  • read data from json file
  • Parse this data and group by day
  • use contribution graph’s API to render this data

JSON read sample

const jsonString = await app.vault.adapter.read(".obsidian/vault-stats.json");
const jsonObject = JSON.parse(jsonString);

contribution graph’s API document: obsidian-contribution-graph/README_ADVANCE.md at master · vran-dev/obsidian-contribution-graph · GitHub

Hi, I am Using the “Reminder” plugin with which my Tasks/to dos look like this:

- [ ] "Some random Task"  ⏰ YYYY-MM-DD 📅 YYYY-MM-DD

in this configuration “:alarm_clock: YYYY-MM-DD” is the Due date or reminder date and “:date: YYYY-MM-DD” is the date on which the task was originally issued.

A completed tasks looks like:

  • “Some Random Task” :white_check_mark: YYYY-MM-DD

Where :white_check_mark: YYYY-MM-DD is the date on which the task is compleded.

Further, I often (espacially in my daily notes, I use “nested tasks” i.e. something like:

  • “Some random Main-Task” :alarm_clock: YYYY-MM-DD :date: YYYY-MM-DD
  • “Some random Sub-Task” :alarm_clock: YYYY-MM-DD :date: YYYY-MM-DD
  • “Some Random already completed Sub-Task” :white_check_mark: YYYY-MM-DD

With this background and the code provided below, I have the following issues:

Issue A: The heat map is somehow disregarding the dates on completed “Sub-Tasks” and is counting them also for later days. I am not 100% sure but I think it is only for those in the daily note. For example today, “sub tasks” that were completed last week are still counted if the main task is not yet completed in the daily note.

Issue B: I would like to have a heat map for how many tasks are due in future. i.e. that (in a different block) the plugin is counting how many tasks have their due date (:alarm_clock: YYYY-MM-DD) as a specific time in future and is displaying a heat map for , lets say the next 6 month or year.

for all this, I would like the plugin to consider every task globally regardless if from meeting notes, dailies or whatever else.

Here is the code I am using right now:

title: Tasks Completed
graphType: month-track
dateRangeValue: 2
dateRangeType: LATEST_YEAR
startOfWeek: 0
showCellRuleIndicators: true
titleStyle:
  textAlign: left
  fontSize: 15px
  fontWeight: normal
dataSource:
  type: ALL_TASK
  value: ""
  dateField:
    type: FILE_CTIME
    value: completed
  filters:
    - id: "1722233363578"
      type: STATUS_IS
      value: COMPLETED
fillTheScreen: true
enableMainContainerShadow: false
cellStyleRules:
  - id: 1722196093823
    min: "1"
    max: "10"
    color: "#63aa82"
    text: ""
  - id: Halloween_a
    color: "#fdd577"
    min: "10"
    max: "20"
  - id: Halloween_b
    color: "#faaa53"
    min: "20"
    max: "30"
  - id: Halloween_c
    color: "#f07c44"
    min: "40"
    max: "50"
  - id: Halloween_d
    color: "#d94e49"
    min: "60"
    max: "70"
  - id: 1722195684421
    min: "70"
    max: "999"
    color: "#7c0793ff"
    text: ""
cellStyle:
  minHeight: 10px
  minWidth: 10px
mainContainerStyle:
  boxShadow: rgba(0, 0, 0, 0.16) 0px 1px 4px

I’ve been trying to figure out how to use the task property option for the date field but can’t seem to get it to work.

For example, there’s a task property called task.done which stores the time the task was done in the following format.

However when I try to use this in my code it doesn’t recognize the task as being done and color the map.

This is my code:

title: workout tracker
graphType: default
dateRangeValue: 11
dateRangeType: LATEST_MONTH
startOfWeek: 0
showCellRuleIndicators: true
titleStyle:
  textAlign: left
  fontSize: 15px
  fontWeight: normal
dataSource:
  type: TASK_IN_SPECIFIC_PAGE
  value: '"2025 Planner/Weeky Notes"'
  dateField:
    format: YYYY-MM-DD
    type: TASK_PROPERTY
    value: "task.done"
  filters:
    - id: "1734651687455"
      type: CONTAINS_ANY_TAG
      value:
        - "workout"
    - id: "1734708336244"
      type: STATUS_IS
      value: FULLY_COMPLETED
  countField:
    type: TASK_PROPERTY
fillTheScreen: false
enableMainContainerShadow: false
cellStyleRules: []

Am I missing a setting somewhere? The date format are consistent throughout