gitgraph.js icon indicating copy to clipboard operation
gitgraph.js copied to clipboard

Partial rendering - Paginated rendering

Open dolanmiu opened this issue 6 years ago β€’ 10 comments

Will it be possible in V2 to allow mid-way construction of a gitgraph?

Say a commit history has 1 million commits, but I want to only render 50 commits in a tree somewhere in the middle of the history

dolanmiu avatar Jan 22 '19 01:01 dolanmiu

I guess you can slice or filter your commits before sending them to gitgraph πŸ˜‰ I don't really see the value to load and filter commits inside gitgraph, commits are just an array of objects, so it's really trivial to implement this kind of functionality around gitgraph.

fabien0102 avatar Jan 22 '19 08:01 fabien0102

Its not trivial because a slice of commits may have commits which do not have an parent node. The parent node is way far out, outside of the slice

dolanmiu avatar Jan 22 '19 10:01 dolanmiu

Good point, my next question is where come from your 1 million commits? Usually you already have an API if it's from bitbucket/github/gitlab or you have the "legacy" git filter if you are using the cli.

I think that it's more an issue for tools that give you the 50 commits rather than the tool that do the render.

fabien0102 avatar Jan 22 '19 10:01 fabien0102

1 million commits was just an example to set the story and mood (bad example :joy: )

Yes, it would need to be paginated. Bitbucket paginates it. But if you notice on BitBucket, it partially renders each 50 or so commits in SVG blocks, and seamlessly stitches them together.

A problem they managed to solve is they render the git graph BACKWARDS, starting from the top.

You scroll down the graph to go further back into the past

dolanmiu avatar Jan 22 '19 14:01 dolanmiu

It can be a good challenge to solve, the good thing with the v2 is that we have separate the core and the render, so you should be able to deal with kind of scenario that seperate the render part and the data.

For now we are focused to finish the initial v2 that is more for presentation purpose (the original purpose of this library ^^ It was made to support us to teach git).

If you have some usecases, you can try to tweak gitgraph-react render to handle this kind of case πŸ˜‰

Thanks again for your feedback, it's very valuable πŸ’―

fabien0102 avatar Jan 22 '19 14:01 fabien0102

Hi @dolanmiu πŸ‘‹ Yeah, pretty much what @fabien0102 said.

I wanted to add few things:

  • This scenario you describe is the typical scenario I expect with the import() function. We'll probably have to optimize for performance and rendering when allowing people to import production-like git history to gitgraph.
  • However, I don't want to hold back v2 release with this, so I flagged the import() function as "experimental". It will appear with v2, but we might take a couple of releases to make it right and make it fast.
  • I kinda implemented something similar in the gitgraph-node package. There's a bufferGraphLogger that only renders part of the graphβ€”needed because height of the terminal might be smaller than the graph. Implementation is mostly a graphRenderedData.slice(start, end). So it might already be doable in rendering libraries.

I'll keep the issue open so we collect concrete use-cases we'd like to solve with this. When we have a precise idea of what we want to do (and why), we'll move on this.

As Fabien said: thanks a lot for your feedbacks and suggestions. I'm happy to see you contributing to this fun project πŸ‘ πŸ’―

nicoespeon avatar Feb 02 '19 21:02 nicoespeon

I wrote a custom React renderer to support partial rendering among other things I need to customize in my app. My renderer calls gitgraph-core API directly which allows me to filter data returned by graph.getRenderedData():

const Y_CUTOFF_INITIAL = 1000;

export interface CustomGitgraphProps {
    graph: GitgraphCore<any>;
    // ...
}

export const CustomGitgraph: React.FC<CustomGitgraphProps> = React.memo(
    ({graph}) => {
        const [yCutoff, setYCutoff] = useState(Y_CUTOFF_INITIAL);

        const fullRenderedData = useMemo(
            () => graph.getRenderedData(),
            [graph]
        );

        const partialRenderedData = useMemo(
            () => cutoffRenderedData(fullRenderedData, yCutoff),
            [fullRenderedData, yCutoff]
        );

        return (
            <div>
                {/* render SVG using partialRenderedData */}
            </div>
        );
    }
);

function cutoffRenderedData<TNode>(rd: RenderedData<TNode>, yCutoff: number): RenderedData<TNode> {
    const commits = rd.commits.filter(c => c.y < yCutoff);

    const branchesPaths = new Map<Branch<TNode>, Coordinate[][]>();
    for (const [branch, pp] of rd.branchesPaths.entries()) {
        branchesPaths.set(
            branch,
            pp.map(p =>
                p.filter(c => c.y < (yCutoff + 40))
            ).filter(p => p.length > 0)
        );
    }

    return {...rd, commits, branchesPaths};
}

haizz avatar Apr 25 '19 14:04 haizz

I am using the @gitgraph/js API import() to generate graph from data generated by git2json (as suggested in https://github.com/nicoespeon/gitgraph.js/issues/300#issuecomment-503956005), which returns a json array. However, when I want to just display the latest n commits by slicing the array, it reports that js:1 Uncaught (in promise) TypeError: Cannot read property 'parents' of undefined. Seems that git2json do have have the option to limit the number of commits to return.

Symbolk avatar Jul 12 '19 03:07 Symbolk

BTW - Linux has 0.9 million commits so it's a real-world use case ;)

wmertens avatar Mar 31 '20 16:03 wmertens

I had a use case to do this, we needed to display recent git commits in a dashboard across many, many git projects. The dashboard would only show the top slice of the gitgraph and paginate into the git tree (seamlessly with a infinite scroll pattern) using the github graphql as a backend.

I put a poc together but reached some validation problem with the git graph API as I started to render these partial graphs, which led me here.

+1 for this idea!

kriscoleman avatar Sep 20 '23 17:09 kriscoleman