lucentia-ui 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Chart/BarChart/Bar.d.ts +11 -0
- package/dist/components/Chart/BarChart/Bar.js +4 -0
- package/dist/components/Chart/BarChart/Bar.module.css +0 -0
- package/dist/components/Chart/BarChart/BarChart.d.ts +2 -0
- package/dist/components/Chart/BarChart/BarChart.js +23 -0
- package/dist/components/Chart/BarChart/BarSeries.d.ts +10 -0
- package/dist/components/Chart/BarChart/BarSeries.js +27 -0
- package/dist/components/Chart/BarChart/types.d.ts +10 -0
- package/dist/components/Chart/BarChart/types.js +1 -0
- package/dist/components/Chart/BarChart/utils.d.ts +3 -0
- package/dist/components/Chart/BarChart/utils.js +26 -0
- package/dist/components/Chart/ChartAxis.d.ts +6 -0
- package/dist/components/Chart/ChartAxis.js +6 -0
- package/dist/components/Chart/ChartContainer.d.ts +11 -0
- package/dist/components/Chart/ChartContainer.js +22 -0
- package/dist/components/Chart/ChartContainer.module.css +51 -0
- package/dist/components/Chart/ChartContext.d.ts +7 -0
- package/dist/components/Chart/ChartContext.js +9 -0
- package/dist/components/Chart/ChartGrid.d.ts +6 -0
- package/dist/components/Chart/ChartGrid.js +19 -0
- package/dist/components/Chart/ChartLegend.d.ts +9 -0
- package/dist/components/Chart/ChartLegend.js +19 -0
- package/dist/components/Chart/ChartTooltip.d.ts +8 -0
- package/dist/components/Chart/ChartTooltip.js +12 -0
- package/dist/components/Chart/ChartXAxis.d.ts +5 -0
- package/dist/components/Chart/ChartXAxis.js +16 -0
- package/dist/components/Chart/ChartYAxis.d.ts +6 -0
- package/dist/components/Chart/ChartYAxis.js +11 -0
- package/dist/components/Chart/LineChart/LineChart.d.ts +2 -0
- package/dist/components/Chart/LineChart/LineChart.js +27 -0
- package/dist/components/Chart/LineChart/LinePath.d.ts +9 -0
- package/dist/components/Chart/LineChart/LinePath.js +7 -0
- package/dist/components/Chart/LineChart/LinePoint.d.ts +9 -0
- package/dist/components/Chart/LineChart/LinePoint.js +4 -0
- package/dist/components/Chart/LineChart/LineSeries.d.ts +9 -0
- package/dist/components/Chart/LineChart/LineSeries.js +24 -0
- package/dist/components/Chart/LineChart/types.d.ts +9 -0
- package/dist/components/Chart/LineChart/types.js +1 -0
- package/dist/components/Chart/PieChart/PieChart.d.ts +2 -0
- package/dist/components/Chart/PieChart/PieChart.js +9 -0
- package/dist/components/Chart/PieChart/PieSeries.d.ts +2 -0
- package/dist/components/Chart/PieChart/PieSeries.js +40 -0
- package/dist/components/Chart/PieChart/PieSlice.d.ts +12 -0
- package/dist/components/Chart/PieChart/PieSlice.js +8 -0
- package/dist/components/Chart/PieChart/types.d.ts +18 -0
- package/dist/components/Chart/PieChart/types.js +1 -0
- package/dist/components/Chart/PieChart/utils.d.ts +5 -0
- package/dist/components/Chart/PieChart/utils.js +27 -0
- package/dist/components/Chart/RadarChart/RadarAxis.d.ts +4 -0
- package/dist/components/Chart/RadarChart/RadarAxis.js +16 -0
- package/dist/components/Chart/RadarChart/RadarChart.d.ts +2 -0
- package/dist/components/Chart/RadarChart/RadarChart.js +11 -0
- package/dist/components/Chart/RadarChart/RadarGrid.d.ts +5 -0
- package/dist/components/Chart/RadarChart/RadarGrid.js +20 -0
- package/dist/components/Chart/RadarChart/RadarSeries.d.ts +2 -0
- package/dist/components/Chart/RadarChart/RadarSeries.js +33 -0
- package/dist/components/Chart/RadarChart/types.d.ts +22 -0
- package/dist/components/Chart/RadarChart/types.js +1 -0
- package/dist/components/Chart/RadarChart/utils.d.ts +5 -0
- package/dist/components/Chart/RadarChart/utils.js +16 -0
- package/dist/components/Chart/index.d.ts +15 -0
- package/dist/components/Chart/index.js +18 -0
- package/dist/components/Chart/utils/getNiceTicks.d.ts +1 -0
- package/dist/components/Chart/utils/getNiceTicks.js +20 -0
- package/dist/components/Feedback/Modal/Modal.module.css +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/styles/tokens.css +28 -4
- package/dist/utils/date/generateCalendar.d.ts +5 -0
- package/dist/utils/date/generateCalendar.js +36 -0
- package/package.json +5 -3
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
fill: string;
|
|
7
|
+
onMouseEnter?: () => void;
|
|
8
|
+
onMouseLeave?: () => void;
|
|
9
|
+
};
|
|
10
|
+
export declare const Bar: ({ x, y, width, height, fill, onMouseEnter, onMouseLeave, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const Bar = ({ x, y, width, height, fill, onMouseEnter, onMouseLeave, }) => {
|
|
3
|
+
return (_jsx("rect", { x: x, y: y, width: width, height: height, fill: fill, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: "lucentia-bar", rx: 2 }));
|
|
4
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { ChartContainer } from "../ChartContainer";
|
|
4
|
+
import { ChartGrid } from "../ChartGrid";
|
|
5
|
+
import { ChartTooltip } from "../ChartTooltip";
|
|
6
|
+
import { ChartXAxis } from "../ChartXAxis";
|
|
7
|
+
import { ChartYAxis } from "../ChartYAxis";
|
|
8
|
+
import { getNiceTicks } from "../utils/getNiceTicks";
|
|
9
|
+
import { BarSeries } from "./BarSeries";
|
|
10
|
+
import { getMaxValue } from "./utils";
|
|
11
|
+
export const BarChart = ({ data, keys, height = 300, barGap = 16 }) => {
|
|
12
|
+
const seriesKeys = keys !== null && keys !== void 0 ? keys : Object.keys(data[0]).filter((k) => k !== "label");
|
|
13
|
+
const max = getMaxValue(data, seriesKeys);
|
|
14
|
+
const labels = data.map((d) => d.label);
|
|
15
|
+
const ticks = getNiceTicks(max);
|
|
16
|
+
const [cursor, setCursor] = useState({
|
|
17
|
+
x: 0,
|
|
18
|
+
y: 0,
|
|
19
|
+
});
|
|
20
|
+
const [tooltip, setTooltip] = useState(null);
|
|
21
|
+
// BarChart.tsx の return 部分を修正
|
|
22
|
+
return (_jsx("div", { style: { width: "100%" }, children: _jsxs(ChartContainer, { height: height, onPointerMove: (x, y) => setCursor({ x, y }), children: [_jsx(ChartGrid, {}), _jsx(ChartXAxis, { labels: labels }), _jsx(ChartYAxis, { ticks: ticks, max: ticks[ticks.length - 1] }), _jsx(BarSeries, { data: data, keys: seriesKeys, max: max, gap: barGap, onHover: (label, key, value) => setTooltip({ label, key, value }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: cursor.x + 8, y: cursor.y + 8, children: [_jsx("div", { children: tooltip.label }), _jsxs("strong", { children: [tooltip.key, ": ", tooltip.value] })] }))] }) }));
|
|
23
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
data: any[];
|
|
3
|
+
keys: string[];
|
|
4
|
+
max: number;
|
|
5
|
+
gap: number;
|
|
6
|
+
onHover?: (label: string, key: string, value: number) => void;
|
|
7
|
+
onLeave?: () => void;
|
|
8
|
+
};
|
|
9
|
+
export declare const BarSeries: ({ data, keys, max, gap, onHover, onLeave }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "../ChartContext";
|
|
3
|
+
import { Bar } from "./Bar";
|
|
4
|
+
import { scaleValue } from "./utils";
|
|
5
|
+
export const BarSeries = ({ data, keys, max, gap, onHover, onLeave }) => {
|
|
6
|
+
const { width, height, padding } = useChart();
|
|
7
|
+
const innerWidth = width - padding * 2;
|
|
8
|
+
const innerHeight = height - padding * 2;
|
|
9
|
+
// 1グループあたりの幅(端数を切り捨てることで、右端のはみ出しを防止)
|
|
10
|
+
const groupWidth = Math.floor(innerWidth / data.length);
|
|
11
|
+
const contentWidth = groupWidth - gap;
|
|
12
|
+
const barUnitWidth = contentWidth / keys.length;
|
|
13
|
+
const actualBarWidth = barUnitWidth * 0.8;
|
|
14
|
+
return (_jsx("g", { children: data.map((d, i) => {
|
|
15
|
+
// padding + (i * groupWidth) で確実に計算
|
|
16
|
+
const groupX = padding + i * groupWidth;
|
|
17
|
+
return keys.map((key, j) => {
|
|
18
|
+
var _a;
|
|
19
|
+
const value = Number((_a = d[key]) !== null && _a !== void 0 ? _a : 0);
|
|
20
|
+
const barHeight = scaleValue(value, max, innerHeight);
|
|
21
|
+
// X座標:グループ開始位置 + 棒のオフセット
|
|
22
|
+
const x = groupX + (gap / 2) + (j * barUnitWidth) + (barUnitWidth - actualBarWidth) / 2;
|
|
23
|
+
const y = height - padding - barHeight;
|
|
24
|
+
return (_jsx(Bar, { x: x, y: y, width: actualBarWidth, height: barHeight, onMouseEnter: () => onHover === null || onHover === void 0 ? void 0 : onHover(d.label, key, value), onMouseLeave: onLeave, fill: `var(--chart-color-${j + 1})` }, `${i}-${key}`));
|
|
25
|
+
});
|
|
26
|
+
}) }));
|
|
27
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const getMaxValue = (data, keys) => {
|
|
2
|
+
let max = 0;
|
|
3
|
+
data.forEach((d) => {
|
|
4
|
+
keys.forEach((k) => {
|
|
5
|
+
var _a;
|
|
6
|
+
const v = Number((_a = d[k]) !== null && _a !== void 0 ? _a : 0);
|
|
7
|
+
if (v > max)
|
|
8
|
+
max = v;
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
return max;
|
|
12
|
+
};
|
|
13
|
+
export const scaleValue = (value, max, height) => {
|
|
14
|
+
if (max === 0)
|
|
15
|
+
return 0;
|
|
16
|
+
return (value / max) * height;
|
|
17
|
+
};
|
|
18
|
+
export const getStackMax = (data, keys) => {
|
|
19
|
+
let max = 0;
|
|
20
|
+
data.forEach((d) => {
|
|
21
|
+
const sum = keys.reduce((acc, k) => { var _a; return acc + Number((_a = d[k]) !== null && _a !== void 0 ? _a : 0); }, 0);
|
|
22
|
+
if (sum > max)
|
|
23
|
+
max = sum;
|
|
24
|
+
});
|
|
25
|
+
return max;
|
|
26
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "./ChartContext";
|
|
3
|
+
export const ChartAxis = ({ xLabel, yLabel }) => {
|
|
4
|
+
const { width, height, padding } = useChart();
|
|
5
|
+
return (_jsxs("g", { stroke: "var(--chart-axis)", children: [_jsx("line", { x1: padding, x2: width - padding, y1: height - padding, y2: height - padding }), _jsx("line", { x1: padding, x2: padding, y1: padding, y2: height - padding }), xLabel && (_jsx("text", { x: width / 2, y: height - 6, textAnchor: "middle", fill: "var(--chart-text)", fontSize: "12", children: xLabel })), yLabel && (_jsx("text", { transform: `translate(12 ${height / 2}) rotate(-90)`, textAnchor: "middle", fill: "var(--chart-text)", fontSize: "12", children: yLabel }))] }));
|
|
6
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
type Props = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
width?: number;
|
|
5
|
+
height?: number;
|
|
6
|
+
padding?: number;
|
|
7
|
+
className?: string;
|
|
8
|
+
onPointerMove?: (x: number, y: number) => void;
|
|
9
|
+
};
|
|
10
|
+
export declare const ChartContainer: ({ children, width, height, padding, className, onPointerMove, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import { ChartContext } from "./ChartContext";
|
|
4
|
+
import styles from "./ChartContainer.module.css";
|
|
5
|
+
export const ChartContainer = ({ children, width = 600, height = 300, padding = 32, className, onPointerMove, }) => {
|
|
6
|
+
const svgRef = useRef(null);
|
|
7
|
+
const handleMove = (e) => {
|
|
8
|
+
if (!svgRef.current || !onPointerMove)
|
|
9
|
+
return;
|
|
10
|
+
const rect = svgRef.current.getBoundingClientRect();
|
|
11
|
+
const scaleX = width / rect.width;
|
|
12
|
+
const scaleY = height / rect.height;
|
|
13
|
+
const x = (e.clientX - rect.left) * scaleX;
|
|
14
|
+
const y = (e.clientY - rect.top) * scaleY;
|
|
15
|
+
onPointerMove(x, y);
|
|
16
|
+
};
|
|
17
|
+
return (_jsx(ChartContext.Provider, { value: {
|
|
18
|
+
width,
|
|
19
|
+
height,
|
|
20
|
+
padding,
|
|
21
|
+
}, children: _jsx("svg", { ref: svgRef, viewBox: `0 0 ${width} ${height}`, width: "100%", height: "100%", className: [styles.container, className].filter(Boolean).join(" "), onPointerMove: handleMove, children: children }) }));
|
|
22
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.container {
|
|
2
|
+
background-color: var(--color-surface);
|
|
3
|
+
padding: var(--space-lg);
|
|
4
|
+
border-radius: var(--radius-md);
|
|
5
|
+
overflow: visible;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
:root {
|
|
9
|
+
--chart-color-1: #99cccc; /* 明るすぎないソフトブルー */
|
|
10
|
+
--chart-color-2: #66b2b2;
|
|
11
|
+
--chart-color-3: #4da6a6;
|
|
12
|
+
--chart-color-4: #339999;
|
|
13
|
+
--chart-color-5: #008b8b;
|
|
14
|
+
--chart-color-6: #007a7a; /* base: 以前より落ち着いたトーン */
|
|
15
|
+
--chart-color-7: #006666;
|
|
16
|
+
--chart-color-8: #005252;
|
|
17
|
+
--chart-color-9: #004545;
|
|
18
|
+
--chart-color-10: #003333; /* 締まりのある深い色 */
|
|
19
|
+
|
|
20
|
+
--chart-grid: var(--color-border);
|
|
21
|
+
--chart-axis: var(--color-border);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
html[data-theme="dark"] {
|
|
26
|
+
--chart-color-1: #80d5d4; /* Base: ここをスタート地点にして視認性を確保 */
|
|
27
|
+
--chart-color-2: #6bc2c1;
|
|
28
|
+
--chart-color-3: #57afae; /* 1,2,3の間で明確な色の沈み込みを作成 */
|
|
29
|
+
--chart-color-4: #439d9c;
|
|
30
|
+
--chart-color-5: #308b8b;
|
|
31
|
+
--chart-color-6: #1c797a;
|
|
32
|
+
--chart-color-7: #09686a;
|
|
33
|
+
--chart-color-8: #005759;
|
|
34
|
+
--chart-color-9: #004749;
|
|
35
|
+
--chart-color-10: #00383a; /* 最終地点はかなり深く */
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.lucentia-bar {
|
|
39
|
+
transform-origin: bottom;
|
|
40
|
+
animation: barGrow 0.5s ease;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@keyframes barGrow {
|
|
44
|
+
from {
|
|
45
|
+
transform: scaleY(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
to {
|
|
49
|
+
transform: scaleY(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
export const ChartContext = createContext(null);
|
|
3
|
+
export const useChart = () => {
|
|
4
|
+
const ctx = useContext(ChartContext);
|
|
5
|
+
if (!ctx) {
|
|
6
|
+
throw new Error("Chart components must be used inside ChartContainer");
|
|
7
|
+
}
|
|
8
|
+
return ctx;
|
|
9
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "./ChartContext";
|
|
3
|
+
export const ChartGrid = ({ rows = 4, columns = 4 }) => {
|
|
4
|
+
const { width, height, padding } = useChart();
|
|
5
|
+
const innerWidth = width - padding * 2;
|
|
6
|
+
const innerHeight = height - padding * 2;
|
|
7
|
+
const rowHeight = innerHeight / rows;
|
|
8
|
+
const colWidth = innerWidth / columns;
|
|
9
|
+
const lines = [];
|
|
10
|
+
for (let i = 0; i <= rows; i++) {
|
|
11
|
+
const y = padding + rowHeight * i;
|
|
12
|
+
lines.push(_jsx("line", { x1: padding, x2: width - padding, y1: y, y2: y, stroke: "var(--chart-grid)" }, `row-${i}`));
|
|
13
|
+
}
|
|
14
|
+
for (let i = 0; i <= columns; i++) {
|
|
15
|
+
const x = padding + colWidth * i;
|
|
16
|
+
lines.push(_jsx("line", { y1: padding, y2: height - padding, x1: x, x2: x, stroke: "var(--chart-grid)" }, `col-${i}`));
|
|
17
|
+
}
|
|
18
|
+
return _jsx("g", { children: lines });
|
|
19
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export const ChartLegend = ({ items }) => {
|
|
3
|
+
return (_jsx("div", { style: {
|
|
4
|
+
display: "flex",
|
|
5
|
+
gap: "12px",
|
|
6
|
+
flexWrap: "wrap",
|
|
7
|
+
marginTop: "8px",
|
|
8
|
+
}, children: items.map((item) => (_jsxs("div", { style: {
|
|
9
|
+
display: "flex",
|
|
10
|
+
alignItems: "center",
|
|
11
|
+
gap: "6px",
|
|
12
|
+
fontSize: "12px",
|
|
13
|
+
}, children: [_jsx("span", { style: {
|
|
14
|
+
width: 12,
|
|
15
|
+
height: 12,
|
|
16
|
+
background: item.color,
|
|
17
|
+
display: "inline-block",
|
|
18
|
+
} }), item.label] }, item.label))) }));
|
|
19
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const ChartTooltip = ({ x, y, children }) => {
|
|
3
|
+
return (_jsx("foreignObject", { x: x, y: y, width: 120, height: 64, style: { borderRadius: "var(--radius-sm)", overflow: "visible" }, children: _jsx("div", { style: {
|
|
4
|
+
background: "var(--color-surface)",
|
|
5
|
+
backdropFilter: "var(--blur)",
|
|
6
|
+
border: "1px solid var(--color-border)",
|
|
7
|
+
borderRadius: "var(--radius-sm)",
|
|
8
|
+
padding: "var(--space-md)",
|
|
9
|
+
fontSize: "var(--font-size-14)",
|
|
10
|
+
color: "var(--color-on-surface)",
|
|
11
|
+
}, children: children }) }));
|
|
12
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "./ChartContext";
|
|
3
|
+
export const ChartXAxis = ({ labels }) => {
|
|
4
|
+
const { width, height, padding } = useChart();
|
|
5
|
+
// 描画可能領域の計算
|
|
6
|
+
const innerWidth = width - padding * 2;
|
|
7
|
+
// 1ラベルあたりの幅
|
|
8
|
+
const step = innerWidth / (labels.length > 1 ? labels.length - 1 : 1);
|
|
9
|
+
return (_jsx("g", { fill: "var(--color-on-surface)", children: labels.map((label, i) => {
|
|
10
|
+
const x = padding + (innerWidth / labels.length) * (i + 0.5);
|
|
11
|
+
const y = height - padding + 20;
|
|
12
|
+
return (_jsx("text", { x: x, y: y, textAnchor: "middle" // 水平方向の中央揃え
|
|
13
|
+
, dominantBaseline: "hanging" // テキストの上端をy座標に合わせる(より制御しやすくなります)
|
|
14
|
+
, fontSize: "var(--font-size-14)", children: label }, i));
|
|
15
|
+
}) }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "./ChartContext";
|
|
3
|
+
export const ChartYAxis = ({ ticks, max }) => {
|
|
4
|
+
const { width, height, padding } = useChart();
|
|
5
|
+
const innerHeight = height - padding * 2;
|
|
6
|
+
return (_jsx("g", { fill: "var(--color-on-surface)", children: ticks.map((tick, i) => {
|
|
7
|
+
const ratio = tick / max;
|
|
8
|
+
const y = height - padding - ratio * innerHeight;
|
|
9
|
+
return (_jsxs("g", { children: [_jsx("text", { x: padding - 8, y: y, textAnchor: "end", dominantBaseline: "middle", fontSize: "var(--font-size-14)", children: tick }), _jsx("line", { x1: padding, x2: width - padding, y1: y, y2: y, stroke: "var(--chart-grid)", strokeDasharray: "2" })] }, i));
|
|
10
|
+
}) }));
|
|
11
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { ChartContainer } from "../ChartContainer";
|
|
4
|
+
import { ChartGrid } from "../ChartGrid";
|
|
5
|
+
import { ChartAxis } from "../ChartAxis";
|
|
6
|
+
import { ChartXAxis } from "../ChartXAxis";
|
|
7
|
+
import { ChartYAxis } from "../ChartYAxis";
|
|
8
|
+
import { ChartTooltip } from "../ChartTooltip";
|
|
9
|
+
import { LineSeries } from "./LineSeries";
|
|
10
|
+
import { getMaxValue } from "../BarChart/utils";
|
|
11
|
+
import { getNiceTicks } from "../utils/getNiceTicks";
|
|
12
|
+
export const LineChart = ({ data, keys, height = 300 }) => {
|
|
13
|
+
const seriesKeys = keys !== null && keys !== void 0 ? keys : Object.keys(data[0]).filter((k) => k !== "label");
|
|
14
|
+
const max = getMaxValue(data, seriesKeys);
|
|
15
|
+
const ticks = getNiceTicks(max);
|
|
16
|
+
const labels = data.map((d) => d.label);
|
|
17
|
+
const [cursor, setCursor] = useState({
|
|
18
|
+
x: 0,
|
|
19
|
+
y: 0,
|
|
20
|
+
});
|
|
21
|
+
const [tooltip, setTooltip] = useState(null);
|
|
22
|
+
return (_jsx("div", { style: { width: "100%" }, children: _jsxs(ChartContainer, { height: height, onPointerMove: (x, y) => setCursor({ x, y }), children: [_jsx(ChartGrid, {}), _jsx(ChartAxis, {}), _jsx(ChartYAxis, { ticks: ticks, max: ticks[ticks.length - 1] }), _jsx(ChartXAxis, { labels: labels }), _jsx(LineSeries, { data: data, keys: seriesKeys, max: ticks[ticks.length - 1], onHover: (label, key, value) => setTooltip({
|
|
23
|
+
label,
|
|
24
|
+
key,
|
|
25
|
+
value,
|
|
26
|
+
}), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: cursor.x + 12, y: cursor.y + 12, children: [_jsx("div", { children: tooltip.label }), _jsxs("strong", { children: [tooltip.key, ": ", tooltip.value] })] }))] }) }));
|
|
27
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const LinePath = ({ points, color }) => {
|
|
3
|
+
const d = points
|
|
4
|
+
.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`)
|
|
5
|
+
.join(" ");
|
|
6
|
+
return _jsx("path", { d: d, fill: "none", stroke: color, strokeWidth: 3 });
|
|
7
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
cx: number;
|
|
3
|
+
cy: number;
|
|
4
|
+
color: string;
|
|
5
|
+
onMouseEnter?: () => void;
|
|
6
|
+
onMouseLeave?: () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const LinePoint: ({ cx, cy, color, onMouseEnter, onMouseLeave, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const LinePoint = ({ cx, cy, color, onMouseEnter, onMouseLeave, }) => {
|
|
3
|
+
return (_jsx("circle", { cx: cx, cy: cy, r: 5, fill: color, stroke: "var(--color-surface)", strokeWidth: 2, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }));
|
|
4
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
data: any[];
|
|
3
|
+
keys: string[];
|
|
4
|
+
max: number;
|
|
5
|
+
onHover?: (label: string, key: string, value: number) => void;
|
|
6
|
+
onLeave?: () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const LineSeries: ({ data, keys, max, onHover, onLeave }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "../ChartContext";
|
|
3
|
+
import { scaleValue } from "../BarChart/utils";
|
|
4
|
+
import { LinePath } from "./LinePath";
|
|
5
|
+
import { LinePoint } from "./LinePoint";
|
|
6
|
+
export const LineSeries = ({ data, keys, max, onHover, onLeave }) => {
|
|
7
|
+
const { width, height, padding } = useChart();
|
|
8
|
+
const innerWidth = width - padding * 2;
|
|
9
|
+
const innerHeight = height - padding * 2;
|
|
10
|
+
// XAxisと同じ中央配置ロジック
|
|
11
|
+
const groupWidth = innerWidth / data.length;
|
|
12
|
+
return (_jsx("g", { children: keys.map((key, kIndex) => {
|
|
13
|
+
const points = data.map((d, i) => {
|
|
14
|
+
var _a;
|
|
15
|
+
const value = Number((_a = d[key]) !== null && _a !== void 0 ? _a : 0);
|
|
16
|
+
const x = padding + groupWidth * (i + 0.5);
|
|
17
|
+
const y = height -
|
|
18
|
+
padding -
|
|
19
|
+
scaleValue(value, max, innerHeight);
|
|
20
|
+
return { x, y, value, label: d.label };
|
|
21
|
+
});
|
|
22
|
+
return (_jsxs("g", { children: [_jsx(LinePath, { points: points, color: `var(--color-primary)` }), points.map((p, i) => (_jsx(LinePoint, { cx: p.x, cy: p.y, color: `var(--color-primary)`, onMouseEnter: () => onHover === null || onHover === void 0 ? void 0 : onHover(p.label, key, p.value), onMouseLeave: onLeave }, i)))] }, key));
|
|
23
|
+
}) }));
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { ChartContainer } from "../ChartContainer";
|
|
4
|
+
import { ChartTooltip } from "../ChartTooltip";
|
|
5
|
+
import { PieSeries } from "./PieSeries";
|
|
6
|
+
export const PieChart = ({ data, width = 300, height = 300, radius, innerRadius = 0, }) => {
|
|
7
|
+
const [tooltip, setTooltip] = useState(null);
|
|
8
|
+
return (_jsxs(ChartContainer, { width: width, height: height, children: [_jsx(PieSeries, { data: data, radius: radius, innerRadius: innerRadius, onHover: (label, value, x, y) => setTooltip({ label, value, x, y }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: tooltip.x + 10, y: tooltip.y - 10, children: [_jsx("div", { children: tooltip.label }), _jsx("div", { style: { fontWeight: "var(--font-weight-bold)" }, children: tooltip.value })] }))] }));
|
|
9
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useChart } from "../ChartContext";
|
|
4
|
+
import { PieSlice } from "./PieSlice";
|
|
5
|
+
import { describeArc } from "./utils";
|
|
6
|
+
export const PieSeries = ({ data, radius, innerRadius = 0, onHover, onLeave, }) => {
|
|
7
|
+
const { width, height } = useChart();
|
|
8
|
+
const [hoverIndex, setHoverIndex] = useState(null);
|
|
9
|
+
const cx = width / 2;
|
|
10
|
+
const cy = height / 2;
|
|
11
|
+
const r = radius !== null && radius !== void 0 ? radius : Math.min(width, height) / 2;
|
|
12
|
+
const total = data.reduce((sum, d) => sum + d.value, 0);
|
|
13
|
+
let startAngle = 0;
|
|
14
|
+
const getSVGPoint = (e) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const svg = e.currentTarget.ownerSVGElement;
|
|
17
|
+
if (!svg)
|
|
18
|
+
return { x: 0, y: 0 };
|
|
19
|
+
const pt = svg.createSVGPoint();
|
|
20
|
+
pt.x = e.clientX;
|
|
21
|
+
pt.y = e.clientY;
|
|
22
|
+
const cursorpt = pt.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
|
|
23
|
+
return { x: cursorpt.x, y: cursorpt.y };
|
|
24
|
+
};
|
|
25
|
+
return (_jsx("g", { children: data.map((d, i) => {
|
|
26
|
+
const angle = (d.value / total) * 360;
|
|
27
|
+
const endAngle = startAngle + angle;
|
|
28
|
+
const path = describeArc(cx, cy, r, startAngle, endAngle, innerRadius);
|
|
29
|
+
startAngle = endAngle;
|
|
30
|
+
const scale = hoverIndex === i ? 1.04 : 1;
|
|
31
|
+
return (_jsx(PieSlice, { d: path, color: `var(--chart-color-${i + 1})`, cx: cx, cy: cy, scale: scale, onMouseMove: (e) => {
|
|
32
|
+
setHoverIndex(i);
|
|
33
|
+
const { x, y } = getSVGPoint(e);
|
|
34
|
+
onHover === null || onHover === void 0 ? void 0 : onHover(d.label, d.value, x, y);
|
|
35
|
+
}, onMouseLeave: () => {
|
|
36
|
+
setHoverIndex(null);
|
|
37
|
+
onLeave === null || onLeave === void 0 ? void 0 : onLeave();
|
|
38
|
+
} }, i));
|
|
39
|
+
}) }));
|
|
40
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { MouseEvent } from "react";
|
|
2
|
+
type Props = {
|
|
3
|
+
d: string;
|
|
4
|
+
color: string;
|
|
5
|
+
cx: number;
|
|
6
|
+
cy: number;
|
|
7
|
+
scale?: number;
|
|
8
|
+
onMouseMove?: (e: MouseEvent<SVGPathElement>) => void;
|
|
9
|
+
onMouseLeave?: () => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const PieSlice: ({ d, color, cx, cy, scale, onMouseMove, onMouseLeave, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export const PieSlice = ({ d, color, cx, cy, scale = 1, onMouseMove, onMouseLeave, }) => {
|
|
3
|
+
return (_jsx("path", { d: d, fill: color, transform: `scale(${scale})`, style: {
|
|
4
|
+
cursor: "default",
|
|
5
|
+
transformOrigin: `${cx}px ${cy}px`,
|
|
6
|
+
transition: "transform 120ms ease",
|
|
7
|
+
}, onMouseMove: onMouseMove, onMouseLeave: onMouseLeave }));
|
|
8
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type PieDatum = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: number;
|
|
4
|
+
};
|
|
5
|
+
export type PieChartProps = {
|
|
6
|
+
data: PieDatum[];
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
radius?: number;
|
|
10
|
+
innerRadius?: number;
|
|
11
|
+
};
|
|
12
|
+
export type PieSeriesProps = {
|
|
13
|
+
data: PieDatum[];
|
|
14
|
+
radius?: number;
|
|
15
|
+
innerRadius?: number;
|
|
16
|
+
onHover?: (label: string, value: number, x: number, y: number) => void;
|
|
17
|
+
onLeave?: () => void;
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const polarToCartesian = (cx, cy, r, angle) => {
|
|
2
|
+
const rad = (angle - 90) * (Math.PI / 180);
|
|
3
|
+
return {
|
|
4
|
+
x: cx + r * Math.cos(rad),
|
|
5
|
+
y: cy + r * Math.sin(rad),
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export const describeArc = (cx, cy, r, startAngle, endAngle, innerRadius = 0) => {
|
|
9
|
+
const outerStart = polarToCartesian(cx, cy, r, endAngle);
|
|
10
|
+
const outerEnd = polarToCartesian(cx, cy, r, startAngle);
|
|
11
|
+
const largeArcFlag = endAngle - startAngle > 180 ? 1 : 0;
|
|
12
|
+
if (innerRadius === 0) {
|
|
13
|
+
return ` M ${outerStart.x} ${outerStart.y}
|
|
14
|
+
A ${r} ${r} 0 ${largeArcFlag} 0 ${outerEnd.x} ${outerEnd.y}
|
|
15
|
+
L ${cx} ${cy}
|
|
16
|
+
Z
|
|
17
|
+
`;
|
|
18
|
+
}
|
|
19
|
+
const innerStart = polarToCartesian(cx, cy, innerRadius, endAngle);
|
|
20
|
+
const innerEnd = polarToCartesian(cx, cy, innerRadius, startAngle);
|
|
21
|
+
return ` M ${outerStart.x} ${outerStart.y}
|
|
22
|
+
A ${r} ${r} 0 ${largeArcFlag} 0 ${outerEnd.x} ${outerEnd.y}
|
|
23
|
+
L ${innerEnd.x} ${innerEnd.y}
|
|
24
|
+
A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 1 ${innerStart.x} ${innerStart.y}
|
|
25
|
+
Z
|
|
26
|
+
`;
|
|
27
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "../ChartContext";
|
|
3
|
+
import { polarToCartesian } from "./utils";
|
|
4
|
+
export const RadarAxis = ({ data, }) => {
|
|
5
|
+
const { width, height } = useChart();
|
|
6
|
+
const cx = width / 2;
|
|
7
|
+
const cy = height / 2;
|
|
8
|
+
const radius = Math.min(width, height) / 2 - 24;
|
|
9
|
+
const step = (Math.PI * 2) / data.length;
|
|
10
|
+
return (_jsx("g", { fontSize: 14, textAnchor: "middle", fill: "var(--color-on-surface)", children: data.map((d, i) => {
|
|
11
|
+
const angle = i * step - Math.PI / 2;
|
|
12
|
+
const lineEnd = polarToCartesian(cx, cy, radius, angle);
|
|
13
|
+
const labelPos = polarToCartesian(cx, cy, radius + 16, angle);
|
|
14
|
+
return (_jsxs("g", { children: [_jsx("line", { x1: cx, y1: cy, x2: lineEnd.x, y2: lineEnd.y, stroke: "var(--chart-grid)" }), _jsx("text", { x: labelPos.x, y: labelPos.y, children: d.label })] }, i));
|
|
15
|
+
}) }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { ChartContainer } from "../ChartContainer";
|
|
4
|
+
import { ChartTooltip } from "../ChartTooltip";
|
|
5
|
+
import { RadarGrid } from "./RadarGrid";
|
|
6
|
+
import { RadarAxis } from "./RadarAxis";
|
|
7
|
+
import { RadarSeries } from "./RadarSeries";
|
|
8
|
+
export const RadarChart = ({ data, width = 320, height = 320, levels = 5, }) => {
|
|
9
|
+
const [tooltip, setTooltip] = useState(null);
|
|
10
|
+
return (_jsxs(ChartContainer, { width: width, height: height, children: [" ", _jsx(RadarGrid, { data: data, levels: levels }), _jsx(RadarAxis, { data: data }), _jsx(RadarSeries, { data: data, onHover: (label, value, x, y) => setTooltip({ label, value, x, y }), onLeave: () => setTooltip(null) }), tooltip && (_jsxs(ChartTooltip, { x: tooltip.x + 10, y: tooltip.y - 10, children: [_jsx("div", { children: tooltip.label }), _jsx("div", { children: tooltip.value })] }))] }));
|
|
11
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "../ChartContext";
|
|
3
|
+
import { polarToCartesian } from "./utils";
|
|
4
|
+
export const RadarGrid = ({ data, levels = 5, }) => {
|
|
5
|
+
const { width, height } = useChart();
|
|
6
|
+
const axes = data.length;
|
|
7
|
+
const cx = width / 2;
|
|
8
|
+
const cy = height / 2;
|
|
9
|
+
const radius = Math.min(width, height) / 2 - 24;
|
|
10
|
+
const step = (Math.PI * 2) / axes;
|
|
11
|
+
return (_jsx("g", { stroke: "var(--chart-grid)", fill: "none", children: [...Array(levels)].map((_, level) => {
|
|
12
|
+
const r = (radius / levels) * (level + 1);
|
|
13
|
+
const points = [...Array(axes)].map((_, i) => {
|
|
14
|
+
const angle = i * step - Math.PI / 2;
|
|
15
|
+
const p = polarToCartesian(cx, cy, r, angle);
|
|
16
|
+
return `${p.x},${p.y}`;
|
|
17
|
+
});
|
|
18
|
+
return (_jsx("polygon", { points: points.join(" ") }, level));
|
|
19
|
+
}) }));
|
|
20
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChart } from "../ChartContext";
|
|
3
|
+
import { createRadarPath, polarToCartesian, } from "./utils";
|
|
4
|
+
export const RadarSeries = ({ data, onHover, onLeave, }) => {
|
|
5
|
+
const { width, height } = useChart();
|
|
6
|
+
const cx = width / 2;
|
|
7
|
+
const cy = height / 2;
|
|
8
|
+
const radius = Math.min(width, height) / 2 - 24;
|
|
9
|
+
const values = data.map((d) => d.value);
|
|
10
|
+
const max = Math.max(...values);
|
|
11
|
+
const path = createRadarPath(cx, cy, radius, values, max);
|
|
12
|
+
const step = (Math.PI * 2) / data.length;
|
|
13
|
+
const getSVGPoint = (e) => {
|
|
14
|
+
var _a;
|
|
15
|
+
const svg = e.currentTarget.ownerSVGElement;
|
|
16
|
+
if (!svg)
|
|
17
|
+
return { x: 0, y: 0 };
|
|
18
|
+
const pt = svg.createSVGPoint();
|
|
19
|
+
pt.x = e.clientX;
|
|
20
|
+
pt.y = e.clientY;
|
|
21
|
+
const cursorpt = pt.matrixTransform((_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse());
|
|
22
|
+
return { x: cursorpt.x, y: cursorpt.y };
|
|
23
|
+
};
|
|
24
|
+
return (_jsxs("g", { children: [" ", _jsx("path", { d: path, fill: "var(--chart-color-1)", fillOpacity: 0.25, stroke: "var(--chart-color-1)", strokeWidth: 2 }), data.map((d, i) => {
|
|
25
|
+
const r = (d.value / max) * radius;
|
|
26
|
+
const angle = i * step - Math.PI / 2;
|
|
27
|
+
const p = polarToCartesian(cx, cy, r, angle);
|
|
28
|
+
return (_jsx("circle", { cx: p.x, cy: p.y, r: 12, fillOpacity: 0, style: { cursor: "default" }, onMouseMove: (e) => {
|
|
29
|
+
const { x, y } = getSVGPoint(e);
|
|
30
|
+
onHover === null || onHover === void 0 ? void 0 : onHover(d.label, d.value, x, y);
|
|
31
|
+
}, onMouseLeave: onLeave }, i));
|
|
32
|
+
})] }));
|
|
33
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type RadarDatum = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: number;
|
|
4
|
+
};
|
|
5
|
+
export type RadarChartProps = {
|
|
6
|
+
data: RadarDatum[];
|
|
7
|
+
width?: number;
|
|
8
|
+
height?: number;
|
|
9
|
+
levels?: number;
|
|
10
|
+
};
|
|
11
|
+
export type RadarSeriesProps = {
|
|
12
|
+
data: RadarDatum[];
|
|
13
|
+
onHover?: (label: string, value: number, x: number, y: number) => void;
|
|
14
|
+
onLeave?: () => void;
|
|
15
|
+
};
|
|
16
|
+
export type RadarGridProps = {
|
|
17
|
+
data: RadarDatum[];
|
|
18
|
+
levels?: number;
|
|
19
|
+
};
|
|
20
|
+
export type RadarAxisProps = {
|
|
21
|
+
data: RadarDatum[];
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const polarToCartesian = (cx, cy, r, angle) => {
|
|
2
|
+
return {
|
|
3
|
+
x: cx + r * Math.cos(angle),
|
|
4
|
+
y: cy + r * Math.sin(angle),
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
export const createRadarPath = (cx, cy, radius, values, max) => {
|
|
8
|
+
const step = (Math.PI * 2) / values.length;
|
|
9
|
+
const points = values.map((v, i) => {
|
|
10
|
+
const r = (v / max) * radius;
|
|
11
|
+
const angle = i * step - Math.PI / 2;
|
|
12
|
+
const p = polarToCartesian(cx, cy, r, angle);
|
|
13
|
+
return `${p.x} ${p.y}`;
|
|
14
|
+
});
|
|
15
|
+
return `M ${points.join(" L ")} Z`;
|
|
16
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { ChartContainer } from "./ChartContainer";
|
|
2
|
+
export { ChartTooltip } from "./ChartTooltip";
|
|
3
|
+
export { ChartLegend } from "./ChartLegend";
|
|
4
|
+
export { ChartAxis } from "./ChartAxis";
|
|
5
|
+
export { ChartXAxis } from "./ChartXAxis";
|
|
6
|
+
export { ChartYAxis } from "./ChartYAxis";
|
|
7
|
+
export { ChartGrid } from "./ChartGrid";
|
|
8
|
+
export { BarChart } from "./BarChart/BarChart";
|
|
9
|
+
export type { BarChartProps } from "./BarChart/types";
|
|
10
|
+
export { LineChart } from "./LineChart/LineChart";
|
|
11
|
+
export type { LineChartProps } from "./LineChart/types";
|
|
12
|
+
export { PieChart } from "./PieChart/PieChart";
|
|
13
|
+
export type { PieChartProps, PieDatum } from "./PieChart/types";
|
|
14
|
+
export { RadarChart } from "./RadarChart/RadarChart";
|
|
15
|
+
export type { RadarChartProps, RadarDatum } from "./RadarChart/types";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// =========================
|
|
2
|
+
// Core
|
|
3
|
+
// =========================
|
|
4
|
+
export { ChartContainer } from "./ChartContainer";
|
|
5
|
+
export { ChartTooltip } from "./ChartTooltip";
|
|
6
|
+
export { ChartLegend } from "./ChartLegend";
|
|
7
|
+
// Axis / Grid
|
|
8
|
+
export { ChartAxis } from "./ChartAxis";
|
|
9
|
+
export { ChartXAxis } from "./ChartXAxis";
|
|
10
|
+
export { ChartYAxis } from "./ChartYAxis";
|
|
11
|
+
export { ChartGrid } from "./ChartGrid";
|
|
12
|
+
// =========================
|
|
13
|
+
// Charts
|
|
14
|
+
// =========================
|
|
15
|
+
export { BarChart } from "./BarChart/BarChart";
|
|
16
|
+
export { LineChart } from "./LineChart/LineChart";
|
|
17
|
+
export { PieChart } from "./PieChart/PieChart";
|
|
18
|
+
export { RadarChart } from "./RadarChart/RadarChart";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getNiceTicks: (max: number, tickCount?: number) => number[];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const getNiceTicks = (max, tickCount = 5) => {
|
|
2
|
+
if (max === 0)
|
|
3
|
+
return [0];
|
|
4
|
+
const roughStep = max / (tickCount - 1);
|
|
5
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(roughStep)));
|
|
6
|
+
const residual = roughStep / magnitude;
|
|
7
|
+
let niceStep = magnitude;
|
|
8
|
+
if (residual > 5)
|
|
9
|
+
niceStep = 10 * magnitude;
|
|
10
|
+
else if (residual > 2)
|
|
11
|
+
niceStep = 5 * magnitude;
|
|
12
|
+
else if (residual > 1)
|
|
13
|
+
niceStep = 2 * magnitude;
|
|
14
|
+
const niceMax = Math.ceil(max / niceStep) * niceStep;
|
|
15
|
+
const ticks = [];
|
|
16
|
+
for (let v = 0; v <= niceMax; v += niceStep) {
|
|
17
|
+
ticks.push(v);
|
|
18
|
+
}
|
|
19
|
+
return ticks;
|
|
20
|
+
};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -13,3 +13,7 @@ export * from "./components/Typography";
|
|
|
13
13
|
export * from "./components/Select";
|
|
14
14
|
export * from "./components/Switch";
|
|
15
15
|
export * from "./components/Feedback/Modal";
|
|
16
|
+
/* ===== Chart ===== */
|
|
17
|
+
export * from "./components/Chart";
|
|
18
|
+
/* ===== Extra ===== */
|
|
19
|
+
export * from "./components/Extra/Clock";
|
package/dist/styles/tokens.css
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
--line-tight: 1.2;
|
|
15
15
|
--line-snug: 1.35;
|
|
16
|
+
--line-normal: 1.5;
|
|
16
17
|
--line-comfort: 1.7;
|
|
17
18
|
|
|
18
19
|
--font-weight-regular: 400;
|
|
@@ -63,8 +64,19 @@
|
|
|
63
64
|
--color-surface-container: #e9efeebf;
|
|
64
65
|
|
|
65
66
|
--color-border: #bbcccc;
|
|
66
|
-
--color-scrim: rgba(129, 129, 129, 0.25);
|
|
67
67
|
|
|
68
|
+
--chart-color-1: #99cccc;
|
|
69
|
+
--chart-color-2: #66b2b2;
|
|
70
|
+
--chart-color-3: #4da6a6;
|
|
71
|
+
--chart-color-4: #339999;
|
|
72
|
+
--chart-color-5: #008b8b;
|
|
73
|
+
--chart-color-6: #007a7a;
|
|
74
|
+
--chart-color-7: #006666;
|
|
75
|
+
--chart-color-8: #005252;
|
|
76
|
+
--chart-color-9: #004545;
|
|
77
|
+
--chart-color-10: #003333;
|
|
78
|
+
|
|
79
|
+
--color-scrim: rgba(129, 129, 129, 0.25);
|
|
68
80
|
--color-shadow-l: rgba(255, 255, 255, 1);
|
|
69
81
|
--color-shadow-d: rgba(0, 0, 0, 0.2);
|
|
70
82
|
|
|
@@ -91,7 +103,8 @@
|
|
|
91
103
|
-4px -4px 16px 8px var(--color-shadow-l),
|
|
92
104
|
4px 4px 16px 8px var(--color-shadow-d);
|
|
93
105
|
|
|
94
|
-
--shadow-
|
|
106
|
+
--shadow-overlay-md: 0px 2px 8px 2px var(--color-shadow-d);
|
|
107
|
+
--shadow-overlay-lg: 0px 4px 16px 8px var(--color-shadow-d);
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
html[data-theme="dark"] {
|
|
@@ -116,11 +129,22 @@ html[data-theme="dark"] {
|
|
|
116
129
|
--color-surface: #1e2927bf;
|
|
117
130
|
--color-on-surface: #c3cbca;
|
|
118
131
|
--color-on-surface-variant: #dde4e380;
|
|
119
|
-
--color-surface-container: #
|
|
132
|
+
--color-surface-container: #262d2dbf;
|
|
120
133
|
|
|
121
134
|
--color-border: #889392;
|
|
122
|
-
--color-scrim: rgba(0, 0, 0, 0.25);
|
|
123
135
|
|
|
136
|
+
--chart-color-1: #80d5d4;
|
|
137
|
+
--chart-color-2: #6bc2c1;
|
|
138
|
+
--chart-color-3: #57afae;
|
|
139
|
+
--chart-color-4: #439d9c;
|
|
140
|
+
--chart-color-5: #308b8b;
|
|
141
|
+
--chart-color-6: #1c797a;
|
|
142
|
+
--chart-color-7: #09686a;
|
|
143
|
+
--chart-color-8: #005759;
|
|
144
|
+
--chart-color-9: #004749;
|
|
145
|
+
--chart-color-10: #00383a;
|
|
146
|
+
|
|
147
|
+
--color-scrim: rgba(0, 0, 0, 0.25);
|
|
124
148
|
--color-shadow-l: rgba(255, 255, 255, 0.25);
|
|
125
149
|
--color-shadow-d: rgba(0, 0, 0, 1);
|
|
126
150
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const generateCalendar = (baseDate) => {
|
|
2
|
+
const year = baseDate.getFullYear();
|
|
3
|
+
const month = baseDate.getMonth();
|
|
4
|
+
// 月初
|
|
5
|
+
const firstDayOfMonth = new Date(year, month, 1);
|
|
6
|
+
// 月初の曜日(0=日)
|
|
7
|
+
const startDay = firstDayOfMonth.getDay();
|
|
8
|
+
// 今月の日数
|
|
9
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
10
|
+
// 先月の日数
|
|
11
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
12
|
+
const days = [];
|
|
13
|
+
// ① 前月
|
|
14
|
+
for (let i = startDay - 1; i >= 0; i--) {
|
|
15
|
+
days.push({
|
|
16
|
+
date: new Date(year, month - 1, daysInPrevMonth - i),
|
|
17
|
+
isCurrentMonth: false,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// ② 当月
|
|
21
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
22
|
+
days.push({
|
|
23
|
+
date: new Date(year, month, i),
|
|
24
|
+
isCurrentMonth: true,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// ③ 次月
|
|
28
|
+
const remaining = 42 - days.length;
|
|
29
|
+
for (let i = 1; i <= remaining; i++) {
|
|
30
|
+
days.push({
|
|
31
|
+
date: new Date(year, month + 1, i),
|
|
32
|
+
isCurrentMonth: false,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return days;
|
|
36
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lucentia-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "React UI design token and component system based on neumorphism, featuring two color themes: light and dark.",
|
|
5
5
|
"homepage": "https://lucentia.rikiyamatsuda.com/en",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"**/*.css"
|
|
24
24
|
],
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"react": ">=18"
|
|
26
|
+
"react": ">=18",
|
|
27
|
+
"react-dom": ">=18"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
30
|
"build": "tsc -p tsconfig.json && npm run copy:assets",
|
|
@@ -32,9 +33,10 @@
|
|
|
32
33
|
},
|
|
33
34
|
"license": "MIT",
|
|
34
35
|
"dependencies": {
|
|
36
|
+
"@floating-ui/react": "^0.27.0",
|
|
35
37
|
"clsx": "^2.1.1"
|
|
36
38
|
},
|
|
37
39
|
"devDependencies": {
|
|
38
40
|
"cpy-cli": "^6.0.0"
|
|
39
41
|
}
|
|
40
|
-
}
|
|
42
|
+
}
|