vran-dev / obsidian-contribution-graph

generate interactive gitxxx style contribution graph for obsidian, use it to track your goals, habits, or anything else you want to track.
Apache License 2.0
258 stars 6 forks source link

Filtering based on Specific Property & Combined Create/Modify time #74

Open j-finger opened 8 months ago

j-finger commented 8 months ago

I have my notes organised with custom file properties such as subject:EE3010 amongst other things.

image

It would be nice to have an input field in the setup where you can add the property value that you want to match. At the moment it works for finding all the notes with a subject property, but it would also be nice to match results based on the value of that property

image

image

It would also be nice to be able to have a combined option for both File Create Time & File Modify Time i.e. File Create or Modify Time

image

vran-dev commented 8 months ago

This feature will complicate the plugin and I need to evaluate it effort.

now, you can implement it based on API usage: https://github.com/vran-dev/obsidian-contribution-graph/blob/master/README_ADVANCE.md

j-finger commented 8 months ago

Thanks for the update, I can achieve what I want using this new functionality.

However I have noticed that the links to the cell contributions disappears when using this new method. I'm having difficulty understanding how to implement the onCellClick functionality to display a list of linked notes corresponding to a specific date directly within the heatmap interface as it works in the basic codeblock.

image


If anyone is interested, here is my solution to creating a combined file creation & modification graph. Note I have just organised my vault properly instead of using advanced file property searches for the moment

const searchFolder = '"2. Area/Study/Digital Signal Processing - EE3010"'
const dateRange = 240
const to = dv.luxon.DateTime.now().toFormat('yyyy-MM-dd');
const from = dv.luxon.DateTime.now().minus({ days: dateRange }).toFormat('yyyy-MM-dd');

// Fetch all pages from the specified folder
const pages = dataview.pages(searchFolder);

// Initialize an empty map for counts
const counts = {};

// Function to increment the count for a given date
function incrementCount(date) {
    if (counts[date]) {
        counts[date].value++;
    } else {
        counts[date] = { date, value: 1 };
    }
}

// Iterate over pages to count ctime and mtime
for (let page of pages) {
    const createdDate = page.file.ctime.toFormat('yyyy-MM-dd');
    const modifiedDate = page.file.mtime.toFormat('yyyy-MM-dd');
    incrementCount(createdDate);
    if (createdDate !== modifiedDate) { // Only increment modified date if it's different
        incrementCount(modifiedDate);
    }
}

// Convert the map to an array for the graph
const combineddata = Object.values(counts);

const calendarData = {
    title: "dataviewjs Codeblock",
    data: combineddata,
    fromDate: from,
    toDate: to,
    cellStyleRules: [
        {
            color: "#fdd577",
            min: 1,
            max: 2,
        },
        {
            color: "#faaa53",
            min: 2,
            max: 3,
        },
        {
            color: "#f07c44",
            min: 3,
            max: 4,
        },
        {
            color: "#d94e49",
            min: 4,
            max: 999,
        },
    ],
};
renderContributionGraph(this.container, calendarData);
D-Simona-G commented 7 months ago

Thanks for the update, I can achieve what I want using this new functionality.

However I have noticed that the links to the cell contributions disappears when using this new method. I'm having difficulty understanding how to implement the onCellClick functionality to display a list of linked notes corresponding to a specific date directly within the heatmap interface as it works in the basic codeblock.

image

If anyone is interested, here is my solution to creating a combined file creation & modification graph. Note I have just organised my vault properly instead of using advanced file property searches for the moment

const searchFolder = '"2. Area/Study/Digital Signal Processing - EE3010"'
const dateRange = 240
const to = dv.luxon.DateTime.now().toFormat('yyyy-MM-dd');
const from = dv.luxon.DateTime.now().minus({ days: dateRange }).toFormat('yyyy-MM-dd');

// Fetch all pages from the specified folder
const pages = dataview.pages(searchFolder);

// Initialize an empty map for counts
const counts = {};

// Function to increment the count for a given date
function incrementCount(date) {
    if (counts[date]) {
        counts[date].value++;
    } else {
        counts[date] = { date, value: 1 };
    }
}

// Iterate over pages to count ctime and mtime
for (let page of pages) {
    const createdDate = page.file.ctime.toFormat('yyyy-MM-dd');
    const modifiedDate = page.file.mtime.toFormat('yyyy-MM-dd');
    incrementCount(createdDate);
    if (createdDate !== modifiedDate) { // Only increment modified date if it's different
        incrementCount(modifiedDate);
    }
}

// Convert the map to an array for the graph
const combineddata = Object.values(counts);

const calendarData = {
  title: "dataviewjs Codeblock",
    data: combineddata,
    fromDate: from,
    toDate: to,
    cellStyleRules: [
      {
          color: "#fdd577",
          min: 1,
          max: 2,
      },
      {
          color: "#faaa53",
          min: 2,
          max: 3,
      },
      {
          color: "#f07c44",
          min: 3,
          max: 4,
      },
      {
          color: "#d94e49",
          min: 4,
          max: 999,
      },
  ],
};
renderContributionGraph(this.container, calendarData);

The links to the contributing files are disappearing from the rendered graph for me too when I use the API programmatically. If I figure out how to make them work, I'll update my comment.

j-finger commented 7 months ago

The links still don't work but I have made an update to my code such that it automatically creates a heatmap for the folder the file is currently in (good for templates)

```dataviewjs
const searchFolder = `"${dv.current().file.folder}"`;
const dateRange = 240
const to = dv.luxon.DateTime.now().toFormat('yyyy-MM-dd');
const from = dv.luxon.DateTime.now().minus({ days: dateRange }).toFormat('yyyy-MM-dd');

// Fetch all pages from the specified folder
const pages = dataview.pages(searchFolder);

// Initialize an empty map for counts
const counts = {};

// Function to increment the count for a given date
function incrementCount(date) {
    if (counts[date]) {
        counts[date].value++;
    } else {
        counts[date] = { date, value: 1 };
    }
}

// Iterate over pages to count ctime and mtime
for (let page of pages) {
    const createdDate = page.file.ctime.toFormat('yyyy-MM-dd');
    const modifiedDate = page.file.mtime.toFormat('yyyy-MM-dd');
    incrementCount(createdDate);
    if (createdDate !== modifiedDate) { // Only increment modified date if it's different
        incrementCount(modifiedDate);
    }
}

// Convert the map to an array for the graph
const combineddata = Object.values(counts);

const calendarData = {
    data: combineddata,
    fromDate: from,
    toDate: to,
    cellStyleRules: [
        {
            color: "#fdd577",
            min: 1,
            max: 2,
        },
        {
            color: "#faaa53",
            min: 2,
            max: 3,
        },
        {
            color: "#f07c44",
            min: 3,
            max: 4,
        },
        {
            color: "#d94e49",
            min: 4,
            max: 999,
        },
    ],
};
renderContributionGraph(this.container, calendarData);
D-Simona-G commented 7 months ago

@j-finger Thanks for sharing! I had a look around last night and it seems to be non-trivial to add the links back as the functionality that controls that is not exposed. I will dig it into it more.

Have you tried using Dataview properties of type [key:: value] so far?

j-finger commented 7 months ago

Have you tried using Dataview properties of type [key:: value] so far?

I have not, have you figured out a way to do this yet? The functionality would be nice, I'll have a little dig at it and report back here if I make any progress.

D-Simona-G commented 7 months ago

@j-finger I ended up not needing to do that, but shouldn't be too difficult.

The [key:: value] properties are going to be properties of the objects retrieved by dv.pages(), at the same level with the file property. So you can filter or group by those or do pretty much whatever you like.