@@ -54,28 +54,33 @@ function dodge(y, x, anchor, padding, options) {
54
54
for ( let I of facets ) {
55
55
const tree = IntervalTree ( ) ;
56
56
I = I . filter ( R ? i => finite ( X [ i ] ) && positive ( R [ i ] ) : i => finite ( X [ i ] ) ) ;
57
+ const intervals = new Float64Array ( 2 * I . length ) ;
57
58
for ( const i of I ) {
58
- const intervals = [ ] ;
59
59
const l = X [ i ] - radius ( i ) ;
60
60
const h = X [ i ] + radius ( i ) ;
61
61
62
62
// For any previously placed circles that may overlap this circle, compute
63
63
// the y-positions that place this circle tangent to these other circles.
64
64
// https://observablehq.com/@mbostock /circle-offset-along-line
65
+ let k = 0 ;
65
66
tree . queryInterval ( l - padding , h + padding , ( [ , , j ] ) => {
66
67
const yj = Y [ j ] ;
67
68
const dx = X [ i ] - X [ j ] ;
68
69
const dr = padding + ( R ? R [ i ] + R [ j ] : 2 * r ) ;
69
70
const dy = Math . sqrt ( dr * dr - dx * dx ) ;
70
- intervals . push ( [ yj - dy , yj + dy ] ) ;
71
+ intervals [ k ++ ] = yj - dy ;
72
+ intervals [ k ++ ] = yj + dy ;
71
73
} ) ;
72
74
73
75
// Find the best y-value where this circle can fit.
74
- for ( let y of intervals . flat ( ) . sort ( compare ) ) {
75
- if ( intervals . every ( ( [ lo , hi ] ) => y <= lo || y >= hi ) ) {
76
- Y [ i ] = y ;
77
- break ;
76
+ out: for ( const y of intervals . slice ( 0 , k ) . sort ( compare ) ) {
77
+ for ( let j = 0 ; j < k ; j += 2 ) {
78
+ if ( y > intervals [ j ] && y < intervals [ j + 1 ] ) {
79
+ continue out;
80
+ }
78
81
}
82
+ Y [ i ] = y ;
83
+ break ;
79
84
}
80
85
81
86
// Insert the placed circle into the interval tree.
0 commit comments