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 dbd53814d072dd9e920ce878502c6943f11896f6
Author: Ovilia <[email protected]>
AuthorDate: Wed Oct 9 17:36:46 2024 +0800

    refactor(stage): using compoundPath
---
 custom-series/stage/src/index.ts | 280 +++++++++++++++++++++------------------
 1 file changed, 150 insertions(+), 130 deletions(-)

diff --git a/custom-series/stage/src/index.ts b/custom-series/stage/src/index.ts
index 71eb248..d365229 100644
--- a/custom-series/stage/src/index.ts
+++ b/custom-series/stage/src/index.ts
@@ -51,6 +51,16 @@ interface StageItemPayload {
   envelope?: Envelope;
 }
 
+interface MyPathProps {}
+
+class MyPath {
+  constructor() {}
+
+  buildPath(ctx: CanvasRenderingContext2D) {
+    console.log('build', ctx);
+  }
+}
+
 const renderItem = (
   params: echarts.CustomSeriesRenderItemParams,
   api: echarts.CustomSeriesRenderItemAPI
@@ -112,6 +122,7 @@ const renderItem = (
     style: {
       fill: color,
     },
+    z2: 10,
   });
   boxes.push(shape);
   params.context.boxes = boxes;
@@ -136,6 +147,7 @@ const renderItem = (
         text,
         verticalAlign: 'bottom',
       },
+      z2: 20,
     });
     renderedStages[stageIndex] = true;
   }
@@ -152,50 +164,53 @@ const renderItem = (
 
     const envelope: Envelope = itemPayload.envelope || {};
     if (envelope.show !== false && boxes.length > 1) {
+      const envelopePaths: Path[] = [];
+      const envelopeDebugPaths: Path[] = [];
       const margin = echarts.zrUtil.retrieve2(envelope.margin as number, 2);
 
       // Sort boxes by x, then by y
       boxes.sort((a, b) => a.x - b.x || a.y - b.y);
 
       const coordSys = params.coordSys as any;
-      const dpr = envelope.dpr == null ? 2 : envelope.dpr || 1;
-      const canvasWidth = coordSys.width * dpr;
-      const canvasHeight = coordSys.height * dpr;
-      const canvas = createCanvas(canvasWidth, canvasHeight);
-      const ox = coordSys.x;
-      const oy = coordSys.y;
-
-      const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
+      // const dpr = envelope.dpr == null ? 2 : envelope.dpr || 1;
+      // const canvasWidth = coordSys.width;
+      // const canvasHeight = coordSys.height;
+      // const canvas = createCanvas(canvasWidth, canvasHeight);
+      // const ox = coordSys.x;
+      // const oy = coordSys.y;
+
+      // const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
       if (allColors.length > 0 && !envelope.color) {
-        const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
-        for (let i = 0; i < allColors.length; i++) {
-          // For example, if there are 4 colors, the gradient stops are 1/8,
-          // 3/8, 5/8, 7/8.
-          gradient.addColorStop(
-            (i * 2 + 1) / (allColors.length * 2),
-            allColors[i]
-          );
-        }
-        ctx.fillStyle = gradient;
+        // const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
+        // for (let i = 0; i < allColors.length; i++) {
+        //   // For example, if there are 4 colors, the gradient stops are 1/8,
+        //   // 3/8, 5/8, 7/8.
+        //   gradient.addColorStop(
+        //     (i * 2 + 1) / (allColors.length * 2),
+        //     allColors[i]
+        //   );
+        // }
+        // ctx.fillStyle = gradient;
       } else {
-        ctx.fillStyle = envelope.color || '#888';
+        // ctx.fillStyle = envelope.color || '#888';
       }
       const opacity = zrUtil.retrieve2(envelope.opacity as number, 0.25);
 
       for (let i = 0; i < boxes.length; i++) {
         const box = boxes[i];
 
-        drawRoundedRect(
-          ctx,
-          (box.x - margin - ox) * dpr,
-          (box.y - margin - oy) * dpr,
-          (box.width + margin * 2) * dpr,
-          (box.height + margin * 2) * dpr,
-          (Math.min(borderRadius, box.width / 2) + margin) * dpr
-        );
+        envelopePaths.push({
+          type: 'rect',
+          shape: {
+            x: box.x - margin,
+            y: box.y - margin,
+            width: box.width + margin * 2,
+            height: box.height + margin * 2,
+            r: Math.min(borderRadius, box.width / 2) + margin,
+          },
+        });
 
         if (i > 0) {
-          ctx.beginPath();
           const prevBox = boxes[i - 1];
           const isPrevLower = prevBox.y > box.y + box.height;
           const height = isPrevLower
@@ -213,85 +228,126 @@ const renderItem = (
           // Draw outer border-radius
           if (isPrevLower) {
             if (box.x - margin - prevBox.x > 0) {
-              const right = Math.ceil((box.x - margin - ox) * dpr);
-              const bottom = (prevBox.y - margin - oy) * dpr;
-              const r =
-                Math.min((box.x - margin - prevBox.x) / 2, externalRadius) *
-                dpr;
-              ctx.moveTo(right, bottom + r);
-              ctx.arc(right - r, bottom - r, r, 0, Math.PI / 2);
-              ctx.lineTo(right, bottom + margin * dpr);
-              ctx.lineTo(right, bottom - r);
-            }
-
-            if (box.x + box.width - prevBox.x - prevBox.width - margin > 0) {
-              const top = (box.y + box.height + margin - oy) * dpr;
-              const left = Math.floor(
-                (prevBox.x + prevBox.width + margin - ox) * dpr
+              const right = Math.ceil(box.x - margin);
+              const bottom = prevBox.y - margin;
+              const r = Math.min(
+                (box.x - margin - prevBox.x) / 2,
+                externalRadius
               );
-              const r =
-                Math.min(
-                  (box.x + box.width - prevBox.x - prevBox.width - margin) / 2,
-                  externalRadius
-                ) * dpr;
-              ctx.moveTo(left, top + r);
-              ctx.arc(left + r, top + r, r, Math.PI, Math.PI * 1.5);
-              ctx.lineTo(left, top - margin * dpr);
-              ctx.lineTo(left, top);
-            }
-          } else {
-            if (box.x - margin - prevBox.x > 0) {
-              const right = Math.ceil((box.x - margin - ox) * dpr);
-              const top = (prevBox.y + prevBox.height + margin - oy) * dpr;
-              const r =
-                Math.min((box.x - margin - prevBox.x) / 2, externalRadius) *
-                dpr;
-              ctx.moveTo(right, top + r);
-              ctx.arc(right - r, top + r, r, -Math.PI / 2, 0);
-              ctx.lineTo(right, top - margin * dpr);
-              ctx.lineTo(right - r, top);
-            }
 
-            if (box.x + box.width - prevBox.x - prevBox.width - margin > 0) {
-              const bottom = (box.y - margin - oy) * dpr;
-              const left = Math.floor(
-                (prevBox.x + prevBox.width + margin - ox) * dpr
-              );
-              const r =
-                Math.min(
-                  (box.x + box.width - prevBox.x - prevBox.width - margin) / 2,
-                  externalRadius
-                ) * dpr;
-              ctx.moveTo(left + r, bottom);
-              ctx.arc(left + r, bottom - r, r, Math.PI / 2, Math.PI);
-              ctx.lineTo(left, bottom + (margin + borderRadius) * dpr);
-              ctx.lineTo(left + r, bottom);
+              envelopePaths.push({
+                type: 'path',
+                shape: {
+                  pathData: `M${right},${bottom + r}A${r},${r},0,0,1,${
+                    right - r
+                  },${bottom}L${right},${bottom + margin}L${right},${
+                    bottom - r
+                  }Z`,
+                },
+              });
+              // const path = ((right, bottom, r, margin) => {
+              //   return {
+              //     buildPath: (ctx) => {
+              //       ctx.moveTo(right, bottom + r);
+              //       ctx.arc(right - r, bottom + r, r, 0, Math.PI / 2);
+              //       ctx.lineTo(right, bottom + margin);
+              //       ctx.lineTo(right, bottom - r);
+              //     },
+              //   };
+              // })(right, bottom, r, margin);
+              // envelopeDebugPaths.push(path);
+
+              // ctx.moveTo(right, bottom + r);
+              // ctx.arc(right - r, bottom - r, r, 0, Math.PI / 2);
+              // ctx.lineTo(right, bottom + margin);
+              // ctx.lineTo(right, bottom - r);
             }
           }
-          ctx.closePath();
-          ctx.fill();
+
+          //   if (box.x + box.width - prevBox.x - prevBox.width - margin > 0) 
{
+          //     const top = (box.y + box.height + margin);
+          //     const left = Math.floor(
+          //       (prevBox.x + prevBox.width + margin)
+          //     );
+          //     const r =
+          //       Math.min(
+          //         (box.x + box.width - prevBox.x - prevBox.width - margin) 
/ 2,
+          //         externalRadius
+          //       );
+          //     ctx.moveTo(left, top + r);
+          //     ctx.arc(left + r, top + r, r, Math.PI, Math.PI * 1.5);
+          //     ctx.lineTo(left, top - margin);
+          //     ctx.lineTo(left, top);
+          //   }
+          // } else {
+          //   if (box.x - margin - prevBox.x > 0) {
+          //     const right = Math.ceil((box.x - margin));
+          //     const top = (prevBox.y + prevBox.height + margin);
+          //     const r =
+          //       Math.min((box.x - margin - prevBox.x) / 2, externalRadius) *
+          //       dpr;
+          //     ctx.moveTo(right, top + r);
+          //     ctx.arc(right - r, top + r, r, -Math.PI / 2, 0, false); // 
Top-right corner
+          //     ctx.lineTo(right, top - margin);
+          //     ctx.lineTo(right - r, top);
+          //   }
+
+          //   if (box.x + box.width - prevBox.x - prevBox.width - margin > 0) 
{
+          //     const bottom = (box.y - margin);
+          //     const left = Math.floor(
+          //       (prevBox.x + prevBox.width + margin)
+          //     );
+          //     const r =
+          //       Math.min(
+          //         (box.x + box.width - prevBox.x - prevBox.width - margin) 
/ 2,
+          //         externalRadius
+          //       );
+          //     ctx.moveTo(left + r, bottom);
+          //     ctx.arc(left + r, bottom - r, r, Math.PI / 2, Math.PI);
+          //     ctx.lineTo(left, bottom + (margin + borderRadius));
+          //     ctx.lineTo(left + r, bottom);
+          //   }
+          // }
+          // ctx.closePath();
+          // ctx.fill();
 
           // Draw bars between boxes
-          ctx.fillRect(
-            (prevBox.x + prevBox.width + margin - ox) * dpr,
-            (y - oy) * dpr,
-            (box.x - prevBox.x - prevBox.width - margin * 2) * dpr,
-            height * dpr
-          );
+          envelopePaths.push({
+            type: 'rect',
+            shape: {
+              x: prevBox.x + prevBox.width + margin,
+              y: y + height,
+              width: box.x - prevBox.x - prevBox.width - margin * 2,
+              height: -height,
+            },
+          });
         }
       }
 
       children.push({
-        type: 'image',
+        type: 'compoundPath',
+        shape: {
+          paths: envelopePaths,
+        },
+        style: {
+          fill: envelope.color || '#888',
+          opacity: 0.2,
+        },
+        silent: true,
+        z2: 200,
+      });
+
+      children.push({
+        type: 'compoundPath',
+        shape: {
+          paths: envelopeDebugPaths,
+        },
         style: {
-          image: canvas,
-          x: coordSys.x * dpr,
-          y: coordSys.y * dpr,
-          opacity,
+          fill: envelope.color || '#f00',
+          opacity: 0.9,
         },
         silent: true,
-        scaleX: 1 / dpr,
-        scaleY: 1 / dpr,
+        z2: 200,
       });
     }
   }
@@ -302,42 +358,6 @@ const renderItem = (
   } as CustomRootElementOption;
 };
 
-function createCanvas(width, height) {
-  const canvas = document.createElement('canvas');
-  canvas.width = width;
-  canvas.height = height;
-  return canvas;
-}
-
-function drawRoundedRect(
-  ctx: CanvasRenderingContext2D,
-  x: number,
-  y: number,
-  width: number,
-  height: number,
-  radius: number
-) {
-  ctx.beginPath();
-  ctx.moveTo(x + radius, y); // Move to the top-left corner
-  ctx.lineTo(x + width - radius, y); // Top edge
-  ctx.arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0, false); // 
Top-right corner
-  ctx.lineTo(x + width, y + height - radius); // Right edge
-  ctx.arc(
-    x + width - radius,
-    y + height - radius,
-    radius,
-    0,
-    Math.PI / 2,
-    false
-  ); // Bottom-right corner
-  ctx.lineTo(x + radius, y + height); // Bottom edge
-  ctx.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI, 
false); // Bottom-left corner
-  ctx.lineTo(x, y + radius); // Left edge
-  ctx.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 1.5, false); // 
Top-left corner
-  ctx.closePath();
-  ctx.fill();
-}
-
 export default {
   install(registers: EChartsExtensionInstallRegisters) {
     registers.registerCustomSeries(


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

Reply via email to