pyret-npm 0.0.70 → 0.0.71

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.
Files changed (14) hide show
  1. package/package.json +2 -1
  2. package/pyret-lang/build/phaseA/base.jarr +1916 -806
  3. package/pyret-lang/build/phaseA/lib-compiled/charts-d9ab4ce9dff6abe771a0ea5d7862476d87e5f7e2a7574918748d38ff2dc812d2-module.js +634 -417
  4. package/pyret-lang/build/phaseA/lib-compiled/charts-d9ab4ce9dff6abe771a0ea5d7862476d87e5f7e2a7574918748d38ff2dc812d2-static.js +633 -416
  5. package/pyret-lang/build/phaseA/lib-compiled/charts-lib-359cf1f1fc9f5068be80e4ee4c0fc54b3b80d94c49a0ce7bcfdbc2581b5b6c6d-module.js +216 -60
  6. package/pyret-lang/build/phaseA/lib-compiled/charts-lib-359cf1f1fc9f5068be80e4ee4c0fc54b3b80d94c49a0ce7bcfdbc2581b5b6c6d-static.js +216 -60
  7. package/pyret-lang/build/phaseA/lib-compiled/charts-util-f886e58756b509074a8868537c3bd3b97897fe96c3aa6eef676b8e05a7a25061-module.js +730 -0
  8. package/pyret-lang/build/phaseA/lib-compiled/charts-util-f886e58756b509074a8868537c3bd3b97897fe96c3aa6eef676b8e05a7a25061-static.js +729 -0
  9. package/pyret-lang/build/phaseA/lib-compiled/image-lib-58d2019095acfc12fa49dbf7e05aa5a2cec3a3e43648163e897d166faeca8361-module.js +36 -34
  10. package/pyret-lang/build/phaseA/lib-compiled/image-lib-58d2019095acfc12fa49dbf7e05aa5a2cec3a3e43648163e897d166faeca8361-static.js +36 -34
  11. package/pyret-lang/build/phaseA/lib-compiled/image-structs-3a02a5ca3f95bf62a639b383a8c880be753c826a64cc74ef5391d698001a0b95-module.js +1 -1
  12. package/pyret-lang/build/phaseA/lib-compiled/libs.arr-7e68a48c40816212db66913a459b12bb293c7e7a23e3b2191d8640a99ee2426c-module.js +1 -1
  13. package/pyret-lang/build/phaseA/lib-compiled/make-image-4db56c34361e89d28ca8a554d7f4729e7b0a0c3c50ac8652ab9c254d11486db4-module.js +1 -1
  14. package/pyret-lang/build/phaseA/lib-compiled/make-image-4db56c34361e89d28ca8a554d7f4729e7b0a0c3c50ac8652ab9c254d11486db4-static.js +1 -1
@@ -1,6 +1,7 @@
1
1
  ({
2
2
  requires: [
3
3
  { 'import-type': 'builtin', 'name': 'image-lib' },
4
+ { "import-type": "builtin", 'name': "charts-util" },
4
5
  ],
5
6
  nativeRequires: [
6
7
  'pyret-base/js/js-numbers',
@@ -19,7 +20,7 @@
19
20
  'plot': "tany",
20
21
  }
21
22
  },
22
- theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, jsnums, vega, canvasLib) {
23
+ theModule: function (RUNTIME, NAMESPACE, uri, IMAGELIB, CHARTSUTILLIB, jsnums, vega, canvasLib) {
23
24
  'use strict';
24
25
 
25
26
 
@@ -59,6 +60,7 @@
59
60
  const cases = RUNTIME.ffi.cases;
60
61
 
61
62
  var IMAGE = get(IMAGELIB, "internal");
63
+ var CHARTSUTIL = get(CHARTSUTILLIB, "values");
62
64
 
63
65
  const ann = function(name, pred) {
64
66
  return RUNTIME.makePrimitiveAnn(name, pred);
@@ -207,6 +209,28 @@
207
209
 
208
210
  //////////////////////////////////////////////////////////////////////////////
209
211
 
212
+ const chartFontConfig = {
213
+ signals: [
214
+ { name: 'fontSizeScale', value: 14 }
215
+ ],
216
+ mark: {
217
+ fontSize: { signal: 'fontSizeScale' }
218
+ },
219
+ text: {
220
+ fontSize: { signal: 'fontSizeScale' }
221
+ },
222
+ title: {
223
+ fontSize: { signal: '1.2 * fontSizeScale' },
224
+ },
225
+ axis: {
226
+ labelFontSize: { signal: 'fontSizeScale' },
227
+ titleFontSize: { signal: 'fontSizeScale' },
228
+ },
229
+ legend: {
230
+ labelFontSize: { signal: 'fontSizeScale' },
231
+ }
232
+ };
233
+
210
234
  function pieChart(globalOptions, rawData) {
211
235
  /*
212
236
  Note: Most of the complexity here is due to supporting the "collapsed" wedge of values,
@@ -457,6 +481,7 @@
457
481
  marks,
458
482
  legends,
459
483
  onExit: defaultImageReturn,
484
+ config: chartFontConfig,
460
485
  };
461
486
  }
462
487
 
@@ -902,6 +927,9 @@
902
927
  const background = getColorOrDefault(globalOptions['backgroundColor'], 'transparent');
903
928
  const axesConfig = dimensions[horizontal ? 'horizontal' : 'vertical']
904
929
  const axis = get_axis(rawData);
930
+ const xAxisType = globalOptions['x-axis-type'];
931
+ const yAxisType = globalOptions['y-axis-type'];
932
+ const bandwidth = toFixnum(get(rawData, 'bandwidth') || 1);
905
933
 
906
934
  const data = [];
907
935
 
@@ -934,14 +962,15 @@
934
962
  name: 'primary',
935
963
  type: 'band',
936
964
  range: axesConfig.primary.range,
937
- domain: { data: 'table', field: 'label' }
965
+ domain: { data: 'table', field: 'label' },
966
+ padding: 1 - bandwidth,
938
967
  },
939
968
  {
940
969
  name: 'secondary',
941
- type: 'linear',
942
970
  range: axesConfig.secondary.range,
943
971
  nice: true, zero: true,
944
- domain: axis ? { signal: 'extent(domain("secondaryLabels"))' } : { data: 'table', field: 'value' }
972
+ domain: axis ? { signal: 'extent(domain("secondaryLabels"))' } : { data: 'table', field: 'value' },
973
+ ...(axesConfig.secondary.name === 'x' ? xAxisType : yAxisType)
945
974
  },
946
975
  {
947
976
  name: 'color',
@@ -1015,6 +1044,7 @@
1015
1044
  axes,
1016
1045
  marks,
1017
1046
  onExit: defaultImageReturn,
1047
+ config: chartFontConfig,
1018
1048
  };
1019
1049
  }
1020
1050
 
@@ -1034,6 +1064,9 @@
1034
1064
  const stackType = get(rawData, 'is-stacked');
1035
1065
  const isStacked = stackType !== 'none';
1036
1066
  const isNotFullStacked = (stackType !== 'relative') && (stackType !== 'percent');
1067
+ const bandwidth = toFixnum(get(rawData, 'bandwidth') || 1);
1068
+ const xAxisType = globalOptions['x-axis-type'];
1069
+ const yAxisType = globalOptions['y-axis-type'];
1037
1070
 
1038
1071
  const data = [];
1039
1072
 
@@ -1114,12 +1147,12 @@
1114
1147
  type: 'band',
1115
1148
  range: axesConfig.primary.range,
1116
1149
  domain: { data: 'table', field: 'label' },
1117
- padding: 0.2
1150
+ padding: 1 - bandwidth
1118
1151
  };
1119
1152
  const secondaryScale = {
1120
1153
  name: 'secondary',
1121
- type: 'linear',
1122
1154
  range: axesConfig.secondary.range,
1155
+ ...(axesConfig.secondary.name === 'x' ? xAxisType : yAxisType),
1123
1156
  nice: true, zero: true,
1124
1157
  domain: (axis && isNotFullStacked) ? { signal: 'extent(domain("secondaryLabels"))' } : { data: 'table', field: 'value1' }
1125
1158
  };
@@ -1300,6 +1333,7 @@
1300
1333
  marks,
1301
1334
  legends,
1302
1335
  onExit: defaultImageReturn,
1336
+ config: chartFontConfig,
1303
1337
  }
1304
1338
  }
1305
1339
 
@@ -1317,6 +1351,8 @@
1317
1351
  const background = getColorOrDefault(globalOptions['backgroundColor'], 'transparent');
1318
1352
  const min = getNumOrDefault(globalOptions['min'], undefined);
1319
1353
  const max = getNumOrDefault(globalOptions['max'], undefined);
1354
+ const xAxisType = globalOptions['x-axis-type'];
1355
+ const yAxisType = globalOptions['y-axis-type'];
1320
1356
 
1321
1357
  const data = [
1322
1358
  {
@@ -1403,8 +1439,8 @@
1403
1439
  },
1404
1440
  update: {
1405
1441
  [PC]: { scale: 'primary', field: 'label', offset: { scale: 'primary', band: 0.5 } },
1406
- [S]: { scale: 'secondary', field: 'lowWhisker' },
1407
- [S2]: { scale: 'secondary', field: 'highWhisker' },
1442
+ [S]: { scale: 'secondary', field: showOutliers ? 'lowWhisker' : 'minVal' },
1443
+ [S2]: { scale: 'secondary', field: showOutliers ? 'highWhisker' : 'maxVal' },
1408
1444
  tooltip: { signal: tooltip }
1409
1445
  },
1410
1446
  }
@@ -1421,7 +1457,7 @@
1421
1457
  update: {
1422
1458
  [PC]: { scale: 'primary', field: 'label', offset: { scale: 'primary', band: 0.5 } },
1423
1459
  [axesConfig.primary.range]: { scale: 'primary', band: 0.25 },
1424
- [S]: { scale: 'secondary', field: 'lowWhisker' },
1460
+ [S]: { scale: 'secondary', field: showOutliers ? 'lowWhisker' : 'minVal' },
1425
1461
  tooltip: { signal: tooltip }
1426
1462
  }
1427
1463
  }
@@ -1438,7 +1474,7 @@
1438
1474
  update: {
1439
1475
  [PC]: { scale: 'primary', field: 'label', offset: { scale: 'primary', band: 0.5 } },
1440
1476
  [axesConfig.primary.range]: { scale: 'primary', band: 0.25 },
1441
- [S]: { scale: 'secondary', field: 'highWhisker' },
1477
+ [S]: { scale: 'secondary', field: showOutliers ? 'highWhisker' : 'maxVal' },
1442
1478
  tooltip: { signal: tooltip }
1443
1479
  }
1444
1480
  }
@@ -1534,7 +1570,7 @@
1534
1570
  },
1535
1571
  {
1536
1572
  name: 'secondary',
1537
- type: 'linear',
1573
+ ...(axesConfig.secondary.name === 'x' ? xAxisType : yAxisType),
1538
1574
  range: axesConfig.secondary.range,
1539
1575
  nice: true, zero: false,
1540
1576
  domain: [{ signal: 'minValue' },{ signal: 'maxValue' }],
@@ -1572,6 +1608,7 @@
1572
1608
  axes,
1573
1609
  marks,
1574
1610
  onExit: defaultImageReturn,
1611
+ config: chartFontConfig,
1575
1612
  };
1576
1613
  }
1577
1614
 
@@ -1585,6 +1622,7 @@
1585
1622
  const width = globalOptions['width'];
1586
1623
  const height = globalOptions['height'];
1587
1624
  const background = getColorOrDefault(globalOptions['backgroundColor'], 'transparent');
1625
+ const yAxisType = globalOptions['y-axis-type'];
1588
1626
 
1589
1627
  const data = [
1590
1628
  {
@@ -1714,12 +1752,14 @@
1714
1752
  name: 'binScale',
1715
1753
  type: 'linear',
1716
1754
  range: 'width',
1755
+ zero: false,
1717
1756
  domain: { data: 'rawTable', field: 'bin1' }
1718
1757
  },
1719
1758
  {
1720
1759
  name: 'countScale',
1721
- type: 'linear',
1722
1760
  range: 'height',
1761
+ ...yAxisType,
1762
+ zero: true,
1723
1763
  domain: { data: 'rawTable', field: 'y1' }
1724
1764
  }
1725
1765
  ];
@@ -1751,6 +1791,7 @@
1751
1791
  axes,
1752
1792
  marks,
1753
1793
  onExit: defaultImageReturn,
1794
+ config: chartFontConfig,
1754
1795
  };
1755
1796
  }
1756
1797
 
@@ -1768,6 +1809,7 @@
1768
1809
  const height = globalOptions['height'];
1769
1810
  const xAxisLabel = globalOptions['x-axis'];
1770
1811
  const yAxisLabel = globalOptions['y-axis'];
1812
+ const yAxisType = globalOptions['y-axis-type'];
1771
1813
  const background = getColorOrDefault(globalOptions['backgroundColor'], 'transparent');
1772
1814
 
1773
1815
  const data = [
@@ -1825,12 +1867,14 @@
1825
1867
  {
1826
1868
  name: 'binScale',
1827
1869
  type: 'linear',
1870
+ zero: false,
1828
1871
  range: { signal: '[0, width - dotSize / 2]' },
1829
1872
  domain: { data: 'rawTable', field: 'value' }
1830
1873
  },
1831
1874
  {
1832
1875
  name: 'dotScale',
1833
- type: 'linear',
1876
+ ...yAxisType,
1877
+ zero: true,
1834
1878
  range: { signal: '[height, dotSize / 2]' },
1835
1879
  domain: { signal: '[0, floor(height / dotSize)]' }
1836
1880
  }
@@ -1911,6 +1955,7 @@
1911
1955
  axes,
1912
1956
  marks,
1913
1957
  onExit: defaultImageReturn,
1958
+ config: chartFontConfig,
1914
1959
  };
1915
1960
  }
1916
1961
 
@@ -1926,6 +1971,7 @@
1926
1971
  const height = globalOptions['height'];
1927
1972
  const xAxisLabel = globalOptions['x-axis'];
1928
1973
  const yAxisLabel = globalOptions['y-axis'];
1974
+ const yAxisType = globalOptions['y-axis-type'];
1929
1975
  const background = getColorOrDefault(globalOptions['backgroundColor'], 'transparent');
1930
1976
 
1931
1977
 
@@ -1958,8 +2004,8 @@
1958
2004
  },
1959
2005
  {
1960
2006
  name: 'secondary',
1961
- type: 'linear',
1962
2007
  range: 'height',
2008
+ ...yAxisType,
1963
2009
  nice: true, zero: true,
1964
2010
  domain: { data: 'bars', field: 'count' }
1965
2011
  }
@@ -2028,6 +2074,7 @@
2028
2074
  axes,
2029
2075
  marks,
2030
2076
  onExit: defaultImageReturn,
2077
+ config: chartFontConfig,
2031
2078
  };
2032
2079
  }
2033
2080
 
@@ -2107,6 +2154,8 @@
2107
2154
  function scatterPlot(globalOptions, rawData, config) {
2108
2155
  const xAxisLabel = globalOptions['x-axis'];
2109
2156
  const yAxisLabel = globalOptions['y-axis'];
2157
+ const xAxisType = globalOptions['x-axis-type'];
2158
+ const yAxisType = globalOptions['y-axis-type'];
2110
2159
  const prefix = config.prefix || ''
2111
2160
  const defaultColor = config.defaultColor || default_colors[0];
2112
2161
  const color = getColorOrDefault(get(rawData, 'color'), defaultColor);
@@ -2126,39 +2175,55 @@
2126
2175
  const xMaxValue = getNumOrDefault(globalOptions['x-max'], undefined);
2127
2176
  const yMinValue = getNumOrDefault(globalOptions['y-min'], undefined);
2128
2177
  const yMaxValue = getNumOrDefault(globalOptions['y-max'], undefined);
2178
+ const imageScaleFactorX = autosizeImage ? '-datum.imageWidth' : -pointSize;
2179
+ const imageScaleFactorY = autosizeImage ? '-datum.imageHeight' : -pointSize;
2129
2180
 
2130
2181
  const points = RUNTIME.ffi.toArray(get(rawData, 'ps'));
2131
-
2182
+ const pointValues = points.map((p) => ({
2183
+ label: get(p, 'label'),
2184
+ x: toFixnum(get(p, 'x')),
2185
+ y: toFixnum(get(p, 'y')),
2186
+ image: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2187
+ none: () => undefined,
2188
+ some: (opaqueImg) => imageToCanvas(opaqueImg.val)
2189
+ }),
2190
+ imageWidth: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2191
+ none: () => undefined,
2192
+ some: (opaqueImg) => opaqueImg.val.getWidth()
2193
+ }),
2194
+ imageHeight: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2195
+ none: () => undefined,
2196
+ some: (opaqueImg) => opaqueImg.val.getHeight()
2197
+ }),
2198
+ imageOffsetX: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2199
+ none: () => undefined,
2200
+ some: (opaqueImg) => opaqueImg.val.getPinholeX() / opaqueImg.val.getWidth()
2201
+ }),
2202
+ imageOffsetY: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2203
+ none: () => undefined,
2204
+ some: (opaqueImg) => opaqueImg.val.getPinholeY() / opaqueImg.val.getHeight()
2205
+ }),
2206
+ }));
2132
2207
  const data = [
2133
2208
  {
2134
2209
  name: `${prefix}rawTable`,
2135
- values: points.map((p) => ({
2136
- label: get(p, 'label'),
2137
- x: toFixnum(get(p, 'x')),
2138
- y: toFixnum(get(p, 'y')),
2139
- image: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2140
- none: () => undefined,
2141
- some: (opaqueImg) => imageToCanvas(opaqueImg.val)
2142
- }),
2143
- imageWidth: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2144
- none: () => undefined,
2145
- some: (opaqueImg) => opaqueImg.val.getWidth()
2146
- }),
2147
- imageHeight: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2148
- none: () => undefined,
2149
- some: (opaqueImg) => opaqueImg.val.getHeight()
2150
- }),
2151
- imageOffsetX: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2152
- none: () => undefined,
2153
- some: (opaqueImg) => opaqueImg.val.getPinholeX() / opaqueImg.val.getWidth()
2154
- }),
2155
- imageOffsetY: cases(RUNTIME.ffi.isOption, 'Option', get(p, 'image'), {
2156
- none: () => undefined,
2157
- some: (opaqueImg) => opaqueImg.val.getPinholeY() / opaqueImg.val.getHeight()
2158
- }),
2159
- })),
2210
+ values: pointValues,
2160
2211
  transform: []
2161
2212
  },
2213
+ {
2214
+ name: `${prefix}tableMarkExtents`,
2215
+ source: `${prefix}rawTable`,
2216
+ transform: [
2217
+ { type: 'formula', as: 'left',
2218
+ expr: `datum.x + (isValid(datum.image) ? datum.imageOffsetX * ${imageScaleFactorX}: ${-pointSize / 2}) / ${prefix}rawDomainUnitInPx` },
2219
+ { type: 'formula', as: 'right',
2220
+ expr: `datum.x + (isValid(datum.image) ? (datum.imageOffsetX * ${imageScaleFactorY} - datum.imageWidth) : ${pointSize}) / ${prefix}rawDomainUnitInPx` },
2221
+ { type: 'formula', as: 'top',
2222
+ expr: `datum.y + (isValid(datum.image) ? datum.imageOffsetY * ${imageScaleFactorY} : ${-pointSize / 2}) / ${prefix}rawRangeUnitInPx` },
2223
+ { type: 'formula', as: 'bot',
2224
+ expr: `datum.y + (isValid(datum.image) ? (datum.imageOffsetY * ${imageScaleFactorY} - datum.imageHeight) : ${pointSize}) / ${prefix}rawRangeUnitInPx` },
2225
+ ],
2226
+ },
2162
2227
  {
2163
2228
  name: `${prefix}table`,
2164
2229
  source: `${prefix}rawTable`,
@@ -2171,22 +2236,87 @@
2171
2236
  },
2172
2237
  ];
2173
2238
 
2174
- const domain = computeDomain(data[0].values.map((v) => v.x));
2175
-
2239
+ // these are measured in pixels
2240
+ let imageOverhangX, imageOverhangY;
2241
+ const imageWidths = pointValues.map((v) => v.imageWidth).filter((v) => v !== undefined);
2242
+ const imageHeights = pointValues.map((v) => v.imageHeight).filter((v) => v !== undefined);
2243
+ if (imageWidths.length === 0 || autosizeImage) {
2244
+ imageOverhangX = pointSize;
2245
+ imageOverhangY = pointSize;
2246
+ } else {
2247
+ let temp;
2248
+ temp = computeDomain(imageWidths);
2249
+ imageOverhangX = temp[1] - temp[0];
2250
+ temp = computeDomain(imageHeights);
2251
+ imageOverhangY = temp[1] - temp[0];
2252
+ }
2253
+ let windowWidth = toFixnum(globalOptions['width']);
2254
+ let windowHeight = toFixnum(globalOptions['height']);
2255
+
2256
+ const rawDomain = computeDomain(pointValues.map((v) => v.x));
2257
+ const rawRange = computeDomain(pointValues.map((v) => v.y));
2258
+ const reducedWidth = windowWidth - imageOverhangX;
2259
+ const reducedHeight = windowHeight - imageOverhangY;
2260
+ const rawDomainUnitInPx = reducedWidth / (rawDomain[1] - rawDomain[0]);
2261
+ const rawRangeUnitInPx = reducedHeight / (rawRange[1] - rawRange[0]);
2262
+ const domain = computeDomain(pointValues.map((v) => {
2263
+ let left, right;
2264
+ if (!autosizeImage || !v.image) {
2265
+ let halfPointSize = pointSize / 2;
2266
+ let inDomainHalfPointSize = halfPointSize / rawDomainUnitInPx;
2267
+ return [v.x - inDomainHalfPointSize, v.x + inDomainHalfPointSize];
2268
+ }
2269
+ left = v.x - v.imageOffsetX * v.imageWidth / rawDomainUnitInPx;
2270
+ right = left + v.imageWidth / rawDomainUnitInPx;
2271
+ return [left, right];
2272
+ }).flat());
2273
+ // console.log("Raw domain", computeDomain(pointValues.map((v) => v.x)), "Point size", pointSize);
2274
+ // console.log({reducedWidth, imageOverhangX, rawDomainUnitInPx});
2275
+ // console.log("Extended domain", domain);
2276
+
2277
+ const range = computeDomain(pointValues.map((v) => {
2278
+ let top, bot;
2279
+ if (!autosizeImage || !v.image) {
2280
+ let halfPointSize = pointSize / 2;
2281
+ let inDomainHalfPointSize = halfPointSize / rawDomainUnitInPx;
2282
+ return [v.y - inDomainHalfPointSize, v.y + inDomainHalfPointSize];
2283
+ }
2284
+ top = v.y + v.imageOffsetY * v.imageHeight / rawDomainUnitInPx;
2285
+ bot = top - v.imageHeight / rawDomainUnitInPx;
2286
+ return [top, bot];
2287
+ }).flat());
2288
+ // console.log("Raw range", computeDomain(pointValues.map((v) => v.y)), "Point size", pointSize);
2289
+ // console.log("Extended range", range);
2290
+
2291
+ function unionExtents(...names) {
2292
+ const names0 = names.map((s) => `${s}[0]`);
2293
+ const names1 = names.map((s) => `${s}[1]`);
2294
+ return `[min(${names0.join(',')}), max(${names1.join(',')})]`
2295
+ }
2176
2296
  const signals = [
2177
- { name: `${prefix}extentX`, update: `extent(pluck(data("${prefix}rawTable"), "x"))` },
2178
- { name: `${prefix}extentY`, update: `extent(pluck(data("${prefix}rawTable"), "y"))` },
2297
+ { name: `${prefix}reducedWidth`, update: `width - ${imageOverhangX}` },
2298
+ { name: `${prefix}reducedHeight`, update: `height - ${imageOverhangY}` },
2299
+ { name: `${prefix}rawDomainUnitInPx`, update: `${prefix}reducedWidth / ${rawDomain[1] - rawDomain[0]}` },
2300
+ { name: `${prefix}rawRangeUnitInPx`, update: `${prefix}reducedHeight / ${rawRange[1] - rawRange[0]}` },
2301
+ { name: `${prefix}extentLeft`, update: `extent(pluck(data("${prefix}tableMarkExtents"), "left"))` },
2302
+ { name: `${prefix}extentRight`, update: `extent(pluck(data("${prefix}tableMarkExtents"), "right"))` },
2303
+ { name: `${prefix}extentTop`, update: `extent(pluck(data("${prefix}tableMarkExtents"), "top"))` },
2304
+ { name: `${prefix}extentBot`, update: `extent(pluck(data("${prefix}tableMarkExtents"), "bot"))` },
2305
+ { name: `${prefix}extentX`, update: unionExtents(`${prefix}extentLeft`, `${prefix}extentRight`) },
2306
+ { name: `${prefix}extentY`, update: unionExtents(`${prefix}extentTop`, `${prefix}extentBot`) },
2179
2307
  ];
2180
2308
  const scales = [
2181
2309
  { name: `${prefix}xscale`,
2182
- type: 'linear',
2310
+ ...xAxisType,
2183
2311
  domain: { signal: `${prefix}extentX` },
2184
2312
  range: 'width',
2313
+ zero: false,
2185
2314
  nice: true },
2186
2315
  { name: `${prefix}yscale`,
2187
- type: 'linear',
2316
+ ...yAxisType,
2188
2317
  domain: { signal: `${prefix}extentY` },
2189
2318
  range: 'height',
2319
+ zero: false,
2190
2320
  nice: true }
2191
2321
  ];
2192
2322
  const marks = [];
@@ -2290,8 +2420,6 @@
2290
2420
  signal: `{ title: "${legend}", Label: datum.label, x: datum.x, y: datum.y }` },
2291
2421
  { signal: `{ title: "${legend}", x: datum.x, y: datum.y }` },
2292
2422
  ];
2293
- const imageScaleFactorX = autosizeImage ? '-datum.imageWidth' : -pointSize;
2294
- const imageScaleFactorY = autosizeImage ? '-datum.imageHeight' : -pointSize;
2295
2423
  marks.push({
2296
2424
  type: 'image',
2297
2425
  from: { data: `${prefix}images` },
@@ -2447,6 +2575,8 @@
2447
2575
  function intervalPlot(globalOptions, rawData, config) {
2448
2576
  const xAxisLabel = globalOptions['x-axis'];
2449
2577
  const yAxisLabel = globalOptions['y-axis'];
2578
+ const xAxisType = globalOptions['x-axis-type'];
2579
+ const yAxisType = globalOptions['y-axis-type'];
2450
2580
  const legend = get(rawData, 'legend') || config.legend;
2451
2581
  const prefix = config.prefix || ''
2452
2582
  const defaultColor = config.defaultColor || default_colors[0];
@@ -2516,15 +2646,17 @@
2516
2646
 
2517
2647
  const scales = [
2518
2648
  { name: `${prefix}xscale`,
2519
- type: 'linear',
2649
+ ...xAxisType,
2520
2650
  domain: { signal: `${prefix}extentX` },
2521
2651
  range: 'width',
2522
- nice: false },
2652
+ nice: false,
2653
+ zero: false },
2523
2654
  { name: `${prefix}yscale`,
2524
- type: 'linear',
2655
+ ...yAxisType,
2525
2656
  domain: { signal: `${prefix}extentY` },
2526
2657
  range: 'height',
2527
- nice: false }
2658
+ nice: false,
2659
+ zero: false }
2528
2660
  ];
2529
2661
  const tooltip = {
2530
2662
  signal: `{ title: datum.label, x: datum.x, y: datum.y, ŷ: datum.yprime, 'y - ŷ': datum.delta }`
@@ -2663,6 +2795,8 @@
2663
2795
  const domain = config.domain;
2664
2796
  const xMinValue = domain[0];
2665
2797
  const xMaxValue = domain[1];
2798
+ const xAxisType = globalOptions['x-axis-type'];
2799
+ const yAxisType = globalOptions['y-axis-type'];
2666
2800
 
2667
2801
  const fraction = (xMaxValue - xMinValue) / (numSamples - 1);
2668
2802
 
@@ -2676,10 +2810,11 @@
2676
2810
  // from the surrounding chart context
2677
2811
  {
2678
2812
  name: `${prefix}yscale`,
2679
- type: 'linear',
2813
+ ...yAxisType,
2680
2814
  domain: { signal: `${prefix}extentY` },
2681
2815
  range: 'height',
2682
- nice: true
2816
+ nice: true,
2817
+ zero: false
2683
2818
  }
2684
2819
  ];
2685
2820
  const tooltip = {
@@ -2775,6 +2910,8 @@
2775
2910
  const numSamples = toFixnum(globalOptions['num-samples']);
2776
2911
  const xAxisLabel = globalOptions['x-axis'];
2777
2912
  const yAxisLabel = globalOptions['y-axis'];
2913
+ const xAxisType = globalOptions['x-axis-type'];
2914
+ const yAxisType = globalOptions['y-axis-type'];
2778
2915
  const width = toFixnum(globalOptions['width']);
2779
2916
  const height = toFixnum(globalOptions['height']);
2780
2917
  const background = getColorOrDefault(globalOptions['backgroundColor'], 'transparent');
@@ -2795,10 +2932,10 @@
2795
2932
  { name: 'yscaleSignal', update: unionScaleSignal(scales.filter((s) => s.name.endsWith('yscale'))) }
2796
2933
  );
2797
2934
  scales.push(
2798
- { name: 'xscale', domain: { signal: 'xscaleSignal' }, range: 'width',
2799
- domainMin: { signal: 'xMinValue' }, domainMax: { signal: 'xMaxValue' } },
2800
- { name: 'yscale', domain: { signal: 'yscaleSignal' }, range: 'height',
2801
- domainMin: { signal: 'yMinValue' }, domainMax: { signal: 'yMaxValue' } }
2935
+ { name: 'xscale', domain: { signal: 'xscaleSignal' }, range: 'width', ...xAxisType,
2936
+ domainMin: { signal: 'xMinValue' }, domainMax: { signal: 'xMaxValue' }, zero: false },
2937
+ { name: 'yscale', domain: { signal: 'yscaleSignal' }, range: 'height', ...yAxisType,
2938
+ domainMin: { signal: 'yMinValue' }, domainMax: { signal: 'yMaxValue' }, zero: false }
2802
2939
  );
2803
2940
 
2804
2941
  // NOTE: For the axes, we're going to want to put the bar lines at the zeros
@@ -2995,7 +3132,9 @@
2995
3132
  marks,
2996
3133
  legends,
2997
3134
  config: {
3135
+ ...chartFontConfig,
2998
3136
  legend: {
3137
+ ...chartFontConfig.legend,
2999
3138
  orient: 'bottom',
3000
3139
  layout: { bottom: { anchor: 'middle' } },
3001
3140
  }
@@ -3131,10 +3270,16 @@
3131
3270
  }
3132
3271
 
3133
3272
  function renderStaticImage(processed, globalOptions, rawData) {
3273
+ function isImageOrCanvas(v) {
3274
+ if (!v) return false;
3275
+ if (IMAGE.isImage(v)) return true;
3276
+ return canvasLib && canvasLib.Canvas && v instanceof canvasLib.Canvas;
3277
+ }
3278
+ const isVegaString = isTrue(globalOptions['vega']);
3134
3279
  return RUNTIME.pauseStack(restarter => {
3135
3280
  try {
3136
- if (canvasLib && canvasLib.Canvas) {
3137
- console.log(JSON.stringify(processed, (k, v) => (v && (IMAGE.isImage(v) || (v instanceof canvasLib.Canvas))) ? v.ariaText : v, 2));
3281
+ if (isVegaString) {
3282
+ return restarter.resume(JSON.stringify(processed, (k, v) => isImageOrCanvas(v) ? v.ariaText : v, 2));
3138
3283
  }
3139
3284
  const width = toFixnum(globalOptions['width']);
3140
3285
  const height = toFixnum(globalOptions['height']);
@@ -3232,10 +3377,21 @@
3232
3377
  }
3233
3378
 
3234
3379
 
3380
+ function configScale(val) {
3381
+ return cases(get(CHARTSUTIL, "is-AxisType"), "AxisType", val, {
3382
+ 'at-linear': () => ({ type: 'linear' }),
3383
+ 'at-power': (pow) => ({ type: 'pow', exponent: toFixnum(pow) }),
3384
+ 'at-log': (base) => ({ type: 'log', base: toFixnum(base) }),
3385
+ 'at-symlog': (base) => ({ type: 'symlog', constant: toFixnum(base) })
3386
+ });
3387
+ }
3235
3388
  function pyretObjToObj(globalOptions) {
3236
3389
  const ret = {};
3237
3390
  for (const field of RUNTIME.getFields(globalOptions)) {
3238
3391
  ret[field] = get(globalOptions, field);
3392
+ if (get(CHARTSUTIL, 'is-AxisType').app(ret[field])) {
3393
+ ret[field] = configScale(ret[field]);
3394
+ }
3239
3395
  }
3240
3396
  return ret;
3241
3397
  }