Skip to content

Commit

Permalink
h
Browse files Browse the repository at this point in the history
  • Loading branch information
holtzy committed Nov 4, 2024
1 parent c21b3cc commit 51319cb
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 7 deletions.
16 changes: 9 additions & 7 deletions pages/course/hover-effect/toggle-class-in-js.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '@/component/ExerciseDoubleSandbox';
import { ExerciseAccordion } from '@/component/ExerciseAccordion';
import { Graph23 } from '@/viz/exercise/PieFirstSolution/Graph';
import { Graph42 } from '@/viz/exercise/PieHoverEffectSolution/Graph';

const previousURL = '/course/hover-effect/css-descendant-selector';
const currentURL = '/course/hover-effect/toggle-class-in-js';
Expand Down Expand Up @@ -204,6 +205,7 @@ const containerRef = useRef();
>
Visit project
</Link>
<Graph42 />
</center>
{/* -
-
Expand All @@ -217,7 +219,7 @@ const containerRef = useRef();
localStorageId={currentLesson.link}
exercises={[
{
title: <span>Your first pie chart! 🍭</span>,
title: <span>Your first pie chart! 🍰</span>,
content: <ExerciseDoubleSandbox exercise={exercises[0]} />,
},
{
Expand All @@ -234,21 +236,21 @@ const exercises: Exercise[] = [
whyItMatters: (
<>
<p>
With the SVG and D3 foundations you’ve built, creating a new chart
type becomes a breeze!
Time to learn a new chart type! Check the{' '}
<Link href="/pie-plot">pie chart</Link> page for the full in-depth
tutorial.
</p>
</>
),
toDo: (
<>
<ul>
<li>A dataset is provided in the sandbox folder.</li>
<li>Build a pie chart representing this dataset.</li>
<li>
Build a Cleveland chart with this dataset. (This chart is a
variation of the lollipop plot and is helpful for comparing two
values across multiple groups.)
Read the <Link href="/pie-plot">pie chart</Link> section for help on
<code>d3.pie()</code> and <code>d3.arc()</code>.
</li>
<li>Check the solution tab to see the intended chart appearance.</li>
</ul>
</>
),
Expand Down
40 changes: 40 additions & 0 deletions viz/exercise/PieHoverEffectPractice/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as d3 from 'd3';
import { data, DataItem } from './data';
import { useRef } from 'react';
import styles from './graph.module.css';

const MARGIN = 30;
const width = 400;
const height = 400;
const colors = ['#98abc5', '#8a89a6', '#7b6888', '#6b486b', '#a05d56'];

export const Graph = () => {
const containerRef = useRef(null);

const radius = Math.min(width, height) / 2 - MARGIN;

const pieGenerator = d3.pie<any, DataItem>().value((d) => d.value);
const pie = pieGenerator(data);

const arcPathGenerator = d3.arc();
const arcs = pie.map((p) =>
arcPathGenerator({
innerRadius: 0,
outerRadius: radius,
startAngle: p.startAngle,
endAngle: p.endAngle,
})
);

return (
<svg width={width} height={height}>
<g transform={`translate(${width / 2}, ${height / 2})`}>
{arcs.map((arc, i) => {
return (
<path key={i} d={arc} fill={colors[i]} className={styles.slice} />
);
})}
</g>
</svg>
);
};
12 changes: 12 additions & 0 deletions viz/exercise/PieHoverEffectPractice/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export type DataItem = {
name: string;
value: number;
};

export const data: DataItem[] = [
{ name: "Mark", value: 90 },
{ name: "Robert", value: 12 },
{ name: "Emily", value: 34 },
{ name: "Marion", value: 53 },
{ name: "Nicolas", value: 98 },
]
12 changes: 12 additions & 0 deletions viz/exercise/PieHoverEffectPractice/graph.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.container .slice {
opacity: 0.8;
cursor: pointer;
}

.container.hasHighlight .slice {
opacity: 0.2;
}

.container.hasHighlight .slice:hover {
opacity: 1;
}
6 changes: 6 additions & 0 deletions viz/exercise/PieHoverEffectPractice/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// File used to render something in codesandbox only
import ReactDOM from 'react-dom';
import { Graph } from './Graph';

const rootElement = document.getElementById('root');
ReactDOM.render(<Graph />, rootElement);
29 changes: 29 additions & 0 deletions viz/exercise/PieHoverEffectPractice/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "pie-chart-basic",
"version": "1.0.0",
"description": "",
"keywords": [],
"main": "index.js",
"dependencies": {
"react": "17.0.2",
"d3": "7.1.1",
"react-dom": "17.0.2",
"react-scripts": "4.0.0"
},
"devDependencies": {
"@babel/runtime": "7.13.8",
"typescript": "4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
60 changes: 60 additions & 0 deletions viz/exercise/PieHoverEffectSolution/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as d3 from 'd3';
import { data, DataItem } from './data';
import { useRef } from 'react';
import styles from './graph.module.css';

const MARGIN = 30;
const width = 400;
const height = 400;
const colors = ['#98abc5', '#8a89a6', '#7b6888', '#6b486b', '#a05d56'];

export const Graph = () => {
const containerRef = useRef(null);

const radius = Math.min(width, height) / 2 - MARGIN;

const pieGenerator = d3.pie<any, DataItem>().value((d) => d.value);
const pie = pieGenerator(data);

const arcPathGenerator = d3.arc();
const arcs = pie.map((p) =>
arcPathGenerator({
innerRadius: 0,
outerRadius: radius,
startAngle: p.startAngle,
endAngle: p.endAngle,
})
);

return (
<svg
width={width}
height={height}
ref={containerRef}
className={styles.container}
>
<g transform={`translate(${width / 2}, ${height / 2})`}>
{arcs.map((arc, i) => {
return (
<path
key={i}
d={arc}
fill={colors[i]}
className={styles.slice}
onMouseEnter={() => {
if (containerRef.current) {
containerRef.current.classList.add(styles.hasHighlight);
}
}}
onMouseLeave={() => {
if (containerRef.current) {
containerRef.current.classList.remove(styles.hasHighlight);
}
}}
/>
);
})}
</g>
</svg>
);
};
12 changes: 12 additions & 0 deletions viz/exercise/PieHoverEffectSolution/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export type DataItem = {
name: string;
value: number;
};

export const data: DataItem[] = [
{ name: "Mark", value: 90 },
{ name: "Robert", value: 12 },
{ name: "Emily", value: 34 },
{ name: "Marion", value: 53 },
{ name: "Nicolas", value: 98 },
]
12 changes: 12 additions & 0 deletions viz/exercise/PieHoverEffectSolution/graph.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.container .slice {
opacity: 0.8;
cursor: pointer;
}

.container.hasHighlight .slice {
opacity: 0.2;
}

.container.hasHighlight .slice:hover {
opacity: 1;
}
6 changes: 6 additions & 0 deletions viz/exercise/PieHoverEffectSolution/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// File used to render something in codesandbox only
import ReactDOM from 'react-dom';
import { Graph } from './Graph';

const rootElement = document.getElementById('root');
ReactDOM.render(<Graph />, rootElement);
29 changes: 29 additions & 0 deletions viz/exercise/PieHoverEffectSolution/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "pie-chart-basic",
"version": "1.0.0",
"description": "",
"keywords": [],
"main": "index.js",
"dependencies": {
"react": "17.0.2",
"d3": "7.1.1",
"react-dom": "17.0.2",
"react-scripts": "4.0.0"
},
"devDependencies": {
"@babel/runtime": "7.13.8",
"typescript": "4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

0 comments on commit 51319cb

Please sign in to comment.