From 94f5a05fff8020b11cb8ccd22f831b872ab393d7 Mon Sep 17 00:00:00 2001 From: Tristan Rahard Date: Tue, 13 Dec 2022 11:58:40 +0100 Subject: [PATCH 1/3] Ajout d'une route et d'un debut de dessin de camembert avec d3js --- pwa/components/Diagrammes/BarChart.tsx | 86 +++++ pwa/components/Diagrammes/Camembert.tsx | 45 +++ pwa/hooks/useD3.js | 13 + pwa/package.json | 4 + pwa/pages/visuCamembert/index.tsx | 29 ++ pwa/pnpm-lock.yaml | 474 ++++++++++++++++++++++++ pwa/styles/globals.css | 30 ++ pwa/tsconfig.json | 2 +- 8 files changed, 682 insertions(+), 1 deletion(-) create mode 100644 pwa/components/Diagrammes/BarChart.tsx create mode 100644 pwa/components/Diagrammes/Camembert.tsx create mode 100644 pwa/hooks/useD3.js create mode 100644 pwa/pages/visuCamembert/index.tsx diff --git a/pwa/components/Diagrammes/BarChart.tsx b/pwa/components/Diagrammes/BarChart.tsx new file mode 100644 index 0000000..1a0dba8 --- /dev/null +++ b/pwa/components/Diagrammes/BarChart.tsx @@ -0,0 +1,86 @@ +import { useD3 } from '../../hooks/useD3'; +import React from 'react'; +import * as d3 from 'd3'; + +function BarChart({ data }: any) { + const ref = useD3( + (svg: any) => { + var margin = { top: 30, right: 30, bottom: 70, left: 60 }, + width = 460 - margin.left - margin.right, + height = 400 - margin.top - margin.bottom; + + // X axis + const x = d3 + .scaleBand() + .range([0, width]) + .domain( + data.map(function (d: any) { + return d.Country; + }) + ) + .padding(0.2); + + const xAxis = (g: any) => + g.attr("transform", `translate(${margin.left}, ${height+10})`) + .call(d3.axisBottom(x)) + .selectAll("text") + .attr("transform", "translate(-10,0)rotate(-45)") + .style("text-anchor", "end"); + + // Y axis + const y = d3.scaleLinear() + .domain([0, 500000]) + .range([height, 0]); + + const yAxis = (g: any) => + g + .attr("transform", `translate(${margin.left}, 10)`) + .style("color", "steelblue") + .call(d3.axisLeft(y).ticks(null, "s")) + .call((g: any) => + g + .append("text") + .attr("x", -margin.left) + .attr("y", 10) + .attr("fill", "currentColor") + .attr("text-anchor", "start") + .text(data.y1) + ); + + // Data + svg.select(".x-axis").call(xAxis); + svg.select(".y-axis").call(yAxis); + + svg.select(".plot-area") + .attr("fill", "steelblue") + .selectAll(".bar") + .data(data) + .join("rect") + .attr("class", "bar") + .attr("x", (d: any) => x(d.Country) + margin.left) + .attr("width", x.bandwidth()) + .attr("y", (d: any) => y(d.Value)) + .attr("height", (d: any) => height - y(d.Value) + 10); + }, + [data.length] + ); + + return ( + + + + + + ); +} + +export default BarChart; diff --git a/pwa/components/Diagrammes/Camembert.tsx b/pwa/components/Diagrammes/Camembert.tsx new file mode 100644 index 0000000..d137e00 --- /dev/null +++ b/pwa/components/Diagrammes/Camembert.tsx @@ -0,0 +1,45 @@ +// src/component/Rectangle/Rectangle.tsx +import React, { useEffect, RefObject } from 'react' +import { select } from 'd3-selection' +import * as d3 from 'd3' +const Camembert = () => { + const ref: RefObject = React.createRef() + useEffect(() => { + draw() + }) + const draw = () => { + var svg = select("body") + .append("svg") + .append("g") + svg.append("g") + .attr("class", "slices"); + svg.append("g") + .attr("class", "labels"); + svg.append("g") + .attr("class", "lines"); + var width = 960, + height = 450, + radius = Math.min(width, height) / 2; + + var pie = d3.pie() + .sort(null) + .value(function(d) { + return d.value; + }); + var arc = d3.arc() + .outerRadius(radius * 0.8) + .innerRadius(radius * 0.4); + + var outerArc = d3.arc() + .innerRadius(radius * 0.9) + .outerRadius(radius * 0.9); + + + } + + return ( +
+
+ ) +} +export default Camembert \ No newline at end of file diff --git a/pwa/hooks/useD3.js b/pwa/hooks/useD3.js new file mode 100644 index 0000000..9da3d03 --- /dev/null +++ b/pwa/hooks/useD3.js @@ -0,0 +1,13 @@ +import React from 'react'; +import * as d3 from 'd3'; + +export const useD3 = (renderChartFn, dependencies) => { + const ref = React.useRef(); + + React.useEffect(() => { + renderChartFn(d3.select(ref.current)); + return () => {}; + }, dependencies); + + return ref; +} diff --git a/pwa/package.json b/pwa/package.json index 48e9dba..d17dce0 100644 --- a/pwa/package.json +++ b/pwa/package.json @@ -10,8 +10,12 @@ }, "dependencies": { "@api-platform/admin": "^3.4.3", + "@types/d3": "^7.4.0", + "@types/d3-selection": "^3.0.3", "bootstrap": "^5.2.2", "bootstrap-icons": "^1.10.2", + "d3": "^7.7.0", + "d3-selection": "^3.0.0", "formik": "^2.2.9", "isomorphic-unfetch": "^3.1.0", "next": "^12.3.3", diff --git a/pwa/pages/visuCamembert/index.tsx b/pwa/pages/visuCamembert/index.tsx new file mode 100644 index 0000000..df83480 --- /dev/null +++ b/pwa/pages/visuCamembert/index.tsx @@ -0,0 +1,29 @@ + +import React from "react"; +import BarChart from "../../components/Diagrammes/BarChart"; +import Camembert from "../../components/Diagrammes/Camembert"; + + +const data = [ + { Country: "Russia", Value: 420000 }, + { Country: "France", Value: 190000 }, + { Country: "United-State", Value: 330000 }, + { Country: "Brazil", Value: 280000 }, + { Country: "Germany", Value: 200000 }, + { Country: "United-Kingdom", Value: 150000 }, + { Country: "China", Value: 350000 } + ]; + + +export default function Home() { + return ( +
+ + + + + + +
+ ) +} \ No newline at end of file diff --git a/pwa/pnpm-lock.yaml b/pwa/pnpm-lock.yaml index eefcea2..c088503 100644 --- a/pwa/pnpm-lock.yaml +++ b/pwa/pnpm-lock.yaml @@ -4,11 +4,15 @@ specifiers: '@api-platform/admin': ^3.4.3 '@babel/core': ^7.20.2 '@popperjs/core': ^2.11.6 + '@types/d3': ^7.4.0 + '@types/d3-selection': ^3.0.3 '@types/node': ^18.11.9 '@types/react': ^18.0.25 '@types/react-dom': ^18.0.9 bootstrap: ^5.2.2 bootstrap-icons: ^1.10.2 + d3: ^7.7.0 + d3-selection: ^3.0.0 eslint: ^8.27.0 eslint-config-next: ^12.3.3 formik: ^2.2.9 @@ -21,8 +25,12 @@ specifiers: dependencies: '@api-platform/admin': 3.4.3_o6ujcdmwt6ni5mv4wdf5n6tg3y + '@types/d3': 7.4.0 + '@types/d3-selection': 3.0.3 bootstrap: 5.2.2_@popperjs+core@2.11.6 bootstrap-icons: 1.10.2 + d3: 7.7.0 + d3-selection: 3.0.0 formik: 2.2.9_react@18.2.0 isomorphic-unfetch: 3.1.0 next: 12.3.3_mqvh5p7ejg4taogoj6tpk3gd5a @@ -834,6 +842,189 @@ packages: tslib: 2.4.1 dev: false + /@types/d3-array/3.0.3: + resolution: {integrity: sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==} + dev: false + + /@types/d3-axis/3.0.1: + resolution: {integrity: sha512-zji/iIbdd49g9WN0aIsGcwcTBUkgLsCSwB+uH+LPVDAiKWENMtI3cJEWt+7/YYwelMoZmbBfzA3qCdrZ2XFNnw==} + dependencies: + '@types/d3-selection': 3.0.3 + dev: false + + /@types/d3-brush/3.0.1: + resolution: {integrity: sha512-B532DozsiTuQMHu2YChdZU0qsFJSio3Q6jmBYGYNp3gMDzBmuFFgPt9qKA4VYuLZMp4qc6eX7IUFUEsvHiXZAw==} + dependencies: + '@types/d3-selection': 3.0.3 + dev: false + + /@types/d3-chord/3.0.1: + resolution: {integrity: sha512-eQfcxIHrg7V++W8Qxn6QkqBNBokyhdWSAS73AbkbMzvLQmVVBviknoz2SRS/ZJdIOmhcmmdCRE/NFOm28Z1AMw==} + dev: false + + /@types/d3-color/3.1.0: + resolution: {integrity: sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==} + dev: false + + /@types/d3-contour/3.0.1: + resolution: {integrity: sha512-C3zfBrhHZvrpAAK3YXqLWVAGo87A4SvJ83Q/zVJ8rFWJdKejUnDYaWZPkA8K84kb2vDA/g90LTQAz7etXcgoQQ==} + dependencies: + '@types/d3-array': 3.0.3 + '@types/geojson': 7946.0.10 + dev: false + + /@types/d3-delaunay/6.0.1: + resolution: {integrity: sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ==} + dev: false + + /@types/d3-dispatch/3.0.1: + resolution: {integrity: sha512-NhxMn3bAkqhjoxabVJWKryhnZXXYYVQxaBnbANu0O94+O/nX9qSjrA1P1jbAQJxJf+VC72TxDX/YJcKue5bRqw==} + dev: false + + /@types/d3-drag/3.0.1: + resolution: {integrity: sha512-o1Va7bLwwk6h03+nSM8dpaGEYnoIG19P0lKqlic8Un36ymh9NSkNFX1yiXMKNMx8rJ0Kfnn2eovuFaL6Jvj0zA==} + dependencies: + '@types/d3-selection': 3.0.3 + dev: false + + /@types/d3-dsv/3.0.0: + resolution: {integrity: sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A==} + dev: false + + /@types/d3-ease/3.0.0: + resolution: {integrity: sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==} + dev: false + + /@types/d3-fetch/3.0.1: + resolution: {integrity: sha512-toZJNOwrOIqz7Oh6Q7l2zkaNfXkfR7mFSJvGvlD/Ciq/+SQ39d5gynHJZ/0fjt83ec3WL7+u3ssqIijQtBISsw==} + dependencies: + '@types/d3-dsv': 3.0.0 + dev: false + + /@types/d3-force/3.0.3: + resolution: {integrity: sha512-z8GteGVfkWJMKsx6hwC3SiTSLspL98VNpmvLpEFJQpZPq6xpA1I8HNBDNSpukfK0Vb0l64zGFhzunLgEAcBWSA==} + dev: false + + /@types/d3-format/3.0.1: + resolution: {integrity: sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==} + dev: false + + /@types/d3-geo/3.0.2: + resolution: {integrity: sha512-DbqK7MLYA8LpyHQfv6Klz0426bQEf7bRTvhMy44sNGVyZoWn//B0c+Qbeg8Osi2Obdc9BLLXYAKpyWege2/7LQ==} + dependencies: + '@types/geojson': 7946.0.10 + dev: false + + /@types/d3-hierarchy/3.1.0: + resolution: {integrity: sha512-g+sey7qrCa3UbsQlMZZBOHROkFqx7KZKvUpRzI/tAp/8erZWpYq7FgNKvYwebi2LaEiVs1klhUfd3WCThxmmWQ==} + dev: false + + /@types/d3-interpolate/3.0.1: + resolution: {integrity: sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==} + dependencies: + '@types/d3-color': 3.1.0 + dev: false + + /@types/d3-path/3.0.0: + resolution: {integrity: sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==} + dev: false + + /@types/d3-polygon/3.0.0: + resolution: {integrity: sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==} + dev: false + + /@types/d3-quadtree/3.0.2: + resolution: {integrity: sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==} + dev: false + + /@types/d3-random/3.0.1: + resolution: {integrity: sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==} + dev: false + + /@types/d3-scale-chromatic/3.0.0: + resolution: {integrity: sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==} + dev: false + + /@types/d3-scale/4.0.2: + resolution: {integrity: sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==} + dependencies: + '@types/d3-time': 3.0.0 + dev: false + + /@types/d3-selection/3.0.3: + resolution: {integrity: sha512-Mw5cf6nlW1MlefpD9zrshZ+DAWL4IQ5LnWfRheW6xwsdaWOb6IRRu2H7XPAQcyXEx1D7XQWgdoKR83ui1/HlEA==} + dev: false + + /@types/d3-shape/3.1.0: + resolution: {integrity: sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA==} + dependencies: + '@types/d3-path': 3.0.0 + dev: false + + /@types/d3-time-format/4.0.0: + resolution: {integrity: sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==} + dev: false + + /@types/d3-time/3.0.0: + resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==} + dev: false + + /@types/d3-timer/3.0.0: + resolution: {integrity: sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==} + dev: false + + /@types/d3-transition/3.0.2: + resolution: {integrity: sha512-jo5o/Rf+/u6uerJ/963Dc39NI16FQzqwOc54bwvksGAdVfvDrqDpVeq95bEvPtBwLCVZutAEyAtmSyEMxN7vxQ==} + dependencies: + '@types/d3-selection': 3.0.3 + dev: false + + /@types/d3-zoom/3.0.1: + resolution: {integrity: sha512-7s5L9TjfqIYQmQQEUcpMAcBOahem7TRoSO/+Gkz02GbMVuULiZzjF2BOdw291dbO2aNon4m2OdFsRGaCq2caLQ==} + dependencies: + '@types/d3-interpolate': 3.0.1 + '@types/d3-selection': 3.0.3 + dev: false + + /@types/d3/7.4.0: + resolution: {integrity: sha512-jIfNVK0ZlxcuRDKtRS/SypEyOQ6UHaFQBKv032X45VvxSJ6Yi5G9behy9h6tNTHTDGh5Vq+KbmBjUWLgY4meCA==} + dependencies: + '@types/d3-array': 3.0.3 + '@types/d3-axis': 3.0.1 + '@types/d3-brush': 3.0.1 + '@types/d3-chord': 3.0.1 + '@types/d3-color': 3.1.0 + '@types/d3-contour': 3.0.1 + '@types/d3-delaunay': 6.0.1 + '@types/d3-dispatch': 3.0.1 + '@types/d3-drag': 3.0.1 + '@types/d3-dsv': 3.0.0 + '@types/d3-ease': 3.0.0 + '@types/d3-fetch': 3.0.1 + '@types/d3-force': 3.0.3 + '@types/d3-format': 3.0.1 + '@types/d3-geo': 3.0.2 + '@types/d3-hierarchy': 3.1.0 + '@types/d3-interpolate': 3.0.1 + '@types/d3-path': 3.0.0 + '@types/d3-polygon': 3.0.0 + '@types/d3-quadtree': 3.0.2 + '@types/d3-random': 3.0.1 + '@types/d3-scale': 4.0.2 + '@types/d3-scale-chromatic': 3.0.0 + '@types/d3-selection': 3.0.3 + '@types/d3-shape': 3.1.0 + '@types/d3-time': 3.0.0 + '@types/d3-time-format': 4.0.0 + '@types/d3-timer': 3.0.0 + '@types/d3-transition': 3.0.2 + '@types/d3-zoom': 3.0.1 + dev: false + + /@types/geojson/7946.0.10: + resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==} + dev: false + /@types/json5/0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true @@ -1200,6 +1391,11 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true + /commander/7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: false + /concat-map/0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1238,6 +1434,254 @@ packages: /csstype/3.1.1: resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + /d3-array/3.2.1: + resolution: {integrity: sha512-gUY/qeHq/yNqqoCKNq4vtpFLdoCdvyNpWoC/KNjhGbhDuQpAM9sIQQKkXSNpXa9h5KySs/gzm7R88WkUutgwWQ==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-axis/3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + dev: false + + /d3-brush/3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1_d3-selection@3.0.0 + dev: false + + /d3-chord/3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.0.1 + dev: false + + /d3-color/3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-contour/4.0.0: + resolution: {integrity: sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.1 + dev: false + + /d3-delaunay/6.0.2: + resolution: {integrity: sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==} + engines: {node: '>=12'} + dependencies: + delaunator: 5.0.0 + dev: false + + /d3-dispatch/3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + dev: false + + /d3-drag/3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + dev: false + + /d3-dsv/3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + dev: false + + /d3-ease/3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-fetch/3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + dependencies: + d3-dsv: 3.0.1 + dev: false + + /d3-force/3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + dev: false + + /d3-format/3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-geo/3.0.1: + resolution: {integrity: sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.1 + dev: false + + /d3-hierarchy/3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate/3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path/3.0.1: + resolution: {integrity: sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==} + engines: {node: '>=12'} + dev: false + + /d3-polygon/3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + dev: false + + /d3-quadtree/3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + dev: false + + /d3-random/3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + dev: false + + /d3-scale-chromatic/3.0.0: + resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + dev: false + + /d3-scale/4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.1 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-selection/3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + dev: false + + /d3-shape/3.1.0: + resolution: {integrity: sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.0.1 + dev: false + + /d3-time-format/4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time/3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.1 + dev: false + + /d3-timer/3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + + /d3-transition/3.0.1_d3-selection@3.0.0: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + dev: false + + /d3-zoom/3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1_d3-selection@3.0.0 + dev: false + + /d3/7.7.0: + resolution: {integrity: sha512-VEwHCMgMjD2WBsxeRGUE18RmzxT9Bn7ghDpzvTEvkLSBAKgTMydJjouZTjspgQfRHpPt/PB3EHWBa6SSyFQq4g==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.1 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.0 + d3-delaunay: 6.0.2 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.0.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.0.1 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.0.0 + d3-selection: 3.0.0 + d3-shape: 3.1.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1_d3-selection@3.0.0 + d3-zoom: 3.0.0 + dev: false + /damerau-levenshtein/1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true @@ -1306,6 +1750,12 @@ packages: has-property-descriptors: 1.0.0 object-keys: 1.1.1 + /delaunator/5.0.0: + resolution: {integrity: sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==} + dependencies: + robust-predicates: 3.0.1 + dev: false + /detect-node/2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: false @@ -1952,6 +2402,13 @@ packages: react-is: 16.13.1 dev: false + /iconv-lite/0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + /ignore/5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} @@ -1996,6 +2453,11 @@ packages: has: 1.0.3 side-channel: 1.0.4 + /internmap/2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + /is-arrayish/0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} dev: false @@ -2879,12 +3341,20 @@ packages: dependencies: glob: 7.2.3 + /robust-predicates/3.0.1: + resolution: {integrity: sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==} + dev: false + /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 dev: true + /rw/1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + /safe-regex-test/1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: @@ -2892,6 +3362,10 @@ packages: get-intrinsic: 1.1.3 is-regex: 1.1.4 + /safer-buffer/2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + /scheduler/0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: diff --git a/pwa/styles/globals.css b/pwa/styles/globals.css index e69de29..0217519 100644 --- a/pwa/styles/globals.css +++ b/pwa/styles/globals.css @@ -0,0 +1,30 @@ +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + width: 960px; + height: 500px; + position: relative; +} + +svg { + width: 100%; + height: 100%; +} + +path.slice{ + stroke-width:2px; +} + +polyline{ + opacity: .3; + stroke: black; + stroke-width: 2px; + fill: none; +} + +button{ + background-color: aqua; +} + +.container{ + margin-left: 50px; +} \ No newline at end of file diff --git a/pwa/tsconfig.json b/pwa/tsconfig.json index 99710e8..217776f 100644 --- a/pwa/tsconfig.json +++ b/pwa/tsconfig.json @@ -15,6 +15,6 @@ "jsx": "preserve", "incremental": true }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "hooks/useD3.js"], "exclude": ["node_modules"] } -- GitLab From c5c2e2e0ee974ec4b47819863baf004322d92a9e Mon Sep 17 00:00:00 2001 From: Tristan RAHARD Date: Fri, 30 Dec 2022 00:01:58 +0100 Subject: [PATCH 2/3] =?UTF-8?q?modification=20du=20Dockerfile=20pour=20cor?= =?UTF-8?q?rection=20d'un=20bug=20d=C3=A9marrage=20pwa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + pwa/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 480190b..e836137 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ !/helm/api-platform/charts/.gitignore /api/src/ventes.txt +/pwa/.pnpm-store/* \ No newline at end of file diff --git a/pwa/Dockerfile b/pwa/Dockerfile index 9a28a2c..366a2e6 100644 --- a/pwa/Dockerfile +++ b/pwa/Dockerfile @@ -24,7 +24,7 @@ COPY --link pnpm-lock.yaml ./ RUN pnpm fetch COPY --link . . -RUN pnpm install -r --offline +RUN pnpm install -r # Development image @@ -33,7 +33,7 @@ FROM deps as dev EXPOSE 3000 ENV PORT 3000 -CMD ["sh", "-c", "pnpm install -r --offline; pnpm dev"] +CMD ["sh", "-c", "pnpm install -r; pnpm dev"] FROM builder_base AS builder -- GitLab From eff5d9157653ef25f1c304aaa6eb2fb7385fe3f6 Mon Sep 17 00:00:00 2001 From: Tristan RAHARD Date: Fri, 30 Dec 2022 00:03:07 +0100 Subject: [PATCH 3/3] =?UTF-8?q?cr=C3=A9ation=20d'une=20page=20de=20visuali?= =?UTF-8?q?sation=20d'un=20camembert=20avec=20valeures=20en=20dur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pwa/components/Diagrammes/BarChart.tsx | 86 ---------------- pwa/components/Diagrammes/Camembert.tsx | 131 ++++++++++++++++-------- pwa/pages/visuCamembert/index.tsx | 18 +--- 3 files changed, 89 insertions(+), 146 deletions(-) delete mode 100644 pwa/components/Diagrammes/BarChart.tsx diff --git a/pwa/components/Diagrammes/BarChart.tsx b/pwa/components/Diagrammes/BarChart.tsx deleted file mode 100644 index 1a0dba8..0000000 --- a/pwa/components/Diagrammes/BarChart.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { useD3 } from '../../hooks/useD3'; -import React from 'react'; -import * as d3 from 'd3'; - -function BarChart({ data }: any) { - const ref = useD3( - (svg: any) => { - var margin = { top: 30, right: 30, bottom: 70, left: 60 }, - width = 460 - margin.left - margin.right, - height = 400 - margin.top - margin.bottom; - - // X axis - const x = d3 - .scaleBand() - .range([0, width]) - .domain( - data.map(function (d: any) { - return d.Country; - }) - ) - .padding(0.2); - - const xAxis = (g: any) => - g.attr("transform", `translate(${margin.left}, ${height+10})`) - .call(d3.axisBottom(x)) - .selectAll("text") - .attr("transform", "translate(-10,0)rotate(-45)") - .style("text-anchor", "end"); - - // Y axis - const y = d3.scaleLinear() - .domain([0, 500000]) - .range([height, 0]); - - const yAxis = (g: any) => - g - .attr("transform", `translate(${margin.left}, 10)`) - .style("color", "steelblue") - .call(d3.axisLeft(y).ticks(null, "s")) - .call((g: any) => - g - .append("text") - .attr("x", -margin.left) - .attr("y", 10) - .attr("fill", "currentColor") - .attr("text-anchor", "start") - .text(data.y1) - ); - - // Data - svg.select(".x-axis").call(xAxis); - svg.select(".y-axis").call(yAxis); - - svg.select(".plot-area") - .attr("fill", "steelblue") - .selectAll(".bar") - .data(data) - .join("rect") - .attr("class", "bar") - .attr("x", (d: any) => x(d.Country) + margin.left) - .attr("width", x.bandwidth()) - .attr("y", (d: any) => y(d.Value)) - .attr("height", (d: any) => height - y(d.Value) + 10); - }, - [data.length] - ); - - return ( - - - - - - ); -} - -export default BarChart; diff --git a/pwa/components/Diagrammes/Camembert.tsx b/pwa/components/Diagrammes/Camembert.tsx index d137e00..f6474ad 100644 --- a/pwa/components/Diagrammes/Camembert.tsx +++ b/pwa/components/Diagrammes/Camembert.tsx @@ -1,45 +1,90 @@ -// src/component/Rectangle/Rectangle.tsx -import React, { useEffect, RefObject } from 'react' -import { select } from 'd3-selection' -import * as d3 from 'd3' +import React, { useEffect, RefObject } from 'react'; +import * as d3 from 'd3'; + +type DataPoint = { label: string; value: number; }; + const Camembert = () => { - const ref: RefObject = React.createRef() - useEffect(() => { - draw() - }) - const draw = () => { - var svg = select("body") - .append("svg") - .append("g") - svg.append("g") - .attr("class", "slices"); - svg.append("g") - .attr("class", "labels"); - svg.append("g") - .attr("class", "lines"); - var width = 960, - height = 450, - radius = Math.min(width, height) / 2; - - var pie = d3.pie() - .sort(null) - .value(function(d) { - return d.value; - }); - var arc = d3.arc() - .outerRadius(radius * 0.8) - .innerRadius(radius * 0.4); - - var outerArc = d3.arc() - .innerRadius(radius * 0.9) - .outerRadius(radius * 0.9); - - - } + const ref: RefObject = React.createRef(); + const data: DataPoint[] = [ + { label: 'Auvergne-Rhône-Alpes', value: 4557 }, + { label: 'Bourgogne-Franche-Comté', value: 2556 }, + { label: 'Bretagne', value: 10555 }, + { label: 'Centre-Val de Loire', value: 7589 }, + { label: 'Corse', value: 8835 }, + { label: 'Grand Est', value: 1616 }, + { label: 'Hauts-de-France', value: 6111 }, + { label: 'Île-de-France', value: 6818 }, + { label: 'Normandie', value: 16168 }, + { label: 'Nouvelle-Aquitaine', value: 1318 }, + { label: 'Occitanie', value: 1368 }, + { label: 'Pays de la Loire', value: 5427 }, + { label: 'Provence-Alpes-Côte d\'Azur', value: 9632 }, + ]; + + useEffect(() => { + draw(); + }); + + const draw = () => { + const container = ref.current; + if (!container) return; + + const width = 900; + const height = 500; + const radius = Math.min(width, height) / 2; + + const color = d3.scaleOrdinal(d3.schemeCategory10); + + const pie = d3.pie() + .sort(null) + .value((d: DataPoint) => d.value); + + const arc = d3.arc>() + .outerRadius(radius - radius/2) + .innerRadius(radius); + + const labelArc = d3.arc>() + .outerRadius(radius+20) + .innerRadius(radius+20); + + const svg = d3.select(container) + .append('svg') + .attr('width', width) + .attr('height', height) + .append('g') + .attr('transform', `translate(${width / 2},${height / 2})`); + + const g = svg.selectAll('.arc') + .data(pie(data)) + .enter().append('g') + .attr('class', 'arc'); + + g.append('path') + .attr('d', arc) + .style('fill', (d: any) => color(d.data.label)); - return ( -
-
- ) -} -export default Camembert \ No newline at end of file + g.append('text') + .attr('transform', (d: any) => { + // Calcul de l'angle moyen + const midAngle = d.endAngle < Math.PI ? d.startAngle / 2 + d.endAngle / 2 : d.startAngle / 2 + d.endAngle / 2 + Math.PI; + // Translation du label pour l'aligner horizontalement avec le diagramme + return `translate(${labelArc.centroid(d)})`; + }) + .attr('dy','.35em') + .style('text-anchor', (d: any) => { + // Si l'angle moyen est supérieur à Math.PI, aligner le label à droite + if (d.endAngle > Math.PI) return 'end'; + // Sinon, aligner le label à gauche + return 'start'; + }) + .text((d: any) => d.data.label + " : " + d.data.value.valueOf()); + + + }; + return ( +
+
+ ); +}; + +export default Camembert; \ No newline at end of file diff --git a/pwa/pages/visuCamembert/index.tsx b/pwa/pages/visuCamembert/index.tsx index df83480..d474560 100644 --- a/pwa/pages/visuCamembert/index.tsx +++ b/pwa/pages/visuCamembert/index.tsx @@ -1,29 +1,13 @@ import React from "react"; -import BarChart from "../../components/Diagrammes/BarChart"; import Camembert from "../../components/Diagrammes/Camembert"; -const data = [ - { Country: "Russia", Value: 420000 }, - { Country: "France", Value: 190000 }, - { Country: "United-State", Value: 330000 }, - { Country: "Brazil", Value: 280000 }, - { Country: "Germany", Value: 200000 }, - { Country: "United-Kingdom", Value: 150000 }, - { Country: "China", Value: 350000 } - ]; - export default function Home() { return (
- - - - - - +
) } \ No newline at end of file -- GitLab