This is an automated email from the ASF dual-hosted git repository.

ovilia pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/echarts-custom-series.git

commit 6b4128bb8eed8c6909ce24734f04f5598b49e80b
Author: Ovilia <[email protected]>
AuthorDate: Wed Mar 12 16:12:16 2025 +0800

    feat(segmentedDoughnut): render item and bg
---
 custom-series/segmentedDoughnut/src/index.ts | 105 ++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 3 deletions(-)

diff --git a/custom-series/segmentedDoughnut/src/index.ts 
b/custom-series/segmentedDoughnut/src/index.ts
index cb11088..db3f76b 100644
--- a/custom-series/segmentedDoughnut/src/index.ts
+++ b/custom-series/segmentedDoughnut/src/index.ts
@@ -17,15 +17,30 @@
  * under the License.
  */
 
-import echarts from 'echarts';
+import echarts, { zrUtil, number } from 'echarts';
 import type {
   CustomRootElementOption,
   CustomSeriesRenderItem,
 } from 'echarts/types/src/chart/custom/CustomSeries.d.ts';
 import type { EChartsExtensionInstallRegisters } from 
'echarts/src/extension.ts';
+import type { CustomElementOption } from 
'echarts/src/chart/custom/CustomSeries.ts';
 
 type SegmentedDoughnutItemPayload = {
-
+  center?: [number | string, number | string];
+  radius?: [number | string, number | string];
+  segmentCount?: number;
+  padAngle?: number;
+  backgroundStyle?: {
+    color?: string;
+    borderColor?: string;
+    borderWidth?: number;
+    borderType?: string;
+    opacity?: number;
+    shadowBlur?: number;
+    shadowColor?: string;
+    shadowOffsetX?: number;
+    shadowOffsetY?: number;
+  }
 };
 
 const renderItem = (
@@ -37,10 +52,94 @@ const renderItem = (
   const cnt = params.dataInsideLength;
   if (params.dataIndex === cnt - 1) {
   }
+  console.log(params, itemPayload);
+
+  const segmentCount = Math.max(1, itemPayload.segmentCount || 1);
+  const value = Math.min(segmentCount, api.value(0) as number || 0);
+
+  const center = itemPayload.center || ['50%', '50%'];
+  const radius = itemPayload.radius || ['50%', '60%'];
+  const width = api.getWidth();
+  const height = api.getHeight();
+  const size = Math.min(width, height);
+  const cx = number.parsePercent(center[0], api.getWidth());
+  const cy = number.parsePercent(center[1], api.getHeight());
+  const r = number.parsePercent(radius[1], size / 2);
+  const r0 = number.parsePercent(radius[0], size / 2);
+
+  const padAngle = (zrUtil.retrieve2(
+    itemPayload.padAngle,
+    2
+  ) || 0) * Math.PI / 180;
+  const pieceAngle = (Math.PI * 2 - padAngle * segmentCount) / segmentCount;
+
+  const backgroundGroup = {
+    type: 'group',
+    children: [] as CustomElementOption[],
+  };
+  const bgStyle = itemPayload.backgroundStyle || {};
+  const backgroundStyle = {
+    fill: bgStyle.color || 'rgba(180, 180, 180, 0.2)',
+    stroke: bgStyle.borderColor || 'none',
+    lineWidth: bgStyle.borderWidth || 0,
+    lineType: bgStyle.borderType || 'solid',
+    opacity: bgStyle.opacity || 1,
+    shadowBlur: bgStyle.shadowBlur || 0,
+    shadowColor: bgStyle.shadowColor || 'rgba(0, 0, 0, 0)',
+    shadowOffsetX: bgStyle.shadowOffsetX || 0,
+    shadowOffsetY: bgStyle.shadowOffsetY || 0,
+  }
+
+  const itemGroup = {
+    type: 'group',
+    children: [] as CustomElementOption[],
+  };
+  const itemStyle = api.style();
+  const itemStyleEmphasis = api.styleEmphasis();
+
+  const startAngle = -Math.PI / 2;
+  const cornerRadius = (r - r0) / 2;
+  for (let i = 0; i < segmentCount; ++i) {
+    const sAngle = startAngle + (pieceAngle + padAngle) * i;
+    const eAngle = startAngle + (pieceAngle + padAngle) * i + pieceAngle;
+    backgroundGroup.children.push({
+      type: 'sector',
+      shape: {
+        cx,
+        cy,
+        r0,
+        r,
+        cornerRadius,
+        startAngle: sAngle,
+        endAngle: eAngle,
+        clockwise: true,
+      },
+      style: backgroundStyle,
+      silent: true
+    });
+
+    if (i < value) {
+      itemGroup.children.push({
+        type: 'sector',
+        shape: {
+          cx,
+          cy,
+          r0,
+          r,
+          cornerRadius,
+          startAngle: sAngle,
+          endAngle: eAngle,
+          clockwise: true,
+        },
+        style: itemStyle,
+        styleEmphasis: itemStyleEmphasis
+      });
+    }
+  }
 
   return {
     type: 'group',
-    children: [],
+    children: [backgroundGroup, itemGroup],
   } as CustomRootElementOption;
 };
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to