@decidables/discountable-elements 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -738,7 +738,6 @@
738
738
  const ascendingBisect = bisector(ascending$1);
739
739
  const bisectRight = ascendingBisect.right;
740
740
  bisector(number$4).center;
741
- var bisect = bisectRight;
742
741
 
743
742
  function count(values, valueof) {
744
743
  let count = 0;
@@ -6055,7 +6054,6 @@
6055
6054
  function areaRingEnd() {
6056
6055
  areaPoint(x00$2, y00$2);
6057
6056
  }
6058
- var pathArea = areaStream;
6059
6057
 
6060
6058
  var x0$2 = Infinity,
6061
6059
  y0$2 = x0$2,
@@ -6079,7 +6077,6 @@
6079
6077
  if (y < y0$2) y0$2 = y;
6080
6078
  if (y > y1) y1 = y;
6081
6079
  }
6082
- var boundsStream$1 = boundsStream;
6083
6080
 
6084
6081
  // TODO Enforce positive area for exterior, negative area for interior?
6085
6082
 
@@ -6162,7 +6159,6 @@
6162
6159
  Z2 += z * 3;
6163
6160
  centroidPoint(x0$1 = x, y0$1 = y);
6164
6161
  }
6165
- var pathCentroid = centroidStream;
6166
6162
 
6167
6163
  function PathContext(context) {
6168
6164
  this._context = context;
@@ -6245,7 +6241,6 @@
6245
6241
  lengthSum.add(sqrt$1(x0 * x0 + y0 * y0));
6246
6242
  x0 = x, y0 = y;
6247
6243
  }
6248
- var pathMeasure = lengthStream;
6249
6244
 
6250
6245
  // Simple caching for constant-radius points.
6251
6246
  let cacheDigits, cacheAppend, cacheRadius, cacheCircle;
@@ -6347,20 +6342,20 @@
6347
6342
  return contextStream.result();
6348
6343
  }
6349
6344
  path.area = function (object) {
6350
- geoStream(object, projectionStream(pathArea));
6351
- return pathArea.result();
6345
+ geoStream(object, projectionStream(areaStream));
6346
+ return areaStream.result();
6352
6347
  };
6353
6348
  path.measure = function (object) {
6354
- geoStream(object, projectionStream(pathMeasure));
6355
- return pathMeasure.result();
6349
+ geoStream(object, projectionStream(lengthStream));
6350
+ return lengthStream.result();
6356
6351
  };
6357
6352
  path.bounds = function (object) {
6358
- geoStream(object, projectionStream(boundsStream$1));
6359
- return boundsStream$1.result();
6353
+ geoStream(object, projectionStream(boundsStream));
6354
+ return boundsStream.result();
6360
6355
  };
6361
6356
  path.centroid = function (object) {
6362
- geoStream(object, projectionStream(pathCentroid));
6363
- return pathCentroid.result();
6357
+ geoStream(object, projectionStream(centroidStream));
6358
+ return centroidStream.result();
6364
6359
  };
6365
6360
  path.projection = function (_) {
6366
6361
  if (!arguments.length) return projection;
@@ -6431,8 +6426,8 @@
6431
6426
  var clip = projection.clipExtent && projection.clipExtent();
6432
6427
  projection.scale(150).translate([0, 0]);
6433
6428
  if (clip != null) projection.clipExtent(null);
6434
- geoStream(object, projection.stream(boundsStream$1));
6435
- fitBounds(boundsStream$1.result());
6429
+ geoStream(object, projection.stream(boundsStream));
6430
+ fitBounds(boundsStream.result());
6436
6431
  if (clip != null) projection.clipExtent(clip);
6437
6432
  return projection;
6438
6433
  }
@@ -7304,7 +7299,7 @@
7304
7299
  r[i] = interpolate(range[i], range[i + 1]);
7305
7300
  }
7306
7301
  return function (x) {
7307
- var i = bisect(domain, x, 1, j) - 1;
7302
+ var i = bisectRight(domain, x, 1, j) - 1;
7308
7303
  return r[i](d[i](x));
7309
7304
  };
7310
7305
  }
@@ -7662,7 +7657,7 @@
7662
7657
  return scale;
7663
7658
  }
7664
7659
  function scale(x) {
7665
- return x == null || isNaN(x = +x) ? unknown : range[bisect(thresholds, x)];
7660
+ return x == null || isNaN(x = +x) ? unknown : range[bisectRight(thresholds, x)];
7666
7661
  }
7667
7662
  scale.invertExtent = function (y) {
7668
7663
  var i = range.indexOf(y);
@@ -7696,7 +7691,7 @@
7696
7691
  unknown,
7697
7692
  n = 1;
7698
7693
  function scale(x) {
7699
- return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;
7694
+ return x != null && x <= x ? range[bisectRight(domain, x, 0, n)] : unknown;
7700
7695
  }
7701
7696
  scale.domain = function (_) {
7702
7697
  return arguments.length ? (domain = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
@@ -13622,17 +13617,19 @@
13622
13617
  interval[intervalDuration] = durations.get(name);
13623
13618
  interval[intervalType] = "utc";
13624
13619
  }
13620
+ const utcFormatIntervals = [["year", utcYear, "utc"], ["month", utcMonth, "utc"], ["day", unixDay, "utc", 6 * durationMonth], ["hour", utcHour, "utc", 3 * durationDay], ["minute", utcMinute, "utc", 6 * durationHour], ["second", second$1, "utc", 30 * durationMinute]];
13621
+ const timeFormatIntervals = [["year", timeYear, "time"], ["month", timeMonth, "time"], ["day", timeDay, "time", 6 * durationMonth], ["hour", timeHour, "time", 3 * durationDay], ["minute", timeMinute, "time", 6 * durationHour], ["second", second$1, "time", 30 * durationMinute]];
13625
13622
 
13626
13623
  // An interleaved array of UTC and local time intervals, in descending order
13627
13624
  // from largest to smallest, used to determine the most specific standard time
13628
13625
  // format for a given array of dates. This is a subset of the tick intervals
13629
13626
  // listed above; we only need the breakpoints where the format changes.
13630
- const formatIntervals = [["year", utcYear, "utc"], ["year", timeYear, "time"], ["month", utcMonth, "utc"], ["month", timeMonth, "time"], ["day", unixDay, "utc", 6 * durationMonth], ["day", timeDay, "time", 6 * durationMonth],
13627
+ const formatIntervals = [utcFormatIntervals[0], timeFormatIntervals[0], utcFormatIntervals[1], timeFormatIntervals[1], utcFormatIntervals[2], timeFormatIntervals[2],
13631
13628
  // Below day, local time typically has an hourly offset from UTC and hence the
13632
13629
  // two are aligned and indistinguishable; therefore, we only consider UTC, and
13633
13630
  // we don’t consider these if the domain only has a single value.
13634
- ["hour", utcHour, "utc", 3 * durationDay], ["minute", utcMinute, "utc", 6 * durationHour], ["second", second$1, "utc", 30 * durationMinute]];
13635
- function parseInterval(input, intervals, type) {
13631
+ ...utcFormatIntervals.slice(3)];
13632
+ function parseTimeInterval(input) {
13636
13633
  let name = `${input}`.toLowerCase();
13637
13634
  if (name.endsWith("s")) name = name.slice(0, -1); // drop plural
13638
13635
  let period = 1;
@@ -13651,22 +13648,26 @@
13651
13648
  period *= 6;
13652
13649
  break;
13653
13650
  }
13654
- let interval = intervals.get(name);
13651
+ let interval = utcIntervals.get(name);
13655
13652
  if (!interval) throw new Error(`unknown interval: ${input}`);
13653
+ if (period > 1 && !interval.every) throw new Error(`non-periodic interval: ${name}`);
13654
+ return [name, period];
13655
+ }
13656
+ function maybeTimeInterval(input) {
13657
+ return asInterval(parseTimeInterval(input), "time");
13658
+ }
13659
+ function maybeUtcInterval(input) {
13660
+ return asInterval(parseTimeInterval(input), "utc");
13661
+ }
13662
+ function asInterval([name, period], type) {
13663
+ let interval = (type === "time" ? timeIntervals : utcIntervals).get(name);
13656
13664
  if (period > 1) {
13657
- if (!interval.every) throw new Error(`non-periodic interval: ${name}`);
13658
13665
  interval = interval.every(period);
13659
13666
  interval[intervalDuration] = durations.get(name) * period;
13660
13667
  interval[intervalType] = type;
13661
13668
  }
13662
13669
  return interval;
13663
13670
  }
13664
- function maybeTimeInterval(interval) {
13665
- return parseInterval(interval, timeIntervals, "time");
13666
- }
13667
- function maybeUtcInterval(interval) {
13668
- return parseInterval(interval, utcIntervals, "utc");
13669
- }
13670
13671
 
13671
13672
  // If the given interval is a standard time interval, we may be able to promote
13672
13673
  // it a larger aligned time interval, rather than showing every nth tick.
@@ -13708,17 +13709,20 @@
13708
13709
  return anchor === "left" || anchor === "right" ? (f1, f2) => `\n${f1}\n${f2}` // extra newline to keep f1 centered
13709
13710
  : anchor === "top" ? (f1, f2) => `${f2}\n${f1}` : (f1, f2) => `${f1}\n${f2}`;
13710
13711
  }
13712
+ function getFormatIntervals(type) {
13713
+ return type === "time" ? timeFormatIntervals : type === "utc" ? utcFormatIntervals : formatIntervals;
13714
+ }
13711
13715
 
13712
13716
  // Given an array of dates, returns the largest compatible standard time
13713
13717
  // interval. If no standard interval is compatible (other than milliseconds,
13714
13718
  // which is universally compatible), returns undefined.
13715
- function inferTimeFormat(dates, anchor) {
13719
+ function inferTimeFormat(type, dates, anchor) {
13716
13720
  const step = max(pairs(dates, (a, b) => Math.abs(b - a))); // maybe undefined!
13717
13721
  if (step < 1000) return formatTimeInterval("millisecond", "utc", anchor);
13718
- for (const [name, interval, type, maxStep] of formatIntervals) {
13722
+ for (const [name, interval, intervalType, maxStep] of getFormatIntervals(type)) {
13719
13723
  if (step > maxStep) break; // e.g., 52 weeks
13720
13724
  if (name === "hour" && !step) break; // e.g., domain with a single date
13721
- if (dates.every(d => interval.floor(d) >= d)) return formatTimeInterval(name, type, anchor);
13725
+ if (dates.every(d => interval.floor(d) >= d)) return formatTimeInterval(name, intervalType, anchor);
13722
13726
  }
13723
13727
  }
13724
13728
  function formatConditional(format1, format2, template) {
@@ -15640,7 +15644,9 @@
15640
15644
  return [x, y];
15641
15645
  }
15642
15646
 
15643
- const categoricalSchemes = new Map([["accent", schemeAccent], ["category10", schemeCategory10], ["dark2", schemeDark2], ["paired", schemePaired], ["pastel1", schemePastel1], ["pastel2", schemePastel2], ["set1", schemeSet1], ["set2", schemeSet2], ["set3", schemeSet3], ["tableau10", schemeTableau10]]);
15647
+ // TODO https://github.com/d3/d3-scale-chromatic/pull/51
15648
+ const schemeObservable10 = ["#4269d0", "#efb118", "#ff725c", "#6cc5b0", "#3ca951", "#ff8ab7", "#a463f2", "#97bbf5", "#9c6b4e", "#9498a0"];
15649
+ const categoricalSchemes = new Map([["accent", schemeAccent], ["category10", schemeCategory10], ["dark2", schemeDark2], ["observable10", schemeObservable10], ["paired", schemePaired], ["pastel1", schemePastel1], ["pastel2", schemePastel2], ["set1", schemeSet1], ["set2", schemeSet2], ["set3", schemeSet3], ["tableau10", schemeTableau10]]);
15644
15650
  function isCategoricalScheme(scheme) {
15645
15651
  return scheme != null && categoricalSchemes.has(`${scheme}`.toLowerCase());
15646
15652
  }
@@ -16223,7 +16229,7 @@
16223
16229
  if (range !== undefined) scheme = undefined; // Don’t re-apply scheme.
16224
16230
  }
16225
16231
  if (scheme === undefined && range === undefined) {
16226
- scheme = type === "ordinal" ? "turbo" : "tableau10";
16232
+ scheme = type === "ordinal" ? "turbo" : "observable10";
16227
16233
  }
16228
16234
  if (scheme !== undefined) {
16229
16235
  if (range !== undefined) {
@@ -16302,8 +16308,7 @@
16302
16308
  } of channels) {
16303
16309
  const candidate = hint?.[key];
16304
16310
  if (candidate === undefined) continue; // no hint here
16305
- if (value === undefined) value = candidate;
16306
- // first hint
16311
+ if (value === undefined) value = candidate; // first hint
16307
16312
  else if (value !== candidate) return; // inconsistent hint
16308
16313
  }
16309
16314
  return value;
@@ -16443,6 +16448,13 @@
16443
16448
  };
16444
16449
  }
16445
16450
 
16451
+ // Determines whether the scale points in the “positive” (right or down) or
16452
+ // “negative” (left or up) direction; if the scale order cannot be determined,
16453
+ // returns NaN; used to assign an appropriate label arrow.
16454
+ function inferScaleOrder(scale) {
16455
+ return Math.sign(orderof(scale.domain())) * Math.sign(orderof(scale.range()));
16456
+ }
16457
+
16446
16458
  // Returns the dimensions of the outer frame; this is subdivided into facets
16447
16459
  // with the margins of each facet collapsing into the outer margins.
16448
16460
  function outerDimensions(dimensions) {
@@ -16667,6 +16679,9 @@
16667
16679
  function formatScaleType(type) {
16668
16680
  return typeof type === "symbol" ? type.description : type;
16669
16681
  }
16682
+ function maybeScaleType(type) {
16683
+ return typeof type === "string" ? `${type}`.toLowerCase() : type;
16684
+ }
16670
16685
 
16671
16686
  // A special type symbol when the x and y scales are replaced with a projection.
16672
16687
  const typeProjection = {
@@ -16680,6 +16695,8 @@
16680
16695
  pivot,
16681
16696
  projection
16682
16697
  }) {
16698
+ type = maybeScaleType(type);
16699
+
16683
16700
  // The facet scales are always band scales; this cannot be changed.
16684
16701
  if (key === "fx" || key === "fy") return "band";
16685
16702
 
@@ -16691,9 +16708,8 @@
16691
16708
  // If a channel dictates a scale type, make sure that it is consistent with
16692
16709
  // the user-specified scale type (if any) and all other channels. For example,
16693
16710
  // barY requires x to be a band scale and disallows any other scale type.
16694
- for (const {
16695
- type: t
16696
- } of channels) {
16711
+ for (const channel of channels) {
16712
+ const t = maybeScaleType(channel.type);
16697
16713
  if (t === undefined) continue;else if (type === undefined) type = t;else if (type !== t) throw new Error(`scale incompatible with channel: ${type} !== ${t}`);
16698
16714
  }
16699
16715
 
@@ -16791,6 +16807,7 @@
16791
16807
  }, coerceValues) {
16792
16808
  for (const c of channels) {
16793
16809
  if (c.value !== undefined) {
16810
+ if (domain === undefined) domain = c.value?.domain; // promote channel domain
16794
16811
  c.value = coerceValues(c.value);
16795
16812
  }
16796
16813
  }
@@ -17716,15 +17733,14 @@
17716
17733
  if (tickFormat === null) tickFormat = () => null;
17717
17734
  const svg = create("svg", context).attr("class", `${className}-ramp`).attr("font-family", "system-ui, sans-serif").attr("font-size", 10).attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).call(svg =>
17718
17735
  // Warning: if you edit this, change defaultClassName.
17719
- svg.append("style").text(`.${className}-ramp {
17736
+ svg.append("style").text(`:where(.${className}-ramp) {
17720
17737
  display: block;
17721
- background: white;
17722
17738
  height: auto;
17723
17739
  height: intrinsic;
17724
17740
  max-width: 100%;
17725
17741
  overflow: visible;
17726
17742
  }
17727
- .${className}-ramp text {
17743
+ :where(.${className}-ramp text) {
17728
17744
  white-space: pre;
17729
17745
  }`)).call(applyInlineStyles, style);
17730
17746
  let tickAdjust = g => g.selectAll(".tick line").attr("y1", marginTop + marginBottom - height);
@@ -17826,6 +17842,12 @@
17826
17842
  return markerCircleFill;
17827
17843
  case "circle-stroke":
17828
17844
  return markerCircleStroke;
17845
+ case "tick":
17846
+ return markerTick("auto");
17847
+ case "tick-x":
17848
+ return markerTick(90);
17849
+ case "tick-y":
17850
+ return markerTick(0);
17829
17851
  }
17830
17852
  throw new Error(`invalid marker: ${marker}`);
17831
17853
  }
@@ -17836,10 +17858,13 @@
17836
17858
  return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", color).attr("stroke", "none").call(marker => marker.append("circle").attr("r", 2.5)).node();
17837
17859
  }
17838
17860
  function markerCircleFill(color, context) {
17839
- return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", color).attr("stroke", "white").attr("stroke-width", 1.5).call(marker => marker.append("circle").attr("r", 3)).node();
17861
+ return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", color).attr("stroke", "var(--plot-background)").attr("stroke-width", 1.5).call(marker => marker.append("circle").attr("r", 3)).node();
17840
17862
  }
17841
17863
  function markerCircleStroke(color, context) {
17842
- return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", "white").attr("stroke", color).attr("stroke-width", 1.5).call(marker => marker.append("circle").attr("r", 3)).node();
17864
+ return create("svg:marker", context).attr("viewBox", "-5 -5 10 10").attr("markerWidth", 6.67).attr("markerHeight", 6.67).attr("fill", "var(--plot-background)").attr("stroke", color).attr("stroke-width", 1.5).call(marker => marker.append("circle").attr("r", 3)).node();
17865
+ }
17866
+ function markerTick(orient) {
17867
+ return (color, context) => create("svg:marker", context).attr("viewBox", "-3 -3 6 6").attr("markerWidth", 6).attr("markerHeight", 6).attr("orient", orient).attr("stroke", color).call(marker => marker.append("path").attr("d", "M0,-3v6")).node();
17843
17868
  }
17844
17869
  let nextMarkerId = 0;
17845
17870
  function applyMarkers(path, mark, {
@@ -17945,7 +17970,7 @@
17945
17970
  ...options,
17946
17971
  [k]: undefined,
17947
17972
  [`${k}1`]: v1 === undefined ? kv : v1,
17948
- [`${k}2`]: v2 === undefined ? kv : v2
17973
+ [`${k}2`]: v2 === undefined && !(v1 === v2 && trivial) ? kv : v2
17949
17974
  };
17950
17975
  }
17951
17976
  let D1, V1;
@@ -18583,7 +18608,7 @@
18583
18608
  function monospaceWidth(text, start = 0, end = text.length) {
18584
18609
  let sum = 0;
18585
18610
  for (let i = start; i < end; i = readCharacter(text, i)) {
18586
- sum += isPictographic(text, i) ? 200 : 100;
18611
+ sum += isPictographic(text, i) ? 126 : 63;
18587
18612
  }
18588
18613
  return sum;
18589
18614
  }
@@ -19425,7 +19450,7 @@
19425
19450
  // possible, or the default ISO format (2014-01-26). TODO We need a better way
19426
19451
  // to infer whether the ordinal scale is UTC or local time.
19427
19452
  function inferTickFormat(scale, data, ticks, tickFormat, anchor) {
19428
- return typeof tickFormat === "function" ? tickFormat : tickFormat === undefined && data && isTemporal(data) ? inferTimeFormat(data, anchor) ?? formatDefault : scale.tickFormat ? scale.tickFormat(typeof ticks === "number" ? ticks : null, tickFormat) : tickFormat === undefined ? formatDefault : typeof tickFormat === "string" ? (isTemporal(scale.domain()) ? utcFormat : format$1)(tickFormat) : constant(tickFormat);
19453
+ return typeof tickFormat === "function" ? tickFormat : tickFormat === undefined && data && isTemporal(data) ? inferTimeFormat(scale.type, data, anchor) ?? formatDefault : scale.tickFormat ? scale.tickFormat(typeof ticks === "number" ? ticks : null, tickFormat) : tickFormat === undefined ? formatDefault : typeof tickFormat === "string" ? (isTemporal(scale.domain()) ? utcFormat : format$1)(tickFormat) : constant(tickFormat);
19429
19454
  }
19430
19455
  function inclusiveRange(interval, min, max) {
19431
19456
  return interval.range(min, interval.offset(interval.floor(max)));
@@ -19461,13 +19486,6 @@
19461
19486
  return scale.bandwidth && !scale.interval ? undefined : "tabular-nums";
19462
19487
  }
19463
19488
 
19464
- // Determines whether the scale points in the “positive” (right or down) or
19465
- // “negative” (left or up) direction; if the scale order cannot be determined,
19466
- // returns NaN; used to assign an appropriate label arrow.
19467
- function inferScaleOrder(scale) {
19468
- return Math.sign(orderof(scale.domain())) * Math.sign(orderof(scale.range()));
19469
- }
19470
-
19471
19489
  // Takes the scale label, and if this is not an ordinal scale and the label was
19472
19490
  // inferred from an associated channel, adds an orientation-appropriate arrow.
19473
19491
  function formatAxisLabel(k, scale, {
@@ -19559,29 +19577,29 @@
19559
19577
  const swatches = create("div", context).attr("class", `${className}-swatches ${className}-swatches-${columns != null ? "columns" : "wrap"}`);
19560
19578
  let extraStyle;
19561
19579
  if (columns != null) {
19562
- extraStyle = `.${className}-swatches-columns .${className}-swatch {
19580
+ extraStyle = `:where(.${className}-swatches-columns .${className}-swatch) {
19563
19581
  display: flex;
19564
19582
  align-items: center;
19565
19583
  break-inside: avoid;
19566
19584
  padding-bottom: 1px;
19567
19585
  }
19568
- .${className}-swatches-columns .${className}-swatch::before {
19586
+ :where(.${className}-swatches-columns .${className}-swatch::before) {
19569
19587
  flex-shrink: 0;
19570
19588
  }
19571
- .${className}-swatches-columns .${className}-swatch-label {
19589
+ :where(.${className}-swatches-columns .${className}-swatch-label) {
19572
19590
  white-space: nowrap;
19573
19591
  overflow: hidden;
19574
19592
  text-overflow: ellipsis;
19575
19593
  }`;
19576
19594
  swatches.style("columns", columns).selectAll().data(scale.domain).enter().append("div").attr("class", `${className}-swatch`).call(swatch, scale, swatchWidth, swatchHeight).call(item => item.append("div").attr("class", `${className}-swatch-label`).attr("title", tickFormat).text(tickFormat));
19577
19595
  } else {
19578
- extraStyle = `.${className}-swatches-wrap {
19596
+ extraStyle = `:where(.${className}-swatches-wrap) {
19579
19597
  display: flex;
19580
19598
  align-items: center;
19581
19599
  min-height: 33px;
19582
19600
  flex-wrap: wrap;
19583
19601
  }
19584
- .${className}-swatches-wrap .${className}-swatch {
19602
+ :where(.${className}-swatches-wrap .${className}-swatch) {
19585
19603
  display: inline-flex;
19586
19604
  align-items: center;
19587
19605
  margin-right: 1em;
@@ -19590,12 +19608,12 @@
19590
19608
  return this.ownerDocument.createTextNode(tickFormat.apply(this, arguments));
19591
19609
  });
19592
19610
  }
19593
- return swatches.call(div => div.insert("style", "*").text(`.${className}-swatches {
19611
+ return swatches.call(div => div.insert("style", "*").text(`:where(.${className}-swatches) {
19594
19612
  font-family: system-ui, sans-serif;
19595
19613
  font-size: 10px;
19596
19614
  margin-bottom: 0.5em;
19597
19615
  }
19598
- .${className}-swatch > svg {
19616
+ :where(.${className}-swatch > svg) {
19599
19617
  margin-right: 0.5em;
19600
19618
  overflow: visible;
19601
19619
  }
@@ -19748,7 +19766,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
19748
19766
 
19749
19767
  const defaults$2 = {
19750
19768
  ariaLabel: "tip",
19751
- fill: "white",
19769
+ fill: "var(--plot-background)",
19752
19770
  stroke: "currentColor"
19753
19771
  };
19754
19772
 
@@ -19772,6 +19790,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
19772
19790
  y1,
19773
19791
  y2,
19774
19792
  anchor,
19793
+ preferredAnchor = "bottom",
19775
19794
  monospace,
19776
19795
  fontFamily = monospace ? "ui-monospace, monospace" : undefined,
19777
19796
  fontSize,
@@ -19828,7 +19847,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
19828
19847
  } // filter: defined
19829
19848
  }, options, defaults$2);
19830
19849
  this.anchor = maybeAnchor$1(anchor, "anchor");
19831
- this.previousAnchor = this.anchor ?? "top-left";
19850
+ this.preferredAnchor = maybeAnchor$1(preferredAnchor, "preferredAnchor");
19832
19851
  this.frameAnchor = maybeFrameAnchor(frameAnchor);
19833
19852
  this.textAnchor = impliedString(textAnchor, "middle");
19834
19853
  this.textPadding = +textPadding;
@@ -19976,8 +19995,8 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
19976
19995
  const [k] = cut(value, w - widthof(label), widthof, ee);
19977
19996
  if (k >= 0) {
19978
19997
  // value is truncated
19979
- value = value.slice(0, k).trimEnd() + ellipsis;
19980
19998
  title = value.trim();
19999
+ value = value.slice(0, k).trimEnd() + ellipsis;
19981
20000
  }
19982
20001
  }
19983
20002
  const line = selection.append("tspan").attr("x", 0).attr("dy", `${lineHeight}em`).text("\u200b"); // zwsp for double-click
@@ -20003,16 +20022,13 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
20003
20022
  w = Math.round(w), h = Math.round(h); // crisp edges
20004
20023
  let a = anchor; // use the specified anchor, if any
20005
20024
  if (a === undefined) {
20006
- a = mark.previousAnchor; // favor the previous anchor, if it fits
20007
20025
  const x = px(i) + ox;
20008
20026
  const y = py(i) + oy;
20009
- const fitLeft = x + w + r * 2 < width;
20010
- const fitRight = x - w - r * 2 > 0;
20011
- const fitTop = y + h + m + r * 2 + 7 < height;
20027
+ const fitLeft = x + w + m + r * 2 < width;
20028
+ const fitRight = x - w - m - r * 2 > 0;
20029
+ const fitTop = y + h + m + r * 2 < height;
20012
20030
  const fitBottom = y - h - m - r * 2 > 0;
20013
- const ax = (/-left$/.test(a) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right";
20014
- const ay = (/^top-/.test(a) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom";
20015
- a = mark.previousAnchor = `${ay}-${ax}`;
20031
+ a = fitLeft && fitRight ? fitTop && fitBottom ? mark.preferredAnchor : fitBottom ? "bottom" : "top" : fitTop && fitBottom ? fitLeft ? "left" : "right" : (fitLeft || fitRight) && (fitTop || fitBottom) ? `${fitBottom ? "bottom" : "top"}-${fitLeft ? "left" : "right"}` : mark.preferredAnchor;
20016
20032
  }
20017
20033
  const path = this.firstChild; // note: assumes exactly two children!
20018
20034
  const text = this.lastChild; // note: assumes exactly two children!
@@ -20487,15 +20503,15 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
20487
20503
  } = dimensions;
20488
20504
  select(svg).attr("class", className).attr("fill", "currentColor").attr("font-family", "system-ui, sans-serif").attr("font-size", 10).attr("text-anchor", "middle").attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`).attr("aria-label", ariaLabel).attr("aria-description", ariaDescription).call(svg =>
20489
20505
  // Warning: if you edit this, change defaultClassName.
20490
- svg.append("style").text(`.${className} {
20506
+ svg.append("style").text(`:where(.${className}) {
20507
+ --plot-background: white;
20491
20508
  display: block;
20492
- background: white;
20493
20509
  height: auto;
20494
20510
  height: intrinsic;
20495
20511
  max-width: 100%;
20496
20512
  }
20497
- .${className} text,
20498
- .${className} tspan {
20513
+ :where(.${className} text),
20514
+ :where(.${className} tspan) {
20499
20515
  white-space: pre;
20500
20516
  }`)).call(applyInlineStyles, style);
20501
20517
 
@@ -20781,11 +20797,13 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
20781
20797
  pointer: tipOptions
20782
20798
  };
20783
20799
  let {
20784
- pointer: p
20800
+ pointer: p,
20801
+ preferredAnchor: a
20785
20802
  } = tipOptions;
20786
20803
  p = /^x$/i.test(p) ? pointerX : /^y$/i.test(p) ? pointerY : pointer; // TODO validate?
20787
20804
  tipOptions = p(derive(mark, tipOptions));
20788
20805
  tipOptions.title = null; // prevent implicit title for primitive data
20806
+ if (a === undefined) tipOptions.preferredAnchor = p === pointerY ? "left" : "bottom";
20789
20807
  const t = tip(mark.data, tipOptions);
20790
20808
  t.facet = mark.facet; // inherit facet settings
20791
20809
  t.facetAnchor = mark.facetAnchor; // inherit facet settings
@@ -21174,7 +21192,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
21174
21192
  const BX2 = bx && setBX2([]);
21175
21193
  const BY1 = by && setBY1([]);
21176
21194
  const BY2 = by && setBY2([]);
21177
- const bin = bing(bx?.(data), by?.(data));
21195
+ const bin = bing(bx, by, data);
21178
21196
  let i = 0;
21179
21197
  for (const o of outputs) o.initialize(data);
21180
21198
  if (sort) sort.initialize(data);
@@ -21403,13 +21421,16 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
21403
21421
  function isTimeThresholds(t) {
21404
21422
  return isTimeInterval(t) || isIterable(t) && isTemporal(t);
21405
21423
  }
21406
- function bing(EX, EY) {
21424
+ function bing(bx, by, data) {
21425
+ const EX = bx?.(data);
21426
+ const EY = by?.(data);
21407
21427
  return EX && EY ? function* (I) {
21408
21428
  const X = EX.bin(I); // first bin on x
21409
21429
  for (const [ix, [x1, x2]] of EX.entries()) {
21410
21430
  const Y = EY.bin(X[ix]); // then bin on y
21411
21431
  for (const [iy, [y1, y2]] of EY.entries()) {
21412
21432
  yield [Y[iy], {
21433
+ data,
21413
21434
  x1,
21414
21435
  y1,
21415
21436
  x2,
@@ -21421,6 +21442,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
21421
21442
  const X = EX.bin(I);
21422
21443
  for (const [i, [x1, x2]] of EX.entries()) {
21423
21444
  yield [X[i], {
21445
+ data,
21424
21446
  x1,
21425
21447
  x2
21426
21448
  }];
@@ -21429,6 +21451,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
21429
21451
  const Y = EY.bin(I);
21430
21452
  for (const [i, [y1, y2]] of EY.entries()) {
21431
21453
  yield [Y[i], {
21454
+ data,
21432
21455
  y1,
21433
21456
  y2
21434
21457
  }];
@@ -21441,7 +21464,7 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
21441
21464
  T = coerceNumbers(T); // for faster bisection
21442
21465
  return I => {
21443
21466
  const B = E.map(() => []);
21444
- for (const i of I) B[bisect(T, V[i]) - 1]?.push(i); // TODO quantization?
21467
+ for (const i of I) B[bisectRight(T, V[i]) - 1]?.push(i); // TODO quantization?
21445
21468
  return B;
21446
21469
  };
21447
21470
  }
@@ -21990,11 +22013,13 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
21990
22013
  x1: {
21991
22014
  value: x1,
21992
22015
  scale: "x",
22016
+ type: x1 != null && x2 == null ? "band" : undefined,
21993
22017
  optional: true
21994
22018
  },
21995
22019
  y1: {
21996
22020
  value: y1,
21997
22021
  scale: "y",
22022
+ type: y1 != null && y2 == null ? "band" : undefined,
21998
22023
  optional: true
21999
22024
  },
22000
22025
  x2: {
@@ -22045,10 +22070,9 @@ ${extraStyle}`)).style("margin-left", marginLeft ? `${+marginLeft}px` : null).st
22045
22070
  rx,
22046
22071
  ry
22047
22072
  } = this;
22048
- return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, {
22049
- x: X1 && X2 && x,
22050
- y: Y1 && Y2 && y
22051
- }, 0, 0).call(g => g.selectAll().data(index).enter().append("rect").call(applyDirectStyles, this).attr("x", X1 && X2 && (projection || !isCollapsed(x)) ? i => Math.min(X1[i], X2[i]) + insetLeft : marginLeft + insetLeft).attr("y", Y1 && Y2 && (projection || !isCollapsed(y)) ? i => Math.min(Y1[i], Y2[i]) + insetTop : marginTop + insetTop).attr("width", X1 && X2 && (projection || !isCollapsed(x)) ? i => Math.max(0, Math.abs(X2[i] - X1[i]) - insetLeft - insetRight) : width - marginRight - marginLeft - insetRight - insetLeft).attr("height", Y1 && Y2 && (projection || !isCollapsed(y)) ? i => Math.max(0, Math.abs(Y1[i] - Y2[i]) - insetTop - insetBottom) : height - marginTop - marginBottom - insetTop - insetBottom).call(applyAttr, "rx", rx).call(applyAttr, "ry", ry).call(applyChannelStyles, this, channels)).node();
22073
+ const bx = (x?.bandwidth ? x.bandwidth() : 0) - insetLeft - insetRight;
22074
+ const by = (y?.bandwidth ? y.bandwidth() : 0) - insetTop - insetBottom;
22075
+ return create("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyTransform, this, {}, 0, 0).call(g => g.selectAll().data(index).enter().append("rect").call(applyDirectStyles, this).attr("x", X1 && (projection || !isCollapsed(x)) ? X2 ? i => Math.min(X1[i], X2[i]) + insetLeft : i => X1[i] + insetLeft : marginLeft + insetLeft).attr("y", Y1 && (projection || !isCollapsed(y)) ? Y2 ? i => Math.min(Y1[i], Y2[i]) + insetTop : i => Y1[i] + insetTop : marginTop + insetTop).attr("width", X1 && (projection || !isCollapsed(x)) ? X2 ? i => Math.max(0, Math.abs(X2[i] - X1[i]) + bx) : bx : width - marginRight - marginLeft - insetRight - insetLeft).attr("height", Y1 && (projection || !isCollapsed(y)) ? Y2 ? i => Math.max(0, Math.abs(Y1[i] - Y2[i]) + by) : by : height - marginTop - marginBottom - insetTop - insetBottom).call(applyAttr, "rx", rx).call(applyAttr, "ry", ry).call(applyChannelStyles, this, channels)).node();
22052
22076
  }
22053
22077
  }
22054
22078
  function rectY(data, options = {}) {