seanlowe / obsidian-timelines

Create a timeline view of all notes with the specified combination of tags
https://seanlowe.github.io/obsidian-timelines/
MIT License
38 stars 2 forks source link

Multi-Type Timelines #43

Open Lavaeolous opened 1 month ago

Lavaeolous commented 1 month ago

As another user noted in the original repo (https://github.com/Darakah/obsidian-timelines/issues/67) it would be nice to add combinable timelines.

My use case would be a timeline containing multiple types of events, the filtering of applicable events should then happen if ANY of the tags noted in the timeline block are found, not when ALL are found.

Currently, the filtering happens in the method filterMDFiles via

return tagList.every((val) => {
logger(`testing val: ${val}`, fileTags.includes(String(val)));
return fileTags.includes(String(val));
});

Overriding this to use .some() instead of .every() is enough, but we would need a way to trigger this filtering when another separator or something is found. I have no idea if there are any conventions for this, but for readability i think maybe use + for AND and | for OR?

Lavaeolous commented 1 month ago

A pretty brutish way to accomplish this would be to change createTagList such as this:

const createTagList = (tagString, timelineTag) => {
    const tagList = [];

    if (tagString.contains("+")) {
        tagString.split('+').forEach((tag) => {
            return parseTag$2(tag, tagList);
        });
        tagList.push(timelineTag);
    }
    else if (tagString.contains("|")) {

        combinedTimeline = true;

        tagString.split('|').forEach((tag) => {
            return parseTag$2(tag, tagList);
        });
        tagList.push(timelineTag);
    }
    else {
        tagString.split(';').forEach((tag) => {
            return parseTag$2(tag, tagList);
        });
        tagList.push(timelineTag);
    }

    return tagList;
};

Here we set a global variable to true if we detect an "|" as a separator, which in turn we can use to switch between .some and .every in filterMDFiles.

seanlowe commented 1 month ago

Hey @Lavaeolous, thanks for creating the issue. I like the way you're describing this, it should be a decent way to implement this. Let me tinker on it for a bit and see if I can't add it shortly.

Life's a little hectic right now, but I'll put aside some time to work on it soon.

seanlowe commented 3 weeks ago

OK, I know it's been a while but I've finally had some time to put some thought into this. Here's kinda what I came up with, let me know your thoughts.

Right now, like you mention, we want to match ALL tags via the tagA;tagB format. I think it would be fine to keep this, so how to complement this existing behaviour with the possibility of either/or tags?

Right now my main choice for implementation would look something like this: tagA|tagB;tagC. In which I would look for all notes with tagC and from within those notes, they can have either tagA or tagB as well.

Is this along the lines of what you were thinking?

Lavaeolous commented 3 weeks ago

Hey, that would do more than i initially thought of (e.g. combining either/or in a single query), which is fine by me! Would this "scale" (for the lack of a better term) to larger queries, e.g. tagA;...;tagA+n|tagB; ... ;tagB+m? Not that i have a use case for that, just out of curiosity.

seanlowe commented 1 week ago

Theoretically, yeah it would scale to whatever level needed. At least, if I write the logic correctly... Hehe that's the kicker, as always

Lavaeolous commented 1 week ago

Thanks, i appreciate your work. Looking forward to the implementation!