Skip to content
This repository has been archived by the owner on Nov 24, 2022. It is now read-only.

Add events as git-like graph #6

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@
"rimraf": "^3.0.0",
"tslint": "^5.20.1",
"typescript": "^3.7.3"
},
"dependencies": {
"@gitgraph/react": "^1.5.4"
}
}
76 changes: 76 additions & 0 deletions src/components/event-branch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import styled from "@emotion/styled";
import * as React from "react";
import { eventBranchCurveHeightPixels, eventDotSize } from "../constants";
import { EventDot } from "./event-dot";
import { EventTimeline } from "./event-timeline";
import { VerticalBezierCurve } from "./vertical-bezier-curve";

const EventBranchContainer = styled.div`
position: absolute;
`;

const CurveContainer = styled.div`
position: absolute;
`;

const OriginContainer = styled.div`
position: absolute;
top: -${eventDotSize};
`;

interface IEventBranchProps {
children: React.ReactNode;
offsetX: number;
offsetY: number;
color: string;
}

export const EventBranch = ({
children,
offsetX,
offsetY,
color,
}: IEventBranchProps) => {
const referencePointX = offsetX > 0 ? offsetX : 0;
const width = Math.abs(offsetX);
const originPositionProperty = offsetX > 0 ? "left" : "right";

return (
<EventBranchContainer
style={{
left: offsetX,
top: offsetY,
}}
>
<EventTimeline color={color}>
<CurveContainer
style={{
left: `calc(-${referencePointX}px + (${eventDotSize}) / 2)`,
top: -eventBranchCurveHeightPixels,

height: eventBranchCurveHeightPixels,
width,
}}
>
<VerticalBezierCurve
color="red"
width={offsetX}
height={eventBranchCurveHeightPixels}
ratio={1}
strokeWidth={2}
/>

<OriginContainer
style={{
[originPositionProperty]: `calc(-${eventDotSize} / 2)`,
}}
>
<EventDot isSpecial />
</OriginContainer>
</CurveContainer>

{children}
</EventTimeline>
</EventBranchContainer>
);
};
22 changes: 22 additions & 0 deletions src/components/event-dot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import styled from "@emotion/styled";
import * as React from "react";
import { eventDotSize } from "../constants";

const Dot = styled.div`
background: currentColor;
width: ${eventDotSize};
height: ${eventDotSize};
border-radius: ${eventDotSize};
`;

const SpecialDot = styled(Dot)`
background: white;
border: 2px solid currentColor;
`;

interface IEventDotProps {
isSpecial?: boolean;
}

export const EventDot = ({ isSpecial = false }: IEventDotProps) =>
isSpecial ? <SpecialDot /> : <Dot />;
48 changes: 48 additions & 0 deletions src/components/event-graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from "@emotion/styled";
import * as React from "react";
import { EventBranch } from "./event-branch";
import { EventItem } from "./event-item";
import { EventTimeline } from "./event-timeline";
const Container = styled.div`
padding: 20vh 0;
width: fit-content;
margin: 0 auto;
`;
const getSpace = (height: number) => <div style={{ height: `${height}rem` }} />;
const hackaburgSpace = 10;
const hackaburgSchoolSpace = 5;
const hashcodeSpace = 5;
const colorHashcode = "rgb(255, 99, 132)";
const colorHackaburg = "#1d74f5";
const colorHackaburgSchool = "#82bd53";
const colorStammtisch = "rgb(255, 159, 64)";
export const EventGraph = () => {
return (
<Container>
<EventTimeline color={colorHackaburg}>
<EventBranch offsetX={250} offsetY={320} color={colorHackaburgSchool}>
<EventItem title="Hackaburg School 2018" />
{getSpace(hackaburgSchoolSpace)}
<EventItem title="Hackaburg School 2019" />
</EventBranch>
<EventBranch offsetX={-340} offsetY={140} color={colorHashcode}>
<EventItem title="Hashcode 2017" />
{getSpace(hashcodeSpace)}
<EventItem title="Hashcode 2018" />
{getSpace(hackaburgSpace)}
<EventItem title="Hashcode 2019" />
</EventBranch>
<EventBranch offsetX={-150} offsetY={500} color={colorStammtisch}>
<EventItem title="Stammtisch" />
</EventBranch>
<EventItem title="Hackaburg 2017" />
{getSpace(hackaburgSpace)}
<EventItem title="Hackaburg 2018" />
{getSpace(hackaburgSpace)}
<EventItem title="Hackaburg 2019" />
{getSpace(hackaburgSpace)}
<EventItem title="Hackaburg 2020" />
</EventTimeline>
</Container>
);
};
39 changes: 39 additions & 0 deletions src/components/event-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import styled from "@emotion/styled";
import * as React from "react";
import { EventDot } from "./event-dot";

const EventItemContainer = styled.div`
display: flex;
flex-direction: row;
align-items: baseline;
`;

const ContentContainer = styled.div`
padding-left: 1rem;
`;

const Title = styled.h3`
margin: 0;
padding: 0;
white-space: nowrap;
`;

const ChildrenContainer = styled.div`
padding: 0.5rem 0;
color: white;
`;

interface IEventItemProps {
children?: React.ReactNode;
title: string;
}

export const EventItem = ({ children, title }: IEventItemProps) => (
<EventItemContainer>
<EventDot />
<ContentContainer>
<Title>{title}</Title>
{children && <ChildrenContainer>{children}</ChildrenContainer>}
</ContentContainer>
</EventItemContainer>
);
45 changes: 45 additions & 0 deletions src/components/event-timeline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import styled from "@emotion/styled";
import * as React from "react";
import { eventDotSize, eventTimelineSize } from "../constants";
import { EventDot } from "./event-dot";

const EventTimelineContainer = styled.div`
position: relative;
`;

const Line = styled.div`
position: absolute;
left: calc(${eventDotSize} / 2 - ${eventTimelineSize} / 2);
top: 0;
bottom: 0;

border-left: 2px solid currentColor;
height: 95%;
`;

const ContentContainer = styled.div`
position: relative;
`;

const InitialEvent = styled.div`
padding-bottom: 5rem;
`;

interface IEventTimelineProps {
children: React.ReactNode;
color: string;
}

export const EventTimeline = ({ children, color }: IEventTimelineProps) => (
<EventTimelineContainer style={{ color }}>
<Line />

<ContentContainer>
<InitialEvent>
<EventDot isSpecial />
</InitialEvent>

{children}
</ContentContainer>
</EventTimelineContainer>
);
149 changes: 149 additions & 0 deletions src/components/new-graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { Gitgraph, templateExtend, TemplateName } from "@gitgraph/react";
import styled from "@emotion/styled";
import * as React from "react";

const Container = styled.div`
padding: 20vh 0;
width: fit-content;
margin: 0 auto;
`;

const GraphContainer = styled.div`
width: 100%;
height: auto;
`;

const hackaburgSpace = 10;
const hackaburgSchoolSpace = 5;
const hashcodeSpace = 5;
const colorHashcode = "#ff6384";
const colorHackaburg = "#1d74f5";
const colorHackaburgSchool = "#82bd53";
const colorStammtisch = "#ff9f40";

const template = templateExtend(TemplateName.Metro, {
branch: {
lineWidth: 5,
label: {
display: false,
},
},
commit: {
dot: {
size: 7.5,
},
message: {
font: "inherit",
displayHash: false,
displayAuthor: false,
},
},
});

const order = ["hashcode", "hb-stammtisch", "master", "hb-school"];

const compareBranchesOrder = (a: string, b: string) => {
return order.indexOf(a) - order.indexOf(b);
};

export const EventGraph = () => {
return (
<Container>
<GraphContainer>
<Gitgraph
options={{
orientation: "vertical-reverse",
compareBranchesOrder: compareBranchesOrder,
template: template,
svgClasses: [""],
}}
>
{(gitgraph) => {
// Simulate git commands with Gitgraph API.
const master = gitgraph.branch({
name: "master",

style: {
color: colorHackaburg,
},
commitDefaultOptions: {
style: {
message: {
color: colorHackaburg,
},
dot: {
color: colorHackaburg,
},
},
},
});
master.commit("Hackaburg 2016");
master.commit("Hackaburg 2017");
master.commit("Hackaburg 2018");

const hashcode = gitgraph.branch({
name: "hashcode",
style: {
color: colorHashcode,
},
commitDefaultOptions: {
style: {
message: {
color: colorHashcode,
},
dot: {
color: colorHashcode,
},
},
},
});
hashcode.commit("Hashcode 2019");

const hackaburgSchool = master.branch({
name: "hb-school",
style: {
color: colorHackaburgSchool,
},
commitDefaultOptions: {
style: {
message: {
color: colorHackaburgSchool,
},
dot: {
color: colorHackaburgSchool,
},
},
},
});
hackaburgSchool.commit("Hackaburg School 2019");

master.commit("Hackaburg 2019");

const stammtisch = master.branch({
name: "hb-stammtisch",
style: {
color: colorStammtisch,
},
commitDefaultOptions: {
style: {
message: {
color: colorStammtisch,
},
dot: {
color: colorStammtisch,
},
},
},
});
stammtisch.commit("Stammtisch");

hashcode.commit("Hashcode 2020");
hackaburgSchool.commit("Hackaburg School 2020");

master.commit("Hackaburg 2021");
}}
</Gitgraph>
</GraphContainer>
</Container>
);
};
Loading