Skip to content

Commit

Permalink
inline & clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil committed Oct 12, 2023
1 parent fc98510 commit 694b0ff
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 66 deletions.
71 changes: 19 additions & 52 deletions src/dimensions.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,34 @@
import {extent, max} from "d3";
import {createProjection, projectionAspectRatio} from "./projection.js";
import {createScales, isOrdinalScale} from "./scales.js";
import {projectionAspectRatio} from "./projection.js";
import {isOrdinalScale} from "./scales.js";
import {offset} from "./style.js";
import {defaultWidth, monospaceWidth} from "./marks/text.js";
import {createScaleFunctions, autoScaleRange, innerDimensions, outerDimensions} from "./scales.js";
import {outerDimensions} from "./scales.js";

const marginMedium = 60;
const marginLarge = 90;

// When axes have "auto" margins, we might need to adjust the margins, after
// seeing the actual tick labels. In that case we’ll compute the dimensions and
// scales a second time.
function autoMarginK(margin, {k: scale, labelAnchor, label}, options, mark, stateByMark, scales, dimensions, context) {
export function autoMarginK(
margin,
{scale, labelAnchor, label},
options,
mark,
stateByMark,
scales,
dimensions,
context
) {
let {data, facets, channels} = stateByMark.get(mark);
if (mark.initializer) ({channels} = mark.initializer(data, facets, {}, scales, dimensions, context));
const width = mark.monospace ? (d) => (monospaceWidth(d) * 3) / 5 : defaultWidth;
const actualLabel = label ?? scales[scale].label;
const width = mark.monospace ? monospaceWidth : defaultWidth;
const labelPenalty =
(label ?? scales[scale].label ?? "") !== "" &&
(labelAnchor === "center" || (labelAnchor == null && scales[scale].bandwidth));
const l =
max(channels.text.value, (t) => (t ? width(`${t}`) : NaN)) +
(actualLabel != null &&
actualLabel !== "" &&
((labelAnchor == null && scales[scale].bandwidth) || labelAnchor === "center")
? 100
: 0);
max(channels.text.value, (t) => (t ? width(`${t}`) : NaN)) * (mark.monospace ? 0.6 : 1) + (labelPenalty ? 100 : 0);
const m = l >= 500 ? marginLarge : l >= 295 ? marginMedium : null;
return m === null
? options
Expand All @@ -31,46 +37,7 @@ function autoMarginK(margin, {k: scale, labelAnchor, label}, options, mark, stat
: {[margin]: m, ...options};
}

export function createDimensionsScales(channels, marks, stateByMark, options, context) {
const scaleDescriptors = createScales(channels, options);
const {dimensions, autoMargins} = createDimensions(scaleDescriptors, marks, options);
autoScaleRange(scaleDescriptors, dimensions); // !! mutates scales ranges…
const scales = createScaleFunctions(scaleDescriptors);
const {fx, fy} = scales;
const subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions;
const superdimensions = fx || fy ? actualDimensions(scaleDescriptors, dimensions) : dimensions;
context.projection = createProjection(options, subdimensions);

// Review the auto margins and create new scales if more space is needed.
const originalOptions = options;
for (const [margin, scale, mark] of autoMargins) {
options = autoMarginK(
margin,
scale,
options,
mark,
stateByMark,
scales,
mark.facet === "super" ? superdimensions : subdimensions,
context
);
}
if (options !== originalOptions) {
const scaleDescriptors = createScales(channels, options);
const {dimensions} = createDimensions(scaleDescriptors, marks, options);
autoScaleRange(scaleDescriptors, dimensions);
const scales = createScaleFunctions(scaleDescriptors);
const {fx, fy} = scaleDescriptors;
const subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions;
const superdimensions = fx || fy ? actualDimensions(scaleDescriptors, dimensions) : dimensions;
context.projection = createProjection(options, subdimensions);
return {scaleDescriptors, scales, dimensions, subdimensions, superdimensions};
}

return {scaleDescriptors, scales, dimensions, subdimensions, superdimensions};
}

function createDimensions(scales, marks, options = {}) {
export function createDimensions(scales, marks, options = {}) {
// Compute the default margins: the maximum of the marks’ margins. While not
// always used, they may be needed to compute the default height of the plot.
let marginTopDefault = 0.5 - offset,
Expand Down
4 changes: 2 additions & 2 deletions src/marks/axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ function axisKy(
const autoMarginRight = margin === undefined &&
marginRight === undefined &&
anchor === "right" &&
x == null && {k, labelAnchor, label};
x == null && {scale: k, labelAnchor, label};
const autoMarginLeft = margin === undefined &&
marginLeft === undefined &&
anchor === "left" &&
x == null && {k, labelAnchor, label};
x == null && {scale: k, labelAnchor, label};
marginRight = margin === undefined ? (anchor === "right" ? 40 : 0) : margin;
marginLeft = margin === undefined ? (anchor === "left" ? 40 : 0) : margin;
return marks(
Expand Down
50 changes: 38 additions & 12 deletions src/plot.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {creator, select} from "d3";
import {createChannel, inferChannelScale} from "./channel.js";
import {createContext} from "./context.js";
import {createDimensionsScales} from "./dimensions.js";
import {createDimensions, autoMarginK, actualDimensions} from "./dimensions.js";
import {createFacets, recreateFacets, facetExclude, facetGroups, facetTranslator, facetFilter} from "./facet.js";
import {pointer, pointerX, pointerY} from "./interactions/pointer.js";
import {createLegends, exposeLegends} from "./legends.js";
Expand All @@ -11,8 +11,9 @@ import {frame} from "./marks/frame.js";
import {tip} from "./marks/tip.js";
import {isColor, isIterable, isNone, isScaleOptions} from "./options.js";
import {arrayify, map, yes, maybeIntervalTransform, subarray} from "./options.js";
import {getGeometryChannels, hasProjection} from "./projection.js";
import {createScales, createScaleFunctions, exposeScales} from "./scales.js";
import {createProjection, getGeometryChannels, hasProjection} from "./projection.js";
import {createScales, createScaleFunctions, autoScaleRange, exposeScales} from "./scales.js";
import {innerDimensions} from "./scales.js";
import {isPosition, registry as scaleRegistry} from "./scales/index.js";
import {applyInlineStyles, maybeClassName} from "./style.js";
import {initializer} from "./transforms/basic.js";
Expand Down Expand Up @@ -158,16 +159,41 @@ export function plot(options = {}) {
return {...state, channels: {...state.channels, ...facetState?.channels}};
};

// Initialize the dimensions and scales.
// Initialize the dimensions and scales. Needs a double take when the left or
// right margins are based on the y (and fy) actual tick labels.
const channels = addScaleChannels(channelsByScale, stateByMark, options);
const {scaleDescriptors, scales, dimensions, subdimensions, superdimensions} = createDimensionsScales(
channels,
marks,
stateByMark,
options,
context
);
const {fx, fy} = scales;
let scaleDescriptors = createScales(channels, options);
let {dimensions, autoMargins} = createDimensions(scaleDescriptors, marks, options);
autoScaleRange(scaleDescriptors, dimensions); // !! mutates scales ranges…
let scales = createScaleFunctions(scaleDescriptors);
let {fx, fy} = scales;
let subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions;
let superdimensions = fx || fy ? actualDimensions(scaleDescriptors, dimensions) : dimensions;
context.projection = createProjection(options, subdimensions);

// Review the auto margins and create new scales if more space is needed.
const originalOptions = options;
for (const [margin, scale, mark] of autoMargins) {
options = autoMarginK(
margin,
scale,
options,
mark,
stateByMark,
scales,
mark.facet === "super" ? superdimensions : subdimensions,
context
);
}
if (options !== originalOptions) {
scaleDescriptors = createScales(channels, options);
dimensions = createDimensions(scaleDescriptors, marks, options).dimensions;
autoScaleRange(scaleDescriptors, dimensions);
({fx, fy} = scales = createScaleFunctions(scaleDescriptors));
subdimensions = fx || fy ? innerDimensions(scaleDescriptors, dimensions) : dimensions;
superdimensions = fx || fy ? actualDimensions(scaleDescriptors, dimensions) : dimensions;
context.projection = createProjection(options, subdimensions);
}

// Allows e.g. the pointer transform to support viewof.
context.dispatchValue = (value) => {
Expand Down

0 comments on commit 694b0ff

Please sign in to comment.