Skip to content

Commit

Permalink
l
Browse files Browse the repository at this point in the history
  • Loading branch information
holtzy committed Oct 25, 2024
1 parent 1b909e5 commit 18a76fb
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 6 deletions.
112 changes: 106 additions & 6 deletions pages/course/axis/bottom-axis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Link from 'next/link';
import { TakeHome } from '@/component/TakeHome';
import { ChartOrSandbox } from '@/component/ChartOrSandbox';
import { AxisBasicDemo } from '@/viz/AxisBasic/AxisBasicDemo';
import { scaleLinear } from 'd3';
import { GraphTIIT } from '@/viz/AxisBottomMinimal/Graph';

const previousURL = '/course/axis/margin-and-translation';
const currentURL = '/course/axis/bottom-axis';
Expand All @@ -18,6 +20,13 @@ const seoDescription = '';
export default function Home() {
const currentLesson = lessonList.find((l) => l.link === currentURL);

const xScale = scaleLinear().domain([0, 100]).range([0, 500]);

console.log(xScale.ticks(2));
console.log(xScale.ticks(5));
console.log(xScale.ticks(9));
console.log(xScale.ticks(10));

if (!currentLesson) {
return null;
}
Expand All @@ -37,17 +46,108 @@ export default function Home() {
description={
<>
<p>
In the previous lesson we learnt how to manage margins efficiently
on our chart.
</p>
<p>
Now, let's see how we can actually create a component that draws a
bottom axis!
In the previous lesson, we learned how to manage <b>margins</b>{' '}
effectively in our chart. Now, let's explore how to create a{' '}
<code>AxisBottom</code> react component that draws a bottom axis!
</p>
</>
}
/>

<h2>
More about <code>scaleLinear()</code>
</h2>
<p>
In the previous lessons we talked a lot about the <b>scaleLinear()</b>{' '}
function of d3.js.
</p>
<p>
You should perfectly understand the code below. If not, go back to the{' '}
<Link href="/course/scales/linear-scale">scale module</Link> of this
course!
</p>
<CodeBlock
code={`
const xScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 500]);
console.log(xScale(0)) // 0
console.log(xScale(100)) // 500
`.trim()}
/>
<p>
What I haven't mentioned yet is that the <code>xScale</code> function
includes a few additional methods that are quite useful:
</p>
<ul>
<li>
<code>xScale.range()</code> returns the range of the scale, which is{' '}
<code>[0, 500]</code> in this case.
</li>
<li>
<code>xScale.ticks(10)</code> generates an array of{' '}
<b>approximately</b> 10 evenly spaced values along the axis. This
function is quite intelligent, producing <b>nicely rounded numbers</b>
, which can be a lifesaver.
</li>

<li>
<code>xScale.domain()</code> provides the input domain of the scale (
<code>[0, 100]</code>)
</li>
</ul>

<h3>Example 🧐</h3>
<CodeBlock
code={`
xScale.ticks(2) // [0, 50, 100]
xScale.ticks(5) // [0, 20, 40, 60, 80]
xScale.ticks(9) // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
xScale.ticks(10) // [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
`.trim()}
/>
<p>See?</p>
<p>
The <code>.ticks()</code> method doesn't always return the <b>exact</b>{' '}
number of ticks you specify. Instead, it identifies the{' '}
<b>most suitable value</b> close to your target to ensure your axis
looks polished and visually appealing!
</p>

{/* -
-
-
-
-
-
-
-
-
-
- */}
<h2>Let's draw! ✏️</h2>
<p>
Now that we know where the ticks are going to be, we just need to draw a
long horizontal line, and a multitude of small ticks with their labels
at those positions!
</p>
<p>
Here is a sandbox with a very minimal example. Take a bit of time to
read the code carefully!
</p>
<CodeSandbox vizName="AxisBottomMinimalDemo" />
{/* -
-
-
-
-
-
-
-
-
-
- */}
<h2>Re-usable Bottom Axis component</h2>
<p>
The code snippet below builds a <code>AxisBottom</code> component. It is{' '}
Expand Down
5 changes: 5 additions & 0 deletions viz/AxisBottomMinimal/AxisBottomMinimalDemo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Graph } from './Graph';

export const AxisBottomMinimalDemo = ({ width = 700, height = 400 }) => (
<Graph width={width} height={height} />
);
55 changes: 55 additions & 0 deletions viz/AxisBottomMinimal/Graph.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as d3 from 'd3';

const MARGIN = { top: 30, right: 30, bottom: 50, left: 50 };
const TICK_LENGTH = 8;

type GraphProps = {
width: number;
height: number;
};

export const Graph = ({ width, height }: GraphProps) => {
const boundsWidth = width - MARGIN.right - MARGIN.left;
const boundsHeight = height - MARGIN.top - MARGIN.bottom;

const xScale = d3.scaleLinear().domain([0, 100]).range([0, boundsWidth]);

return (
<div>
<svg width={width} height={height}>
<g
width={boundsWidth}
height={boundsHeight}
transform={`translate(${[MARGIN.left, MARGIN.top].join(',')})`}
>
{/* Main horizontal line */}
<line
x1={0}
x2={boundsWidth}
y1={0}
y2={0}
stroke="black"
strokeWidth={0.5}
/>

{/* Ticks and Labels */}
{xScale.ticks(10).map((value) => (
<g key={value} transform={`translate(${xScale(value)}, 0)`}>
<line y2={TICK_LENGTH} stroke="currentColor" />
<text
key={value}
style={{
fontSize: '10px',
textAnchor: 'middle',
transform: 'translateY(20px)',
}}
>
{value}
</text>
</g>
))}
</g>
</svg>
</div>
);
};
5 changes: 5 additions & 0 deletions viz/AxisBottomMinimal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import ReactDOM from "react-dom";
import { AxisBasic } from "./AxisBasic";

const rootElement = document.getElementById("root");
ReactDOM.render(<AxisBasic width={400} height={400} />, rootElement);
29 changes: 29 additions & 0 deletions viz/AxisBottomMinimal/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": {
"d3": "7.1.1",
"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"
]
}

0 comments on commit 18a76fb

Please sign in to comment.