Added word cloud
This commit is contained in:
parent
126a61fc28
commit
91ac58ae53
|
@ -0,0 +1,140 @@
|
|||
import { scaleLog } from "@visx/scale";
|
||||
import { Text } from "@visx/text";
|
||||
import { Wordcloud as VisxWordcloud } from "@visx/Wordcloud";
|
||||
import { mockCategoricalData } from "data/mocks";
|
||||
import React, { useState } from "react";
|
||||
import { Color } from "utils/Color";
|
||||
|
||||
interface ExampleProps {
|
||||
width: number;
|
||||
height: number;
|
||||
showControls?: boolean;
|
||||
}
|
||||
|
||||
export interface WordData {
|
||||
text: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
const colors = [
|
||||
Color.primaryAccent,
|
||||
Color.primaryAccentLight,
|
||||
// Color.primaryAccentLighter,
|
||||
];
|
||||
|
||||
function getWords(): WordData[] {
|
||||
return mockCategoricalData.map((word) => ({
|
||||
text: word.key,
|
||||
value: word.value,
|
||||
}));
|
||||
}
|
||||
|
||||
function getRotationDegree() {
|
||||
const rand = Math.random();
|
||||
const degree = rand > 0.5 ? 60 : -60;
|
||||
return rand * degree;
|
||||
}
|
||||
|
||||
const words = [...getWords(), ...getWords()];
|
||||
|
||||
const fontScale = scaleLog({
|
||||
domain: [
|
||||
Math.min(...words.map((w) => w.value)),
|
||||
Math.max(...words.map((w) => w.value)),
|
||||
],
|
||||
range: [10, 100],
|
||||
});
|
||||
const fontSizeSetter = (datum: WordData) => fontScale(datum.value);
|
||||
|
||||
const fixedValueGenerator = () => 0.5;
|
||||
|
||||
type SpiralType = "archimedean" | "rectangular";
|
||||
|
||||
export default function Wordcloud({
|
||||
width,
|
||||
height,
|
||||
showControls,
|
||||
}: ExampleProps) {
|
||||
const [spiralType, setSpiralType] = useState<SpiralType>("rectangular");
|
||||
const [withRotation, setWithRotation] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="wordcloud">
|
||||
<VisxWordcloud
|
||||
words={words}
|
||||
width={width}
|
||||
height={height}
|
||||
fontSize={fontSizeSetter}
|
||||
font="Inconsolata"
|
||||
padding={30}
|
||||
spiral={spiralType}
|
||||
rotate={0}
|
||||
random={fixedValueGenerator}
|
||||
>
|
||||
{(cloudWords) =>
|
||||
cloudWords.map((w, i) => (
|
||||
<Text
|
||||
key={w.text}
|
||||
fill={colors[i % colors.length]}
|
||||
textAnchor={"middle"}
|
||||
transform={`translate(${w.x ?? 0}, ${w.y ?? 0})`}
|
||||
fontSize={w.size}
|
||||
fontFamily={w.font}
|
||||
fontWeight={300}
|
||||
>
|
||||
{w.text}
|
||||
</Text>
|
||||
))
|
||||
}
|
||||
</VisxWordcloud>
|
||||
{showControls && (
|
||||
<div>
|
||||
<label>
|
||||
Spiral type
|
||||
<select
|
||||
onChange={(e) => setSpiralType(e.target.value as SpiralType)}
|
||||
value={spiralType}
|
||||
>
|
||||
<option key={"archimedean"} value={"archimedean"}>
|
||||
archimedean
|
||||
</option>
|
||||
<option key={"rectangular"} value={"rectangular"}>
|
||||
rectangular
|
||||
</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
With rotation
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={withRotation}
|
||||
onChange={() => setWithRotation(!withRotation)}
|
||||
/>
|
||||
</label>
|
||||
<br />
|
||||
</div>
|
||||
)}
|
||||
<style jsx>{`
|
||||
.wordcloud {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
user-select: none;
|
||||
}
|
||||
.wordcloud svg {
|
||||
margin: 1rem 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wordcloud label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.wordcloud textarea {
|
||||
min-height: 100px;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
"@visx/axis": "^2.10.0",
|
||||
"@visx/grid": "^2.10.0",
|
||||
"@visx/shape": "^2.10.0",
|
||||
"@visx/wordcloud": "^2.10.0",
|
||||
"next": "12.1.6",
|
||||
"react": "18.1.0",
|
||||
"react-dom": "18.1.0"
|
||||
|
@ -571,6 +572,19 @@
|
|||
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/d3": {
|
||||
"version": "3.5.47",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.47.tgz",
|
||||
"integrity": "sha512-VkWIQoZXLFdcBGe5pdBKJmTU3fmpXvo/KV6ixvTzOMl1yJ2hbTXpfvsziag0kcaerPDwas2T0vxojwQG3YwivQ=="
|
||||
},
|
||||
"node_modules/@types/d3-cloud": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-cloud/-/d3-cloud-1.2.5.tgz",
|
||||
"integrity": "sha512-vEIER9DsEBUOdpRiwCh3n1qE+cV6h4e1LhxhY2sLt+m8LPNAIkOOhTlqk0JDiBwD+ZPM8ynFAOU3AuPuVYBFBA==",
|
||||
"dependencies": {
|
||||
"@types/d3": "^3"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-color": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz",
|
||||
|
@ -982,6 +996,19 @@
|
|||
"react": "^16.3.0-0 || ^17.0.0-0 || ^18.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@visx/wordcloud": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@visx/wordcloud/-/wordcloud-2.10.0.tgz",
|
||||
"integrity": "sha512-SN3W9VbnU/qYofPG5xlN0jJWFTMo5v9jlJtWFLgTy9aHV3CtclyyEAQ6/+VPrKWuNR5bgtOSegiE8EJdobrStg==",
|
||||
"dependencies": {
|
||||
"@types/d3-cloud": "1.2.5",
|
||||
"@visx/group": "2.10.0",
|
||||
"d3-cloud": "^1.2.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0-0 || ^17.0.0-0 || ^18.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
|
||||
|
@ -1429,11 +1456,24 @@
|
|||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-cloud": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-cloud/-/d3-cloud-1.2.5.tgz",
|
||||
"integrity": "sha512-4s2hXZgvs0CoUIw31oBAGrHt9Kt/7P9Ik5HIVzISFiWkD0Ga2VLAuO/emO/z1tYIpE7KG2smB4PhMPfFMJpahw==",
|
||||
"dependencies": {
|
||||
"d3-dispatch": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-color": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
||||
},
|
||||
"node_modules/d3-dispatch": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
|
||||
"integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
|
||||
},
|
||||
"node_modules/d3-format": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
|
||||
|
@ -4659,6 +4699,19 @@
|
|||
"integrity": "sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/d3": {
|
||||
"version": "3.5.47",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.47.tgz",
|
||||
"integrity": "sha512-VkWIQoZXLFdcBGe5pdBKJmTU3fmpXvo/KV6ixvTzOMl1yJ2hbTXpfvsziag0kcaerPDwas2T0vxojwQG3YwivQ=="
|
||||
},
|
||||
"@types/d3-cloud": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-cloud/-/d3-cloud-1.2.5.tgz",
|
||||
"integrity": "sha512-vEIER9DsEBUOdpRiwCh3n1qE+cV6h4e1LhxhY2sLt+m8LPNAIkOOhTlqk0JDiBwD+ZPM8ynFAOU3AuPuVYBFBA==",
|
||||
"requires": {
|
||||
"@types/d3": "^3"
|
||||
}
|
||||
},
|
||||
"@types/d3-color": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-1.4.2.tgz",
|
||||
|
@ -4962,6 +5015,16 @@
|
|||
"reduce-css-calc": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"@visx/wordcloud": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@visx/wordcloud/-/wordcloud-2.10.0.tgz",
|
||||
"integrity": "sha512-SN3W9VbnU/qYofPG5xlN0jJWFTMo5v9jlJtWFLgTy9aHV3CtclyyEAQ6/+VPrKWuNR5bgtOSegiE8EJdobrStg==",
|
||||
"requires": {
|
||||
"@types/d3-cloud": "1.2.5",
|
||||
"@visx/group": "2.10.0",
|
||||
"d3-cloud": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.7.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
|
||||
|
@ -5254,11 +5317,24 @@
|
|||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-cloud": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-cloud/-/d3-cloud-1.2.5.tgz",
|
||||
"integrity": "sha512-4s2hXZgvs0CoUIw31oBAGrHt9Kt/7P9Ik5HIVzISFiWkD0Ga2VLAuO/emO/z1tYIpE7KG2smB4PhMPfFMJpahw==",
|
||||
"requires": {
|
||||
"d3-dispatch": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"d3-color": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
|
||||
"integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q=="
|
||||
},
|
||||
"d3-dispatch": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
|
||||
"integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
|
||||
},
|
||||
"d3-format": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"@visx/axis": "^2.10.0",
|
||||
"@visx/grid": "^2.10.0",
|
||||
"@visx/shape": "^2.10.0",
|
||||
"@visx/wordcloud": "^2.10.0",
|
||||
"next": "12.1.6",
|
||||
"react": "18.1.0",
|
||||
"react-dom": "18.1.0"
|
||||
|
|
|
@ -64,7 +64,8 @@ body {
|
|||
|
||||
background-color: var(--primary-background);
|
||||
color: var(--primary-text);
|
||||
font-family: "Inconsolata", "monospace";
|
||||
font-family: Inconsolata, monospace;
|
||||
/* font-family: monospace; */
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -109,4 +110,4 @@ a:hover {
|
|||
--card-background: var(--dark--card-background);
|
||||
--label: var(--dark--label);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,4 +77,4 @@
|
|||
src: local(''),
|
||||
url('../public/fonts/inconsolata-v30-latin-900.woff2') format('woff2'),
|
||||
url('../public/fonts/inconsolata-v30-latin-900.woff') format('woff'),
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import React from "react";
|
||||
|
||||
import Wordcloud from "@/components/Wordcloud";
|
||||
|
||||
import { ColorPalette } from "../components/ColorPalette";
|
||||
|
||||
export default function Home() {
|
||||
|
@ -8,6 +10,7 @@ export default function Home() {
|
|||
<h1>Playground</h1>
|
||||
<p>Show off your components here!</p>
|
||||
<ColorPalette />
|
||||
<Wordcloud width={2000} height={1000} showControls />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue