Skip to content

Commit

Permalink
o
Browse files Browse the repository at this point in the history
  • Loading branch information
holtzy committed Oct 30, 2024
1 parent 67e32dc commit 372ac57
Show file tree
Hide file tree
Showing 17 changed files with 367 additions and 25 deletions.
19 changes: 11 additions & 8 deletions pages/course/responsiveness/introduction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { useDimensions } from '@/hook/use-dimensions';
import { DensityChart } from '@/viz/DensityChartBasic/DensityChart';
import Link from 'next/link';
import { CodeBlock } from '@/component/UI/CodeBlock';
import { TakeHome } from '@/component/TakeHome';

const previousURL = '/course/axis/draw-with-d3';
const previousURL = '/course/axis/project';
const currentURL = '/course/responsiveness/introduction';
const nextURL = '/course/responsiveness/use-dimension-hook';
const seoDescription = '';
Expand Down Expand Up @@ -38,8 +39,8 @@ export default function Home() {
description={
<>
<p>
Most of the visualization components in this gallery accept{' '}
<code>width</code> and <code>height</code> properties.
To build a graph, you need to know the <code>width</code> and{' '}
<code>height</code> of the SVG area.
</p>
<p>
However, we often don't know the exact dimensions we need for our
Expand Down Expand Up @@ -143,14 +144,16 @@ export const DensityPlot = ({ width, height, data }: DensityProps) => {

<h2>Let's Code</h2>
<p>
Let's assume we have a div that is responsive and takes the full width
of an app.
Let's assume we have a <code>div</code> that is responsive and takes the
full width of an app.
</p>
<p>
How can we draw a chart inside this div that also takes up the{' '}
<b>entire space</b> and remains responsive?
How can we draw a chart inside this <code>div</code> that also takes up
the <b>entire space</b> and remains responsive?
</p>
<p>
<TakeHome>Let's find out!</TakeHome> 🙇
</p>
<p>Let's find out! 🙇</p>
</LayoutCourse>
);
}
12 changes: 9 additions & 3 deletions pages/course/responsiveness/use-dimension-hook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import TitleAndDescription from '@/component/TitleAndDescription';
import { LayoutCourse } from '@/component/LayoutCourse';
import { lessonList } from '@/util/lessonList';
import { CodeBlock } from '@/component/UI/CodeBlock';
import { TakeHome } from '@/component/TakeHome';

const previousURL = '/course/responsiveness/introduction';
const currentURL = '/course/responsiveness/use-dimension-hook';
Expand Down Expand Up @@ -51,7 +52,10 @@ export default function Home() {
</a>
.
</p>
<p>Explain more why a hook is what we need.</p>
<p>
That's exactly what we need! A function that we can <b>reuse</b> in all
our chart components and that manages its <b>internal state</b>.
</p>

<h2 id="dimension hook">🎣 Hook to get the container dimensions</h2>
<p>That's how the hook looks like:</p>
Expand Down Expand Up @@ -100,8 +104,10 @@ export const useDimensions = (targetRef: React.RefObject<HTMLDivElement>) => {
<code>window</code> to ensure the dimensions are updated when the window
size changes.
</p>
<p>Why do I have the useLayoutEffect in there?</p>
<p>Explain more in depth how it works.</p>
<p>
I do not want to go too much in depth on how it works. More importantly,
let's see <TakeHome>how to use it</TakeHome>!
</p>
</LayoutCourse>
);
}
139 changes: 126 additions & 13 deletions pages/course/responsiveness/using-the-hook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { LayoutCourse } from '@/component/LayoutCourse';
import { lessonList } from '@/util/lessonList';
import { CodeBlock } from '@/component/UI/CodeBlock';
import { CodeSandbox } from '@/component/CodeSandbox';
import Link from 'next/link';
import { ExerciseAccordion } from '@/component/ExerciseAccordion';
import {
Exercise,
ExerciseDoubleSandbox,
} from '@/component/ExerciseDoubleSandbox';
import { Graph9 } from '@/viz/exercise/ResponsiveDivUseDimensionsSolution/Graph';

const previousURL = '/course/responsiveness/use-dimension-hook';
const currentURL = '/course/responsiveness/using-the-hook';
Expand Down Expand Up @@ -32,25 +39,33 @@ export default function Home() {
description={
<>
<p>
We have a hook that listens for changes in a div's dimensions and
returns those dimensions.
</p>
<p>
Now, it's time to use this hook to inject the dimensions into our
Our <code>use-dimensions</code> hook monitors changes in a{' '}
<code>div</code>'s dimensions and returns those values. Now, let’s{' '}
<b>use</b> this hook to feed the dimensions directly into our
graph!
</p>
</>
}
/>
<h2>Create a ref</h2>
{/* -
-
-
-
-
-
-
- */}
<h2>1️⃣ Create a Ref</h2>
<p>
Start by creating a <code>ref</code> using the React{' '}
Begin by creating a <code>ref</code> with the React{' '}
<code>useRef()</code> function.
</p>
<p>
A <code>ref</code> allows you to target and interact with a specific
HTML element in the DOM of your application.
A <code>ref</code> lets you directly target and interact with a specific
HTML element in your app’s DOM. Remember, we covered this concept in the
module on <Link href="/course/axis/axis-with-d3">D3.js axes</Link>.
</p>

<CodeBlock code={snippet2} />
<br />
<p>
Expand All @@ -59,7 +74,7 @@ export default function Home() {
</p>
<CodeBlock code={snippet4} />

<h2>Use the hook</h2>
<h2>2️⃣ Use the hook</h2>
<p>
Then, pass this newly created <code>chartRef</code> to the hook:
</p>
Expand All @@ -70,7 +85,8 @@ export default function Home() {
properties: <code>height</code> and <code>width</code>. These properties
can be used in your chart component. 🔥
</p>
<blockquote>

<blockquote className="mt-2">
Pro tip: Before building a responsive visualization, use{' '}
<code>console.log()</code> to check the <code>chartSize</code> object
and ensure everything is working correctly.
Expand All @@ -81,15 +97,44 @@ export default function Home() {
//
*/}
<h2 id="application">📊 Application</h2>
<p>You’re all set!</p>
<p>
You’re all set! Just pass the values from <code>chartSize</code> to the
visualization component, and it will become responsive.
Just pass the values from <code>chartSize</code> to the visualization
component, and it will become responsive.
</p>
<p>Here is a full example with code:</p>
<br />
<div style={{ maxWidth: 2000 }} className="full-bleed w-full z-50">
<CodeSandbox vizName={'DensityChartResponsive'} />
</div>
{/* -
-
-
-
-
-
-
-
- */}

<h2>Exercices</h2>
<ExerciseAccordion
localStorageId={currentLesson.link}
exercises={[
{
title: <span>Responsive div ↔️</span>,
content: <ExerciseDoubleSandbox exercise={exercices[0]} />,
},
{
title: (
<span>
First use of the <code>use-dimensions</code> hook 🫧
</span>
),
content: <ExerciseDoubleSandbox exercise={exercices[1]} />,
},
]}
/>
</LayoutCourse>
);
}
Expand All @@ -111,3 +156,71 @@ return(
</div>
)
`.trim();

const exercices: Exercise[] = [
{
whyItMatters: (
<>
<p>CSS knows very well how to handle responsiveness. But do you?</p>
<p>
There are numerous caveats to keep in mind! For instance, a{' '}
<code>div</code> does not have a<code>height</code> by default.
</p>
<p>
I strongly encourage you to put a bg color to your chart container to
double check it behaves as expected.
</p>
</>
),
toDo: (
<ul>
<li>
Open the <code>Graph</code> component.
</li>
<li>
Make it render a div with a width of 100% and a grey background.
</li>
<li>
Inside this container, render another div with a height of 300px, add
margins of 30px, and set a red background.
</li>
</ul>
),
practiceSandbox: 'exercise/ResponsiveDivSolutionPractice',
solutionSandbox: 'exercise/ResponsiveDivSolutionSolution',
},
{
whyItMatters: (
<>
<p>Direct application of this lesson and the previous.</p>
</>
),
toDo: (
<>
<p>
The red rectangle is <b>responsive</b>. Let's find its{' '}
<code>width</code> and <code>height</code>!
</p>
<ul>
<li>
Create a new file named <code>use-dimensions.tsx</code>, and copy
the content of the <code>UseDimensions</code> hook into it.
</li>
<li>
Set up a <code>chartRef</code> and attach it to the red rectangle{' '}
<code>div</code>.
</li>
<li>
Use the hook to retrieve the dimensions and display them within the
red rectangle using <code>p</code> elements.
</li>
<li>
Resize the window to verify that the dimensions update as expected.
</li>
</ul>
</>
),
practiceSandbox: 'exercise/ResponsiveDivUseDimensionsPractice',
solutionSandbox: 'exercise/ResponsiveDivUseDimensionsSolution',
},
];
2 changes: 1 addition & 1 deletion util/lessonList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ export const lessonList: Lesson[] = [
),
readTime: 4,
link: '/course/responsiveness/use-dimension-hook',
status: 'wip',
status: 'free',
moduleId: 'responsiveness',
},
{
Expand Down
7 changes: 7 additions & 0 deletions viz/exercise/ResponsiveDivPractice/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Graph = () => {
return (
<div>
<div></div>
</div>
);
};
6 changes: 6 additions & 0 deletions viz/exercise/ResponsiveDivPractice/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);
28 changes: 28 additions & 0 deletions viz/exercise/ResponsiveDivPractice/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "pie-chart-basic",
"version": "1.0.0",
"description": "",
"keywords": [],
"main": "index.js",
"dependencies": {
"react": "17.0.2",
"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"
]
}
12 changes: 12 additions & 0 deletions viz/exercise/ResponsiveDivSolution/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const Graph = () => {
return (
<div
style={{
backgroundColor: 'grey',
width: '100%',
}}
>
<div style={{ backgroundColor: 'red', margin: 30, height: 300 }}></div>
</div>
);
};
6 changes: 6 additions & 0 deletions viz/exercise/ResponsiveDivSolution/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);
28 changes: 28 additions & 0 deletions viz/exercise/ResponsiveDivSolution/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "pie-chart-basic",
"version": "1.0.0",
"description": "",
"keywords": [],
"main": "index.js",
"dependencies": {
"react": "17.0.2",
"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"
]
}
12 changes: 12 additions & 0 deletions viz/exercise/ResponsiveDivUseDimensionsPractice/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const Graph = () => {
return (
<div
style={{
backgroundColor: 'grey',
width: '100%',
}}
>
<div style={{ backgroundColor: 'red', margin: 30, height: 300 }}></div>
</div>
);
};
6 changes: 6 additions & 0 deletions viz/exercise/ResponsiveDivUseDimensionsPractice/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);
Loading

0 comments on commit 372ac57

Please sign in to comment.