migrate to storybook for ui-test, demo

This commit is contained in:
takeyuichi
2025-03-07 15:47:13 +09:00
parent 1323a2ada6
commit 444e976b93
27 changed files with 1463 additions and 12241 deletions
-1
View File
@@ -1 +0,0 @@
SKIP_PREFLIGHT_CHECK=true
-25
View File
@@ -1,25 +0,0 @@
*~
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-46
View File
@@ -1,46 +0,0 @@
{
"name": "demo-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.2.4",
"@types/node": "^18.11.12",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"chart.js": "^4.0.1",
"chartjs-plugin-stacked100": "^1.2.1",
"react": "^18.2.0",
"react-chartjs-2": "^5.0.1",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.4",
"web-vitals": "^3.1.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

-43
View File
@@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

-25
View File
@@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
-3
View File
@@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
-28
View File
@@ -1,28 +0,0 @@
import { Chart, registerables } from "chart.js";
import { Bar } from "react-chartjs-2";
import ChartjsPluginStacked100 from "chartjs-plugin-stacked100";
Chart.register(...registerables, ChartjsPluginStacked100);
const ExampleChart = () => (
<div>
<Bar
data={{
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "better", data: [15, 10], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "good", data: [10, 8], backgroundColor: "rgba(100, 181, 246, 0.6)" },
],
}}
options={{
indexAxis: "y",
plugins: {
stacked100: { enable: true },
},
}}
/>
</div>
);
export default ExampleChart;
-13
View File
@@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
-11
View File
@@ -1,11 +0,0 @@
import React from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import ExampleChart from "./ExampleChart";
const root = createRoot(document.getElementById("root")!);
root.render(
<React.StrictMode>
<ExampleChart />
</React.StrictMode>,
);
-1
View File
@@ -1 +0,0 @@
/// <reference types="react-scripts" />
-26
View File
@@ -1,26 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
File diff suppressed because it is too large Load Diff
-13
View File
@@ -1,13 +0,0 @@
<html>
<head>
<meta charset="UTF-8" />
<style type="text/css">
.my-chart-container {
max-width: 600px;
max-height: 400px;
margin-bottom: 2em;
}
</style>
</head>
<body></body>
</html>
-585
View File
@@ -1,585 +0,0 @@
import { Chart, ChartConfiguration, registerables } from "chart.js";
import ChartPluginStacked100 from "../../src/index";
Chart.register(...registerables, ChartPluginStacked100);
const COLORS = {
red: "rgba(244, 143, 177, 0.6)",
yellow: "rgba(255, 235, 59, 0.6)",
blue: "rgba(100, 181, 246, 0.6)",
green: "rgba(51, 255, 74, 0.4)",
};
// config: ChartConfiguration<"bar" | "line", DefaultDataPoint<"bar" | "line">, unknown>
const createChart = (title: string, config: ChartConfiguration): void => {
const container = document.createElement("div");
container.className = "my-chart-container";
const header = document.createElement("h3");
header.innerText = title;
container.appendChild(header);
const canvas = document.createElement("canvas");
container.appendChild(canvas);
document.body.appendChild(container);
new Chart(canvas, config);
};
createChart("Case.1 basic pattern", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, 10], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.2 stack group pattern", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "L1", stack: "Stack 0", data: [3, 2], backgroundColor: COLORS.red },
{ label: "L2", stack: "Stack 0", data: [1, 1], backgroundColor: COLORS.yellow },
{ label: "L1", stack: "Stack 1", data: [0, 3], backgroundColor: COLORS.blue },
{ label: "L2", stack: "Stack 1", data: [1, 4], backgroundColor: COLORS.green },
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.3 stacked vertical bar", {
type: "bar",
data: {
labels: ["Hoge", "Fuga"],
datasets: [
{ label: "L1", data: [10, 9], backgroundColor: COLORS.red },
{ label: "L2", data: [20, 6], backgroundColor: COLORS.yellow },
{ label: "L3", data: [30, 3], backgroundColor: COLORS.blue },
],
},
options: {
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.4 stacked area", {
type: "line",
data: {
labels: ["2017-10-18", "2017-10-19", "2017-10-20"],
datasets: [
{ label: "L1", fill: true, data: [1, 2, 0], backgroundColor: COLORS.red },
{ label: "L2", fill: true, data: [1, 1, 3], backgroundColor: COLORS.yellow },
{ label: "L3", fill: true, data: [1, 1, 2], backgroundColor: COLORS.blue },
{ label: "L4", fill: true, data: [1, 3, 1], backgroundColor: COLORS.green },
],
},
options: {
scales: {
x: { stacked: true },
y: { stacked: true },
},
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.5 stacked area with objects as data points", {
type: "line",
data: {
labels: ["2017-10-18", "2017-10-19", "2017-10-20"],
datasets: [
{
label: "L1",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 2 },
{ x: "2017-10-20", y: 0 },
],
backgroundColor: COLORS.red,
},
{
label: "L2",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 1 },
{ x: "2017-10-20", y: 3 },
],
backgroundColor: COLORS.yellow,
},
{
label: "L3",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 1 },
{ x: "2017-10-20", y: 2 },
],
backgroundColor: COLORS.blue,
},
{
label: "L4",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 3 },
{ x: "2017-10-20", y: 1 },
],
backgroundColor: COLORS.green,
},
] as any,
},
options: {
scales: {
x: { stacked: true },
y: { stacked: true },
},
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.6 horizontal bar chart with objects as data points", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [
{ x: 5, y: "Foo" },
{ x: 25, y: "Bar" },
],
backgroundColor: COLORS.red,
},
{
label: "better",
data: [
{ x: 15, y: "Foo" },
{ x: 10, y: "Bar" },
],
backgroundColor: COLORS.yellow,
},
{
label: "good",
data: [
{ x: 10, y: "Foo" },
{ x: 8, y: "Bar" },
],
backgroundColor: COLORS.blue,
},
] as any,
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.7 Negative values", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [-5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, -10], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true, fixNegativeScale: true },
},
},
});
createChart("Case.8 Different data length", {
type: "bar",
data: {
labels: ["Foo", "Bar", "Baz", "Quuz"],
datasets: [
{ label: "bad", data: [-5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, -10, 6, 4], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8, 11], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true, fixNegativeScale: true },
},
},
});
createChart("Case.9 Objects as data points with undefined value", {
type: "bar",
data: {
labels: ["Foo", "Bar", "Baz", "Quuz"],
datasets: [
{
label: "bad",
data: [
{ x: 0, y: -5 },
{ x: 1, y: 25 },
{ x: 2, y: undefined },
{ x: 3, y: undefined },
],
backgroundColor: COLORS.red,
},
{
label: "better",
data: [
{ x: 0, y: 15 },
{ x: 1, y: -10 },
{ x: 2, y: 6 },
{ x: 3, y: 4 },
],
backgroundColor: COLORS.yellow,
},
{
label: "good",
data: [
{ x: 0, y: 10 },
{ x: 1, y: 8 },
{ x: 2, y: 11 },
{ x: 3, y: undefined },
],
backgroundColor: COLORS.blue,
},
],
},
options: {
indexAxis: "x",
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.10 Relative percentage to maxium value", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, 10], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true, individual: true },
},
},
});
createChart("Case.11 Relative percentage with stack", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "L1", stack: "Stack 0", data: [3, 2], backgroundColor: COLORS.red },
{ label: "L2", stack: "Stack 0", data: [1, 1], backgroundColor: COLORS.yellow },
{ label: "L1", stack: "Stack 1", data: [0, 3], backgroundColor: COLORS.blue },
{ label: "L2", stack: "Stack 1", data: [1, 4], backgroundColor: COLORS.green },
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true, individual: true } },
scales: {
x: { stacked: true },
y: { stacked: true },
},
},
});
createChart("Case.12 Multiple axis(combo horizontal bar/line)", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
xAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
xAxisID: "axis1",
},
{
type: "line",
label: "good",
data: [43, 24],
backgroundColor: COLORS.blue,
xAxisID: "axis2",
},
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
y: {
stacked: true,
},
axis1: {
position: "top",
},
axis2: {
position: "bottom",
},
},
},
});
createChart("Case.13 Multiple axis(combo vertical bar/line)", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
yAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
yAxisID: "axis1",
},
{
type: "line",
label: "good",
data: [43, 24],
backgroundColor: COLORS.blue,
yAxisID: "axis2",
},
],
},
options: {
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
x: {
stacked: true,
},
axis1: {
position: "left",
},
axis2: {
position: "right",
},
},
},
});
createChart("Case.14 Multiple axis with stack(combo horizontal bar/line)", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
stack: "stack 0",
xAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
stack: "stack 0",
xAxisID: "axis1",
},
{
label: "good",
data: [10, 20],
backgroundColor: COLORS.blue,
stack: "stack 1",
xAxisID: "axis1",
},
{
label: "very good",
data: [5, 24],
backgroundColor: COLORS.green,
stack: "stack 1",
xAxisID: "axis1",
},
{
type: "line",
label: "L1",
data: [43, 24],
xAxisID: "axis2",
},
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
axis1: {
position: "top",
},
axis2: {
position: "bottom",
},
},
},
});
createChart("Case.15 Multiple stacked axis with stack(combo vertical bar/line)", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
stack: "stack 0",
yAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
stack: "stack 0",
yAxisID: "axis1",
},
{
label: "good",
data: [10, 20],
backgroundColor: COLORS.blue,
stack: "stack 1",
yAxisID: "axis1",
},
{
label: "very good",
data: [5, 24],
backgroundColor: COLORS.green,
stack: "stack 1",
yAxisID: "axis1",
},
{
type: "line",
label: "L1",
data: [43, 24],
yAxisID: "axis2",
},
],
},
options: {
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
axis1: {
position: "left",
},
axis2: {
position: "right",
},
},
},
});
createChart("Case.16 horizontal bar chart with parsing option", {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [
{ foo: 5, bar: "Foo" },
{ foo: 25, bar: "Bar" },
],
backgroundColor: COLORS.red,
},
{
label: "better",
data: [
{ foo: 15, bar: "Foo" },
{ foo: 10, bar: "Bar" },
],
backgroundColor: COLORS.yellow,
},
{
label: "good",
data: [
{ foo2: 10, bar2: "Foo" },
{ foo2: 8, bar2: "Bar" },
],
parsing: { xAxisKey: "foo2", yAxisKey: "bar2" },
backgroundColor: COLORS.blue,
},
] as any,
},
options: {
indexAxis: "y",
parsing: { xAxisKey: "foo", yAxisKey: "bar" },
plugins: { stacked100: { enable: true } },
},
});
createChart("Case.17 Complex parsing options", {
type: "bar",
data: {
labels: ["Alice", "Bob"],
datasets: [
{
label: "bad",
data: [{ count: 1, user: "Alice" }],
backgroundColor: COLORS.red,
parsing: {
xAxisKey: "user",
yAxisKey: "count",
},
},
{
label: "better",
data: [{ count: 2, user: "Bob" }],
backgroundColor: COLORS.yellow,
parsing: {
xAxisKey: "user",
yAxisKey: "count",
},
},
{
label: "good",
data: [
{ count: 3, user: "Alice" },
{ count: 1, user: "Bob" },
],
backgroundColor: COLORS.blue,
parsing: {
xAxisKey: "user",
yAxisKey: "count",
},
},
],
},
options: {
plugins: {
stacked100: {
enable: true,
},
},
},
} as any);
+7 -2
View File
@@ -5,7 +5,7 @@
"main": "build/index.js",
"types": "build/index.d.ts",
"scripts": {
"start": "webpack serve --mode development --config ./webpack/demo.config.js",
"start": "storybook dev -p 6006",
"build:demo": "webpack --mode production --config ./webpack/demo.config.js",
"build:plugin": "webpack --mode production --config ./webpack/plugin.config.js",
"type": "yarn tsc src/*.ts --declaration --emitDeclarationOnly --outDir build --skipLibCheck",
@@ -14,7 +14,6 @@
"dev": "yarn eslint && yarn test",
"test": "jest --silent ./src/**",
"test:watch": "jest --watch ./src/**",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"repository": {
@@ -44,6 +43,9 @@
"@storybook/test": "^8.6.3",
"@types/chart.js": "^2.9.41",
"@types/jest": "^29.5.14",
"@types/mdx": "^2.0.13",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"@vitest/browser": "^3.0.7",
@@ -56,6 +58,9 @@
"jest": "^29.7.0",
"playwright": "^1.50.1",
"prettier": "^3.3.3",
"react": "^19.0.0",
"react-chartjs-2": "^5.3.0",
"react-dom": "^19.0.0",
"storybook": "^8.6.3",
"terser-webpack-plugin": "^5.3.10",
"ts-jest": "^29.2.5",
-53
View File
@@ -1,53 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test";
import { Button } from "./Button";
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: "Example/Button",
component: Button,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: "centered",
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
tags: ["autodocs"],
// More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: {
backgroundColor: { control: "color" },
},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
args: { onClick: fn() },
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
args: {
primary: true,
label: "Button",
},
};
export const Secondary: Story = {
args: {
label: "Button",
},
};
export const Large: Story = {
args: {
size: "large",
label: "Button",
},
};
export const Small: Story = {
args: {
size: "small",
label: "Button",
},
};
-37
View File
@@ -1,37 +0,0 @@
import React from 'react';
import './button.css';
export interface ButtonProps {
/** Is this the principal call to action on the page? */
primary?: boolean;
/** What background color to use */
backgroundColor?: string;
/** How large should the button be? */
size?: 'small' | 'medium' | 'large';
/** Button contents */
label: string;
/** Optional click handler */
onClick?: () => void;
}
/** Primary UI component for user interaction */
export const Button = ({
primary = false,
size = 'medium',
backgroundColor,
label,
...props
}: ButtonProps) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (
<button
type="button"
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
style={{ backgroundColor }}
{...props}
>
{label}
</button>
);
};
+18 -38
View File
@@ -1,42 +1,22 @@
import { Meta } from "@storybook/blocks";
import { Meta, Markdown } from "@storybook/blocks";
export const RightArrow = () => (
<svg
viewBox="0 0 14 14"
width="8px"
height="14px"
style={{
marginLeft: "4px",
display: "inline-block",
shapeRendering: "inherit",
verticalAlign: "middle",
fill: "currentColor",
"path fill": "currentColor",
}}
>
<path d="m11.1 7.35-5.5 5.5a.5.5 0 0 1-.7-.7L10.04 7 4.9 1.85a.5.5 0 1 1 .7-.7l5.5 5.5c.2.2.2.5 0 .7Z" />
</svg>
);
<Meta title="Options" />
<Meta title="Configure your project" />
## Options
<div className="sb-container">
<div className='sb-section-title'>
# Configure your project
Because Storybook works separately from your app, you'll need to configure it for your specific stack and setup. Below, explore guides for configuring Storybook with popular frameworks and tools. If you get stuck, learn how you can ask for help from our community.
</div>
<div className="sb-section">
<div className="sb-section-item">
</div>
</div>
</div>
<style>
<Markdown>
{`
.sb-container {
margin-bottom: 48px;
}
`}
</style>
| Name | Type | Default |
| :------------------ | :---------------------------- | :------ |
| enable | boolean | false |
| replaceTooltipLabel | boolean | true |
| fixNegativeScale | boolean | true |
| individual | boolean | false |
| round | "off" or "down" or "up" | "off" |
| precision | number | 1 |
| axisId | string | - |
For more details, please see here: https://github.com/y-takey/chartjs-plugin-stacked100#options
`}
</Markdown>
+641
View File
@@ -0,0 +1,641 @@
import type { Meta, StoryObj } from "@storybook/react";
import { StackedBarChart } from "./StackedBarChart";
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta: Meta = {
title: "Plain",
component: StackedBarChart,
parameters: {
// Optional parameter to center the component in the Canvas.
// More info: https://storybook.js.org/docs/configure/story-layout
layout: "centered",
},
// This component will have an automatically generated Autodocs entry:
// https://storybook.js.org/docs/writing-docs/autodocs
tags: ["autodocs"],
// More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: {},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked:
// https://storybook.js.org/docs/essentials/actions#action-args
} satisfies Meta<typeof StackedBarChart>;
export default meta;
type Story = StoryObj<typeof meta>;
const COLORS = {
red: "rgba(244, 143, 177, 0.6)",
yellow: "rgba(255, 235, 59, 0.6)",
blue: "rgba(100, 181, 246, 0.6)",
green: "rgba(51, 255, 74, 0.4)",
};
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Story1: Story = {
name: "1. basic pattern",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, 10], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true } },
},
},
};
export const Story2: Story = {
name: "2. stack group pattern",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "L1", stack: "Stack 0", data: [3, 2], backgroundColor: COLORS.red },
{ label: "L2", stack: "Stack 0", data: [1, 1], backgroundColor: COLORS.yellow },
{ label: "L1", stack: "Stack 1", data: [0, 3], backgroundColor: COLORS.blue },
{ label: "L2", stack: "Stack 1", data: [1, 4], backgroundColor: COLORS.green },
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true } },
},
},
};
export const Story3: Story = {
name: "3. stacked vertical bar",
args: {
type: "bar",
data: {
labels: ["Hoge", "Fuga"],
datasets: [
{ label: "L1", data: [10, 9], backgroundColor: COLORS.red },
{ label: "L2", data: [20, 6], backgroundColor: COLORS.yellow },
{ label: "L3", data: [30, 3], backgroundColor: COLORS.blue },
],
},
options: {
plugins: { stacked100: { enable: true } },
},
},
};
export const Story4: Story = {
name: "4. stacked area",
args: {
type: "line",
data: {
labels: ["2017-10-18", "2017-10-19", "2017-10-20"],
datasets: [
{ label: "L1", fill: true, data: [1, 2, 0], backgroundColor: COLORS.red },
{ label: "L2", fill: true, data: [1, 1, 3], backgroundColor: COLORS.yellow },
{ label: "L3", fill: true, data: [1, 1, 2], backgroundColor: COLORS.blue },
{ label: "L4", fill: true, data: [1, 3, 1], backgroundColor: COLORS.green },
],
},
options: {
scales: {
x: { stacked: true },
y: { stacked: true },
},
plugins: { stacked100: { enable: true } },
},
},
};
export const Story5: Story = {
name: "5. stacked area with objects as data points",
args: {
type: "line",
data: {
labels: ["2017-10-18", "2017-10-19", "2017-10-20"],
datasets: [
{
label: "L1",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 2 },
{ x: "2017-10-20", y: 0 },
],
backgroundColor: COLORS.red,
},
{
label: "L2",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 1 },
{ x: "2017-10-20", y: 3 },
],
backgroundColor: COLORS.yellow,
},
{
label: "L3",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 1 },
{ x: "2017-10-20", y: 2 },
],
backgroundColor: COLORS.blue,
},
{
label: "L4",
fill: true,
data: [
{ x: "2017-10-18", y: 1 },
{ x: "2017-10-19", y: 3 },
{ x: "2017-10-20", y: 1 },
],
backgroundColor: COLORS.green,
},
],
},
options: {
scales: {
x: { stacked: true },
y: { stacked: true },
},
plugins: { stacked100: { enable: true } },
},
},
};
export const Story6: Story = {
name: "6. horizontal bar chart with objects as data points",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [
{ x: 5, y: "Foo" },
{ x: 25, y: "Bar" },
],
backgroundColor: COLORS.red,
},
{
label: "better",
data: [
{ x: 15, y: "Foo" },
{ x: 10, y: "Bar" },
],
backgroundColor: COLORS.yellow,
},
{
label: "good",
data: [
{ x: 10, y: "Foo" },
{ x: 8, y: "Bar" },
],
backgroundColor: COLORS.blue,
},
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true } },
},
},
};
export const Story7: Story = {
name: "7. Negative values",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [-5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, -10], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true, fixNegativeScale: true },
},
},
},
};
export const Story8: Story = {
name: "8. Different data length",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar", "Baz", "Quuz"],
datasets: [
{ label: "bad", data: [-5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, -10, 6, 4], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8, 11], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true, fixNegativeScale: true },
},
},
},
};
export const Story9: Story = {
name: "9. Objects as data points with undefined value",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar", "Baz", "Quuz"],
datasets: [
{
label: "bad",
data: [
{ x: 0, y: -5 },
{ x: 1, y: 25 },
{ x: 2, y: undefined },
{ x: 3, y: undefined },
],
backgroundColor: COLORS.red,
},
{
label: "better",
data: [
{ x: 0, y: 15 },
{ x: 1, y: -10 },
{ x: 2, y: 6 },
{ x: 3, y: 4 },
],
backgroundColor: COLORS.yellow,
},
{
label: "good",
data: [
{ x: 0, y: 10 },
{ x: 1, y: 8 },
{ x: 2, y: 11 },
{ x: 3, y: undefined },
],
backgroundColor: COLORS.blue,
},
],
},
options: {
indexAxis: "x",
plugins: { stacked100: { enable: true } },
},
},
};
export const Story10: Story = {
name: "10. Relative percentage to maxium value",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: COLORS.red },
{ label: "better", data: [15, 10], backgroundColor: COLORS.yellow },
{ label: "good", data: [10, 8], backgroundColor: COLORS.blue },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true, individual: true },
},
},
},
};
export const Story11: Story = {
name: "11. Relative percentage with stack",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "L1", stack: "Stack 0", data: [3, 2], backgroundColor: COLORS.red },
{ label: "L2", stack: "Stack 0", data: [1, 1], backgroundColor: COLORS.yellow },
{ label: "L1", stack: "Stack 1", data: [0, 3], backgroundColor: COLORS.blue },
{ label: "L2", stack: "Stack 1", data: [1, 4], backgroundColor: COLORS.green },
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true, individual: true } },
scales: {
x: { stacked: true },
y: { stacked: true },
},
},
},
};
export const Story12: Story = {
name: "12. Multiple axis(combo horizontal bar/line)",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
xAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
xAxisID: "axis1",
},
{
type: "line",
label: "good",
data: [43, 24],
backgroundColor: COLORS.blue,
xAxisID: "axis2",
},
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
y: {
stacked: true,
},
axis1: {
position: "top",
},
axis2: {
position: "bottom",
},
},
},
},
};
export const Story13: Story = {
name: "13. Multiple axis(combo vertical bar/line)",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
yAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
yAxisID: "axis1",
},
{
type: "line",
label: "good",
data: [43, 24],
backgroundColor: COLORS.blue,
yAxisID: "axis2",
},
],
},
options: {
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
x: {
stacked: true,
},
axis1: {
position: "left",
},
axis2: {
position: "right",
},
},
},
},
};
export const Story14: Story = {
name: "14. Multiple axis with stack(combo horizontal bar/line)",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
stack: "stack 0",
xAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
stack: "stack 0",
xAxisID: "axis1",
},
{
label: "good",
data: [10, 20],
backgroundColor: COLORS.blue,
stack: "stack 1",
xAxisID: "axis1",
},
{
label: "very good",
data: [5, 24],
backgroundColor: COLORS.green,
stack: "stack 1",
xAxisID: "axis1",
},
{
type: "line",
label: "L1",
data: [43, 24],
xAxisID: "axis2",
},
],
},
options: {
indexAxis: "y",
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
axis1: {
position: "top",
},
axis2: {
position: "bottom",
},
},
},
},
};
export const Story15: Story = {
name: "15. Multiple stacked axis with stack(combo vertical bar/line)",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [5, 25],
backgroundColor: COLORS.red,
stack: "stack 0",
yAxisID: "axis1",
},
{
label: "better",
data: [15, 10],
backgroundColor: COLORS.yellow,
stack: "stack 0",
yAxisID: "axis1",
},
{
label: "good",
data: [10, 20],
backgroundColor: COLORS.blue,
stack: "stack 1",
yAxisID: "axis1",
},
{
label: "very good",
data: [5, 24],
backgroundColor: COLORS.green,
stack: "stack 1",
yAxisID: "axis1",
},
{
type: "line",
label: "L1",
data: [43, 24],
yAxisID: "axis2",
},
],
},
options: {
plugins: { stacked100: { enable: true, axisId: "axis1" } },
scales: {
axis1: {
position: "left",
},
axis2: {
position: "right",
},
},
},
},
};
export const Story16: Story = {
name: "16. horizontal bar chart with parsing option",
args: {
type: "bar",
data: {
labels: ["Foo", "Bar"],
datasets: [
{
label: "bad",
data: [
{ foo: 5, bar: "Foo" },
{ foo: 25, bar: "Bar" },
],
backgroundColor: COLORS.red,
},
{
label: "better",
data: [
{ foo: 15, bar: "Foo" },
{ foo: 10, bar: "Bar" },
],
backgroundColor: COLORS.yellow,
},
{
label: "good",
data: [
{ foo2: 10, bar2: "Foo" },
{ foo2: 8, bar2: "Bar" },
],
parsing: { xAxisKey: "foo2", yAxisKey: "bar2" },
backgroundColor: COLORS.blue,
},
],
},
options: {
indexAxis: "y",
parsing: { xAxisKey: "foo", yAxisKey: "bar" },
plugins: { stacked100: { enable: true } },
},
},
};
export const Story17: Story = {
name: "17. Complex parsing options",
args: {
type: "bar",
data: {
labels: ["Alice", "Bob"],
datasets: [
{
label: "bad",
data: [{ count: 1, user: "Alice" }],
backgroundColor: COLORS.red,
parsing: {
xAxisKey: "user",
yAxisKey: "count",
},
},
{
label: "better",
data: [{ count: 2, user: "Bob" }],
backgroundColor: COLORS.yellow,
parsing: {
xAxisKey: "user",
yAxisKey: "count",
},
},
{
label: "good",
data: [
{ count: 3, user: "Alice" },
{ count: 1, user: "Bob" },
],
backgroundColor: COLORS.blue,
parsing: {
xAxisKey: "user",
yAxisKey: "count",
},
},
],
},
options: {
plugins: {
stacked100: {
enable: true,
},
},
},
},
};
+51
View File
@@ -0,0 +1,51 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Chart, registerables } from "chart.js";
import ChartjsPluginStacked100 from "../index";
import { Bar } from "react-chartjs-2";
Chart.register(...registerables, ChartjsPluginStacked100);
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta: Meta = {
title: "React Chartjs 2",
component: Bar,
parameters: {
// Optional parameter to center the component in the Canvas.
// More info: https://storybook.js.org/docs/configure/story-layout
layout: "centered",
},
// This component will have an automatically generated Autodocs entry:
// https://storybook.js.org/docs/writing-docs/autodocs
tags: ["autodocs"],
// More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: {},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked:
// https://storybook.js.org/docs/essentials/actions#action-args
} satisfies Meta<typeof Bar>;
export default meta;
type Story = StoryObj<typeof meta>;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Story1: Story = {
name: "Bar",
args: {
data: {
labels: ["Foo", "Bar"],
datasets: [
{ label: "bad", data: [5, 25], backgroundColor: "rgba(244, 143, 177, 0.6)" },
{ label: "better", data: [15, 10], backgroundColor: "rgba(255, 235, 59, 0.6)" },
{ label: "good", data: [10, 8], backgroundColor: "rgba(100, 181, 246, 0.6)" },
],
},
options: {
indexAxis: "y",
plugins: {
stacked100: { enable: true },
},
},
},
};
+17
View File
@@ -0,0 +1,17 @@
import React from "react";
import { Chart, registerables, ChartConfiguration } from "chart.js";
import ChartjsPluginStacked100 from "../index";
Chart.register(...registerables, ChartjsPluginStacked100);
export const StackedBarChart: React.FC<ChartConfiguration> = props => {
const canvasRef = React.useRef<HTMLCanvasElement>(null);
React.useEffect(() => {
// deep copy
const clonedProps = JSON.parse(JSON.stringify(props));
new Chart(canvasRef.current, clonedProps);
}, [props]);
return <canvas ref={canvasRef} width={600} height={400} />;
};
-30
View File
@@ -1,30 +0,0 @@
.storybook-button {
display: inline-block;
cursor: pointer;
border: 0;
border-radius: 3em;
font-weight: 700;
line-height: 1;
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.storybook-button--primary {
background-color: #555ab9;
color: white;
}
.storybook-button--secondary {
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
background-color: transparent;
color: #333;
}
.storybook-button--small {
padding: 10px 16px;
font-size: 12px;
}
.storybook-button--medium {
padding: 11px 20px;
font-size: 14px;
}
.storybook-button--large {
padding: 12px 24px;
font-size: 16px;
}
+3 -1
View File
@@ -1,11 +1,13 @@
{
"compilerOptions": {
"jsx": "react",
"noImplicitAny": true,
"outDir": "build",
"module": "esnext",
"target": "es5",
"allowJs": true,
"sourceMap": true,
"skipLibCheck": true,
"declaration": true,
"emitDeclarationOnly": true,
"ignoreDeprecations": "5.0",
@@ -13,6 +15,6 @@
"moduleResolution": "node",
"esModuleInterop": true
},
"include": ["src", "examples/demo"],
"include": ["src"],
"exclude": ["node_modules"]
}
+726 -689
View File
File diff suppressed because it is too large Load Diff