Chartチャート
データビジュアライゼーションのためのチャートコンポーネントです。円グラフ、棒グラフ、折れ線グラフなどをサポートし、データの視覚化を容易にします。
更新 2025/7/28
Pie Chart
usePieChartPropsフックを使用することで、円グラフを作成できます。データの割合や構成比を視覚的に表現する際に使用します。
import { ResponsivePie } from "@nivo/pie";
import { usePieChartProps } from "@serendie/ui";
import { styled } from "../../../styled-system/jsx";
const ChartContainer = styled("div", {
base: {
height: "400px",
width: "100%",
margin: "0 auto",
},
});
const pieData = [
{ id: "Desktop", label: "Desktop", value: 45 },
{ id: "Mobile", label: "Mobile", value: 30 },
{ id: "Tablet", label: "Tablet", value: 15 },
{ id: "Smart TV", label: "Smart TV", value: 10 },
];
export function PieChartSample() {
const pieProps = usePieChartProps("primary");
return (
<ChartContainer>
<ResponsivePie data={pieData} {...pieProps} />
</ChartContainer>
);
}
Line Chart
useLineChartPropsフックを使用することで、時系列データなどを表現する線グラフを作成できます。複数のデータ系列を同時に表示することも可能です。
import { ResponsiveLine } from "@nivo/line";
import { useLineChartProps } from "@serendie/ui";
import { styled } from "../../../styled-system/jsx";
const ChartContainer = styled("div", {
base: {
height: "300px",
width: "100%",
margin: "0 auto",
},
});
const lineData = [
{
id: "Desktop",
data: [
{ x: "Jan", y: 120 },
{ x: "Feb", y: 150 },
{ x: "Mar", y: 180 },
{ x: "Apr", y: 220 },
{ x: "May", y: 240 },
{ x: "Jun", y: 280 },
],
},
{
id: "Mobile",
data: [
{ x: "Jan", y: 80 },
{ x: "Feb", y: 100 },
{ x: "Mar", y: 120 },
{ x: "Apr", y: 140 },
{ x: "May", y: 180 },
{ x: "Jun", y: 200 },
],
},
{
id: "Tablet",
data: [
{ x: "Jan", y: 40 },
{ x: "Feb", y: 45 },
{ x: "Mar", y: 50 },
{ x: "Apr", y: 55 },
{ x: "May", y: 60 },
{ x: "Jun", y: 65 },
],
},
];
export function LineChartSample() {
const lineProps = useLineChartProps("multi");
return (
<ChartContainer>
<ResponsiveLine
data={lineData}
{...lineProps}
axisBottom={{
legend: "Month",
legendPosition: "middle",
legendOffset: 36,
}}
axisLeft={{
legend: "Value",
legendPosition: "middle",
legendOffset: -40,
}}
/>
</ChartContainer>
);
}
Bar Chart
useBarChartPropsフックを使用することで、棒グラフを作成できます。縦棒グラフと横棒グラフの両方に対応しています。
Vertical Bar Chart
Horizontal Bar Chart
import { ResponsiveBar } from "@nivo/bar";
import { useBarChartProps } from "@serendie/ui";
import { styled } from "../../../styled-system/jsx";
const Container = styled("div", {
base: {
display: "flex",
flexDirection: "column",
gap: "sd.system.dimension.spacing.xlarge",
},
});
const ChartSection = styled("div", {
base: {
display: "flex",
flexDirection: "column",
gap: "sd.system.dimension.spacing.small",
},
});
const ChartTitle = styled("h3", {
base: {
fontSize: "sd.system.typography.fontSize.medium",
fontWeight: "sd.system.typography.fontWeight.bold",
margin: 0,
},
});
const VerticalChartContainer = styled("div", {
base: {
height: "300px",
width: "100%",
margin: "0 auto",
},
});
const HorizontalChartContainer = styled("div", {
base: {
height: "400px",
width: "100%",
margin: "0 auto",
},
});
const barData = [
{ month: "Jan", value: 30 },
{ month: "Feb", value: 45 },
{ month: "Mar", value: 60 },
{ month: "Apr", value: 35 },
{ month: "May", value: 50 },
{ month: "Jun", value: 70 },
];
export function BarChartSample() {
const verticalBarProps = useBarChartProps("primary");
const horizontalBarProps = useBarChartProps("notice");
return (
<Container>
<ChartSection>
<ChartTitle>Vertical Bar Chart</ChartTitle>
<VerticalChartContainer>
<ResponsiveBar
data={barData}
keys={["value"]}
indexBy="month"
{...verticalBarProps}
/>
</VerticalChartContainer>
</ChartSection>
<ChartSection>
<ChartTitle>Horizontal Bar Chart</ChartTitle>
<HorizontalChartContainer>
<ResponsiveBar
data={barData}
keys={["value"]}
indexBy="month"
{...horizontalBarProps}
layout="horizontal"
axisTop={null}
axisRight={null}
axisBottom={{
legend: "Value",
legendPosition: "middle",
legendOffset: 32,
}}
axisLeft={{
legend: "Month",
legendPosition: "middle",
legendOffset: -40,
}}
/>
</HorizontalChartContainer>
</ChartSection>
</Container>
);
}
Piled Bar Chart
複数のセグメントを積み上げて構成比を表現する、積み上げ棒グラフを作成できます。カテゴリー内の内訳を視覚化する際に使用します。
import { ResponsiveBar } from "@nivo/bar";
import { useBarChartProps } from "@serendie/ui";
import { styled } from "../../../styled-system/jsx";
import serendieTokens from "@serendie/design-token";
const ChartContainer = styled("div", {
base: {
height: "400px",
width: "100%",
margin: "0 auto",
},
});
const stackedData = [
{
category: "Category A",
segment1: 20,
segment2: 20,
segment3: 20,
segment4: 20,
segment5: 20,
},
{
category: "Category B",
segment1: 15,
segment2: 25,
segment3: 20,
segment4: 25,
segment5: 15,
},
{
category: "Category C",
segment1: 30,
segment2: 15,
segment3: 20,
segment4: 20,
segment5: 15,
},
{
category: "Category D",
segment1: 10,
segment2: 20,
segment3: 30,
segment4: 25,
segment5: 15,
},
];
export function StackedBarChartSample() {
const barProps = useBarChartProps("primary");
const labelFormat = (datum: string | number) =>
Number(datum) > 0 ? "20%" : "";
const spacingTokens = serendieTokens.sd.system.dimension.spacing;
const margin = {
top: parseInt(spacingTokens.large, 10),
right: parseInt(spacingTokens.fiveExtraLarge, 10),
bottom: parseInt(spacingTokens.fourExtraLarge, 10),
left: parseInt(spacingTokens.fiveExtraLarge, 10),
};
return (
<ChartContainer>
<ResponsiveBar
data={stackedData}
keys={["segment1", "segment2", "segment3", "segment4", "segment5"]}
indexBy="category"
labelFormat={labelFormat}
axisRight={{
format: (value: number) => value + "%",
}}
{...barProps}
margin={margin}
/>
</ChartContainer>
);
}