|
1 |
| -import {extent, format, timeFormat, utcFormat} from "d3"; |
| 1 | +import {extent, format, scaleIdentity, timeFormat, utcFormat} from "d3"; |
2 | 2 | import {formatDefault} from "../format.js";
|
3 | 3 | import {marks} from "../mark.js";
|
4 | 4 | import {radians} from "../math.js";
|
@@ -129,32 +129,35 @@ function axisKy(
|
129 | 129 | })
|
130 | 130 | : null,
|
131 | 131 | !isNoneish(fill) && label !== null
|
132 |
| - ? text( |
133 |
| - [], |
134 |
| - labelOptions({fill, fillOpacity, ...options}, function (data, facets, channels, scales, dimensions) { |
135 |
| - const scale = scales[k]; |
136 |
| - const {marginTop, marginRight, marginBottom, marginLeft} = (k === "y" && dimensions.inset) || dimensions; |
137 |
| - const cla = labelAnchor ?? (scale.bandwidth ? "center" : "top"); |
138 |
| - const clo = labelOffset ?? (anchor === "right" ? marginRight : marginLeft) - 3; |
139 |
| - if (cla === "center") { |
140 |
| - this.textAnchor = undefined; // middle |
141 |
| - this.lineAnchor = anchor === "right" ? "bottom" : "top"; |
142 |
| - this.frameAnchor = anchor; |
143 |
| - this.rotate = -90; |
144 |
| - } else { |
145 |
| - this.textAnchor = anchor === "right" ? "end" : "start"; |
146 |
| - this.lineAnchor = cla; |
147 |
| - this.frameAnchor = `${cla}-${anchor}`; |
148 |
| - this.rotate = 0; |
149 |
| - } |
150 |
| - this.dy = cla === "top" ? 3 - marginTop : cla === "bottom" ? marginBottom - 3 : 0; |
151 |
| - this.dx = anchor === "right" ? clo : -clo; |
152 |
| - this.ariaLabel = `${k}-axis label`; |
153 |
| - return { |
154 |
| - facets: [[0]], |
155 |
| - channels: {text: {value: [formatAxisLabel(k, scale, {anchor, label, labelAnchor: cla, labelArrow})]}} |
156 |
| - }; |
157 |
| - }) |
| 132 | + ? Object.assign( |
| 133 | + text( |
| 134 | + [], |
| 135 | + labelOptions({fill, fillOpacity, ...options}, function (data, facets, channels, scales, dimensions) { |
| 136 | + const scale = scales[k]; |
| 137 | + const {marginTop, marginRight, marginBottom, marginLeft} = (k === "y" && dimensions.inset) || dimensions; |
| 138 | + const cla = labelAnchor ?? (scale.bandwidth ? "center" : "top"); |
| 139 | + const clo = labelOffset ?? (anchor === "right" ? marginRight : marginLeft) - 3; |
| 140 | + if (cla === "center") { |
| 141 | + this.textAnchor = undefined; // middle |
| 142 | + this.lineAnchor = anchor === "right" ? "bottom" : "top"; |
| 143 | + this.frameAnchor = anchor; |
| 144 | + this.rotate = -90; |
| 145 | + } else { |
| 146 | + this.textAnchor = anchor === "right" ? "end" : "start"; |
| 147 | + this.lineAnchor = cla; |
| 148 | + this.frameAnchor = `${cla}-${anchor}`; |
| 149 | + this.rotate = 0; |
| 150 | + } |
| 151 | + this.dy = cla === "top" ? 3 - marginTop : cla === "bottom" ? marginBottom - 3 : 0; |
| 152 | + this.dx = anchor === "right" ? clo : -clo; |
| 153 | + this.ariaLabel = `${k}-axis label`; |
| 154 | + return { |
| 155 | + facets: [[0]], |
| 156 | + channels: {text: {value: [formatAxisLabel(k, scale, {anchor, label, labelAnchor: cla, labelArrow})]}} |
| 157 | + }; |
| 158 | + }) |
| 159 | + ), |
| 160 | + {zoom: null} |
158 | 161 | )
|
159 | 162 | : null
|
160 | 163 | );
|
@@ -230,29 +233,32 @@ function axisKx(
|
230 | 233 | })
|
231 | 234 | : null,
|
232 | 235 | !isNoneish(fill) && label !== null
|
233 |
| - ? text( |
234 |
| - [], |
235 |
| - labelOptions({fill, fillOpacity, ...options}, function (data, facets, channels, scales, dimensions) { |
236 |
| - const scale = scales[k]; |
237 |
| - const {marginTop, marginRight, marginBottom, marginLeft} = (k === "x" && dimensions.inset) || dimensions; |
238 |
| - const cla = labelAnchor ?? (scale.bandwidth ? "center" : "right"); |
239 |
| - const clo = labelOffset ?? (anchor === "top" ? marginTop : marginBottom) - 3; |
240 |
| - if (cla === "center") { |
241 |
| - this.frameAnchor = anchor; |
242 |
| - this.textAnchor = undefined; // middle |
243 |
| - } else { |
244 |
| - this.frameAnchor = `${anchor}-${cla}`; |
245 |
| - this.textAnchor = cla === "right" ? "end" : "start"; |
246 |
| - } |
247 |
| - this.lineAnchor = anchor; |
248 |
| - this.dy = anchor === "top" ? -clo : clo; |
249 |
| - this.dx = cla === "right" ? marginRight - 3 : cla === "left" ? 3 - marginLeft : 0; |
250 |
| - this.ariaLabel = `${k}-axis label`; |
251 |
| - return { |
252 |
| - facets: [[0]], |
253 |
| - channels: {text: {value: [formatAxisLabel(k, scale, {anchor, label, labelAnchor: cla, labelArrow})]}} |
254 |
| - }; |
255 |
| - }) |
| 236 | + ? Object.assign( |
| 237 | + text( |
| 238 | + [], |
| 239 | + labelOptions({fill, fillOpacity, ...options}, function (data, facets, channels, scales, dimensions) { |
| 240 | + const scale = scales[k]; |
| 241 | + const {marginTop, marginRight, marginBottom, marginLeft} = (k === "x" && dimensions.inset) || dimensions; |
| 242 | + const cla = labelAnchor ?? (scale.bandwidth ? "center" : "right"); |
| 243 | + const clo = labelOffset ?? (anchor === "top" ? marginTop : marginBottom) - 3; |
| 244 | + if (cla === "center") { |
| 245 | + this.frameAnchor = anchor; |
| 246 | + this.textAnchor = undefined; // middle |
| 247 | + } else { |
| 248 | + this.frameAnchor = `${anchor}-${cla}`; |
| 249 | + this.textAnchor = cla === "right" ? "end" : "start"; |
| 250 | + } |
| 251 | + this.lineAnchor = anchor; |
| 252 | + this.dy = anchor === "top" ? -clo : clo; |
| 253 | + this.dx = cla === "right" ? marginRight - 3 : cla === "left" ? 3 - marginLeft : 0; |
| 254 | + this.ariaLabel = `${k}-axis label`; |
| 255 | + return { |
| 256 | + facets: [[0]], |
| 257 | + channels: {text: {value: [formatAxisLabel(k, scale, {anchor, label, labelAnchor: cla, labelArrow})]}} |
| 258 | + }; |
| 259 | + }) |
| 260 | + ), |
| 261 | + {zoom: null} |
256 | 262 | )
|
257 | 263 | : null
|
258 | 264 | );
|
@@ -507,8 +513,10 @@ function labelOptions(
|
507 | 513 |
|
508 | 514 | function axisMark(mark, k, ariaLabel, data, options, initialize) {
|
509 | 515 | let channels;
|
| 516 | + let u; |
510 | 517 |
|
511 | 518 | function axisInitializer(data, facets, _channels, scales, dimensions, context) {
|
| 519 | + u = arguments; |
512 | 520 | const initializeFacets = data == null && (k === "fx" || k === "fy");
|
513 | 521 | const {[k]: scale} = scales;
|
514 | 522 | if (!scale) throw new Error(`missing scale: ${k}`);
|
@@ -564,6 +572,24 @@ function axisMark(mark, k, ariaLabel, data, options, initialize) {
|
564 | 572 | channels = {};
|
565 | 573 | }
|
566 | 574 | m.ariaLabel = ariaLabel;
|
| 575 | + m.zoom = function (g, transform) { |
| 576 | + if (!(k === "x" || k === "y")) return g; |
| 577 | + const [, , , {[k]: scale}, dimensions, context] = [...u]; |
| 578 | + if (scale.bandwidth) return g; // TODO ordinal scales? |
| 579 | + const scale2 = transform[k === "x" ? "rescaleX" : "rescaleY"](scale ?? scaleIdentity()); |
| 580 | + const ticks = scale2.ticks(); |
| 581 | + g.replaceWith( |
| 582 | + (g = m.render.call( |
| 583 | + m, |
| 584 | + ticks.map((d, i) => i), |
| 585 | + {[k]: scale2}, |
| 586 | + {[k]: ticks.map(scale2), text: ticks}, |
| 587 | + dimensions, |
| 588 | + context |
| 589 | + )) |
| 590 | + ); |
| 591 | + return g; |
| 592 | + }; |
567 | 593 | return m;
|
568 | 594 | }
|
569 | 595 |
|
|
0 commit comments