pissang commented on a change in pull request #13416:
URL: 
https://github.com/apache/incubator-echarts/pull/13416#discussion_r506262241



##########
File path: src/chart/gauge/GaugeView.ts
##########
@@ -312,165 +324,296 @@ class GaugeView extends ChartView {
         posInfo: PosInfo,
         startAngle: number,
         endAngle: number,
-        clockwise: boolean
+        clockwise: boolean,
+        axisLineWidth: number
     ) {
 
         const group = this.group;
         const oldData = this._data;
+        const oldProgressData = this._progressData;
+        const progressList = [] as graphic.Path[];
 
-        if (!seriesModel.get(['pointer', 'show'])) {
-            // Remove old element
-            oldData && oldData.eachItemGraphicEl(function (el) {
-                group.remove(el);
-            });
-            return;
-        }
-
-        const valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
-        const angleExtent = [startAngle, endAngle];
+        const showPointer = seriesModel.get(['pointer', 'show']);
+        const progressModel = seriesModel.getModel('progress');
+        const showProgress = progressModel.get('show');
 
         const data = seriesModel.getData();
         const valueDim = data.mapDimension('value');
+        const minVal = +seriesModel.get('min');
+        const maxVal = +seriesModel.get('max');
+        const valueExtent = [minVal, maxVal];
+        const angleExtent = [startAngle, endAngle];
 
-        data.diff(oldData)
-            .add(function (idx) {
-                const pointer = new PointerPath({
+        function createPointer(idx: number, angle: number) {
+            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
+            const pointerModel = itemModel.getModel('pointer');
+            const pointerWidth = parsePercent(pointerModel.get('width'), 
posInfo.r);
+            const pointerLength = parsePercent(pointerModel.get('length'), 
posInfo.r);
+            
+            const pointerStr = seriesModel.get(['pointer', 'icon']);
+            const pointerOffset = pointerModel.get('offsetCenter');
+            const pointerKeepAspect = pointerModel.get('keepAspect');
+            let pointer;
+            if (pointerStr.indexOf('path://') === 0) {
+                pointer = createSymbol(
+                    pointerStr,
+                    parsePercent(pointerOffset[0], posInfo.r) - pointerWidth / 
2,
+                    parsePercent(pointerOffset[1], posInfo.r) - pointerLength,
+                    pointerWidth,
+                    pointerLength,
+                    null,
+                    pointerKeepAspect
+                ) as graphic.Path;
+            }
+            else {
+                pointer = new PointerPath({
                     shape: {
-                        angle: startAngle
+                        angle: -Math.PI / 2,
+                        width: parsePercent(pointerModel.get('width'), 
posInfo.r),
+                        r: parsePercent(pointerModel.get('length'), posInfo.r)
                     }
-                });
+                })
+            }
+            pointer.rotation = -(angle + Math.PI / 2);
+            pointer.x = posInfo.cx;
+            pointer.y = posInfo.cy;
+            return pointer;
+        }
 
-                graphic.initProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, idx) as number, 
valueExtent, angleExtent, true)
-                    }
-                }, seriesModel);
+        function createProgress(idx: number, endAngle: number) {
+            const roundCap = progressModel.get('roundCap');
+            const ProgressPath = roundCap ? Sausage : graphic.Sector;
 
-                group.add(pointer);
-                data.setItemGraphicEl(idx, pointer);
-            })
-            .update(function (newIdx, oldIdx) {
-                const pointer = oldData.getItemGraphicEl(oldIdx) as 
PointerPath;
+            const isOverlap = progressModel.get('overlap');
+            const progressWidth = isOverlap ? progressModel.get('width') : 
axisLineWidth / data.count();
+            const r0 = isOverlap ? posInfo.r - progressWidth : posInfo.r - 
(idx + 1) * progressWidth;
+            const r = isOverlap ? posInfo.r : posInfo.r - idx * progressWidth;
+            const progressSilent = progressModel.get('silent');
+            const progress = new ProgressPath({
+                shape: {
+                    startAngle: startAngle,
+                    endAngle: endAngle,
+                    cx: posInfo.cx,
+                    cy: posInfo.cy,
+                    clockwise: clockwise,
+                    r0: r0,
+                    r: r
+                },
+                // 是否相应鼠标事件
+                silent: progressSilent
+            });
+            isOverlap && (progress.z2 = maxVal - (data.get(valueDim, idx) as 
number) % maxVal);
+            return progress;
+        }
 
-                graphic.updateProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, newIdx) as number, 
valueExtent, angleExtent, true)
+        if (showProgress || showPointer) {
+            data.diff(oldData)
+                .add(function (idx) {
+                    if (showPointer) {
+                        const pointer = createPointer(idx, startAngle);
+                        graphic.initProps(pointer, {
+                            rotation: -(linearMap(data.get(valueDim, idx) as 
number, valueExtent, angleExtent, true) + Math.PI / 2)
+                        }, seriesModel);
+                        group.add(pointer);
+                        data.setItemGraphicEl(idx, pointer);
                     }
-                }, seriesModel);
-
-                group.add(pointer);
-                data.setItemGraphicEl(newIdx, pointer);
-            })
-            .remove(function (idx) {
-                const pointer = oldData.getItemGraphicEl(idx);
-                group.remove(pointer);
-            })
-            .execute();
-
-        data.eachItemGraphicEl(function (pointer: PointerPath, idx) {
-            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
-            const pointerModel = itemModel.getModel('pointer');
-            const emphasisModel = itemModel.getModel('emphasis');
-
-            pointer.setShape({
-                x: posInfo.cx,
-                y: posInfo.cy,
-                width: parsePercent(
-                    pointerModel.get('width'), posInfo.r
-                ),
-                r: parsePercent(pointerModel.get('length'), posInfo.r)
-            });
 
-            pointer.useStyle(itemModel.getModel('itemStyle').getItemStyle());
+                    if (showProgress) {
+                        const progress = createProgress(idx, startAngle) as 
graphic.Sector;
+                        const isClip = progressModel.get('clip');
+                        graphic.initProps(progress, {
+                            shape: {
+                                endAngle: linearMap(data.get(valueDim, idx) as 
number, valueExtent, angleExtent, isClip)
+                            }
+                        }, seriesModel);
+                        group.add(progress);
+                        progressList[idx] = progress;
+                    }
+                })
+                .update(function (newIdx, oldIdx) {
+                    if (showPointer) {
+                        const previousPointer = 
oldData.getItemGraphicEl(oldIdx) as PointerPath;
+                        const previousRotate = previousPointer.rotation;
+                        group.remove(previousPointer);
+                        const pointer = createPointer(newIdx, previousRotate);
+                        pointer.rotation = previousRotate;
+                        graphic.updateProps(pointer, {
+                            rotation: -(linearMap(data.get(valueDim, newIdx) 
as number, valueExtent, angleExtent, true) + Math.PI / 2)
+                        }, seriesModel);
+                        group.add(pointer);
+                        data.setItemGraphicEl(newIdx, pointer);
+                    }
 
-            if (pointer.style.fill === 'auto') {
-                pointer.setStyle('fill', getColor(
-                    linearMap(data.get(valueDim, idx) as number, valueExtent, 
[0, 1], true)
-                ));
-            }
+                    if (showProgress) {
+                        const previousProgress = oldProgressData[oldIdx];
+                        const previousEndAngle = 
previousProgress.shape.endAngle;

Review comment:
       Same issues with above.

##########
File path: src/chart/gauge/GaugeSeries.ts
##########
@@ -40,14 +40,54 @@ interface LabelFormatter {
 }
 
 interface PointerOption {
+    icon?: string
     show?: boolean
+    keepAspect?: boolean
+    itemStyle?: ItemStyleOption
     /**
      * Can be percent
      */
+    offsetCenter?: (number | string)[]
     length?: number | string
     width?: number
 }
 
+interface AnchorOption {
+    show?: boolean
+    showAbove?: boolean
+    anchorSize?: number
+    icon?: string

Review comment:
       It can be `size` instead of `anchorSize` here. Since it's already in the 
`anchor` option.

##########
File path: src/chart/gauge/GaugeView.ts
##########
@@ -312,165 +324,296 @@ class GaugeView extends ChartView {
         posInfo: PosInfo,
         startAngle: number,
         endAngle: number,
-        clockwise: boolean
+        clockwise: boolean,
+        axisLineWidth: number
     ) {
 
         const group = this.group;
         const oldData = this._data;
+        const oldProgressData = this._progressData;
+        const progressList = [] as graphic.Path[];
 
-        if (!seriesModel.get(['pointer', 'show'])) {
-            // Remove old element
-            oldData && oldData.eachItemGraphicEl(function (el) {
-                group.remove(el);
-            });
-            return;
-        }
-
-        const valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
-        const angleExtent = [startAngle, endAngle];
+        const showPointer = seriesModel.get(['pointer', 'show']);
+        const progressModel = seriesModel.getModel('progress');
+        const showProgress = progressModel.get('show');
 
         const data = seriesModel.getData();
         const valueDim = data.mapDimension('value');
+        const minVal = +seriesModel.get('min');
+        const maxVal = +seriesModel.get('max');
+        const valueExtent = [minVal, maxVal];
+        const angleExtent = [startAngle, endAngle];
 
-        data.diff(oldData)
-            .add(function (idx) {
-                const pointer = new PointerPath({
+        function createPointer(idx: number, angle: number) {
+            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
+            const pointerModel = itemModel.getModel('pointer');
+            const pointerWidth = parsePercent(pointerModel.get('width'), 
posInfo.r);
+            const pointerLength = parsePercent(pointerModel.get('length'), 
posInfo.r);
+            
+            const pointerStr = seriesModel.get(['pointer', 'icon']);
+            const pointerOffset = pointerModel.get('offsetCenter');
+            const pointerKeepAspect = pointerModel.get('keepAspect');
+            let pointer;
+            if (pointerStr.indexOf('path://') === 0) {
+                pointer = createSymbol(

Review comment:
       pointerStr can starts with 'image://'. Or being `rect`, `triangle`.
   
   I think set `icon: null` can use the default `PointerPath` icon. Otherwise 
use `createSymbol`.

##########
File path: src/chart/gauge/GaugeView.ts
##########
@@ -312,165 +324,296 @@ class GaugeView extends ChartView {
         posInfo: PosInfo,
         startAngle: number,
         endAngle: number,
-        clockwise: boolean
+        clockwise: boolean,
+        axisLineWidth: number
     ) {
 
         const group = this.group;
         const oldData = this._data;
+        const oldProgressData = this._progressData;
+        const progressList = [] as graphic.Path[];
 
-        if (!seriesModel.get(['pointer', 'show'])) {
-            // Remove old element
-            oldData && oldData.eachItemGraphicEl(function (el) {
-                group.remove(el);
-            });
-            return;
-        }
-
-        const valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
-        const angleExtent = [startAngle, endAngle];
+        const showPointer = seriesModel.get(['pointer', 'show']);
+        const progressModel = seriesModel.getModel('progress');
+        const showProgress = progressModel.get('show');
 
         const data = seriesModel.getData();
         const valueDim = data.mapDimension('value');
+        const minVal = +seriesModel.get('min');
+        const maxVal = +seriesModel.get('max');
+        const valueExtent = [minVal, maxVal];
+        const angleExtent = [startAngle, endAngle];
 
-        data.diff(oldData)
-            .add(function (idx) {
-                const pointer = new PointerPath({
+        function createPointer(idx: number, angle: number) {
+            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
+            const pointerModel = itemModel.getModel('pointer');
+            const pointerWidth = parsePercent(pointerModel.get('width'), 
posInfo.r);
+            const pointerLength = parsePercent(pointerModel.get('length'), 
posInfo.r);
+            
+            const pointerStr = seriesModel.get(['pointer', 'icon']);
+            const pointerOffset = pointerModel.get('offsetCenter');
+            const pointerKeepAspect = pointerModel.get('keepAspect');
+            let pointer;
+            if (pointerStr.indexOf('path://') === 0) {
+                pointer = createSymbol(
+                    pointerStr,
+                    parsePercent(pointerOffset[0], posInfo.r) - pointerWidth / 
2,
+                    parsePercent(pointerOffset[1], posInfo.r) - pointerLength,
+                    pointerWidth,
+                    pointerLength,
+                    null,
+                    pointerKeepAspect
+                ) as graphic.Path;
+            }
+            else {
+                pointer = new PointerPath({
                     shape: {
-                        angle: startAngle
+                        angle: -Math.PI / 2,
+                        width: parsePercent(pointerModel.get('width'), 
posInfo.r),
+                        r: parsePercent(pointerModel.get('length'), posInfo.r)
                     }
-                });
+                })
+            }
+            pointer.rotation = -(angle + Math.PI / 2);
+            pointer.x = posInfo.cx;
+            pointer.y = posInfo.cy;
+            return pointer;
+        }
 
-                graphic.initProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, idx) as number, 
valueExtent, angleExtent, true)
-                    }
-                }, seriesModel);
+        function createProgress(idx: number, endAngle: number) {
+            const roundCap = progressModel.get('roundCap');
+            const ProgressPath = roundCap ? Sausage : graphic.Sector;
 
-                group.add(pointer);
-                data.setItemGraphicEl(idx, pointer);
-            })
-            .update(function (newIdx, oldIdx) {
-                const pointer = oldData.getItemGraphicEl(oldIdx) as 
PointerPath;
+            const isOverlap = progressModel.get('overlap');
+            const progressWidth = isOverlap ? progressModel.get('width') : 
axisLineWidth / data.count();
+            const r0 = isOverlap ? posInfo.r - progressWidth : posInfo.r - 
(idx + 1) * progressWidth;
+            const r = isOverlap ? posInfo.r : posInfo.r - idx * progressWidth;
+            const progressSilent = progressModel.get('silent');
+            const progress = new ProgressPath({
+                shape: {
+                    startAngle: startAngle,
+                    endAngle: endAngle,
+                    cx: posInfo.cx,
+                    cy: posInfo.cy,
+                    clockwise: clockwise,
+                    r0: r0,
+                    r: r
+                },
+                // 是否相应鼠标事件
+                silent: progressSilent
+            });
+            isOverlap && (progress.z2 = maxVal - (data.get(valueDim, idx) as 
number) % maxVal);
+            return progress;
+        }
 
-                graphic.updateProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, newIdx) as number, 
valueExtent, angleExtent, true)
+        if (showProgress || showPointer) {
+            data.diff(oldData)
+                .add(function (idx) {
+                    if (showPointer) {
+                        const pointer = createPointer(idx, startAngle);
+                        graphic.initProps(pointer, {
+                            rotation: -(linearMap(data.get(valueDim, idx) as 
number, valueExtent, angleExtent, true) + Math.PI / 2)
+                        }, seriesModel);
+                        group.add(pointer);
+                        data.setItemGraphicEl(idx, pointer);
                     }
-                }, seriesModel);
-
-                group.add(pointer);
-                data.setItemGraphicEl(newIdx, pointer);
-            })
-            .remove(function (idx) {
-                const pointer = oldData.getItemGraphicEl(idx);
-                group.remove(pointer);
-            })
-            .execute();
-
-        data.eachItemGraphicEl(function (pointer: PointerPath, idx) {
-            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
-            const pointerModel = itemModel.getModel('pointer');
-            const emphasisModel = itemModel.getModel('emphasis');
-
-            pointer.setShape({
-                x: posInfo.cx,
-                y: posInfo.cy,
-                width: parsePercent(
-                    pointerModel.get('width'), posInfo.r
-                ),
-                r: parsePercent(pointerModel.get('length'), posInfo.r)
-            });
 
-            pointer.useStyle(itemModel.getModel('itemStyle').getItemStyle());
+                    if (showProgress) {
+                        const progress = createProgress(idx, startAngle) as 
graphic.Sector;
+                        const isClip = progressModel.get('clip');
+                        graphic.initProps(progress, {
+                            shape: {
+                                endAngle: linearMap(data.get(valueDim, idx) as 
number, valueExtent, angleExtent, isClip)
+                            }
+                        }, seriesModel);
+                        group.add(progress);
+                        progressList[idx] = progress;
+                    }
+                })
+                .update(function (newIdx, oldIdx) {
+                    if (showPointer) {
+                        const previousPointer = 
oldData.getItemGraphicEl(oldIdx) as PointerPath;
+                        const previousRotate = previousPointer.rotation;
+                        group.remove(previousPointer);
+                        const pointer = createPointer(newIdx, previousRotate);
+                        pointer.rotation = previousRotate;
+                        graphic.updateProps(pointer, {
+                            rotation: -(linearMap(data.get(valueDim, newIdx) 
as number, valueExtent, angleExtent, true) + Math.PI / 2)
+                        }, seriesModel);
+                        group.add(pointer);
+                        data.setItemGraphicEl(newIdx, pointer);
+                    }
 
-            if (pointer.style.fill === 'auto') {
-                pointer.setStyle('fill', getColor(
-                    linearMap(data.get(valueDim, idx) as number, valueExtent, 
[0, 1], true)
-                ));
-            }
+                    if (showProgress) {
+                        const previousProgress = oldProgressData[oldIdx];
+                        const previousEndAngle = 
previousProgress.shape.endAngle;
+                        group.remove(previousProgress);
+                        const progress = createProgress(newIdx, 
previousEndAngle) as graphic.Sector;
+                        const isClip = progressModel.get('clip');
+                        graphic.updateProps(progress, {
+                            shape: {
+                                endAngle: linearMap(data.get(valueDim, newIdx) 
as number, valueExtent, angleExtent, isClip)
+                            }
+                        }, seriesModel);
+                        group.add(progress);
+                        progressList[newIdx] = progress;
+                    }
+                })
+                .remove(function (idx) {
+                    if (showPointer) {
+                        const pointer = oldData.getItemGraphicEl(idx);
+                        group.remove(pointer);
+                    }
 
+                    if (showProgress) {
+                        const progress = oldProgressData[idx];
+                        group.remove(progress);
+                    }
+                })
+                .execute();
+
+            data.each(function (idx) {
+                const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
+                const emphasisModel = itemModel.getModel('emphasis');
+                if (showPointer) {
+                    const pointer = data.getItemGraphicEl(idx) as PointerPath;
+                    pointer.useStyle(data.getItemVisual(idx, 'style'));
+                    pointer.setStyle(itemModel.getModel(['pointer', 
'itemStyle']).getItemStyle());
+                    if (pointer.style.fill === 'auto') {
+                        pointer.setStyle('fill', getColor(
+                            linearMap(data.get(valueDim, idx) as number, 
valueExtent, [0, 1], true)
+                        ));
+                    }
+    
+                    (pointer as ECElement).z2EmphasisLift = 0
+                    setStatesStylesFromModel(pointer, itemModel);
+                    enableHoverEmphasis(pointer, emphasisModel.get('focus'), 
emphasisModel.get('blurScope'));
+                }
 
-            setStatesStylesFromModel(pointer, itemModel);
-            enableHoverEmphasis(pointer, emphasisModel.get('focus'), 
emphasisModel.get('blurScope'));
-        });
+                if (showProgress) {
+                    const progress = progressList[idx];
+                    progress.useStyle(data.getItemVisual(idx, 'style'));
+                    progress.setStyle(itemModel.getModel(['progress', 
'itemStyle']).getItemStyle());
+                    setStatesStylesFromModel(progress, itemModel);
+                    enableHoverEmphasis(progress, emphasisModel.get('focus'), 
emphasisModel.get('blurScope'));
+                }
+            });
 
-        this._data = data;
+            this._data = data;
+            this._progressData = progressList;
+        }
+        else {
+            if (!showPointer) {

Review comment:
       I think there is no need to check `if (!showPointer)` here.  Since in 
this branch, `showPointer` and `showProgress` are all false.
   
   Also, there is a `removeAll` code above. All the elements have been removed 
already. Also same issue in the above `add` `update`, `remove` callback

##########
File path: src/chart/gauge/GaugeView.ts
##########
@@ -312,165 +324,296 @@ class GaugeView extends ChartView {
         posInfo: PosInfo,
         startAngle: number,
         endAngle: number,
-        clockwise: boolean
+        clockwise: boolean,
+        axisLineWidth: number
     ) {
 
         const group = this.group;
         const oldData = this._data;
+        const oldProgressData = this._progressData;
+        const progressList = [] as graphic.Path[];
 
-        if (!seriesModel.get(['pointer', 'show'])) {
-            // Remove old element
-            oldData && oldData.eachItemGraphicEl(function (el) {
-                group.remove(el);
-            });
-            return;
-        }
-
-        const valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
-        const angleExtent = [startAngle, endAngle];
+        const showPointer = seriesModel.get(['pointer', 'show']);
+        const progressModel = seriesModel.getModel('progress');
+        const showProgress = progressModel.get('show');
 
         const data = seriesModel.getData();
         const valueDim = data.mapDimension('value');
+        const minVal = +seriesModel.get('min');
+        const maxVal = +seriesModel.get('max');
+        const valueExtent = [minVal, maxVal];
+        const angleExtent = [startAngle, endAngle];
 
-        data.diff(oldData)
-            .add(function (idx) {
-                const pointer = new PointerPath({
+        function createPointer(idx: number, angle: number) {
+            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
+            const pointerModel = itemModel.getModel('pointer');
+            const pointerWidth = parsePercent(pointerModel.get('width'), 
posInfo.r);
+            const pointerLength = parsePercent(pointerModel.get('length'), 
posInfo.r);
+            
+            const pointerStr = seriesModel.get(['pointer', 'icon']);
+            const pointerOffset = pointerModel.get('offsetCenter');
+            const pointerKeepAspect = pointerModel.get('keepAspect');
+            let pointer;
+            if (pointerStr.indexOf('path://') === 0) {
+                pointer = createSymbol(
+                    pointerStr,
+                    parsePercent(pointerOffset[0], posInfo.r) - pointerWidth / 
2,
+                    parsePercent(pointerOffset[1], posInfo.r) - pointerLength,
+                    pointerWidth,
+                    pointerLength,
+                    null,
+                    pointerKeepAspect
+                ) as graphic.Path;
+            }
+            else {
+                pointer = new PointerPath({
                     shape: {
-                        angle: startAngle
+                        angle: -Math.PI / 2,
+                        width: parsePercent(pointerModel.get('width'), 
posInfo.r),
+                        r: parsePercent(pointerModel.get('length'), posInfo.r)
                     }
-                });
+                })
+            }
+            pointer.rotation = -(angle + Math.PI / 2);
+            pointer.x = posInfo.cx;
+            pointer.y = posInfo.cy;
+            return pointer;
+        }
 
-                graphic.initProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, idx) as number, 
valueExtent, angleExtent, true)
-                    }
-                }, seriesModel);
+        function createProgress(idx: number, endAngle: number) {
+            const roundCap = progressModel.get('roundCap');
+            const ProgressPath = roundCap ? Sausage : graphic.Sector;
 
-                group.add(pointer);
-                data.setItemGraphicEl(idx, pointer);
-            })
-            .update(function (newIdx, oldIdx) {
-                const pointer = oldData.getItemGraphicEl(oldIdx) as 
PointerPath;
+            const isOverlap = progressModel.get('overlap');
+            const progressWidth = isOverlap ? progressModel.get('width') : 
axisLineWidth / data.count();
+            const r0 = isOverlap ? posInfo.r - progressWidth : posInfo.r - 
(idx + 1) * progressWidth;
+            const r = isOverlap ? posInfo.r : posInfo.r - idx * progressWidth;
+            const progressSilent = progressModel.get('silent');
+            const progress = new ProgressPath({

Review comment:
       series already has a `silent` configuration. There is no need to add 
`silent` in the progress option.

##########
File path: src/chart/gauge/GaugeView.ts
##########
@@ -312,165 +324,296 @@ class GaugeView extends ChartView {
         posInfo: PosInfo,
         startAngle: number,
         endAngle: number,
-        clockwise: boolean
+        clockwise: boolean,
+        axisLineWidth: number
     ) {
 
         const group = this.group;
         const oldData = this._data;
+        const oldProgressData = this._progressData;
+        const progressList = [] as graphic.Path[];
 
-        if (!seriesModel.get(['pointer', 'show'])) {
-            // Remove old element
-            oldData && oldData.eachItemGraphicEl(function (el) {
-                group.remove(el);
-            });
-            return;
-        }
-
-        const valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];
-        const angleExtent = [startAngle, endAngle];
+        const showPointer = seriesModel.get(['pointer', 'show']);
+        const progressModel = seriesModel.getModel('progress');
+        const showProgress = progressModel.get('show');
 
         const data = seriesModel.getData();
         const valueDim = data.mapDimension('value');
+        const minVal = +seriesModel.get('min');
+        const maxVal = +seriesModel.get('max');
+        const valueExtent = [minVal, maxVal];
+        const angleExtent = [startAngle, endAngle];
 
-        data.diff(oldData)
-            .add(function (idx) {
-                const pointer = new PointerPath({
+        function createPointer(idx: number, angle: number) {
+            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
+            const pointerModel = itemModel.getModel('pointer');
+            const pointerWidth = parsePercent(pointerModel.get('width'), 
posInfo.r);
+            const pointerLength = parsePercent(pointerModel.get('length'), 
posInfo.r);
+            
+            const pointerStr = seriesModel.get(['pointer', 'icon']);
+            const pointerOffset = pointerModel.get('offsetCenter');
+            const pointerKeepAspect = pointerModel.get('keepAspect');
+            let pointer;
+            if (pointerStr.indexOf('path://') === 0) {
+                pointer = createSymbol(
+                    pointerStr,
+                    parsePercent(pointerOffset[0], posInfo.r) - pointerWidth / 
2,
+                    parsePercent(pointerOffset[1], posInfo.r) - pointerLength,
+                    pointerWidth,
+                    pointerLength,
+                    null,
+                    pointerKeepAspect
+                ) as graphic.Path;
+            }
+            else {
+                pointer = new PointerPath({
                     shape: {
-                        angle: startAngle
+                        angle: -Math.PI / 2,
+                        width: parsePercent(pointerModel.get('width'), 
posInfo.r),
+                        r: parsePercent(pointerModel.get('length'), posInfo.r)
                     }
-                });
+                })
+            }
+            pointer.rotation = -(angle + Math.PI / 2);
+            pointer.x = posInfo.cx;
+            pointer.y = posInfo.cy;
+            return pointer;
+        }
 
-                graphic.initProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, idx) as number, 
valueExtent, angleExtent, true)
-                    }
-                }, seriesModel);
+        function createProgress(idx: number, endAngle: number) {
+            const roundCap = progressModel.get('roundCap');
+            const ProgressPath = roundCap ? Sausage : graphic.Sector;
 
-                group.add(pointer);
-                data.setItemGraphicEl(idx, pointer);
-            })
-            .update(function (newIdx, oldIdx) {
-                const pointer = oldData.getItemGraphicEl(oldIdx) as 
PointerPath;
+            const isOverlap = progressModel.get('overlap');
+            const progressWidth = isOverlap ? progressModel.get('width') : 
axisLineWidth / data.count();
+            const r0 = isOverlap ? posInfo.r - progressWidth : posInfo.r - 
(idx + 1) * progressWidth;
+            const r = isOverlap ? posInfo.r : posInfo.r - idx * progressWidth;
+            const progressSilent = progressModel.get('silent');
+            const progress = new ProgressPath({
+                shape: {
+                    startAngle: startAngle,
+                    endAngle: endAngle,
+                    cx: posInfo.cx,
+                    cy: posInfo.cy,
+                    clockwise: clockwise,
+                    r0: r0,
+                    r: r
+                },
+                // 是否相应鼠标事件
+                silent: progressSilent
+            });
+            isOverlap && (progress.z2 = maxVal - (data.get(valueDim, idx) as 
number) % maxVal);
+            return progress;
+        }
 
-                graphic.updateProps(pointer, {
-                    shape: {
-                        angle: linearMap(data.get(valueDim, newIdx) as number, 
valueExtent, angleExtent, true)
+        if (showProgress || showPointer) {
+            data.diff(oldData)
+                .add(function (idx) {
+                    if (showPointer) {
+                        const pointer = createPointer(idx, startAngle);
+                        graphic.initProps(pointer, {
+                            rotation: -(linearMap(data.get(valueDim, idx) as 
number, valueExtent, angleExtent, true) + Math.PI / 2)
+                        }, seriesModel);
+                        group.add(pointer);
+                        data.setItemGraphicEl(idx, pointer);
                     }
-                }, seriesModel);
-
-                group.add(pointer);
-                data.setItemGraphicEl(newIdx, pointer);
-            })
-            .remove(function (idx) {
-                const pointer = oldData.getItemGraphicEl(idx);
-                group.remove(pointer);
-            })
-            .execute();
-
-        data.eachItemGraphicEl(function (pointer: PointerPath, idx) {
-            const itemModel = data.getItemModel<GaugeDataItemOption>(idx);
-            const pointerModel = itemModel.getModel('pointer');
-            const emphasisModel = itemModel.getModel('emphasis');
-
-            pointer.setShape({
-                x: posInfo.cx,
-                y: posInfo.cy,
-                width: parsePercent(
-                    pointerModel.get('width'), posInfo.r
-                ),
-                r: parsePercent(pointerModel.get('length'), posInfo.r)
-            });
 
-            pointer.useStyle(itemModel.getModel('itemStyle').getItemStyle());
+                    if (showProgress) {
+                        const progress = createProgress(idx, startAngle) as 
graphic.Sector;
+                        const isClip = progressModel.get('clip');
+                        graphic.initProps(progress, {
+                            shape: {
+                                endAngle: linearMap(data.get(valueDim, idx) as 
number, valueExtent, angleExtent, isClip)
+                            }
+                        }, seriesModel);
+                        group.add(progress);
+                        progressList[idx] = progress;
+                    }
+                })
+                .update(function (newIdx, oldIdx) {
+                    if (showPointer) {
+                        const previousPointer = 
oldData.getItemGraphicEl(oldIdx) as PointerPath;
+                        const previousRotate = previousPointer.rotation;
+                        group.remove(previousPointer);

Review comment:
       Should check if `previousPointer` exists.  It's possible to have error 
when switching the `show` property from false to true.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org
For additional commands, e-mail: commits-h...@echarts.apache.org

Reply via email to