@uwdata/mosaic-plot 0.13.0 → 0.14.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwdata/mosaic-plot",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "A Mosaic-powered plotting framework based on Observable Plot.",
5
5
  "keywords": [
6
6
  "data",
@@ -26,10 +26,10 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@observablehq/plot": "^0.6.17",
29
- "@uwdata/mosaic-core": "^0.13.0",
30
- "@uwdata/mosaic-sql": "^0.13.0",
29
+ "@uwdata/mosaic-core": "^0.14.0",
30
+ "@uwdata/mosaic-sql": "^0.14.0",
31
31
  "d3": "^7.9.0",
32
32
  "isoformat": "^0.2.1"
33
33
  },
34
- "gitHead": "b5a0e03e200c0f04c46562a288f084ffc9f6ad55"
34
+ "gitHead": "a882aab60867e4e9d9738bc950aa9de32729a806"
35
35
  }
@@ -1,8 +1,6 @@
1
- import { ExprNode, add, dateBin, div, float64, floor, interval, mul, sub } from '@uwdata/mosaic-sql';
1
+ import { ExprNode, binDate, binHistogram } from '@uwdata/mosaic-sql';
2
2
  import { Transform } from '../symbols.js';
3
3
  import { channelScale } from '../marks/util/channel-scale.js';
4
- import { bins } from './bin-step.js';
5
- import { timeInterval } from './time-interval.js';
6
4
 
7
5
  const EXTENT = new Set([
8
6
  'rectY-x', 'rectX-y', 'rect-x', 'rect-y', 'ruleY-x', 'ruleX-y'
@@ -54,29 +52,12 @@ class BinTransformNode extends ExprNode {
54
52
  toString() {
55
53
  const { mark, channel, column, options } = this;
56
54
  const { type, min, max } = mark.channelField(channel);
57
- const { interval: i, steps, offset = 0 } = options;
58
- const ival = i ?? (
59
- type === 'date' || hasTimeScale(mark, channel) ? 'date' : 'number'
60
- );
61
-
62
- let result;
63
- if (ival === 'number') {
64
- // perform number binning
65
- const { apply, sqlApply, sqlInvert } = channelScale(mark, channel);
66
- const b = bins(apply(min), apply(max), options);
67
- const col = sqlApply(column);
68
- const alpha = float64((b.max - b.min) / b.steps);
69
- const bin = floor(div(b.min === 0 ? col : sub(col, b.min), alpha));
70
- const expr = add(b.min, mul(alpha, offset ? add(offset, bin) : bin));
71
- result = sqlInvert(expr);
72
- } else {
73
- // perform date/time binning
74
- const { interval: unit, step = 1 } = ival === 'date'
75
- ? timeInterval(min, max, steps || 40)
76
- : options;
77
- const bin = dateBin(column, unit, step);
78
- result = offset ? add(bin, interval(unit, offset * step)) : bin;
79
- }
55
+ const isDate = options.interval
56
+ || type === 'date'
57
+ || hasTimeScale(mark, channel);
58
+ const result = isDate
59
+ ? binDate(column, [min, max], options)
60
+ : binHistogram(column, [min, max], options, channelScale(mark, channel));
80
61
  return `${result}`;
81
62
  }
82
63
  }
@@ -1,43 +0,0 @@
1
- export function binStep(span, steps, minstep = 0, logb = Math.LN10) {
2
- let v;
3
-
4
- const level = Math.ceil(Math.log(steps) / logb);
5
- let step = Math.max(
6
- minstep,
7
- Math.pow(10, Math.round(Math.log(span) / logb) - level)
8
- );
9
-
10
- // increase step size if too many bins
11
- while (Math.ceil(span / step) > steps) { step *= 10; }
12
-
13
- // decrease step size if allowed
14
- const div = [5, 2];
15
- for (let i = 0, n = div.length; i < n; ++i) {
16
- v = step / div[i];
17
- if (v >= minstep && span / v <= steps) step = v;
18
- }
19
-
20
- return step;
21
- }
22
-
23
- export function bins(min, max, options) {
24
- let { step, steps, minstep = 0, nice = true } = options;
25
-
26
- if (nice !== false) {
27
- // use span to determine step size
28
- const span = max - min;
29
- const logb = Math.LN10;
30
- step = step || binStep(span, steps || 25, minstep, logb);
31
-
32
- // adjust min/max relative to step
33
- let v = Math.log(step);
34
- const precision = v >= 0 ? 0 : ~~(-v / logb) + 1;
35
- const eps = Math.pow(10, -precision - 1);
36
- v = Math.floor(min / step + eps) * step;
37
- min = min < v ? v - step : v;
38
- max = Math.ceil(max / step) * step;
39
- steps = Math.round((max - min) / step);
40
- }
41
-
42
- return { min, max, steps };
43
- }
@@ -1,53 +0,0 @@
1
- import { bisector } from 'd3';
2
- import { binStep } from './bin-step.js';
3
-
4
- const YEAR = 'year';
5
- const MONTH = 'month';
6
- const DAY = 'day';
7
- const HOUR = 'hour';
8
- const MINUTE = 'minute';
9
- const SECOND = 'second';
10
- const MILLISECOND = 'millisecond';
11
-
12
- const durationSecond = 1000;
13
- const durationMinute = durationSecond * 60;
14
- const durationHour = durationMinute * 60;
15
- const durationDay = durationHour * 24;
16
- const durationWeek = durationDay * 7;
17
- const durationMonth = durationDay * 30;
18
- const durationYear = durationDay * 365;
19
-
20
- /** @type {[string, number, number][]} */
21
- const intervals = [
22
- [SECOND, 1, durationSecond],
23
- [SECOND, 5, 5 * durationSecond],
24
- [SECOND, 15, 15 * durationSecond],
25
- [SECOND, 30, 30 * durationSecond],
26
- [MINUTE, 1, durationMinute],
27
- [MINUTE, 5, 5 * durationMinute],
28
- [MINUTE, 15, 15 * durationMinute],
29
- [MINUTE, 30, 30 * durationMinute],
30
- [ HOUR, 1, durationHour ],
31
- [ HOUR, 3, 3 * durationHour ],
32
- [ HOUR, 6, 6 * durationHour ],
33
- [ HOUR, 12, 12 * durationHour ],
34
- [ DAY, 1, durationDay ],
35
- [ DAY, 7, durationWeek ],
36
- [ MONTH, 1, durationMonth ],
37
- [ MONTH, 3, 3 * durationMonth ],
38
- [ YEAR, 1, durationYear ]
39
- ];
40
-
41
- export function timeInterval(min, max, steps) {
42
- const span = max - min;
43
- const target = span / steps;
44
- let i = bisector(i => i[2]).right(intervals, target);
45
- if (i === intervals.length) {
46
- return { interval: YEAR, step: binStep(span / durationYear, steps) };
47
- } else if (i) {
48
- i = intervals[target / intervals[i - 1][2] < intervals[i][2] / target ? i - 1 : i];
49
- return { interval: i[0], step: i[1] };
50
- } else {
51
- return { interval: MILLISECOND, step: binStep(span, steps, 1) };
52
- }
53
- }