-
-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add repos/contributors treemap to list activity page (#1853)
- Loading branch information
1 parent
5344c59
commit 70a67f0
Showing
11 changed files
with
253 additions
and
34 deletions.
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
components/molecules/ContributionsTreemap/contributions-treemap.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { useSpring, animated } from "@react-spring/web"; | ||
import dynamic from "next/dynamic"; | ||
import Card from "components/atoms/Card/card"; | ||
import { SpecialNode } from "stories/molecules/treemap-prototype/special-node"; | ||
import { ContributorNode } from "stories/molecules/treemap-prototype/contributor-node"; | ||
import ClientOnly from "components/atoms/ClientOnly/client-only"; | ||
import type { NodeMouseEventHandler, NodeProps } from "@nivo/treemap"; | ||
|
||
interface ContributionsTreemapProps { | ||
data: any; | ||
color: string; | ||
onClick: NodeMouseEventHandler<object>; | ||
repoId: number | null; | ||
setRepoId: (repoId: number | null) => void; | ||
} | ||
|
||
function BreadCrumb({ isActive, ...rest }: any) { | ||
const separatorStyle = useSpring(isActive ? { opacity: 1 } : { opacity: 0 }); | ||
const textStyle = useSpring(isActive ? { opacity: 1, translateX: 0 } : { opacity: 0, translateX: 100 }); | ||
|
||
return ( | ||
<> | ||
<animated.div className={"px-1"} style={separatorStyle}> | ||
{"/"} | ||
</animated.div> | ||
<animated.div style={textStyle} {...rest} /> | ||
</> | ||
); | ||
} | ||
|
||
const ResponsiveTreeMapHtml = dynamic(() => import("@nivo/treemap").then((module) => module.ResponsiveTreeMapHtml)); | ||
|
||
export const ContributionsTreemap = ({ setRepoId, repoId, data, color, onClick }: ContributionsTreemapProps) => { | ||
return ( | ||
<Card className="grid place-content-stretch"> | ||
<div className="grid"> | ||
{/* Label: Text */} | ||
<div className="text-lg text-slate-900 mb-2 flex"> | ||
<button className="cursor-pointer" onClick={() => setRepoId(null)}> | ||
Repos | ||
</button> | ||
<div> </div> | ||
<BreadCrumb isActive={repoId !== null}>Contributors</BreadCrumb> | ||
</div> | ||
<div className="rounded-md overflow-hidden grid place-content-stretch"> | ||
<div className="grid" style={{ gridArea: "1 / 1" }}> | ||
<ClientOnly> | ||
<ResponsiveTreeMapHtml | ||
data={data} | ||
tile="squarify" | ||
labelSkipSize={12} | ||
innerPadding={4} | ||
leavesOnly | ||
orientLabel={false} | ||
nodeComponent={ | ||
repoId === null | ||
? SpecialNode | ||
: // TODO: Sort this out later | ||
(ContributorNode as <Datum extends object>({ | ||
node, | ||
animatedProps, | ||
borderWidth, | ||
enableLabel, | ||
labelSkipSize, | ||
}: NodeProps<Datum>) => JSX.Element) | ||
} | ||
colors={color} | ||
nodeOpacity={1} | ||
borderWidth={0} | ||
onClick={onClick} | ||
motionConfig={"default"} | ||
/> | ||
</ClientOnly> | ||
</div> | ||
</div> | ||
</div> | ||
</Card> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import useSWR, { Fetcher } from "swr"; | ||
import publicApiFetcher from "lib/utils/public-api-fetcher"; | ||
|
||
export const useContributionsByProject = ({ | ||
listId, | ||
range, | ||
initialData, | ||
}: { | ||
listId: string; | ||
range: number; | ||
initialData?: DbProjectContributions[]; | ||
}) => { | ||
const { data, error } = useSWR<DbProjectContributions[]>( | ||
`lists/${listId}/stats/contributions-by-project?range=${range}`, | ||
publicApiFetcher as Fetcher<DbProjectContributions[], Error> | ||
// { | ||
// fallbackData: { | ||
// `lists/${listId}/stats/contributions-by-project?range=${range}`: initialData | ||
// }, | ||
// } | ||
); | ||
|
||
return { | ||
data, | ||
error, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import useSWR, { Fetcher } from "swr"; | ||
import { useState } from "react"; | ||
import publicApiFetcher from "lib/utils/public-api-fetcher"; | ||
|
||
export const useContributorsByProject = (listId: string, range: number) => { | ||
const [repoId, setRepoId] = useState<number | null>(null); | ||
const { data, error } = useSWR<DBProjectContributor[]>( | ||
`lists/${listId}/stats/top-project-contributions-by-contributor?repoId=${repoId}&range=${range}`, | ||
publicApiFetcher as Fetcher<DBProjectContributor[], Error> | ||
); | ||
|
||
return { | ||
data, | ||
error, | ||
setRepoId, | ||
repoId, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
export function stringToHSLAColor({ | ||
id, | ||
saturation = 90, | ||
lightness = 48, | ||
alpha = 1, | ||
}: { | ||
id: string; | ||
saturation?: number; | ||
lightness?: number; | ||
alpha?: number; | ||
}) { | ||
// Ensure valid values for saturation and lightness (0-100) and alpha (0-1) | ||
saturation = Math.min(Math.max(saturation, 0), 100); | ||
lightness = Math.min(Math.max(lightness, 0), 100); | ||
alpha = Math.min(Math.max(alpha, 0), 1); | ||
|
||
// Use a simple hashing algorithm to generate H, S, and L values | ||
let hash = 0; | ||
for (let i = 0; i < id.length; i++) { | ||
hash = id.charCodeAt(i) + ((hash << 5) - hash); | ||
} | ||
|
||
const h = ((hash % 360) + 360) % 360; // Ensure H value is between 0 and 360 | ||
|
||
return `hsla(${h}, ${saturation}%, ${lightness}%, ${alpha})`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { SpringValue, to } from "@react-spring/web"; | ||
|
||
/** | ||
There are several utility functions in the @nico/* packages that are ESM only. If you are | ||
unable to dynamically import them for usage in your project, you can copy the source code | ||
here and use this instead. | ||
You'll know if you need to do this if you see an error like this: | ||
Error: require() of ES Module /Users/nicktaylor/dev/work/app/node_modules/@nivo/treemap/node_modules/d3-color/src/index.js from /Users/nicktaylor/dev/work/app/node_modules/@nivo/treemap/node_modules/@nivo/colors/dist/nivo-colors.cjs.js not supported. | ||
Instead change the require of index.js in /Users/nicktaylor/dev/work/app/node_modules/@nivo/treemap/node_modules/@nivo/colors/dist/nivo-colors.cjs.js to a dynamic import() which is available in all CommonJS modules. | ||
**/ | ||
|
||
// See https://github.com/plouc/nivo/blob/master/packages/treemap/src/transitions.ts#L6-L7 | ||
export function htmlNodeTransform(x: SpringValue<number>, y: SpringValue<number>) { | ||
return to([x, y], (x, y) => `translate(${x}px, ${y}px)`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.