Skip to content

Commit

Permalink
set context.path early (#2252)
Browse files Browse the repository at this point in the history
* Set context.path early

* adopt context.path

* don't scale twice! adds a unit test

* define path with projection

* pretty

* better test
  • Loading branch information
Fil authored Jan 3, 2025
1 parent 7d18179 commit 164fb66
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 22 deletions.
7 changes: 3 additions & 4 deletions src/marks/line.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {geoPath, line as shapeLine} from "d3";
import {line as shapeLine} from "d3";
import {create} from "../context.js";
import {curveAuto, maybeCurveAuto} from "../curve.js";
import {Mark} from "../mark.js";
Expand Down Expand Up @@ -67,7 +67,7 @@ export class Line extends Mark {
.attr(
"d",
curve === curveAuto && context.projection
? sphereLine(context.projection, X, Y)
? sphereLine(context.path(), X, Y)
: shapeLine()
.curve(curve)
.defined((i) => i >= 0)
Expand All @@ -79,8 +79,7 @@ export class Line extends Mark {
}
}

function sphereLine(projection, X, Y) {
const path = geoPath(projection);
function sphereLine(path, X, Y) {
X = coerceNumbers(X);
Y = coerceNumbers(Y);
return (I) => {
Expand Down
7 changes: 3 additions & 4 deletions src/marks/link.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {geoPath, pathRound as path} from "d3";
import {pathRound as path} from "d3";
import {create} from "../context.js";
import {curveAuto, maybeCurveAuto} from "../curve.js";
import {Mark} from "../mark.js";
Expand Down Expand Up @@ -52,7 +52,7 @@ export class Link extends Mark {
.attr(
"d",
curve === curveAuto && context.projection
? sphereLink(context.projection, X1, Y1, X2, Y2)
? sphereLink(context.path(), X1, Y1, X2, Y2)
: (i) => {
const p = path();
const c = curve(p);
Expand All @@ -70,8 +70,7 @@ export class Link extends Mark {
}
}

function sphereLink(projection, X1, Y1, X2, Y2) {
const path = geoPath(projection);
function sphereLink(path, X1, Y1, X2, Y2) {
X1 = coerceNumbers(X1);
Y1 = coerceNumbers(Y1);
X2 = coerceNumbers(X2);
Expand Down
10 changes: 5 additions & 5 deletions src/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ export function plot(options = {}) {
context.className = className;
context.projection = createProjection(options, subdimensions);

// A path generator for marks that want to draw GeoJSON.
context.path = function () {
return geoPath(this.projection ?? xyProjection(scales));
};

// Allows e.g. the axis mark to determine faceting lazily.
context.filterFacets = (data, channels) => {
return facetFilter(facets, {channels, groups: facetGroups(data, channels)});
Expand Down Expand Up @@ -236,11 +241,6 @@ export function plot(options = {}) {
facetTranslate = facetTranslator(fx, fy, dimensions);
}

// A path generator for marks that want to draw GeoJSON.
context.path = function () {
return geoPath(this.projection ?? xyProjection(scales));
};

// Compute value objects, applying scales and projection as needed.
for (const [mark, state] of stateByMark) {
state.values = mark.scale(state.channels, scales, context);
Expand Down
13 changes: 5 additions & 8 deletions src/transforms/centroid.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {geoCentroid as GeoCentroid, geoPath} from "d3";
import {geoCentroid as GeoCentroid} from "d3";
import {memoize1} from "../memoize.js";
import {identity, valueof} from "../options.js";
import {initializer} from "./basic.js";
Expand All @@ -9,20 +9,17 @@ export function centroid({geometry = identity, ...options} = {}) {
// Suppress defaults for x and y since they will be computed by the initializer.
// Propagate the (memoized) geometry channel in case it’s still needed.
{...options, x: null, y: null, geometry: {transform: getG}},
(data, facets, channels, scales, dimensions, {projection}) => {
(data, facets, channels, scales, dimensions, context) => {
const G = getG(data);
const n = G.length;
const X = new Float64Array(n);
const Y = new Float64Array(n);
const path = geoPath(projection);
for (let i = 0; i < n; ++i) [X[i], Y[i]] = path.centroid(G[i]);
const {centroid} = context.path();
for (let i = 0; i < n; ++i) [X[i], Y[i]] = centroid(G[i]);
return {
data,
facets,
channels: {
x: {value: X, scale: projection == null ? "x" : null, source: null},
y: {value: Y, scale: projection == null ? "y" : null, source: null}
}
channels: {x: {value: X, scale: null, source: null}, y: {value: Y, scale: null, source: null}}
};
}
);
Expand Down
Loading

0 comments on commit 164fb66

Please sign in to comment.