Skip to content

Commit dc99f76

Browse files
committed
feat(plugin): add shouldRedrawOnBusUpdate callback option to focusSeries
1 parent 2e9bc52 commit dc99f76

File tree

1 file changed

+31
-6
lines changed

1 file changed

+31
-6
lines changed

src/plugins/focusSeries.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ export type FocusSeriesPluginMessageBus = {
9494
/**
9595
* Configuration options for the focus series plugin.
9696
*/
97-
export type FocusSeriesPluginOptions = {
97+
export type FocusSeriesPluginOptions<
98+
T extends CursorPluginMessageBus & FocusSeriesPluginMessageBus,
99+
> = {
98100
/**
99101
* The vertical distance in pixels required to focus a series.
100102
* If the cursor's Y position is within this threshold of a Y value, that series is considered focused.
@@ -124,6 +126,25 @@ export type FocusSeriesPluginOptions = {
124126
* @default false
125127
*/
126128
readonly rebuildPaths?: boolean;
129+
130+
/**
131+
*
132+
* For charts that are configured with this plugin, this callback is used to determine if the chart
133+
* should redraw when the plugin bus updates. It is an additional condition to the base condition `cursor?.sourceId !== u.root.id`
134+
* which is always applied first to prevent the source chart from redrawing twice.
135+
*
136+
* This can be used to add filtering logic, such as only reacting to specific source charts.
137+
*
138+
* @default undefined (always redraw for non-source charts)
139+
*/
140+
readonly shouldRedrawOnBusUpdate?: (params: {
141+
/** The current chart instance (the one evaluating whether to redraw) */
142+
readonly u: uPlot;
143+
/** Current cursor state from the bus (may be from another chart) */
144+
readonly cursor: T["cursor"];
145+
/** Current focus series state from the bus */
146+
readonly focusSeries: T["focusSeries"];
147+
}) => boolean;
127148
};
128149

129150
type SeriesFocusRedrawOptions = {
@@ -144,7 +165,7 @@ const seriesFocusRedraw = (u: uPlot, options: SeriesFocusRedrawOptions = {}) =>
144165
for (let i = 1; i < u.series.length; i++) {
145166
const s = u.series[i]!;
146167

147-
if (!focusTargets || !focusTargets.length) {
168+
if (!focusTargets?.length) {
148169
s.alpha = 1; // restore alpha of all series
149170
continue;
150171
}
@@ -197,7 +218,7 @@ const seriesFocusRedraw = (u: uPlot, options: SeriesFocusRedrawOptions = {}) =>
197218
* @returns A plugin factory function that creates the focus series plugin instance
198219
*/
199220
export const focusSeries = (
200-
options: FocusSeriesPluginOptions = {},
221+
options: FocusSeriesPluginOptions<CursorPluginMessageBus & FocusSeriesPluginMessageBus> = {},
201222
): UplotPluginFactory<CursorPluginMessageBus & FocusSeriesPluginMessageBus> => {
202223
return ({ bus }) => {
203224
if (!bus) {
@@ -247,14 +268,18 @@ export const focusSeries = (
247268
dispose = createRoot((dispose) => {
248269
createEffect(() => {
249270
const cursor = bus.data.cursor;
250-
const focus = bus.data.focusSeries;
271+
const focusSeries = bus.data.focusSeries;
272+
273+
const isNotSourceChart = cursor?.sourceId !== u.root.id;
274+
const userRedrawCondition =
275+
options.shouldRedrawOnBusUpdate?.({ u, cursor, focusSeries }) ?? true;
251276

252-
if (cursor?.sourceId !== u.root.id) {
277+
if (isNotSourceChart && userRedrawCondition) {
253278
seriesFocusRedraw(u, {
254279
unfocusedAlpha,
255280
focusedAlpha,
256281
rebuildPaths,
257-
focusTargets: focus?.targets,
282+
focusTargets: focusSeries?.targets,
258283
});
259284
}
260285
});

0 commit comments

Comments
 (0)