You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by wa...@apache.org on 2026/09/16 09:16:10 UTC

(echarts) branch jitter-rng created (now 02edddaef)

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

plainheart pushed a change to branch jitter-rng
in repository https://gitbox.apache.org/repos/asf/echarts.git


      at 02edddaef feat(scatter): add `jitterRng` option to configure a custom random number generator or a random seed for deterministic jitter layout

This branch includes the following new commits:

     new 02edddaef feat(scatter): add `jitterRng` option to configure a custom random number generator or a random seed for deterministic jitter layout

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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


(echarts) 01/01: feat(scatter): add `jitterRng` option to configure a custom random number generator or a random seed for deterministic jitter layout

Posted by wa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

plainheart pushed a commit to branch jitter-rng
in repository https://gitbox.apache.org/repos/asf/echarts.git

commit 02edddaef7cebae1053f1ed1dc392395559964e2
Author: plainheart <yh...@all-my-life.cn>
AuthorDate: Wed Sep 16 17:15:13 2026 +0800

    feat(scatter): add `jitterRng` option to configure a custom random number generator or a random seed for deterministic jitter layout
---
 src/chart/scatter/jitterLayout.ts |  7 +++++--
 src/coord/axisCommonTypes.ts      |  1 +
 src/util/jitter.ts                | 20 ++++++++++++--------
 3 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/chart/scatter/jitterLayout.ts b/src/chart/scatter/jitterLayout.ts
index a68ea6550..44d9b1024 100644
--- a/src/chart/scatter/jitterLayout.ts
+++ b/src/chart/scatter/jitterLayout.ts
@@ -26,6 +26,7 @@ import createRenderPlanner from '../helper/createRenderPlanner';
 import { COORD_SYS_TYPE_CARTESIAN_2D } from '../../coord/cartesian/GridModel';
 import { COORD_SYS_TYPE_SINGLE } from '../../coord/single/AxisModel';
 import { validateUpstreamOutputRange } from '../../util/model';
+import type { AxisBaseModel } from '../../coord/AxisBaseModel';
 
 export default function jitterLayout(): StageHandler {
     return {
@@ -58,6 +59,8 @@ export default function jitterLayout(): StageHandler {
                 return;
             }
 
+            const jitterRng = (baseAxis.model as AxisBaseModel).get('jitterRng');
+
             return {
                 progress(params, data): void {
                     const points = data.getLayout('points') as Float32Array;
@@ -79,7 +82,7 @@ export default function jitterLayout(): StageHandler {
 
                         if (jitterOnY) {
                             // x is fixed, and y is floating
-                            const jittered = fixJitter(baseAxis, layout[0], layout[1], size / 2);
+                            const jittered = fixJitter(baseAxis, layout[0], layout[1], size / 2, jitterRng);
                             if (hasPoints) {
                                 points[offset + 1] = jittered;
                             }
@@ -89,7 +92,7 @@ export default function jitterLayout(): StageHandler {
                         }
                         else if (jitterOnX) {
                             // y is fixed, and x is floating
-                            const jittered = fixJitter(baseAxis, layout[1], layout[0], size / 2);
+                            const jittered = fixJitter(baseAxis, layout[1], layout[0], size / 2, jitterRng);
                             if (hasPoints) {
                                 points[offset] = jittered;
                             }
diff --git a/src/coord/axisCommonTypes.ts b/src/coord/axisCommonTypes.ts
index 058dea900..cd57a673d 100644
--- a/src/coord/axisCommonTypes.ts
+++ b/src/coord/axisCommonTypes.ts
@@ -128,6 +128,7 @@ export interface AxisBaseOptionCommon extends ComponentOption,
     jitter?: number;
     jitterOverlap?: boolean;
     jitterMargin?: number;
+    jitterRng?: () => number;
 
     breaks?: AxisBreakOption[];
     breakArea?: {
diff --git a/src/util/jitter.ts b/src/util/jitter.ts
index c0e1e394e..352d3f971 100644
--- a/src/util/jitter.ts
+++ b/src/util/jitter.ts
@@ -61,7 +61,8 @@ export function fixJitter(
     fixedAxis: Axis2D | SingleAxis,
     fixedCoord: number,
     floatCoord: number,
-    radius: number
+    radius: number,
+    rng?: () => number
 ): number {
     if (fixedAxis instanceof Axis2D) {
         const scaleType = fixedAxis.scale.type;
@@ -80,25 +81,27 @@ export function fixJitter(
     const bandWidth = isOrdinalScale(fixedAxis.scale)
         ? calcBandWidth(fixedAxis).w
         : null;
+    !rng && (rng = Math.random);
     if (jitterOverlap) {
-        return fixJitterIgnoreOverlaps(floatCoord, jitter, bandWidth, radius);
+        return fixJitterIgnoreOverlaps(floatCoord, jitter, bandWidth, radius, rng);
     }
-    return fixJitterAvoidOverlaps(fixedAxis, fixedCoord, floatCoord, radius, jitter, jitterMargin);
+    return fixJitterAvoidOverlaps(fixedAxis, fixedCoord, floatCoord, radius, jitter, jitterMargin, rng);
 }
 
 function fixJitterIgnoreOverlaps(
     floatCoord: number,
     jitter: number,
     bandWidth: number | null,
-    radius: number
+    radius: number,
+    rng: () => number
 ): number {
     // Don't clamp single axis
     if (bandWidth === null) {
-        return floatCoord + (Math.random() - 0.5) * jitter;
+        return floatCoord + (rng() - 0.5) * jitter;
     }
     const maxJitter = bandWidth - radius * 2;
     const actualJitter = Math.min(Math.max(0, jitter), maxJitter);
-    return floatCoord + (Math.random() - 0.5) * actualJitter;
+    return floatCoord + (rng() - 0.5) * actualJitter;
 }
 
 function fixJitterAvoidOverlaps(
@@ -107,7 +110,8 @@ function fixJitterAvoidOverlaps(
     floatCoord: number,
     radius: number,
     jitter: number,
-    margin: number
+    margin: number,
+    rng: () => number
 ): number {
     const store = inner(fixedAxis);
     if (!store.items) {
@@ -129,7 +133,7 @@ function fixJitterAvoidOverlaps(
     if (distance > jitter / 2 || (bandWidth && distance > bandWidth / 2 - radius)) {
         // If the new item is moved too far, then give up.
         // Fall back to random jitter.
-        return fixJitterIgnoreOverlaps(floatCoord, jitter, bandWidth, radius);
+        return fixJitterIgnoreOverlaps(floatCoord, jitter, bandWidth, radius, rng);
     }
 
     // Add new point to array


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