diff --git a/pages/course/scales/linear-scale.tsx b/pages/course/scales/linear-scale.tsx
index 20568441..5a44d19e 100644
--- a/pages/course/scales/linear-scale.tsx
+++ b/pages/course/scales/linear-scale.tsx
@@ -4,6 +4,16 @@ import { LayoutCourse } from '@/component/LayoutCourse';
import { lessonList } from '@/util/lessonList';
import Link from 'next/link';
import { CircleScaleExercise } from '@/component/interactiveTeaching/CircleScaleExercise';
+import { CodeBlock } from '@/component/UI/CodeBlock';
+import { ExerciseAccordion } from '@/component/ExerciseAccordion';
+import {
+ Exercise,
+ ExerciseDoubleSandbox,
+} from '@/component/ExerciseDoubleSandbox';
+import { Graph1 } from '@/viz/exercise/linearScaleBarSizeSolution/Graph';
+import { Graph4 } from '@/viz/exercise/linearScaleMirrorSolution/Graph';
+import { Graph3 } from '@/viz/exercise/linearScaleReverseSolution/Graph';
+import { Graph2 } from '@/viz/exercise/linearScaleThreeBarsSolution/Graph';
const previousURL = '/course/scales/introduction';
const currentURL = '/course/scales/linear-scale';
@@ -13,6 +23,10 @@ const seoDescription = '';
export default function Home() {
const currentLesson = lessonList.find((l) => l.link === currentURL);
+ if (!currentLesson) {
+ return null;
+ }
+
return (
It expects 2 inputs: a domain and a range .
- 🏠 Domain
+ 🏠 Domain
Usually an array of length 2. It provides the min
and the{' '}
max
of the values we have in the dataset.
- 📏 Range
+ 📏 Range
Usually an array of length 2. It provides the start and the end of the
- positions we are targeting in pixel.
+ positions we are targeting in pixel .
+
+
+
- The output is a function that expects only 1 argument. You give it a
- value from the domain, and it returns the corresponding value in the
- Range
+ The output is a function that takes a single argument. You
+ provide a value from the domain, and it returns the corresponding value
+ from the range.
+
+ Let's create a scale to address the issue with the green circles above!
+
+
{/* -
-
@@ -84,10 +117,150 @@ export default function Home() {
-
-
-
+- */}
+ Exercices
+ Control bar size with a scale,
+ content: ,
+ },
+ {
+ title: Three Bars! ,
+ content: ,
+ },
+ {
+ title: Reverse direction ,
+ content: ,
+ },
+ {
+ title: Mirror barplot ,
+ content: ,
+ },
+ ]}
+ />
+ {/* -
+-
+-
+-
+-
+-
- */}
Much more power
The scaleLinear function actually make much more than that!!!
+
+
+
+
+
);
}
+
+const exercices: Exercise[] = [
+ {
+ whyItMatters: (
+ <>
+
+ Now that you know what a scale is, time to write your first scale!
+
+ >
+ ),
+ toDo: (
+
+ Create a barplot with 1 bar only.
+ The SVG area is 500px wide. Your dataset goes from 0 to 100.
+
+ Draw a horizontal bar that goes from the very left, and has a length
+ that represents a value of 82 in the dataset.
+
+
+ ),
+ practiceSandbox: 'exercise/linearScaleBarSizePractice',
+ solutionSandbox: 'exercise/linearScaleBarSizeSolution',
+ },
+ {
+ whyItMatters: (
+ <>
+
+ Once a scale is available, everything you draw on your screen will go
+ through it to determine positions!
+
+
+ Also, see how convenient scales are when it comes to adding margins!
+
+ >
+ ),
+ toDo: (
+
+ Now create 3 bars.
+ Vertical positions are written manually
+
+ Widths must represent the value 34
, 53
and{' '}
+ 82
+
+
+ ⚠️ You must leave a margin of 20px on the left hand side.
+
+
+ ),
+ practiceSandbox: 'exercise/linearScaleThreeBarsPractice',
+ solutionSandbox: 'exercise/linearScaleThreeBarsSolution',
+ },
+
+ {
+ whyItMatters: (
+ <>
+ Scales are very useful to reverse the direction of drawing
+ >
+ ),
+ toDo: (
+
+
+ Let's draw one single bar that represents the value 82
+
+ But this time, the bar must go from the right to the left.
+
+ Hint: reverse the range
array!
+
+
+ ),
+ practiceSandbox: 'exercise/linearScaleReversePractice',
+ solutionSandbox: 'exercise/linearScaleReverseSolution',
+ },
+
+ {
+ whyItMatters: (
+ <>
+
+ The logic behind each functions of the d3-shape
module is
+ the same.
+
+
+ If you have a good understanding of d3.line(), you're on the right way
+ to build any other chart type!
+
+ >
+ ),
+ toDo: (
+ <>
+
+ Let's create a mirror histogram!! The mirror histogram looks like
+ this:
+
+
+ Create 2 scales!
+
+ Values are 23
, 55
, 87
on the
+ left, and 12
, 43
, 98
on the
+ right
+
+
+ >
+ ),
+ practiceSandbox: 'exercise/linearScaleMirrorPractice',
+ solutionSandbox: 'exercise/linearScaleMirrorSolution',
+ },
+];
diff --git a/viz/exercise/linearScaleBarSizePractice/Graph.tsx b/viz/exercise/linearScaleBarSizePractice/Graph.tsx
new file mode 100644
index 00000000..cf661381
--- /dev/null
+++ b/viz/exercise/linearScaleBarSizePractice/Graph.tsx
@@ -0,0 +1,21 @@
+import { scaleLinear } from 'd3';
+
+export const Graph = () => {
+ // Create scale here
+ const scale = '';
+
+ return (
+
+
+ {/* Use the scale in this rect!!! */}
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleBarSizePractice/index.js b/viz/exercise/linearScaleBarSizePractice/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleBarSizePractice/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleBarSizePractice/package.json b/viz/exercise/linearScaleBarSizePractice/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleBarSizePractice/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleBarSizeSolution/Graph.tsx b/viz/exercise/linearScaleBarSizeSolution/Graph.tsx
new file mode 100644
index 00000000..5a644d32
--- /dev/null
+++ b/viz/exercise/linearScaleBarSizeSolution/Graph.tsx
@@ -0,0 +1,19 @@
+import { scaleLinear } from 'd3';
+
+export const Graph = () => {
+ const scale = scaleLinear().domain([0, 100]).range([0, 500]);
+
+ return (
+
+
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleBarSizeSolution/index.js b/viz/exercise/linearScaleBarSizeSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleBarSizeSolution/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleBarSizeSolution/package.json b/viz/exercise/linearScaleBarSizeSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleBarSizeSolution/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleMirrorPractice/Graph.tsx b/viz/exercise/linearScaleMirrorPractice/Graph.tsx
new file mode 100644
index 00000000..8490ac7d
--- /dev/null
+++ b/viz/exercise/linearScaleMirrorPractice/Graph.tsx
@@ -0,0 +1,87 @@
+import { scaleLinear } from 'd3';
+
+const WIDTH = 500;
+const PADDING_CENTER = 20;
+
+export const Graph = () => {
+ const scaleLeft = '';
+
+ const scaleRight = '';
+
+ return (
+
+ {/* Background */}
+
+
+ {/* Grid */}
+
+
+
+ {/* Right Bars */}
+
+
+
+
+ {/* Left Bars */}
+
+
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleMirrorPractice/index.js b/viz/exercise/linearScaleMirrorPractice/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleMirrorPractice/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleMirrorPractice/package.json b/viz/exercise/linearScaleMirrorPractice/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleMirrorPractice/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleMirrorSolution/Graph.tsx b/viz/exercise/linearScaleMirrorSolution/Graph.tsx
new file mode 100644
index 00000000..e803e1b8
--- /dev/null
+++ b/viz/exercise/linearScaleMirrorSolution/Graph.tsx
@@ -0,0 +1,91 @@
+import { scaleLinear } from 'd3';
+
+const WIDTH = 500;
+const PADDING_CENTER = 20;
+
+export const Graph = () => {
+ const scaleLeft = scaleLinear()
+ .domain([100, 0])
+ .range([0, WIDTH / 2 - PADDING_CENTER / 2]);
+
+ const scaleRight = scaleLinear()
+ .domain([0, 100])
+ .range([0, WIDTH / 2 + PADDING_CENTER / 2, WIDTH]);
+
+ return (
+
+ {/* Background */}
+
+
+ {/* Grid */}
+
+
+
+ {/* Right Bars */}
+
+
+
+
+ {/* Left Bars */}
+
+
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleMirrorSolution/index.js b/viz/exercise/linearScaleMirrorSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleMirrorSolution/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleMirrorSolution/package.json b/viz/exercise/linearScaleMirrorSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleMirrorSolution/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleReversePractice/Graph.tsx b/viz/exercise/linearScaleReversePractice/Graph.tsx
new file mode 100644
index 00000000..01224fa6
--- /dev/null
+++ b/viz/exercise/linearScaleReversePractice/Graph.tsx
@@ -0,0 +1,26 @@
+import { scaleLinear } from 'd3';
+
+const WIDTH = 500;
+
+export const Graph = () => {
+ // create the scale, reverse the domain!
+ const scale = '';
+
+ return (
+
+ {/* Background */}
+
+
+
+ {/* Bar */}
+
+ );
+};
diff --git a/viz/exercise/linearScaleReversePractice/index.js b/viz/exercise/linearScaleReversePractice/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleReversePractice/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleReversePractice/package.json b/viz/exercise/linearScaleReversePractice/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleReversePractice/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleReverseSolution/Graph.tsx b/viz/exercise/linearScaleReverseSolution/Graph.tsx
new file mode 100644
index 00000000..b477d865
--- /dev/null
+++ b/viz/exercise/linearScaleReverseSolution/Graph.tsx
@@ -0,0 +1,32 @@
+import { scaleLinear } from 'd3';
+
+const WIDTH = 500;
+
+export const Graph = () => {
+ const scale = scaleLinear().domain([100, 0]).range([0, WIDTH]);
+
+ return (
+
+ {/* Background */}
+
+
+
+ {/* Bar */}
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleReverseSolution/index.js b/viz/exercise/linearScaleReverseSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleReverseSolution/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleReverseSolution/package.json b/viz/exercise/linearScaleReverseSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleReverseSolution/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleThreeBarsPractice/Graph.tsx b/viz/exercise/linearScaleThreeBarsPractice/Graph.tsx
new file mode 100644
index 00000000..a68c5716
--- /dev/null
+++ b/viz/exercise/linearScaleThreeBarsPractice/Graph.tsx
@@ -0,0 +1,33 @@
+import { scaleLinear } from 'd3';
+
+const MARGIN = 20;
+
+export const Graph = () => {
+ // create a scale here! Include the MARGIN!
+ const scale = '';
+
+ return (
+
+ {/* Background */}
+
+
+ {/* Grid */}
+
+
+
+
+ {/* Bars: update the positions to reflect the margin and the bar values!!!!! */}
+
+
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleThreeBarsPractice/index.js b/viz/exercise/linearScaleThreeBarsPractice/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleThreeBarsPractice/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleThreeBarsPractice/package.json b/viz/exercise/linearScaleThreeBarsPractice/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleThreeBarsPractice/package.json
@@ -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"
+ ]
+}
diff --git a/viz/exercise/linearScaleThreeBarsSolution/Graph.tsx b/viz/exercise/linearScaleThreeBarsSolution/Graph.tsx
new file mode 100644
index 00000000..365c78c0
--- /dev/null
+++ b/viz/exercise/linearScaleThreeBarsSolution/Graph.tsx
@@ -0,0 +1,50 @@
+import { scaleLinear } from 'd3';
+
+const MARGIN = 20;
+
+export const Graph = () => {
+ const scale = scaleLinear().domain([0, 100]).range([MARGIN, 500]);
+
+ return (
+
+ {/* Background */}
+
+
+ {/* Grid */}
+
+
+
+
+ {/* Bars */}
+
+
+
+
+ );
+};
diff --git a/viz/exercise/linearScaleThreeBarsSolution/index.js b/viz/exercise/linearScaleThreeBarsSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/linearScaleThreeBarsSolution/index.js
@@ -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( , rootElement);
diff --git a/viz/exercise/linearScaleThreeBarsSolution/package.json b/viz/exercise/linearScaleThreeBarsSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/linearScaleThreeBarsSolution/package.json
@@ -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"
+ ]
+}