diff --git a/pages/course/svg/d3-shape.tsx b/pages/course/svg/d3-shape.tsx
index 5f03ce34..188bb0c2 100644
--- a/pages/course/svg/d3-shape.tsx
+++ b/pages/course/svg/d3-shape.tsx
@@ -13,6 +13,7 @@ import {
} from '@/component/ExerciseDoubleSandbox';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/component/UI/tabs';
import { Caption } from '@/component/UI/Caption';
+import { GraphTOTO } from '@/viz/exercise/d3LineMultipleLineChartSolution/Graph';
const previousURL = '/course/svg/path-element';
const currentURL = '/course/svg/d3-shape';
@@ -341,8 +342,16 @@ multiply(4, 6))
),
content: ,
},
+ {
+ title: Multiple lines!,
+ content: ,
+ },
+ {
+ title: Line chart with filled area,
+ content: ,
+ },
]}
- />{' '}
+ />
);
}
@@ -431,4 +440,84 @@ const exercices: Exercise[] = [
practiceSandbox: 'exercise/d3AreaFunctionPractice',
solutionSandbox: 'exercise/d3AreaFunctionSolution',
},
+
+ {
+ whyItMatters: (
+ <>
+
+ Using the area()
function is almost the same as the{' '}
+ line()
function.
+
+
+ That's the magic of the d3-shape
module, you switch from
+ one shape to the other easily!
+
+ >
+ ),
+ toDo: (
+
+ -
+ Let's switch to an area chart, thanks to the
d3.area()
{' '}
+ function. Three methods must be chained to area()
:
+
+ -
+
x()
is the same as for the line chart.
+
+ -
+
y0()
: Y coordinate of the bottom of the area
+
+ -
+
y1()
Y coordinate of the top.
+
+
+ ),
+ practiceSandbox: 'exercise/d3LineMultipleLineChartPractice',
+ solutionSandbox: 'exercise/d3LineMultipleLineChartSolution',
+ },
+
+ {
+ whyItMatters: (
+ <>
+
+ Once the path generator is available, it can be used to create as many
+ elements as you wish!
+
+ >
+ ),
+ toDo: (
+
+ - This time, 2 datasets are available. We want to draw 2 lines.
+ - Create a line path generator.
+ -
+ Use the path generator twice, once per dataset, to create 2 paths and
+ draw them!
+
+
+ ),
+ practiceSandbox: 'exercise/d3LineMultipleLineChartPractice',
+ solutionSandbox: 'exercise/d3LineMultipleLineChartSolution',
+ },
+
+ {
+ whyItMatters: (
+ <>
+
+ A chart is essentially a combination of shapes! Once you know how to
+ build them individually, it's just a matter of drawing them together!
+
+ >
+ ),
+ toDo: (
+
+ - Create both a line generator and an area generator
+ - Add 2 paths to the SVG: the area first, the line second.
+ -
+ Use low opacity for the area and a stroke width of 2 for the line.
+
+
+ ),
+
+ practiceSandbox: 'exercise/d3LineFilledAreaPractice',
+ solutionSandbox: 'exercise/d3LineFilledAreaSolution',
+ },
];
diff --git a/viz/exercise/d3LineFilledAreaPractice/Graph.tsx b/viz/exercise/d3LineFilledAreaPractice/Graph.tsx
new file mode 100644
index 00000000..cfbe29d5
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaPractice/Graph.tsx
@@ -0,0 +1,25 @@
+import { line } from 'd3';
+
+// Positions in pixels
+const data = [
+ { x: 0, y: 40 },
+ { x: 50, y: 70 },
+ { x: 100, y: 150 },
+ { x: 200, y: 50 },
+ { x: 300, y: 250 },
+];
+
+export const Graph = () => {
+ // Use the line() function of d3 to create a path generator that expects data as input
+ const lineGenerator = '';
+
+ // Use the lineGenerator function above to build the path string
+ const path = '';
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/Graph.tsx b/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/Graph.tsx
new file mode 100644
index 00000000..72f1f517
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/Graph.tsx
@@ -0,0 +1,24 @@
+import { line } from 'd3';
+
+// Positions in pixels
+const data = [
+ { x: 0, y: 40 },
+ { x: 50, y: 70 },
+ { x: 100, y: 150 },
+ { x: 200, y: 50 },
+ { x: 300, y: 250 },
+];
+
+export const Graph = () => {
+ const lineGenerator = line()
+ .x((d) => d.x)
+ .y((d) => d.y);
+
+ const path = lineGenerator(data);
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/index.js b/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/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/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/package.json b/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaPractice/d3LineFunctionBasicSolution/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/d3LineFilledAreaPractice/index.js b/viz/exercise/d3LineFilledAreaPractice/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaPractice/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/d3LineFilledAreaPractice/package.json b/viz/exercise/d3LineFilledAreaPractice/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaPractice/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/d3LineFilledAreaSolution/Graph.tsx b/viz/exercise/d3LineFilledAreaSolution/Graph.tsx
new file mode 100644
index 00000000..07d10423
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaSolution/Graph.tsx
@@ -0,0 +1,38 @@
+import { area, line } from 'd3';
+
+// Positions in pixels
+const data = [
+ { x: 0, y: 40 },
+ { x: 50, y: 70 },
+ { x: 100, y: 150 },
+ { x: 200, y: 50 },
+ { x: 300, y: 250 },
+];
+
+export const Graph = () => {
+ const lineGenerator = line()
+ .x((d) => d.x)
+ .y((d) => d.y);
+
+ const areaGenerator = area()
+ .x((d) => d.x)
+ .y0((d) => 300)
+ .y1((d) => d.y);
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/d3LineFilledAreaSolution/index.js b/viz/exercise/d3LineFilledAreaSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaSolution/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/d3LineFilledAreaSolution/package.json b/viz/exercise/d3LineFilledAreaSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/d3LineFilledAreaSolution/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/d3LineMultipleLineChartPractice/Graph.tsx b/viz/exercise/d3LineMultipleLineChartPractice/Graph.tsx
new file mode 100644
index 00000000..52fe19b0
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartPractice/Graph.tsx
@@ -0,0 +1,30 @@
+import { line } from 'd3';
+
+// Positions in pixels
+const data = [
+ { x: 0, y: 40 },
+ { x: 50, y: 70 },
+ { x: 100, y: 150 },
+ { x: 200, y: 50 },
+ { x: 300, y: 250 },
+];
+
+const data2 = [
+ { x: 0, y: 140 },
+ { x: 50, y: 20 },
+ { x: 100, y: 110 },
+ { x: 200, y: 150 },
+ { x: 300, y: 50 },
+];
+
+export const Graph = () => {
+ const lineGenerator = line()
+ .x((d) => d.x)
+ .y((d) => d.y);
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/Graph.tsx b/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/Graph.tsx
new file mode 100644
index 00000000..72f1f517
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/Graph.tsx
@@ -0,0 +1,24 @@
+import { line } from 'd3';
+
+// Positions in pixels
+const data = [
+ { x: 0, y: 40 },
+ { x: 50, y: 70 },
+ { x: 100, y: 150 },
+ { x: 200, y: 50 },
+ { x: 300, y: 250 },
+];
+
+export const Graph = () => {
+ const lineGenerator = line()
+ .x((d) => d.x)
+ .y((d) => d.y);
+
+ const path = lineGenerator(data);
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/index.js b/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/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/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/package.json b/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartPractice/d3LineFunctionBasicSolution/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/d3LineMultipleLineChartPractice/index.js b/viz/exercise/d3LineMultipleLineChartPractice/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartPractice/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/d3LineMultipleLineChartPractice/package.json b/viz/exercise/d3LineMultipleLineChartPractice/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartPractice/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/d3LineMultipleLineChartSolution/Graph.tsx b/viz/exercise/d3LineMultipleLineChartSolution/Graph.tsx
new file mode 100644
index 00000000..aedf4eac
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartSolution/Graph.tsx
@@ -0,0 +1,31 @@
+import { line } from 'd3';
+
+// Positions in pixels
+const data = [
+ { x: 0, y: 40 },
+ { x: 50, y: 70 },
+ { x: 100, y: 150 },
+ { x: 200, y: 50 },
+ { x: 300, y: 250 },
+];
+
+const data2 = [
+ { x: 0, y: 140 },
+ { x: 50, y: 20 },
+ { x: 100, y: 110 },
+ { x: 200, y: 150 },
+ { x: 300, y: 50 },
+];
+
+export const Graph = () => {
+ const lineGenerator = line()
+ .x((d) => d.x)
+ .y((d) => d.y);
+
+ return (
+
+ );
+};
diff --git a/viz/exercise/d3LineMultipleLineChartSolution/index.js b/viz/exercise/d3LineMultipleLineChartSolution/index.js
new file mode 100644
index 00000000..fa564d27
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartSolution/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/d3LineMultipleLineChartSolution/package.json b/viz/exercise/d3LineMultipleLineChartSolution/package.json
new file mode 100644
index 00000000..84ed1985
--- /dev/null
+++ b/viz/exercise/d3LineMultipleLineChartSolution/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"
+ ]
+}