When using Material UI SparkLineChart component, showing all highlights without the user needing to hover over the information can be complicated, especially because there are no properties that can do this for us
We are going to create a custom component that creates a circle, and we are going to show this component for every piece of data passed to the chart. You can also add conditionals or filters to this new component. That way, you can render the highlights conditionally. For example, we only show highlights if the value is more than 100. Take into consideration, for this example, we also show dates and data on the tooltips of the highlights. You can remove dateData and xAxis if you don't need them
import { SparkLineChart } from "@mui/x-charts";
import {
unstable_useLineSeries,
useXScale,
useYScale,
} from "@mui/x-charts/hooks";
import React from "react";
const Highlights = ({
data,
dataIndex,
color,
}: {
data: number;
dataIndex: number;
color: string;
}) => {
if (!data) {
return null;
}
const xScale = useXScale();
const yScale = useYScale();
const lineSeries = unstable_useLineSeries();
if (lineSeries) {
const yData = lineSeries.series[lineSeries.seriesOrder[0]].data;
const xData = xScale.domain();
const xValue: any = xData[dataIndex];
const yValue: any = yData[dataIndex];
/**
* You can add logic to filter which highlights to show
* for example only show if value received is bigger than
* 200
*/
if (yValue > 200) {
return (
<circle
cx={xScale(xValue)}
cy={yScale(yValue)}
// r controls the size of the dots
r={3.6}
// Stroke and fill control de color of the highlights
stroke={color}
fill={color}
/>
);
}
return null;
} else {
return null;
}
};
const generateTooltip = (value: number | null): string => {
// Check if value is null
if (!value) {
return "Data not available";
}
let tooltip: string = value.toString();
// Format tooltip with specific format
return tooltip;
};
// Generate unit name for tooltip:
const generateDateTooltip = (value: any): string => {
// Check if value is null
if (!value) {
return "Data not available";
}
const tooltip: string = `${value.toISOString().slice(0, 10)}`;
return tooltip;
};
export const ChartHighlights = ({
data,
dateData,
}: {
data: number[];
dateData: Date[];
}) => {
/**
* You can remove xAsis property and dateData if you dont want
* to show the date on the tooltip of the highlights, be sure data and
* dates have the same length
*/
return data.length === dateData.length ? (
<SparkLineChart
showTooltip
showHighlight
area
valueFormatter={(value) => generateTooltip(value)}
data={data}
xAxis={{
data: dateData,
valueFormatter: (value) => generateDateTooltip(value),
fill: "#000000",
stroke: "#000000",
}}
>
<>
{data.map((singleData, index) => (
<Highlights
data={singleData}
dataIndex={index}
// Values must have an unique key
key={`${data[index]}-${dateData[index]}`}
// Color used on highlights
color="#000000"
/>
// You can pass more components if you need here
))}
</>
</SparkLineChart>
) : null;
};
Example of how to use this component
<div style={{ width: "100%", height: "15rem" }}>
<ChartHighlights
data={[450, 293, 328, 100, 114, 275, 215, 300, 218, 400]}
dateData={[
new Date("2024-08-01T00:00:00.643Z"),
new Date("2024-08-02T00:00:00.643Z"),
new Date("2024-08-03T00:00:00.643Z"),
new Date("2024-08-04T00:00:00.643Z"),
new Date("2024-08-05T00:00:00.643Z"),
new Date("2024-08-06T00:00:00.643Z"),
new Date("2024-08-07T00:00:00.643Z"),
new Date("2024-08-08T00:00:00.643Z"),
new Date("2024-08-09T00:00:00.643Z"),
new Date("2024-08-10T00:00:00.643Z"),
]}
/>
</div>
You can find a CodeSandbox with the implementation on the following link https://codesandbox.io/p/sandbox/hidden-leaf-qrwpnt