Removed files
This commit is contained in:
parent
a03e85e643
commit
8417f08f60
|
@ -1,19 +0,0 @@
|
||||||
.word:hover {
|
|
||||||
text-shadow: var(--primary-accent) 0 0 calc(20rem / 16);
|
|
||||||
text-anchor: "middle";
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip {
|
|
||||||
font-family: "Inconsolata", monospace;
|
|
||||||
font-weight: bold;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
background-color: white;
|
|
||||||
color: var(--navy);
|
|
||||||
box-shadow: var(--card-background) 0px calc(1rem / 16) calc(2rem / 16);
|
|
||||||
pointer-events: none;
|
|
||||||
padding: calc(10rem / 16);
|
|
||||||
font-size: calc(18rem / 16);
|
|
||||||
border-radius: calc(10rem / 16);
|
|
||||||
}
|
|
|
@ -1,201 +0,0 @@
|
||||||
import { localPoint } from "@visx/event";
|
|
||||||
import { Point } from "@visx/point";
|
|
||||||
import { scaleLog } from "@visx/scale";
|
|
||||||
import { Text } from "@visx/text";
|
|
||||||
import { TooltipWithBounds, useTooltip, withTooltip } from "@visx/tooltip";
|
|
||||||
import { Wordcloud as VisxWordcloud } from "@visx/wordcloud";
|
|
||||||
import React from "react";
|
|
||||||
import { Color } from "utils/Color";
|
|
||||||
|
|
||||||
import styles from "./WordCloud.module.css";
|
|
||||||
|
|
||||||
interface WordCloudProps {
|
|
||||||
data: Array<WordData>;
|
|
||||||
width?: number;
|
|
||||||
height?: number;
|
|
||||||
wordPadding?: number;
|
|
||||||
fontWeight?: number;
|
|
||||||
minFontSize?: number;
|
|
||||||
maxFontSize?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface WordData {
|
|
||||||
text: string;
|
|
||||||
value: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wordColors = [Color.primaryAccent, Color.primaryAccentLight];
|
|
||||||
const fixedValueGenerator = () => 0.5;
|
|
||||||
const TOOLTIP_HORIZONTAL_SHIFT_SCALER = 12.0;
|
|
||||||
|
|
||||||
export const WordCloud = withTooltip(
|
|
||||||
({
|
|
||||||
data,
|
|
||||||
width = 1000,
|
|
||||||
height = 500,
|
|
||||||
wordPadding = 30,
|
|
||||||
fontWeight = 500,
|
|
||||||
minFontSize = 20,
|
|
||||||
maxFontSize = 150,
|
|
||||||
}: WordCloudProps) => {
|
|
||||||
const {
|
|
||||||
tooltipData,
|
|
||||||
tooltipLeft,
|
|
||||||
tooltipTop,
|
|
||||||
tooltipOpen,
|
|
||||||
showTooltip,
|
|
||||||
hideTooltip,
|
|
||||||
} = useTooltip<WordData>();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<WordCloudWordsMemoized
|
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
data={data}
|
|
||||||
wordPadding={wordPadding}
|
|
||||||
fontWeight={fontWeight}
|
|
||||||
minFontSize={minFontSize}
|
|
||||||
maxFontSize={maxFontSize}
|
|
||||||
showTooltip={(data, left, top) => {
|
|
||||||
showTooltip({
|
|
||||||
tooltipData: data,
|
|
||||||
tooltipLeft: left,
|
|
||||||
tooltipTop: top,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
hideTooltip={hideTooltip}
|
|
||||||
tooltipLeft={tooltipLeft}
|
|
||||||
tooltipTop={tooltipTop}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{tooltipOpen && tooltipData ? (
|
|
||||||
<TooltipWithBounds
|
|
||||||
// set this to random so it correctly updates with parent bounds
|
|
||||||
key={Math.random()}
|
|
||||||
top={tooltipTop}
|
|
||||||
left={tooltipLeft}
|
|
||||||
unstyled
|
|
||||||
applyPositionStyle
|
|
||||||
id={styles.tooltip}
|
|
||||||
>
|
|
||||||
{tooltipData.text} ({tooltipData.value})
|
|
||||||
</TooltipWithBounds>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
type WordCloudWordsProps = WordCloudProps & {
|
|
||||||
data: Array<WordData>;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
wordPadding: number;
|
|
||||||
fontWeight: number;
|
|
||||||
minFontSize: number;
|
|
||||||
maxFontSize: number;
|
|
||||||
showTooltip: (
|
|
||||||
data: WordData,
|
|
||||||
tooltipLeft: number,
|
|
||||||
tooltipTop: number
|
|
||||||
) => void;
|
|
||||||
hideTooltip: () => void;
|
|
||||||
// These next props are just used to stop the component from updating when it doesnt need to,
|
|
||||||
// but they are not needed to render the component
|
|
||||||
tooltipLeft?: number;
|
|
||||||
tooltipTop?: number;
|
|
||||||
};
|
|
||||||
const WordCloudWords: React.FC<WordCloudWordsProps> = ({
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
data,
|
|
||||||
wordPadding = 30,
|
|
||||||
fontWeight = 400,
|
|
||||||
minFontSize = 20,
|
|
||||||
maxFontSize = 100,
|
|
||||||
showTooltip,
|
|
||||||
hideTooltip,
|
|
||||||
}) => {
|
|
||||||
const fontScale = scaleLog({
|
|
||||||
domain: [
|
|
||||||
Math.min(...data.map((w) => w.value)),
|
|
||||||
Math.max(...data.map((w) => w.value)),
|
|
||||||
],
|
|
||||||
range: [minFontSize, maxFontSize],
|
|
||||||
});
|
|
||||||
const fontSizeSetter = (datum: WordData) => fontScale(datum.value);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<VisxWordcloud
|
|
||||||
words={data}
|
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
fontSize={fontSizeSetter}
|
|
||||||
font="Inconsolata, monospace"
|
|
||||||
padding={wordPadding}
|
|
||||||
spiral={"rectangular"}
|
|
||||||
rotate={0}
|
|
||||||
random={fixedValueGenerator}
|
|
||||||
>
|
|
||||||
{(cloudWords) =>
|
|
||||||
cloudWords.map((w, i) => {
|
|
||||||
return (
|
|
||||||
<Text
|
|
||||||
key={w.text}
|
|
||||||
fill={wordColors[i % wordColors.length]}
|
|
||||||
transform={`translate(${w.x ?? 0}, ${w.y ?? 0})`}
|
|
||||||
fontSize={w.size}
|
|
||||||
fontFamily={w.font}
|
|
||||||
fontWeight={fontWeight}
|
|
||||||
className={styles.word}
|
|
||||||
textAnchor="middle"
|
|
||||||
onMouseMove={
|
|
||||||
((e: React.MouseEvent<SVGTextElement, MouseEvent>) => {
|
|
||||||
const eventSvgCoords = localPoint(
|
|
||||||
// ownerSVGElement is given by visx docs but not recognized by typescript
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
e.target.ownerSVGElement as Element,
|
|
||||||
e
|
|
||||||
) as Point;
|
|
||||||
|
|
||||||
if (w.text) {
|
|
||||||
showTooltip(
|
|
||||||
{ text: w.text, value: data[i].value },
|
|
||||||
eventSvgCoords.x -
|
|
||||||
w.text.length * TOOLTIP_HORIZONTAL_SHIFT_SCALER,
|
|
||||||
eventSvgCoords.y
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log(e, eventSvgCoords);
|
|
||||||
}) as React.MouseEventHandler<SVGTextElement>
|
|
||||||
}
|
|
||||||
onMouseLeave={(_) => hideTooltip()}
|
|
||||||
>
|
|
||||||
{w.text}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</VisxWordcloud>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const shouldNotRerender = (
|
|
||||||
prevProps: WordCloudWordsProps,
|
|
||||||
nextProps: WordCloudWordsProps
|
|
||||||
) => {
|
|
||||||
if (
|
|
||||||
prevProps.tooltipLeft !== nextProps.tooltipLeft ||
|
|
||||||
prevProps.tooltipTop !== nextProps.tooltipTop ||
|
|
||||||
nextProps.tooltipLeft === undefined ||
|
|
||||||
nextProps.tooltipTop === undefined
|
|
||||||
) {
|
|
||||||
return true; // do not re-render
|
|
||||||
}
|
|
||||||
return false; // will re-render
|
|
||||||
};
|
|
||||||
|
|
||||||
const WordCloudWordsMemoized = React.memo(WordCloudWords, shouldNotRerender);
|
|
Loading…
Reference in New Issue