nicoespeon / gitgraph.js

[ARCHIVED] A JavaScript library to draw pretty git graphs in the browser
https://www.nicoespeon.com/gitgraph.js
MIT License
3.02k stars 361 forks source link

Partial rendering - Paginated rendering #215

Closed dolanmiu closed 3 months ago

dolanmiu commented 5 years ago

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

fabien0102 commented 5 years ago

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.

dolanmiu commented 5 years ago

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

fabien0102 commented 5 years ago

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.

dolanmiu commented 5 years ago

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

fabien0102 commented 5 years ago

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 ๐Ÿ’ฏ

nicoespeon commented 5 years ago

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

I wanted to add few things:

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 ๐Ÿ‘ ๐Ÿ’ฏ

haizz commented 5 years ago

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};
}
Symbolk commented 5 years ago

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.

wmertens commented 4 years ago

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

kriscoleman commented 1 year ago

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!