|  | 
 | /* | 
 | * Licensed to the Apache Software Foundation (ASF) under one | 
 | * or more contributor license agreements.  See the NOTICE file | 
 | * distributed with this work for additional information | 
 | * regarding copyright ownership.  The ASF licenses this file | 
 | * to you under the Apache License, Version 2.0 (the | 
 | * "License"); you may not use this file except in compliance | 
 | * with the License.  You may obtain a copy of the License at | 
 | * | 
 | *   http://www.apache.org/licenses/LICENSE-2.0 | 
 | * | 
 | * Unless required by applicable law or agreed to in writing, | 
 | * software distributed under the License is distributed on an | 
 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | * KIND, either express or implied.  See the License for the | 
 | * specific language governing permissions and limitations | 
 | * under the License. | 
 | */ | 
 |  | 
 |  | 
 | /** | 
 |  * AUTO-GENERATED FILE. DO NOT MODIFY. | 
 |  */ | 
 |  | 
 | /* | 
 | * Licensed to the Apache Software Foundation (ASF) under one | 
 | * or more contributor license agreements.  See the NOTICE file | 
 | * distributed with this work for additional information | 
 | * regarding copyright ownership.  The ASF licenses this file | 
 | * to you under the Apache License, Version 2.0 (the | 
 | * "License"); you may not use this file except in compliance | 
 | * with the License.  You may obtain a copy of the License at | 
 | * | 
 | *   http://www.apache.org/licenses/LICENSE-2.0 | 
 | * | 
 | * Unless required by applicable law or agreed to in writing, | 
 | * software distributed under the License is distributed on an | 
 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | * KIND, either express or implied.  See the License for the | 
 | * specific language governing permissions and limitations | 
 | * under the License. | 
 | */ | 
 | import Axis2D from '../coord/cartesian/Axis2D.js'; | 
 | import { makeInner } from './model.js'; | 
 | export function needFixJitter(seriesModel, axis) { | 
 |   var coordinateSystem = seriesModel.coordinateSystem; | 
 |   var coordType = coordinateSystem && coordinateSystem.type; | 
 |   var baseAxis = coordinateSystem && coordinateSystem.getBaseAxis && coordinateSystem.getBaseAxis(); | 
 |   var scaleType = baseAxis && baseAxis.scale && baseAxis.scale.type; | 
 |   var seriesValid = coordType === 'cartesian2d' && scaleType === 'ordinal' || coordType === 'single'; | 
 |   var axisValid = axis.model.get('jitter') > 0; | 
 |   return seriesValid && axisValid; | 
 | } | 
 | var inner = makeInner(); | 
 | /** | 
 |  * Fix jitter for overlapping data points. | 
 |  * | 
 |  * @param fixedAxis The axis whose coord doesn't change with jitter. | 
 |  * @param fixedCoord The coord of fixedAxis. | 
 |  * @param floatCoord The coord of the other axis, which should be changed with jittering. | 
 |  * @param radius The radius of the data point, considering the symbol is a circle. | 
 |  * @returns updated floatCoord. | 
 |  */ | 
 | export function fixJitter(fixedAxis, fixedCoord, floatCoord, radius) { | 
 |   if (fixedAxis instanceof Axis2D) { | 
 |     var scaleType = fixedAxis.scale.type; | 
 |     if (scaleType !== 'category' && scaleType !== 'ordinal') { | 
 |       return floatCoord; | 
 |     } | 
 |   } | 
 |   var axisModel = fixedAxis.model; | 
 |   var jitter = axisModel.get('jitter'); | 
 |   var jitterOverlap = axisModel.get('jitterOverlap'); | 
 |   var jitterMargin = axisModel.get('jitterMargin') || 0; | 
 |   // Get band width to limit jitter range | 
 |   var bandWidth = fixedAxis.scale.type === 'ordinal' ? fixedAxis.getBandWidth() : null; | 
 |   if (jitter > 0) { | 
 |     if (jitterOverlap) { | 
 |       return fixJitterIgnoreOverlaps(floatCoord, jitter, bandWidth, radius); | 
 |     } else { | 
 |       return fixJitterAvoidOverlaps(fixedAxis, fixedCoord, floatCoord, radius, jitter, jitterMargin); | 
 |     } | 
 |   } | 
 |   return floatCoord; | 
 | } | 
 | function fixJitterIgnoreOverlaps(floatCoord, jitter, bandWidth, radius) { | 
 |   // Don't clamp single axis | 
 |   if (bandWidth === null) { | 
 |     return floatCoord + (Math.random() - 0.5) * jitter; | 
 |   } | 
 |   var maxJitter = bandWidth - radius * 2; | 
 |   var actualJitter = Math.min(Math.max(0, jitter), maxJitter); | 
 |   return floatCoord + (Math.random() - 0.5) * actualJitter; | 
 | } | 
 | function fixJitterAvoidOverlaps(fixedAxis, fixedCoord, floatCoord, radius, jitter, margin) { | 
 |   var store = inner(fixedAxis); | 
 |   if (!store.items) { | 
 |     store.items = []; | 
 |   } | 
 |   var items = store.items; | 
 |   // Try both positive and negative directions, choose the one with smaller movement | 
 |   var overlapA = placeJitterOnDirection(items, fixedCoord, floatCoord, radius, jitter, margin, 1); | 
 |   var overlapB = placeJitterOnDirection(items, fixedCoord, floatCoord, radius, jitter, margin, -1); | 
 |   var minFloat = Math.abs(overlapA - floatCoord) < Math.abs(overlapB - floatCoord) ? overlapA : overlapB; | 
 |   // Clamp only category axis | 
 |   var bandWidth = fixedAxis.scale.type === 'ordinal' ? fixedAxis.getBandWidth() : null; | 
 |   var distance = Math.abs(minFloat - floatCoord); | 
 |   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); | 
 |   } | 
 |   // Add new point to array | 
 |   items.push({ | 
 |     fixedCoord: fixedCoord, | 
 |     floatCoord: minFloat, | 
 |     r: radius | 
 |   }); | 
 |   return minFloat; | 
 | } | 
 | function placeJitterOnDirection(items, fixedCoord, floatCoord, radius, jitter, margin, direction) { | 
 |   var y = floatCoord; | 
 |   // Check all existing items for overlap and find the maximum adjustment needed | 
 |   for (var i = 0; i < items.length; i++) { | 
 |     var item = items[i]; | 
 |     var dx = fixedCoord - item.fixedCoord; | 
 |     var dy = y - item.floatCoord; | 
 |     var d2 = dx * dx + dy * dy; | 
 |     var r = radius + item.r + margin; | 
 |     if (d2 < r * r) { | 
 |       // Has overlap, calculate required adjustment | 
 |       var requiredY = item.floatCoord + Math.sqrt(r * r - dx * dx) * direction; | 
 |       // Check if this adjustment would move too far | 
 |       if (Math.abs(requiredY - floatCoord) > jitter / 2) { | 
 |         return Number.MAX_VALUE; // Give up | 
 |       } | 
 |       // Update y only when it's larger to the center | 
 |       if (direction === 1 && requiredY > y || direction === -1 && requiredY < y) { | 
 |         y = requiredY; | 
 |         // Loop from the start again | 
 |         i = -1; // Reset index to recheck all items | 
 |         continue; // Recalculate with the new y position | 
 |       } | 
 |     } | 
 |   } | 
 |   return y; | 
 | } |