"use client"
import { Chart, useChart } from "@chakra-ui/charts"
import { Scatter, ScatterChart, XAxis, YAxis } from "recharts"
const Demo = () => {
const chart = useChart({
data: [
{ temperature: 14.2, sales: 215 },
{ temperature: 16.4, sales: 325 },
{ temperature: 11.9, sales: 185 },
{ temperature: 15.2, sales: 332 },
{ temperature: 18.5, sales: 406 },
{ temperature: 22.1, sales: 522 },
{ temperature: 19.4, sales: 412 },
{ temperature: 25.1, sales: 614 },
{ temperature: 23.4, sales: 544 },
{ temperature: 18.1, sales: 421 },
{ temperature: 22.6, sales: 445 },
{ temperature: 17.2, sales: 408 },
],
series: [{ name: "sales", color: "teal.solid" }],
})
return (
<Chart.Root maxH="sm" chart={chart}>
<ScatterChart>
<XAxis
type="number"
dataKey={chart.key("temperature")}
stroke={chart.color("border")}
tickFormatter={(value) => `${value}°C`}
domain={[10, "dataMax + 3"]}
/>
<YAxis
type="number"
dataKey={chart.key("sales")}
stroke={chart.color("border")}
/>
{chart.series.map((series, index) => (
<Scatter
name={series.name?.toString()}
key={index}
data={chart.data}
fill={chart.color(series.color)}
isAnimationActive={false}
/>
))}
</ScatterChart>
</Chart.Root>
)
}
用法
import { Chart, useChart } from "@chakra-ui/charts"
import { Scatter, ScatterChart, XAxis, YAxis } from "recharts"
<Chart.Root>
<ScatterChart>
<XAxis />
<YAxis />
<Scatter />
</ScatterChart>
</Chart.Root>
示例
多系列
这是一个包含多系列散点图的示例。
"use client"
import { Chart, useChart } from "@chakra-ui/charts"
import { Scatter, ScatterChart, Tooltip, XAxis, YAxis } from "recharts"
const Demo = () => {
const chart = useChart({
data: [
{ x: 100, y: 200, id: "group1" },
{ x: 120, y: 100, id: "group1" },
{ x: 170, y: 300, id: "group1" },
{ x: 140, y: 250, id: "group1" },
{ x: 150, y: 400, id: "group1" },
{ x: 110, y: 280, id: "group1" },
{ x: 200, y: 260, id: "group2" },
{ x: 240, y: 290, id: "group2" },
{ x: 190, y: 290, id: "group2" },
{ x: 198, y: 250, id: "group2" },
{ x: 180, y: 280, id: "group2" },
{ x: 210, y: 220, id: "group2" },
],
series: [
{ label: "Group 1", color: "blue.solid" },
{ label: "Group 2", color: "green.solid" },
],
})
const groupedData = chart.groupBy("id")
return (
<Chart.Root maxH="sm" chart={chart}>
<ScatterChart margin={{ top: 20, right: 30, bottom: 5, left: 0 }}>
<XAxis
type="number"
dataKey={chart.key("x")}
stroke={chart.color("border")}
domain={["dataMin - 10", "dataMax + 10"]}
/>
<YAxis
type="number"
dataKey={chart.key("y")}
stroke={chart.color("border")}
/>
<Tooltip
cursor={{ strokeDasharray: "3 3" }}
content={<Chart.Tooltip hideLabel />}
/>
{chart.series.map((series, index) => (
<Scatter
name={series.label?.toString()}
key={index}
data={groupedData[index]}
fill={chart.color(series.color)}
isAnimationActive={false}
/>
))}
</ScatterChart>
</Chart.Root>
)
}
图例
渲染 Chart.Legend
组件以显示散点图的图例。
"use client"
import { Chart, useChart } from "@chakra-ui/charts"
import { Legend, Scatter, ScatterChart, XAxis, YAxis } from "recharts"
const Demo = () => {
const chart = useChart({
data: [
{ x: 100, y: 200 },
{ x: 120, y: 100 },
{ x: 170, y: 300 },
{ x: 140, y: 250 },
{ x: 150, y: 400 },
{ x: 110, y: 280 },
],
series: [{ label: "Group 1", color: "blue.solid" }],
})
return (
<Chart.Root maxH="sm" chart={chart}>
<ScatterChart margin={{ top: 20, right: 30, bottom: 5, left: 0 }}>
<XAxis
type="number"
dataKey={chart.key("x")}
stroke={chart.color("border")}
/>
<Legend content={<Chart.Legend />} />
<YAxis
type="number"
dataKey={chart.key("y")}
stroke={chart.color("border")}
/>
{chart.series.map((series, index) => (
<Scatter
name={series.label?.toString()}
key={index}
data={chart.data}
fill={chart.color(series.color)}
isAnimationActive={false}
/>
))}
</ScatterChart>
</Chart.Root>
)
}
趋势线
这是一个使用最小二乘回归法在图表上显示趋势线的示例。
要显示趋势线,我们使用来自 recharts
库的 Scatter
组件。
<Scatter data={trendLine} shape={() => <Fragment />} />
"use client"
import { Chart, useChart } from "@chakra-ui/charts"
import { Fragment, useMemo } from "react"
import { Scatter, ScatterChart, XAxis, YAxis } from "recharts"
const Demo = () => {
const chart = useChart({
data: [
{ temperature: 14.2, sales: 215 },
{ temperature: 16.4, sales: 325 },
{ temperature: 11.9, sales: 185 },
{ temperature: 15.2, sales: 332 },
{ temperature: 18.5, sales: 406 },
{ temperature: 22.1, sales: 522 },
{ temperature: 19.4, sales: 412 },
{ temperature: 25.1, sales: 614 },
{ temperature: 23.4, sales: 544 },
{ temperature: 18.1, sales: 421 },
{ temperature: 22.6, sales: 445 },
{ temperature: 17.2, sales: 408 },
],
series: [{ name: "sales", color: "teal.solid" }],
})
const trendLine = useMemo(() => getTrendLine(chart.data), [chart.data])
return (
<Chart.Root maxH="sm" chart={chart}>
<ScatterChart margin={{ top: 20, right: 30, bottom: 5, left: 0 }}>
<XAxis
type="number"
dataKey={chart.key("temperature")}
stroke={chart.color("border")}
domain={[10, "dataMax + 3"]}
/>
<YAxis
type="number"
dataKey={chart.key("sales")}
stroke={chart.color("border")}
/>
<Scatter
isAnimationActive={false}
line={{ stroke: chart.color("red.solid") }}
data={trendLine}
stroke="none"
strokeWidth={2}
shape={() => <Fragment />}
/>
{chart.series.map((series, index) => (
<Scatter
name={series.label?.toString()}
key={index}
data={chart.data}
fill={chart.color(series.color)}
isAnimationActive={false}
/>
))}
</ScatterChart>
</Chart.Root>
)
}
interface Item {
temperature: number
sales: number
}
function getTrendLine(data: Item[]): [Item, Item] {
// Calculate means
const meanX =
data.reduce((sum, item) => sum + item.temperature, 0) / data.length
const meanY = data.reduce((sum, item) => sum + item.sales, 0) / data.length
// Calculate slope using least squares method
const numerator = data.reduce((sum, item) => {
return sum + (item.temperature - meanX) * (item.sales - meanY)
}, 0)
const denominator = data.reduce((sum, item) => {
return sum + Math.pow(item.temperature - meanX, 2)
}, 0)
const slope = numerator / denominator
const intercept = meanY - slope * meanX
// Get min and max x values to draw line endpoints
const minX = Math.min(...data.map((item) => item.temperature))
const maxX = Math.max(...data.map((item) => item.temperature))
// Return two points that define the trend line
return [
{ temperature: minX, sales: slope * minX + intercept },
{ temperature: maxX, sales: slope * maxX + intercept },
]
}
连接点
要在点之间绘制线条,请将 line
prop 传递给 Scatter
组件。
<Scatter line={{ stroke: "red" }} />
"use client"
import { Chart, useChart } from "@chakra-ui/charts"
import { Scatter, ScatterChart, XAxis, YAxis } from "recharts"
const Demo = () => {
const chart = useChart({
data: [
{ x: 40, y: 200 },
{ x: 120, y: 100 },
{ x: 170, y: 300 },
{ x: 140, y: 250 },
{ x: 150, y: 400 },
{ x: 110, y: 280 },
],
series: [{ label: "Group 1", color: "teal.solid" }],
})
return (
<Chart.Root maxH="sm" chart={chart}>
<ScatterChart margin={{ top: 20, right: 30, bottom: 5, left: 0 }}>
<XAxis
type="number"
dataKey={chart.key("x")}
stroke={chart.color("border")}
/>
<YAxis
type="number"
dataKey={chart.key("y")}
stroke={chart.color("border")}
/>
{chart.series.map((series, index) => (
<Scatter
line={{ stroke: chart.color("border"), strokeWidth: 2 }}
name={series.label?.toString()}
key={index}
data={chart.data}
fill={chart.color(series.color)}
isAnimationActive={false}
/>
))}
</ScatterChart>
</Chart.Root>
)
}