From a8fa04c50f1d66c13da302bad919acff7005bb5f Mon Sep 17 00:00:00 2001 From: diysimon Date: Mon, 30 Mar 2026 19:04:19 +0800 Subject: [PATCH 1/2] fix(candlestick): support cursor option close #21551 --- src/chart/candlestick/CandlestickSeries.ts | 1 + src/chart/candlestick/CandlestickView.ts | 6 + test/candlestick-cursor.html | 272 +++++++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 test/candlestick-cursor.html diff --git a/src/chart/candlestick/CandlestickSeries.ts b/src/chart/candlestick/CandlestickSeries.ts index 55938e3b48..8bcca4d839 100644 --- a/src/chart/candlestick/CandlestickSeries.ts +++ b/src/chart/candlestick/CandlestickSeries.ts @@ -52,6 +52,7 @@ export interface CandlestickStateOption { } export interface CandlestickDataItemOption extends CandlestickStateOption, StatesOptionMixin { + cursor?: string value: CandlestickDataValue } diff --git a/src/chart/candlestick/CandlestickView.ts b/src/chart/candlestick/CandlestickView.ts index 706cae6fcc..64487cdd12 100644 --- a/src/chart/candlestick/CandlestickView.ts +++ b/src/chart/candlestick/CandlestickView.ts @@ -301,6 +301,9 @@ function setBoxCommon(el: NormalBoxPath, data: SeriesData, dataIndex: number, is el.useStyle(data.getItemVisual(dataIndex, 'style')); el.style.strokeNoScale = true; + const cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && el.attr('cursor', cursorStyle); + el.__simpleBox = isSimpleBox; setStatesStylesFromModel(el, itemModel); @@ -429,6 +432,9 @@ function setLargeStyle(sign: number, el: LargeBoxPath, seriesModel: CandlestickS el.useStyle(itemStyle); el.style.fill = null; el.style.stroke = borderColor; + + const cursorStyle = seriesModel.get('cursor'); + cursorStyle && el.attr('cursor', cursorStyle); } diff --git a/test/candlestick-cursor.html b/test/candlestick-cursor.html new file mode 100644 index 0000000000..47abe655b2 --- /dev/null +++ b/test/candlestick-cursor.html @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + +
+
+ + + + From db24e13e71798bfdf8f8aa7f334699e87545ae58 Mon Sep 17 00:00:00 2001 From: 100pah Date: Sat, 11 Apr 2026 02:09:01 +0800 Subject: [PATCH 2/2] feature: dataZoom 'inside' supports to set cursorGrab and cursorGrabbing. --- src/component/dataZoom/InsideZoomModel.ts | 6 +++++ src/component/dataZoom/roams.ts | 11 ++++++++- src/component/helper/RoamController.ts | 12 ++++++++-- test/candlestick-cursor.html | 29 ++++++++++++++++++++++- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/component/dataZoom/InsideZoomModel.ts b/src/component/dataZoom/InsideZoomModel.ts index ad417afc87..639470cb37 100644 --- a/src/component/dataZoom/InsideZoomModel.ts +++ b/src/component/dataZoom/InsideZoomModel.ts @@ -40,6 +40,12 @@ export interface InsideDataZoomOption extends DataZoomOption { preventDefaultMouseMove?: boolean + /** + * Mouse cursor styles on states "can grab" and "grabbing". + */ + cursorGrab?: string + cursorGrabbing?: string + /** * Inside dataZoom don't support textStyle */ diff --git a/src/component/dataZoom/roams.ts b/src/component/dataZoom/roams.ts index 38800b8c35..8b47764705 100644 --- a/src/component/dataZoom/roams.ts +++ b/src/component/dataZoom/roams.ts @@ -29,7 +29,7 @@ import { makeInner } from '../../util/model'; import { Dictionary, RoamOptionMixin, ZRElementEvent } from '../../util/types'; import ExtensionAPI from '../../core/ExtensionAPI'; import InsideZoomModel from './InsideZoomModel'; -import { each, curry, Curry1, HashMap, createHashMap } from 'zrender/src/core/util'; +import { each, curry, Curry1, HashMap, createHashMap, retrieve2 } from 'zrender/src/core/util'; import { DataZoomPayloadBatchItem, collectReferCoordSysModelInfo, DataZoomCoordSysMainType, DataZoomReferCoordSysInfo @@ -198,6 +198,8 @@ function mergeControllerParams( 'type_undefined': -1 }; let preventDefaultMouseMove = true; + let cursorGrab: RoamOption['cursorGrab']; + let cursorGrabbing: RoamOption['cursorGrabbing']; dataZoomInfoMap.each(function (dataZoomInfo) { const dataZoomModel = dataZoomInfo.model; @@ -214,6 +216,11 @@ function mergeControllerParams( // users may be confused why it does not work when multiple insideZooms exist. preventDefaultMouseMove = preventDefaultMouseMove && dataZoomModel.get('preventDefaultMouseMove', true); + + // Intuitively, use the last declared setting in ec option when this axis is covered + // by multiple `dataZoom`s. + cursorGrab = retrieve2(dataZoomModel.get('cursorGrab', true), cursorGrab); + cursorGrabbing = retrieve2(dataZoomModel.get('cursorGrabbing', true), cursorGrabbing); }); return { @@ -234,6 +241,8 @@ function mergeControllerParams( roamTrigger: null, isInSelf: coordSysRecord.containsPoint }, + cursorGrab, + cursorGrabbing, } }; } diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts index 4c057412e5..725aed2882 100644 --- a/src/component/helper/RoamController.ts +++ b/src/component/helper/RoamController.ts @@ -53,6 +53,12 @@ export interface RoamOption { * If fixed the page when pan */ preventDefaultMouseMove?: boolean + + /** + * Cursor styles + */ + cursorGrab?: string // 'grab' by default. + cursorGrabbing?: string // 'grabbing' by default. } type RoamSetting = Omit, 'zInfo'> & { zInfoParsed: { @@ -174,6 +180,8 @@ class RoamController extends Eventful { preventDefaultMouseMove: true, zInfoParsed, triggerInfo, + cursorGrab: 'grab', // CSS cursor 'grab' + cursorGrabbing: 'grabbing', // CSS cursor 'grabbing' }); if (controlType == null) { @@ -257,7 +265,7 @@ class RoamController extends Eventful { if (!target && this._checkPointer(e, x, y)) { // To indicate users that this area is draggable, otherwise users probably cannot kwown // that when hovering out of the shape but still inside the bounding rect. - return 'grab'; + return this._opt.cursorGrab; } if (forReverse) { return target && (target as Displayable).cursor || 'default'; @@ -318,7 +326,7 @@ class RoamController extends Eventful { return; } - zr.setCursorStyle('grabbing'); + zr.setCursorStyle(this._opt.cursorGrabbing); const oldX = this._x; const oldY = this._y; diff --git a/test/candlestick-cursor.html b/test/candlestick-cursor.html index 47abe655b2..92069c9cad 100644 --- a/test/candlestick-cursor.html +++ b/test/candlestick-cursor.html @@ -163,6 +163,7 @@ }, dataZoom: [ { + id: 'inside1', type: 'inside', start: 50, end: 100 @@ -230,7 +231,33 @@ } } ] - } + }, + inputsStyle: 'compact', + inputs: [{ + type: 'select', + text: 'insideZoom.cursorGrab:', + values: [undefined, 'crosshair'], + onchange() { + normalChart.setOption({ + dataZoom: { + id: 'inside1', + cursorGrab: this.value + }, + }); + } + }, { + type: 'select', + text: 'insideZoom.cursorGrabbing:', + values: [undefined, 'crosshair'], + onchange() { + normalChart.setOption({ + dataZoom: { + id: 'inside1', + cursorGrabbing: this.value + }, + }); + } + }] }); installCursorLog(normalChart, 'normal');