From c2c565276906acc4691b578510397c557fceec4b Mon Sep 17 00:00:00 2001 From: Takeshi Kimata <117462761+kimatata@users.noreply.github.com> Date: Sat, 27 Apr 2024 14:08:05 +0900 Subject: [PATCH] Create progress stacked bar chart --- .../[projectId]/runs/[runId]/RunEditor.tsx | 4 + .../runs/[runId]/RunProgressChart.tsx | 79 ++++++++++++ .../runs/[runId]/TestCaseSelector.tsx | 2 +- frontend/package-lock.json | 116 ++++++++++++++++++ frontend/package.json | 2 + 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 frontend/app/projects/[projectId]/runs/[runId]/RunProgressChart.tsx diff --git a/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx b/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx index d40f92e..83e9192 100644 --- a/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx +++ b/frontend/app/projects/[projectId]/runs/[runId]/RunEditor.tsx @@ -26,6 +26,7 @@ import { CopyPlus, CopyMinus, } from "lucide-react"; +import RunProgressChart from "./RunProgressChart"; import TestCaseSelector from "./TestCaseSelector"; import { testRunStatus } from "@/config/selection"; import { RunType, RunCaseType, RunCaseInfoType } from "@/types/run"; @@ -279,6 +280,9 @@ export default function RunEditor({ projectId, runId }: Props) { + + +
Select test cases
diff --git a/frontend/app/projects/[projectId]/runs/[runId]/RunProgressChart.tsx b/frontend/app/projects/[projectId]/runs/[runId]/RunProgressChart.tsx new file mode 100644 index 0000000..04f8f6c --- /dev/null +++ b/frontend/app/projects/[projectId]/runs/[runId]/RunProgressChart.tsx @@ -0,0 +1,79 @@ +import React from "react"; +import { useState } from "react"; +import Chart from "react-apexcharts"; + +// type Props = { +// projectId: string; +// }; + +const testCases = [ + { name: "Passed", value: 12, color: "#17c964" }, + { name: "Failed", value: 3, color: "#f31260" }, + { name: "Skipped", value: 14, color: "#71717a" }, + { name: "Untested", value: 32, color: "#d4d4d8" }, +]; + +// export default function RunProgressChart({ projectId }: Props) { +export default function RunProgressChart() { + const [chartData, setChartData] = useState({ + series: testCases.map((entry) => { + return { + name: entry.name, + data: [entry.value], + }; + }), + options: { + chart: { + type: "bar", + height: 100, + stacked: true, + stackType: "100%", + toolbar: { + show: false, + }, + }, + plotOptions: { + bar: { + horizontal: true, + }, + }, + colors: testCases.map((entry) => { + return entry.color; + }), + legend: { + show: false, + }, + yaxis: { + show: false, + }, + xaxis: { + labels: { + show: false, + }, + axisTicks: { + show: false, + }, + }, + grid: { + show: false, + padding: { + top: -20, + bottom: -20, + left: -20, + }, + }, + }, + }); + return ( +
+

Progress

+ +
+ ); +} diff --git a/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx b/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx index 209495b..d8ee889 100644 --- a/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx +++ b/frontend/app/projects/[projectId]/runs/[runId]/TestCaseSelector.tsx @@ -78,7 +78,7 @@ export default function TestCaseSelector({ } else if (uid === "failed") { return ; } else if (uid === "skipped") { - return ; + return ; } }; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1a1bbf4..3da012c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "@types/node": "20.5.7", "@types/react": "18.2.21", "@types/react-dom": "18.2.7", + "apexcharts": "^3.49.0", "autoprefixer": "10.4.16", "clsx": "^2.0.0", "dayjs": "^1.11.10", @@ -26,6 +27,7 @@ "next-themes": "^0.2.1", "postcss": "8.4.31", "react": "18.2.0", + "react-apexcharts": "^1.4.1", "react-dom": "18.2.0", "tailwind-variants": "^0.1.18", "tailwindcss": "3.3.5", @@ -2861,6 +2863,11 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" + }, "node_modules/acorn": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", @@ -2934,6 +2941,20 @@ "node": ">= 8" } }, + "node_modules/apexcharts": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.49.0.tgz", + "integrity": "sha512-2T9HnbQFLCuYRPndQLmh+bEQFoz0meUbvASaGgiSKDuYhWcLBodJtIpKql2aOtMx4B/sHrWW0dm90HsW4+h2PQ==", + "dependencies": { + "@yr/monotone-cubic-spline": "^1.0.3", + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -5696,6 +5717,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-apexcharts": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz", + "integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "apexcharts": "^3.41.0", + "react": ">=0.13" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -6258,6 +6291,89 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/tailwind-merge": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index a28fb86..bd631c9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "@types/node": "20.5.7", "@types/react": "18.2.21", "@types/react-dom": "18.2.7", + "apexcharts": "^3.49.0", "autoprefixer": "10.4.16", "clsx": "^2.0.0", "dayjs": "^1.11.10", @@ -27,6 +28,7 @@ "next-themes": "^0.2.1", "postcss": "8.4.31", "react": "18.2.0", + "react-apexcharts": "^1.4.1", "react-dom": "18.2.0", "tailwind-variants": "^0.1.18", "tailwindcss": "3.3.5",