1- import { pathRound as path } from "d3" ;
1+ import { geoPath , pathRound as path } from "d3" ;
22import { create } from "../context.js" ;
3- import { Curve } from "../curve.js" ;
3+ import { curveAuto , PathCurve } from "../curve.js" ;
44import { Mark } from "../mark.js" ;
5+ import { coerceNumbers } from "../scales.js" ;
56import { applyChannelStyles , applyDirectStyles , applyIndirectStyles , applyTransform } from "../style.js" ;
67import { markers , applyMarkers } from "./marker.js" ;
78
@@ -26,9 +27,15 @@ export class Link extends Mark {
2627 options ,
2728 defaults
2829 ) ;
29- this . curve = Curve ( curve , tension ) ;
30+ this . curve = PathCurve ( curve , tension ) ;
3031 markers ( this , options ) ;
3132 }
33+ project ( channels , values , context ) {
34+ // For the auto curve, projection is handled at render.
35+ if ( this . curve !== curveAuto ) {
36+ super . project ( channels , values , context ) ;
37+ }
38+ }
3239 render ( index , scales , channels , dimensions , context ) {
3340 const { x1 : X1 , y1 : Y1 , x2 : X2 = X1 , y2 : Y2 = Y1 } = channels ;
3441 const { curve} = this ;
@@ -42,22 +49,43 @@ export class Link extends Mark {
4249 . enter ( )
4350 . append ( "path" )
4451 . call ( applyDirectStyles , this )
45- . attr ( "d" , ( i ) => {
46- const p = path ( ) ;
47- const c = curve ( p ) ;
48- c . lineStart ( ) ;
49- c . point ( X1 [ i ] , Y1 [ i ] ) ;
50- c . point ( X2 [ i ] , Y2 [ i ] ) ;
51- c . lineEnd ( ) ;
52- return p ;
53- } )
52+ . attr (
53+ "d" ,
54+ curve === curveAuto && context . projection
55+ ? sphereLink ( context . projection , X1 , Y1 , X2 , Y2 )
56+ : ( i ) => {
57+ const p = path ( ) ;
58+ const c = curve ( p ) ;
59+ c . lineStart ( ) ;
60+ c . point ( X1 [ i ] , Y1 [ i ] ) ;
61+ c . point ( X2 [ i ] , Y2 [ i ] ) ;
62+ c . lineEnd ( ) ;
63+ return p ;
64+ }
65+ )
5466 . call ( applyChannelStyles , this , channels )
5567 . call ( applyMarkers , this , channels )
5668 )
5769 . node ( ) ;
5870 }
5971}
6072
73+ function sphereLink ( projection , X1 , Y1 , X2 , Y2 ) {
74+ const path = geoPath ( projection ) ;
75+ X1 = coerceNumbers ( X1 ) ;
76+ Y1 = coerceNumbers ( Y1 ) ;
77+ X2 = coerceNumbers ( X2 ) ;
78+ Y2 = coerceNumbers ( Y2 ) ;
79+ return ( i ) =>
80+ path ( {
81+ type : "LineString" ,
82+ coordinates : [
83+ [ X1 [ i ] , Y1 [ i ] ] ,
84+ [ X2 [ i ] , Y2 [ i ] ]
85+ ]
86+ } ) ;
87+ }
88+
6189/** @jsdoc link */
6290export function link ( data , options = { } ) {
6391 let { x, x1, x2, y, y1, y2, ...remainingOptions } = options ;
0 commit comments