1
1
import { create , group , path , select , Delaunay } from "d3" ;
2
2
import { Curve } from "../curve.js" ;
3
- import { maybeTuple , maybeZ } from "../options.js" ;
3
+ import { constant , maybeTuple , maybeZ } from "../options.js" ;
4
4
import { Mark } from "../plot.js" ;
5
- import { applyChannelStyles , applyDirectStyles , applyIndirectStyles , applyTransform , offset } from "../style.js" ;
5
+ import { applyChannelStyles , applyDirectStyles , applyFrameAnchor , applyIndirectStyles , applyTransform , offset } from "../style.js" ;
6
6
import { markers , applyMarkers } from "./marker.js" ;
7
7
8
8
const delaunayLinkDefaults = {
@@ -47,8 +47,8 @@ class DelaunayLink extends Mark {
47
47
super (
48
48
data ,
49
49
[
50
- { name : "x" , value : x , scale : "x" } ,
51
- { name : "y" , value : y , scale : "y" } ,
50
+ { name : "x" , value : x , scale : "x" , optional : true } ,
51
+ { name : "y" , value : y , scale : "y" , optional : true } ,
52
52
{ name : "z" , value : z , optional : true }
53
53
] ,
54
54
options ,
@@ -60,6 +60,9 @@ class DelaunayLink extends Mark {
60
60
render ( index , { x, y} , channels , dimensions ) {
61
61
const { x : X , y : Y , z : Z } = channels ;
62
62
const { dx, dy, curve} = this ;
63
+ const [ cx , cy ] = applyFrameAnchor ( this , dimensions ) ;
64
+ const xi = X ? i => X [ i ] : constant ( cx ) ;
65
+ const yi = Y ? i => Y [ i ] : constant ( cy ) ;
63
66
const mark = this ;
64
67
65
68
function links ( index ) {
@@ -76,14 +79,14 @@ class DelaunayLink extends Mark {
76
79
ti = index [ ti ] ;
77
80
tj = index [ tj ] ;
78
81
newIndex . push ( ++ i ) ;
79
- X1 [ i ] = X [ ti ] ;
80
- Y1 [ i ] = Y [ ti ] ;
81
- X2 [ i ] = X [ tj ] ;
82
- Y2 [ i ] = Y [ tj ] ;
82
+ X1 [ i ] = xi ( ti ) ;
83
+ Y1 [ i ] = yi ( ti ) ;
84
+ X2 [ i ] = xi ( tj ) ;
85
+ Y2 [ i ] = yi ( tj ) ;
83
86
for ( const k in channels ) newChannels [ k ] . push ( channels [ k ] [ tj ] ) ;
84
87
}
85
88
86
- const { halfedges, hull, triangles} = Delaunay . from ( index , i => X [ i ] , i => Y [ i ] ) ;
89
+ const { halfedges, hull, triangles} = Delaunay . from ( index , xi , yi ) ;
87
90
for ( let i = 0 ; i < halfedges . length ; ++ i ) { // inner edges
88
91
const j = halfedges [ i ] ;
89
92
if ( j > i ) link ( triangles [ i ] , triangles [ j ] ) ;
@@ -126,33 +129,37 @@ class AbstractDelaunayMark extends Mark {
126
129
super (
127
130
data ,
128
131
[
129
- { name : "x" , value : x , scale : "x" } ,
130
- { name : "y" , value : y , scale : "y" } ,
132
+ { name : "x" , value : x , scale : "x" , optional : true } ,
133
+ { name : "y" , value : y , scale : "y" , optional : true } ,
131
134
{ name : "z" , value : zof ( options ) , optional : true }
132
135
] ,
133
136
options ,
134
137
defaults
135
138
) ;
136
139
}
137
- render ( index , { x, y} , { x : X , y : Y , z : Z , ...channels } , dimensions ) {
140
+ render ( index , { x, y} , channels , dimensions ) {
141
+ const { x : X , y : Y , z : Z } = channels ;
138
142
const { dx, dy} = this ;
143
+ const [ cx , cy ] = applyFrameAnchor ( this , dimensions ) ;
144
+ const xi = X ? i => X [ i ] : constant ( cx ) ;
145
+ const yi = Y ? i => Y [ i ] : constant ( cy ) ;
139
146
const mark = this ;
140
- function mesh ( render ) {
141
- return function ( index ) {
142
- const delaunay = Delaunay . from ( index , i => X [ i ] , i => Y [ i ] ) ;
143
- select ( this ) . append ( "path" )
144
- . datum ( index [ 0 ] )
145
- . call ( applyDirectStyles , mark )
146
- . attr ( "d" , render ( delaunay , dimensions ) )
147
- . call ( applyChannelStyles , mark , channels ) ;
148
- } ;
147
+
148
+ function mesh ( index ) {
149
+ const delaunay = Delaunay . from ( index , xi , yi ) ;
150
+ select ( this ) . append ( "path" )
151
+ . datum ( index [ 0 ] )
152
+ . call ( applyDirectStyles , mark )
153
+ . attr ( "d" , mark . _render ( delaunay , dimensions ) )
154
+ . call ( applyChannelStyles , mark , channels ) ;
149
155
}
156
+
150
157
return create ( "svg:g" )
151
158
. call ( applyIndirectStyles , this , dimensions )
152
159
. call ( applyTransform , x , y , offset + dx , offset + dy )
153
160
. call ( Z
154
- ? g => g . selectAll ( ) . data ( group ( index , i => Z [ i ] ) . values ( ) ) . enter ( ) . append ( "g" ) . each ( mesh ( this . _render ) )
155
- : g => g . datum ( index ) . each ( mesh ( this . _render ) ) )
161
+ ? g => g . selectAll ( ) . data ( group ( index , i => Z [ i ] ) . values ( ) ) . enter ( ) . append ( "g" ) . each ( mesh )
162
+ : g => g . datum ( index ) . each ( mesh ) )
156
163
. node ( ) ;
157
164
}
158
165
}
@@ -182,8 +189,8 @@ class Voronoi extends Mark {
182
189
super (
183
190
data ,
184
191
[
185
- { name : "x" , value : x , scale : "x" } ,
186
- { name : "y" , value : y , scale : "y" } ,
192
+ { name : "x" , value : x , scale : "x" , optional : true } ,
193
+ { name : "y" , value : y , scale : "y" , optional : true } ,
187
194
{ name : "z" , value : z , optional : true }
188
195
] ,
189
196
options ,
@@ -193,9 +200,12 @@ class Voronoi extends Mark {
193
200
render ( index , { x, y} , channels , dimensions ) {
194
201
const { x : X , y : Y , z : Z } = channels ;
195
202
const { dx, dy} = this ;
203
+ const [ cx , cy ] = applyFrameAnchor ( this , dimensions ) ;
204
+ const xi = X ? i => X [ i ] : constant ( cx ) ;
205
+ const yi = Y ? i => Y [ i ] : constant ( cy ) ;
196
206
197
207
function cells ( index ) {
198
- const delaunay = Delaunay . from ( index , i => X [ i ] , i => Y [ i ] ) ;
208
+ const delaunay = Delaunay . from ( index , xi , yi ) ;
199
209
const voronoi = voronoiof ( delaunay , dimensions ) ;
200
210
select ( this )
201
211
. selectAll ( )
0 commit comments