@@ -3,10 +3,10 @@ import {getSource} from "../channel.js";
3
3
import { create } from "../context.js" ;
4
4
import { defined } from "../defined.js" ;
5
5
import { formatDefault } from "../format.js" ;
6
- import { pointerPosition } from "../interactions/pointer.js" ;
6
+ import { anchorX , anchorY } from "../interactions/pointer.js" ;
7
7
import { Mark } from "../mark.js" ;
8
8
import { maybeAnchor , maybeFrameAnchor , maybeTuple , number , string } from "../options.js" ;
9
- import { applyDirectStyles , applyIndirectStyles , applyTransform , impliedString } from "../style.js" ;
9
+ import { applyDirectStyles , applyFrameAnchor , applyIndirectStyles , applyTransform , impliedString } from "../style.js" ;
10
10
import { inferTickFormat } from "./axis.js" ;
11
11
import { applyIndirectTextStyles , defaultWidth , ellipsis , monospaceWidth } from "./text.js" ;
12
12
import { cut , clipper , splitter , maybeTextOverflow } from "./text.js" ;
@@ -78,25 +78,31 @@ export class Tip extends Mark {
78
78
this . splitLines = splitter ( this ) ;
79
79
this . clipLine = clipper ( this ) ;
80
80
}
81
- render ( index , scales , channels , dimensions , context ) {
81
+ render ( index , scales , values , dimensions , context ) {
82
82
const mark = this ;
83
83
const { x, y, fx, fy} = scales ;
84
84
const { ownerSVGElement : svg , document} = context ;
85
85
const { anchor, monospace, lineHeight, lineWidth} = this ;
86
86
const { textPadding : r , pointerSize : m , pathFilter} = this ;
87
87
const { marginTop, marginLeft} = dimensions ;
88
- const sources = getSources ( channels ) ;
88
+ const sources = getSources ( values ) ;
89
89
90
90
// The anchor position is the middle of x1 & y1 and x2 & y2, if available,
91
91
// or x & y; the former is considered more specific because it’s how we
92
92
// disable the implicit stack and interval transforms. If any dimension is
93
93
// unspecified, we fallback to the frame anchor. We also need to know the
94
94
// facet offsets to detect when the tip would draw outside the plot, and
95
95
// thus we need to change the orientation.
96
- const { x1 : X1 , y1 : Y1 , x2 : X2 , y2 : Y2 , x : X = X1 ?? X2 , y : Y = Y1 ?? Y2 } = channels ;
96
+ const { x1 : X1 , y1 : Y1 , x2 : X2 , y2 : Y2 , x : X = X1 ?? X2 , y : Y = Y1 ?? Y2 } = values ;
97
97
const ox = fx ? fx ( index . fx ) - marginLeft : 0 ;
98
98
const oy = fy ? fy ( index . fy ) - marginTop : 0 ;
99
- const [ px , py ] = pointerPosition ( mark , channels , dimensions ) ;
99
+
100
+ // The order of precedence for the anchor position is: the middle of x1 & y1
101
+ // and x2 & y2; or x1 & y1 (e.g., area); or lastly x & y. If a dimension is
102
+ // unspecified, the frame anchor is used.
103
+ const [ cx , cy ] = applyFrameAnchor ( this , dimensions ) ;
104
+ const px = anchorX ( values , cx ) ;
105
+ const py = anchorY ( values , cy ) ;
100
106
101
107
// Resolve the text metric implementation. We may need an ellipsis for text
102
108
// truncation, so we optimistically compute the ellipsis width.
@@ -123,7 +129,7 @@ export class Tip extends Mark {
123
129
const channel = sources [ key ] ;
124
130
const value = channel . value [ i ] ;
125
131
if ( ! defined ( value ) && channel . scale == null ) continue ;
126
- const color = channel . scale === "color" ? channels [ key ] [ i ] : undefined ;
132
+ const color = channel . scale === "color" ? values [ key ] [ i ] : undefined ;
127
133
if ( key === "x2" && "x1" in sources ) {
128
134
yield [ formatLabel ( scales , channel , "x" ) , formatPair ( sources . x1 , channel , i ) ] ;
129
135
} else if ( key === "y2" && "y1" in sources ) {
0 commit comments