vega 0.2.5 → 0.2.7

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.
@@ -15,6 +15,11 @@
15
15
  ];
16
16
  var homepage = "https://vega.github.io/vega-lite/";
17
17
  var description$1 = "Vega-Lite is a concise high-level language for interactive visualization.";
18
+ var keywords = [
19
+ "vega",
20
+ "chart",
21
+ "visualization"
22
+ ];
18
23
  var main$1 = "build/vega-lite.js";
19
24
  var unpkg = "build/vega-lite.min.js";
20
25
  var jsdelivr = "build/vega-lite.min.js";
@@ -26,9 +31,6 @@
26
31
  vl2pdf: "./bin/vl2pdf",
27
32
  vl2vg: "./bin/vl2vg"
28
33
  };
29
- var directories = {
30
- test: "test"
31
- };
32
34
  var files = [
33
35
  "bin",
34
36
  "build",
@@ -72,7 +74,10 @@
72
74
  "test:runtime:generate": "yarn build:only && del-cli test-runtime/resources && VL_GENERATE_TESTS=true yarn test:runtime",
73
75
  watch: "tsc -p tsconfig.build.json -w",
74
76
  "watch:site": "yarn build:site -w",
75
- "watch:test": "yarn jest --watch test/"
77
+ "watch:test": "yarn jest --watch test/",
78
+ "watch:test:runtime": "NODE_OPTIONS=--experimental-vm-modules TZ=America/Los_Angeles npx jest --watch test-runtime/ --config test-runtime/jest-config.json",
79
+ release: "yarn run prebuild && yarn build && yarn shipit",
80
+ shipit: "auto shipit"
76
81
  };
77
82
  var repository = {
78
83
  type: "git",
@@ -83,53 +88,56 @@
83
88
  url: "https://github.com/vega/vega-lite/issues"
84
89
  };
85
90
  var devDependencies = {
86
- "@babel/core": "^7.16.0",
87
- "@babel/preset-env": "^7.16.0",
88
- "@babel/preset-typescript": "^7.16.0",
89
- "@rollup/plugin-alias": "^3.1.8",
90
- "@rollup/plugin-babel": "^5.3.0",
91
- "@rollup/plugin-commonjs": "^21.0.1",
91
+ "@auto-it/conventional-commits": "^10.34.1",
92
+ "@auto-it/first-time-contributor": "^10.34.1",
93
+ "@babel/core": "^7.17.5",
94
+ "@babel/preset-env": "^7.16.11",
95
+ "@babel/preset-typescript": "^7.16.7",
96
+ "@rollup/plugin-alias": "^3.1.9",
97
+ "@rollup/plugin-babel": "^5.3.1",
98
+ "@rollup/plugin-commonjs": "^22.0.0",
92
99
  "@rollup/plugin-json": "^4.1.0",
93
- "@rollup/plugin-node-resolve": "^13.0.6",
94
- "@types/chai": "^4.2.22",
100
+ "@rollup/plugin-node-resolve": "^13.1.3",
101
+ "@types/chai": "^4.3.0",
95
102
  "@types/d3": "^7.1.0",
96
- "@types/jest": "^27.0.2",
103
+ "@types/jest": "^27.4.1",
97
104
  "@types/mkdirp": "^1.0.2",
98
- "@types/pako": "^1.0.2",
99
- "@typescript-eslint/eslint-plugin": "^5.4.0",
100
- "@typescript-eslint/parser": "^5.4.0",
101
- ajv: "^8.8.0",
105
+ "@types/pako": "^2.0.0",
106
+ "@typescript-eslint/eslint-plugin": "^5.14.0",
107
+ "@typescript-eslint/parser": "^5.14.0",
108
+ ajv: "^8.10.0",
102
109
  "ajv-formats": "^2.1.1",
103
- chai: "^4.3.4",
110
+ auto: "^10.34.1",
111
+ chai: "^4.3.6",
104
112
  cheerio: "^1.0.0-rc.10",
105
- "conventional-changelog-cli": "^2.1.1",
106
- d3: "^7.1.1",
107
- "del-cli": "^4.0.1",
108
- eslint: "^8.2.0",
109
- "eslint-config-prettier": "^8.3.0",
110
- "eslint-plugin-jest": "^25.2.4",
113
+ "conventional-changelog-cli": "^2.2.2",
114
+ d3: "^7.4.4",
115
+ "del-cli": "^5.0.0",
116
+ eslint: "^8.11.0",
117
+ "eslint-config-prettier": "^8.5.0",
118
+ "eslint-plugin-jest": "^26.1.1",
111
119
  "eslint-plugin-prettier": "^4.0.0",
112
- "gh-pages": "^3.2.3",
113
- "highlight.js": "^11.3.1",
114
- jest: "^27.3.1",
115
- "jest-dev-server": "^6.0.0",
120
+ "gh-pages": "^4.0.0",
121
+ "highlight.js": "^11.5.0",
122
+ jest: "^27.5.1",
123
+ "jest-dev-server": "^6.0.3",
116
124
  mkdirp: "^1.0.4",
117
125
  pako: "^2.0.4",
118
- prettier: "^2.4.1",
119
- puppeteer: "^11.0.0",
120
- rollup: "^2.60.0",
126
+ prettier: "^2.5.1",
127
+ puppeteer: "^15.0.0",
128
+ rollup: "^2.70.1",
121
129
  "rollup-plugin-bundle-size": "^1.0.3",
122
130
  "rollup-plugin-sourcemaps": "^0.6.3",
123
131
  "rollup-plugin-terser": "^7.0.2",
124
- serve: "^13.0.2",
125
- terser: "^5.10.0",
126
- "ts-jest": "^27.0.7",
127
- "ts-json-schema-generator": "^0.97.0",
128
- typescript: "~4.5.2",
129
- "vega-cli": "^5.21.0",
130
- "vega-datasets": "~2.2.0",
131
- "vega-embed": "^6.20.2",
132
- "vega-tooltip": "^0.27.0",
132
+ serve: "^14.0.1",
133
+ terser: "^5.12.1",
134
+ "ts-jest": "^27.1.3",
135
+ "ts-json-schema-generator": "^1.0.0",
136
+ "vega-cli": "^5.22.0",
137
+ typescript: "~4.7.2",
138
+ "vega-datasets": "~2.4.0",
139
+ "vega-embed": "^6.20.8",
140
+ "vega-tooltip": "^0.28.0",
133
141
  "yaml-front-matter": "^4.1.1"
134
142
  };
135
143
  var dependencies = {
@@ -139,14 +147,14 @@
139
147
  "fast-deep-equal": "~3.1.3",
140
148
  "fast-json-stable-stringify": "~2.1.0",
141
149
  "json-stringify-pretty-compact": "~3.0.0",
142
- tslib: "~2.3.1",
150
+ tslib: "~2.4.0",
143
151
  "vega-event-selector": "~3.0.0",
144
152
  "vega-expression": "~5.0.0",
145
153
  "vega-util": "~1.17.0",
146
- yargs: "~17.2.1"
154
+ yargs: "~17.5.1"
147
155
  };
148
156
  var peerDependencies = {
149
- vega: "^5.21.0"
157
+ vega: "^5.22.0"
150
158
  };
151
159
  var engines = {
152
160
  node: ">=12"
@@ -158,13 +166,13 @@
158
166
  collaborators: collaborators,
159
167
  homepage: homepage,
160
168
  description: description$1,
169
+ keywords: keywords,
161
170
  main: main$1,
162
171
  unpkg: unpkg,
163
172
  jsdelivr: jsdelivr,
164
173
  module: module,
165
174
  types: types,
166
175
  bin: bin,
167
- directories: directories,
168
176
  files: files,
169
177
  scripts: scripts,
170
178
  repository: repository,
@@ -1739,7 +1747,7 @@
1739
1747
  }
1740
1748
 
1741
1749
  function isExprRef(o) {
1742
- return o && !!o['expr'];
1750
+ return !!(o !== null && o !== void 0 && o.expr);
1743
1751
  }
1744
1752
  function replaceExprRef(index) {
1745
1753
  const props = keys(index || {});
@@ -1835,7 +1843,7 @@
1835
1843
  }
1836
1844
 
1837
1845
  function isSignalRef(o) {
1838
- return o && !!o['signal'];
1846
+ return !!(o !== null && o !== void 0 && o.signal);
1839
1847
  } // TODO: add type of value (Make it VgValueRef<V extends ValueOrGradient> {value?:V ...})
1840
1848
 
1841
1849
  function isVgRangeStep(range) {
@@ -2866,19 +2874,19 @@
2866
2874
  return predicate === null || predicate === void 0 ? void 0 : predicate['param'];
2867
2875
  }
2868
2876
  function isFieldEqualPredicate(predicate) {
2869
- return predicate && !!predicate.field && predicate.equal !== undefined;
2877
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && predicate.equal !== undefined;
2870
2878
  }
2871
2879
  function isFieldLTPredicate(predicate) {
2872
- return predicate && !!predicate.field && predicate.lt !== undefined;
2880
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && predicate.lt !== undefined;
2873
2881
  }
2874
2882
  function isFieldLTEPredicate(predicate) {
2875
- return predicate && !!predicate.field && predicate.lte !== undefined;
2883
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && predicate.lte !== undefined;
2876
2884
  }
2877
2885
  function isFieldGTPredicate(predicate) {
2878
- return predicate && !!predicate.field && predicate.gt !== undefined;
2886
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && predicate.gt !== undefined;
2879
2887
  }
2880
2888
  function isFieldGTEPredicate(predicate) {
2881
- return predicate && !!predicate.field && predicate.gte !== undefined;
2889
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && predicate.gte !== undefined;
2882
2890
  }
2883
2891
  function isFieldRangePredicate(predicate) {
2884
2892
  if (predicate !== null && predicate !== void 0 && predicate.field) {
@@ -2892,11 +2900,11 @@
2892
2900
  return false;
2893
2901
  }
2894
2902
  function isFieldOneOfPredicate(predicate) {
2895
- return predicate && !!predicate.field && (vega.isArray(predicate.oneOf) || vega.isArray(predicate.in)) // backward compatibility
2903
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && (vega.isArray(predicate.oneOf) || vega.isArray(predicate.in)) // backward compatibility
2896
2904
  ;
2897
2905
  }
2898
2906
  function isFieldValidPredicate(predicate) {
2899
- return predicate && !!predicate.field && predicate.valid !== undefined;
2907
+ return !!(predicate !== null && predicate !== void 0 && predicate.field) && predicate.valid !== undefined;
2900
2908
  }
2901
2909
  function isFieldPredicate(predicate) {
2902
2910
  return isFieldOneOfPredicate(predicate) || isFieldEqualPredicate(predicate) || isFieldRangePredicate(predicate) || isFieldLTPredicate(predicate) || isFieldGTPredicate(predicate) || isFieldLTEPredicate(predicate) || isFieldGTEPredicate(predicate);
@@ -3193,7 +3201,7 @@
3193
3201
  return domain === null || domain === void 0 ? void 0 : domain['param'];
3194
3202
  }
3195
3203
  function isDomainUnionWith(domain) {
3196
- return domain && domain['unionWith'];
3204
+ return domain === null || domain === void 0 ? void 0 : domain['unionWith'];
3197
3205
  }
3198
3206
  function isFieldRange(range) {
3199
3207
  return vega.isObject(range) && 'field' in range;
@@ -3304,7 +3312,7 @@
3304
3312
  case 'scheme':
3305
3313
  case 'domainMid':
3306
3314
  if (!isColorChannel(channel)) {
3307
- return cannotUseScalePropertyWithNonColor(channel);
3315
+ return cannotUseScalePropertyWithNonColor(propName);
3308
3316
  }
3309
3317
 
3310
3318
  return undefined;
@@ -3852,17 +3860,62 @@
3852
3860
  }
3853
3861
 
3854
3862
  const field = fieldToFormat(fieldOrDatumDef, expr, normalizeStack);
3863
+ const type = channelDefType(fieldOrDatumDef);
3864
+
3865
+ if (format === undefined && formatType === undefined && config.customFormatTypes) {
3866
+ if (type === 'quantitative') {
3867
+ if (normalizeStack && config.normalizedNumberFormatType) return formatCustomType({
3868
+ fieldOrDatumDef,
3869
+ format: config.normalizedNumberFormat,
3870
+ formatType: config.normalizedNumberFormatType,
3871
+ expr,
3872
+ config
3873
+ });
3874
+
3875
+ if (config.numberFormatType) {
3876
+ return formatCustomType({
3877
+ fieldOrDatumDef,
3878
+ format: config.numberFormat,
3879
+ formatType: config.numberFormatType,
3880
+ expr,
3881
+ config
3882
+ });
3883
+ }
3884
+ }
3885
+
3886
+ if (type === 'temporal' && config.timeFormatType && isFieldDef(fieldOrDatumDef) && fieldOrDatumDef.timeUnit === undefined) {
3887
+ return formatCustomType({
3888
+ fieldOrDatumDef,
3889
+ format: config.timeFormat,
3890
+ formatType: config.timeFormatType,
3891
+ expr,
3892
+ config
3893
+ });
3894
+ }
3895
+ }
3855
3896
 
3856
3897
  if (isFieldOrDatumDefForTimeFormat(fieldOrDatumDef)) {
3857
3898
  var _normalizeTimeUnit, _fieldOrDatumDef$scal;
3858
3899
 
3859
- const signal = timeFormatExpression(field, isFieldDef(fieldOrDatumDef) ? (_normalizeTimeUnit = normalizeTimeUnit(fieldOrDatumDef.timeUnit)) === null || _normalizeTimeUnit === void 0 ? void 0 : _normalizeTimeUnit.unit : undefined, format, config.timeFormat, isScaleFieldDef(fieldOrDatumDef) && ((_fieldOrDatumDef$scal = fieldOrDatumDef.scale) === null || _fieldOrDatumDef$scal === void 0 ? void 0 : _fieldOrDatumDef$scal.type) === ScaleType.UTC);
3900
+ const signal = timeFormatExpression({
3901
+ field,
3902
+ timeUnit: isFieldDef(fieldOrDatumDef) ? (_normalizeTimeUnit = normalizeTimeUnit(fieldOrDatumDef.timeUnit)) === null || _normalizeTimeUnit === void 0 ? void 0 : _normalizeTimeUnit.unit : undefined,
3903
+ format,
3904
+ formatType: config.timeFormatType,
3905
+ rawTimeFormat: config.timeFormat,
3906
+ isUTCScale: isScaleFieldDef(fieldOrDatumDef) && ((_fieldOrDatumDef$scal = fieldOrDatumDef.scale) === null || _fieldOrDatumDef$scal === void 0 ? void 0 : _fieldOrDatumDef$scal.type) === ScaleType.UTC
3907
+ });
3860
3908
  return signal ? {
3861
3909
  signal
3862
3910
  } : undefined;
3863
3911
  }
3864
3912
 
3865
- format = numberFormat(channelDefType(fieldOrDatumDef), format, config);
3913
+ format = numberFormat({
3914
+ type,
3915
+ specifiedFormat: format,
3916
+ config,
3917
+ normalizeStack
3918
+ });
3866
3919
 
3867
3920
  if (isFieldDef(fieldOrDatumDef) && isBinning(fieldOrDatumDef.bin)) {
3868
3921
  const endField = vgField(fieldOrDatumDef, {
@@ -3917,7 +3970,8 @@
3917
3970
  } = _ref2;
3918
3971
  (_field = field) !== null && _field !== void 0 ? _field : field = fieldToFormat(fieldOrDatumDef, expr, normalizeStack);
3919
3972
 
3920
- if (isFieldDef(fieldOrDatumDef) && isBinning(fieldOrDatumDef.bin)) {
3973
+ if (field !== 'datum.value' && // For axis/legend, we can't correctly know the end of the bin from `datum`
3974
+ isFieldDef(fieldOrDatumDef) && isBinning(fieldOrDatumDef.bin)) {
3921
3975
  const endField = vgField(fieldOrDatumDef, {
3922
3976
  expr,
3923
3977
  binSuffix: 'end'
@@ -3934,16 +3988,48 @@
3934
3988
  function guideFormat(fieldOrDatumDef, type, format, formatType, config, omitTimeFormatConfig) {
3935
3989
  if (isCustomFormatType(formatType)) {
3936
3990
  return undefined; // handled in encode block
3991
+ } else if (format === undefined && formatType === undefined && config.customFormatTypes) {
3992
+ if (channelDefType(fieldOrDatumDef) === 'quantitative') {
3993
+ if (config.normalizedNumberFormatType && isPositionFieldOrDatumDef(fieldOrDatumDef) && fieldOrDatumDef.stack === 'normalize') {
3994
+ return undefined; // handled in encode block
3995
+ }
3996
+
3997
+ if (config.numberFormatType) {
3998
+ return undefined; // handled in encode block
3999
+ }
4000
+ }
4001
+ }
4002
+
4003
+ if (isPositionFieldOrDatumDef(fieldOrDatumDef) && fieldOrDatumDef.stack === 'normalize' && config.normalizedNumberFormat) {
4004
+ return numberFormat({
4005
+ type: 'quantitative',
4006
+ config,
4007
+ normalizeStack: true
4008
+ });
3937
4009
  }
3938
4010
 
3939
4011
  if (isFieldOrDatumDefForTimeFormat(fieldOrDatumDef)) {
3940
4012
  var _normalizeTimeUnit2;
3941
4013
 
3942
4014
  const timeUnit = isFieldDef(fieldOrDatumDef) ? (_normalizeTimeUnit2 = normalizeTimeUnit(fieldOrDatumDef.timeUnit)) === null || _normalizeTimeUnit2 === void 0 ? void 0 : _normalizeTimeUnit2.unit : undefined;
3943
- return timeFormat(format, timeUnit, config, omitTimeFormatConfig);
4015
+
4016
+ if (timeUnit === undefined && config.customFormatTypes && config.timeFormatType) {
4017
+ return undefined; // hanlded in encode block
4018
+ }
4019
+
4020
+ return timeFormat({
4021
+ specifiedFormat: format,
4022
+ timeUnit,
4023
+ config,
4024
+ omitTimeFormatConfig
4025
+ });
3944
4026
  }
3945
4027
 
3946
- return numberFormat(type, format, config);
4028
+ return numberFormat({
4029
+ type,
4030
+ specifiedFormat: format,
4031
+ config
4032
+ });
3947
4033
  }
3948
4034
  function guideFormatType(formatType, fieldOrDatumDef, scaleType) {
3949
4035
  if (formatType && (isSignalRef(formatType) || formatType === 'number' || formatType === 'time')) {
@@ -3951,7 +4037,9 @@
3951
4037
  }
3952
4038
 
3953
4039
  if (isFieldOrDatumDefForTimeFormat(fieldOrDatumDef) && scaleType !== 'time' && scaleType !== 'utc') {
3954
- return 'time';
4040
+ var _normalizeTimeUnit3;
4041
+
4042
+ return isFieldDef(fieldOrDatumDef) && (_normalizeTimeUnit3 = normalizeTimeUnit(fieldOrDatumDef === null || fieldOrDatumDef === void 0 ? void 0 : fieldOrDatumDef.timeUnit)) !== null && _normalizeTimeUnit3 !== void 0 && _normalizeTimeUnit3.utc ? 'utc' : 'time';
3955
4043
  }
3956
4044
 
3957
4045
  return undefined;
@@ -3960,7 +4048,14 @@
3960
4048
  * Returns number format for a fieldDef.
3961
4049
  */
3962
4050
 
3963
- function numberFormat(type, specifiedFormat, config) {
4051
+ function numberFormat(_ref3) {
4052
+ let {
4053
+ type,
4054
+ specifiedFormat,
4055
+ config,
4056
+ normalizeStack
4057
+ } = _ref3;
4058
+
3964
4059
  // Specified format in axis/legend has higher precedence than fieldDef.format
3965
4060
  if (vega.isString(specifiedFormat)) {
3966
4061
  return specifiedFormat;
@@ -3968,7 +4063,7 @@
3968
4063
 
3969
4064
  if (type === QUANTITATIVE) {
3970
4065
  // we only apply the default if the field is quantitative
3971
- return config.numberFormat;
4066
+ return normalizeStack ? config.normalizedNumberFormat : config.numberFormat;
3972
4067
  }
3973
4068
 
3974
4069
  return undefined;
@@ -3977,7 +4072,14 @@
3977
4072
  * Returns time format for a fieldDef for use in guides.
3978
4073
  */
3979
4074
 
3980
- function timeFormat(specifiedFormat, timeUnit, config, omitTimeFormatConfig) {
4075
+ function timeFormat(_ref4) {
4076
+ let {
4077
+ specifiedFormat,
4078
+ timeUnit,
4079
+ config,
4080
+ omitTimeFormatConfig
4081
+ } = _ref4;
4082
+
3981
4083
  if (specifiedFormat) {
3982
4084
  return specifiedFormat;
3983
4085
  }
@@ -3996,16 +4098,20 @@
3996
4098
  }
3997
4099
 
3998
4100
  function binNumberFormatExpr(field, format, formatType, config) {
3999
- var _ref3;
4101
+ var _ref5;
4000
4102
 
4001
4103
  if (isCustomFormatType(formatType)) {
4002
4104
  return customFormatExpr(formatType, field, format);
4003
4105
  }
4004
4106
 
4005
- return formatExpr(field, (_ref3 = vega.isString(format) ? format : undefined) !== null && _ref3 !== void 0 ? _ref3 : config.numberFormat);
4107
+ return formatExpr(field, (_ref5 = vega.isString(format) ? format : undefined) !== null && _ref5 !== void 0 ? _ref5 : config.numberFormat);
4006
4108
  }
4007
4109
 
4008
4110
  function binFormatExpression(startField, endField, format, formatType, config) {
4111
+ if (format === undefined && formatType === undefined && config.customFormatTypes && config.numberFormatType) {
4112
+ return binFormatExpression(startField, endField, config.numberFormat, config.numberFormatType, config);
4113
+ }
4114
+
4009
4115
  const start = binNumberFormatExpr(startField, format, formatType, config);
4010
4116
  const end = binNumberFormatExpr(endField, format, formatType, config);
4011
4117
  return "".concat(fieldValidPredicate(startField, false), " ? \"null\" : ").concat(start, " + \"").concat(BIN_RANGE_DELIMITER, "\" + ").concat(end);
@@ -4014,10 +4120,22 @@
4014
4120
  * Returns the time expression used for axis/legend labels or text mark for a temporal field
4015
4121
  */
4016
4122
 
4017
- function timeFormatExpression(field, timeUnit, format, rawTimeFormat, // should be provided only for actual text and headers, not axis/legend labels
4018
- isUTCScale) {
4123
+ function timeFormatExpression(_ref6) {
4124
+ let {
4125
+ field,
4126
+ timeUnit,
4127
+ format,
4128
+ formatType,
4129
+ rawTimeFormat,
4130
+ isUTCScale
4131
+ } = _ref6;
4132
+
4019
4133
  if (!timeUnit || format) {
4020
4134
  // If there is no time unit, or if user explicitly specifies format for axis/legend/text.
4135
+ if (!timeUnit && formatType) {
4136
+ return "".concat(formatType, "(").concat(field, ", '").concat(format, "')");
4137
+ }
4138
+
4021
4139
  format = vega.isString(format) ? format : rawTimeFormat; // only use provided timeFormat if there is no timeUnit.
4022
4140
 
4023
4141
  return "".concat(isUTCScale ? 'utc' : 'time', "Format(").concat(field, ", '").concat(format, "')");
@@ -4049,13 +4167,13 @@
4049
4167
  return c in SORT_BY_CHANNEL_INDEX;
4050
4168
  }
4051
4169
  function isSortByEncoding(sort) {
4052
- return !!sort && !!sort['encoding'];
4170
+ return !!(sort !== null && sort !== void 0 && sort['encoding']);
4053
4171
  }
4054
4172
  function isSortField(sort) {
4055
- return !!sort && (sort['op'] === 'count' || !!sort['field']);
4173
+ return sort && (sort['op'] === 'count' || !!sort['field']);
4056
4174
  }
4057
4175
  function isSortArray(sort) {
4058
- return !!sort && vega.isArray(sort);
4176
+ return sort && vega.isArray(sort);
4059
4177
  }
4060
4178
 
4061
4179
  function isFacetMapping(f) {
@@ -4217,15 +4335,15 @@
4217
4335
  */
4218
4336
 
4219
4337
  function hasConditionalFieldDef(channelDef) {
4220
- const condition = channelDef && channelDef['condition'];
4338
+ const condition = channelDef === null || channelDef === void 0 ? void 0 : channelDef['condition'];
4221
4339
  return !!condition && !vega.isArray(condition) && isFieldDef(condition);
4222
4340
  }
4223
4341
  function hasConditionalFieldOrDatumDef(channelDef) {
4224
- const condition = channelDef && channelDef['condition'];
4342
+ const condition = channelDef === null || channelDef === void 0 ? void 0 : channelDef['condition'];
4225
4343
  return !!condition && !vega.isArray(condition) && isFieldOrDatumDef(condition);
4226
4344
  }
4227
4345
  function hasConditionalValueDef(channelDef) {
4228
- const condition = channelDef && channelDef['condition'];
4346
+ const condition = channelDef === null || channelDef === void 0 ? void 0 : channelDef['condition'];
4229
4347
  return !!condition && (vega.isArray(condition) || isValueDef(condition));
4230
4348
  }
4231
4349
  function isFieldDef(channelDef) {
@@ -4233,7 +4351,7 @@
4233
4351
  return channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');
4234
4352
  }
4235
4353
  function channelDefType(channelDef) {
4236
- return channelDef && channelDef['type'];
4354
+ return channelDef === null || channelDef === void 0 ? void 0 : channelDef['type'];
4237
4355
  }
4238
4356
  function isDatumDef(channelDef) {
4239
4357
  return channelDef && 'datum' in channelDef;
@@ -5082,7 +5200,7 @@
5082
5200
  }
5083
5201
  };
5084
5202
  function isConditionalAxisValue(v) {
5085
- return v && v['condition'];
5203
+ return v === null || v === void 0 ? void 0 : v.condition;
5086
5204
  }
5087
5205
  const AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title'];
5088
5206
  /**
@@ -5955,7 +6073,7 @@
5955
6073
  ...(isMarkDef(partBaseSpec.mark) ? partBaseSpec.mark : {
5956
6074
  type: partBaseSpec.mark
5957
6075
  }),
5958
- style: "".concat(mark, "-").concat(part),
6076
+ style: "".concat(mark, "-").concat(String(part)),
5959
6077
  ...(vega.isBoolean(markDef[part]) ? {} : markDef[part])
5960
6078
  }
5961
6079
  }];
@@ -7047,13 +7165,13 @@
7047
7165
  }
7048
7166
  };
7049
7167
  function isLegendBinding(bind) {
7050
- return !!bind && (bind === 'legend' || !!bind.legend);
7168
+ return bind === 'legend' || !!(bind !== null && bind !== void 0 && bind.legend);
7051
7169
  }
7052
7170
  function isLegendStreamBinding(bind) {
7053
7171
  return isLegendBinding(bind) && vega.isObject(bind);
7054
7172
  }
7055
7173
  function isSelectionParameter(param) {
7056
- return !!param['select'];
7174
+ return !!(param !== null && param !== void 0 && param['select']);
7057
7175
  }
7058
7176
 
7059
7177
  function assembleParameterSignals(params) {
@@ -7122,34 +7240,6 @@
7122
7240
  return 'hconcat' in spec;
7123
7241
  }
7124
7242
 
7125
- function isFitType(autoSizeType) {
7126
- return autoSizeType === 'fit' || autoSizeType === 'fit-x' || autoSizeType === 'fit-y';
7127
- }
7128
- function getFitType(sizeType) {
7129
- return sizeType ? "fit-".concat(getPositionScaleChannel(sizeType)) : 'fit';
7130
- }
7131
- const TOP_LEVEL_PROPERTIES = ['background', 'padding' // We do not include "autosize" here as it is supported by only unit and layer specs and thus need to be normalized
7132
- ];
7133
- function extractTopLevelProperties(t, includeParams) {
7134
- const o = {};
7135
-
7136
- for (const p of TOP_LEVEL_PROPERTIES) {
7137
- if (t && t[p] !== undefined) {
7138
- o[p] = signalRefOrValue(t[p]);
7139
- }
7140
- }
7141
-
7142
- if (includeParams) {
7143
- o.params = t.params;
7144
- }
7145
-
7146
- return o;
7147
- }
7148
-
7149
- /**
7150
- * Common properties for all types of specification
7151
- */
7152
-
7153
7243
  function getStepFor(_ref) {
7154
7244
  let {
7155
7245
  step,
@@ -7318,7 +7408,8 @@
7318
7408
  },
7319
7409
  concat: {
7320
7410
  spacing: DEFAULT_SPACING
7321
- }
7411
+ },
7412
+ normalizedNumberFormat: '.0%'
7322
7413
  }; // Tableau10 color palette, copied from `vegaScale.scheme('tableau10')`
7323
7414
 
7324
7415
  const tab10 = ['#4c78a8', '#f58518', '#e45756', '#72b7b2', '#54a24b', '#eeca3b', '#b279a2', '#ff9da6', '#9d755d', '#bab0ac'];
@@ -7598,7 +7689,7 @@
7598
7689
  }
7599
7690
  const MARK_STYLES = new Set(['view', ...PRIMITIVE_MARKS]);
7600
7691
  const VL_ONLY_CONFIG_PROPERTIES = ['color', 'fontSize', 'background', // We apply background to the spec directly.
7601
- 'padding', 'facet', 'concat', 'numberFormat', 'timeFormat', 'countTitle', 'header', 'axisQuantitative', 'axisTemporal', 'axisDiscrete', 'axisPoint', 'axisXBand', 'axisXPoint', 'axisXDiscrete', 'axisXQuantitative', 'axisXTemporal', 'axisYBand', 'axisYPoint', 'axisYDiscrete', 'axisYQuantitative', 'axisYTemporal', 'scale', 'selection', 'overlay' // FIXME: Redesign and unhide this
7692
+ 'padding', 'facet', 'concat', 'numberFormat', 'numberFormatType', 'normalizedNumberFormat', 'normalizedNumberFormatType', 'timeFormat', 'countTitle', 'header', 'axisQuantitative', 'axisTemporal', 'axisDiscrete', 'axisPoint', 'axisXBand', 'axisXPoint', 'axisXDiscrete', 'axisXQuantitative', 'axisXTemporal', 'axisYBand', 'axisYPoint', 'axisYDiscrete', 'axisYQuantitative', 'axisYTemporal', 'scale', 'selection', 'overlay' // FIXME: Redesign and unhide this
7602
7693
  ];
7603
7694
  const VL_ONLY_ALL_MARK_SPECIFIC_CONFIG_PROPERTY_INDEX = {
7604
7695
  view: ['continuousWidth', 'continuousHeight', 'discreteWidth', 'discreteHeight', 'step'],
@@ -7907,14 +7998,11 @@
7907
7998
  case 'radius':
7908
7999
  return 'theta';
7909
8000
  }
7910
- } // Note: CompassQL uses this method and only pass in required properties of each argument object.
7911
- // If required properties change, make sure to update CompassQL.
7912
-
8001
+ }
7913
8002
 
7914
8003
  function stack(m, encoding) {
7915
8004
  var _stackedFieldDef$scal, _stackedFieldDef$scal2;
7916
8005
 
7917
- let opt = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
7918
8006
  const mark = isMarkDef(m) ? m.type : m; // Should have stackable mark
7919
8007
 
7920
8008
  if (!STACKABLE_MARKS.has(mark)) {
@@ -8011,11 +8099,8 @@
8011
8099
 
8012
8100
 
8013
8101
  if (stackedFieldDef !== null && stackedFieldDef !== void 0 && (_stackedFieldDef$scal = stackedFieldDef.scale) !== null && _stackedFieldDef$scal !== void 0 && _stackedFieldDef$scal.type && (stackedFieldDef === null || stackedFieldDef === void 0 ? void 0 : (_stackedFieldDef$scal2 = stackedFieldDef.scale) === null || _stackedFieldDef$scal2 === void 0 ? void 0 : _stackedFieldDef$scal2.type) !== ScaleType.LINEAR) {
8014
- if (opt.disallowNonLinearStack) {
8015
- return null;
8016
- } else {
8017
- warn(cannotStackNonLinearScale(stackedFieldDef.scale.type));
8018
- }
8102
+ warn(cannotStackNonLinearScale(stackedFieldDef.scale.type));
8103
+ return null;
8019
8104
  } // Check if it is a ranged mark
8020
8105
 
8021
8106
 
@@ -9283,6 +9368,30 @@
9283
9368
  return autosize;
9284
9369
  }
9285
9370
 
9371
+ function isFitType(autoSizeType) {
9372
+ return autoSizeType === 'fit' || autoSizeType === 'fit-x' || autoSizeType === 'fit-y';
9373
+ }
9374
+ function getFitType(sizeType) {
9375
+ return sizeType ? "fit-".concat(getPositionScaleChannel(sizeType)) : 'fit';
9376
+ }
9377
+ const TOP_LEVEL_PROPERTIES = ['background', 'padding' // We do not include "autosize" here as it is supported by only unit and layer specs and thus need to be normalized
9378
+ ];
9379
+ function extractTopLevelProperties(t, includeParams) {
9380
+ const o = {};
9381
+
9382
+ for (const p of TOP_LEVEL_PROPERTIES) {
9383
+ if (t && t[p] !== undefined) {
9384
+ o[p] = signalRefOrValue(t[p]);
9385
+ }
9386
+ }
9387
+
9388
+ if (includeParams) {
9389
+ o.params = t.params;
9390
+ }
9391
+
9392
+ return o;
9393
+ }
9394
+
9286
9395
  /**
9287
9396
  * Generic class for storing properties that are explicitly specified
9288
9397
  * and implicitly determined by the compiler.
@@ -9602,14 +9711,26 @@
9602
9711
  }
9603
9712
  function assembleUnitSelectionData(model, data) {
9604
9713
  const dataCopy = [...data];
9714
+ const unit = unitName(model, {
9715
+ escape: false
9716
+ });
9605
9717
 
9606
9718
  for (const selCmpt of vals((_model$component$sele3 = model.component.selection) !== null && _model$component$sele3 !== void 0 ? _model$component$sele3 : {})) {
9607
9719
  var _model$component$sele3;
9608
9720
 
9609
- const init = {
9721
+ const store = {
9610
9722
  name: selCmpt.name + STORE
9611
9723
  };
9612
9724
 
9725
+ if (selCmpt.project.hasSelectionId) {
9726
+ store.transform = [{
9727
+ type: 'collect',
9728
+ sort: {
9729
+ field: SELECTION_ID
9730
+ }
9731
+ }];
9732
+ }
9733
+
9613
9734
  if (selCmpt.init) {
9614
9735
  const fields = selCmpt.project.items.map(proj => {
9615
9736
  const {
@@ -9618,10 +9739,11 @@
9618
9739
  } = proj;
9619
9740
  return rest;
9620
9741
  });
9621
- init.values = selCmpt.init.map(i => ({
9622
- unit: unitName(model, {
9623
- escape: false
9624
- }),
9742
+ store.values = selCmpt.project.hasSelectionId ? selCmpt.init.map(i => ({
9743
+ unit,
9744
+ [SELECTION_ID]: assembleInit(i, false)[0]
9745
+ })) : selCmpt.init.map(i => ({
9746
+ unit,
9625
9747
  fields,
9626
9748
  values: assembleInit(i, false)
9627
9749
  }));
@@ -9630,7 +9752,7 @@
9630
9752
  const contains = dataCopy.filter(d => d.name === selCmpt.name + STORE);
9631
9753
 
9632
9754
  if (!contains.length) {
9633
- dataCopy.push(init);
9755
+ dataCopy.push(store);
9634
9756
  }
9635
9757
  }
9636
9758
 
@@ -9787,9 +9909,10 @@
9787
9909
  this._children = []; // equivalent to removing every child link one by one
9788
9910
 
9789
9911
  parent.removeChild(this);
9790
- parent.parent.removeChild(parent); // swap two nodes
9912
+ const loc = parent.parent.removeChild(parent); // swap two nodes but maintain order in children
9791
9913
 
9792
- this.parent = newParent;
9914
+ this._parent = newParent;
9915
+ newParent.addChild(this, loc);
9793
9916
  parent.parent = this;
9794
9917
  }
9795
9918
 
@@ -10022,6 +10145,8 @@
10022
10145
 
10023
10146
  _defineProperty(this, "hasField", void 0);
10024
10147
 
10148
+ _defineProperty(this, "hasSelectionId", void 0);
10149
+
10025
10150
  _defineProperty(this, "timeUnit", void 0);
10026
10151
 
10027
10152
  _defineProperty(this, "items", void 0);
@@ -10033,6 +10158,7 @@
10033
10158
  this.items = items;
10034
10159
  this.hasChannel = {};
10035
10160
  this.hasField = {};
10161
+ this.hasSelectionId = false;
10036
10162
  }
10037
10163
 
10038
10164
  }
@@ -10164,6 +10290,7 @@
10164
10290
  };
10165
10291
  proj.items.push(parsed[field] = p);
10166
10292
  proj.hasField[field] = proj.hasChannel[channel] = parsed[field];
10293
+ proj.hasSelectionId = proj.hasSelectionId || field === SELECTION_ID;
10167
10294
  }
10168
10295
  } else {
10169
10296
  warn(cannotProjectOnChannelWithoutField(channel));
@@ -10182,6 +10309,7 @@
10182
10309
  };
10183
10310
  proj.items.push(p);
10184
10311
  proj.hasField[field] = p;
10312
+ proj.hasSelectionId = proj.hasSelectionId || field === SELECTION_ID;
10185
10313
  }
10186
10314
 
10187
10315
  if (init) {
@@ -10199,7 +10327,7 @@
10199
10327
  signals: (model, selCmpt, allSignals) => {
10200
10328
  const name = selCmpt.name + TUPLE_FIELDS;
10201
10329
  const hasSignal = allSignals.filter(s => s.name === name);
10202
- return hasSignal.length > 0 ? allSignals : allSignals.concat({
10330
+ return hasSignal.length > 0 || selCmpt.project.hasSelectionId ? allSignals : allSignals.concat({
10203
10331
  name,
10204
10332
  value: selCmpt.project.items.map(proj => {
10205
10333
  const {
@@ -10579,14 +10707,7 @@
10579
10707
  const name = selCmpt.name;
10580
10708
  const fieldsSg = name + TUPLE_FIELDS;
10581
10709
  const project = selCmpt.project;
10582
- const datum = '(item().isVoronoi ? datum.datum : datum)';
10583
- const values = project.items.map(p => {
10584
- const fieldDef = model.fieldDef(p.channel); // Binned fields should capture extents, for a range test against the raw field.
10585
-
10586
- return fieldDef !== null && fieldDef !== void 0 && fieldDef.bin ? "[".concat(datum, "[").concat(vega.stringValue(model.vgField(p.channel, {})), "], ") + "".concat(datum, "[").concat(vega.stringValue(model.vgField(p.channel, {
10587
- binSuffix: 'end'
10588
- })), "]]") : "".concat(datum, "[").concat(vega.stringValue(p.field), "]");
10589
- }).join(', '); // Only add a discrete selection to the store if a datum is present _and_
10710
+ const datum = '(item().isVoronoi ? datum.datum : datum)'; // Only add a discrete selection to the store if a datum is present _and_
10590
10711
  // the interaction isn't occurring on a group mark. This guards against
10591
10712
  // polluting interactive state with invalid values in faceted displays
10592
10713
  // as the group marks are also data-driven. We force the update to account
@@ -10594,17 +10715,31 @@
10594
10715
  // whitespace followed by a click in whitespace; the store should only
10595
10716
  // be cleared on the second click).
10596
10717
 
10597
- const update = "unit: ".concat(unitName(model), ", fields: ").concat(fieldsSg, ", values");
10598
- const events = selCmpt.events;
10599
10718
  const brushes = vals((_model$component$sele = model.component.selection) !== null && _model$component$sele !== void 0 ? _model$component$sele : {}).reduce((acc, cmpt) => {
10600
10719
  return cmpt.type === 'interval' ? acc.concat(cmpt.name + BRUSH) : acc;
10601
10720
  }, []).map(b => "indexof(item().mark.name, '".concat(b, "') < 0")).join(' && ');
10602
- const test = "datum && item().mark.marktype !== 'group'".concat(brushes ? " && ".concat(brushes) : '');
10721
+ const test = "datum && item().mark.marktype !== 'group' && indexof(item().mark.role, 'legend') < 0".concat(brushes ? " && ".concat(brushes) : '');
10722
+ let update = "unit: ".concat(unitName(model), ", ");
10723
+
10724
+ if (selCmpt.project.hasSelectionId) {
10725
+ update += "".concat(SELECTION_ID, ": ").concat(datum, "[").concat(vega.stringValue(SELECTION_ID), "]");
10726
+ } else {
10727
+ const values = project.items.map(p => {
10728
+ const fieldDef = model.fieldDef(p.channel); // Binned fields should capture extents, for a range test against the raw field.
10729
+
10730
+ return fieldDef !== null && fieldDef !== void 0 && fieldDef.bin ? "[".concat(datum, "[").concat(vega.stringValue(model.vgField(p.channel, {})), "], ") + "".concat(datum, "[").concat(vega.stringValue(model.vgField(p.channel, {
10731
+ binSuffix: 'end'
10732
+ })), "]]") : "".concat(datum, "[").concat(vega.stringValue(p.field), "]");
10733
+ }).join(', ');
10734
+ update += "fields: ".concat(fieldsSg, ", values: [").concat(values, "]");
10735
+ }
10736
+
10737
+ const events = selCmpt.events;
10603
10738
  return signals.concat([{
10604
10739
  name: name + TUPLE,
10605
10740
  on: events ? [{
10606
10741
  events,
10607
- update: "".concat(test, " ? {").concat(update, ": [").concat(values, "]} : null"),
10742
+ update: "".concat(test, " ? {").concat(update, "} : null"),
10608
10743
  force: true
10609
10744
  }] : []
10610
10745
  }]);
@@ -10785,22 +10920,24 @@
10785
10920
  } = getFormatMixins(fieldDef);
10786
10921
  value = binFormatExpression(startField, endField, format, formatType, config);
10787
10922
  toSkip[channel2] = true;
10788
- } else if (stack && stack.fieldChannel === channel && stack.offset === 'normalize') {
10789
- const {
10790
- format,
10791
- formatType
10792
- } = getFormatMixins(fieldDef);
10793
- value = formatSignalRef({
10794
- fieldOrDatumDef: fieldDef,
10795
- format,
10796
- formatType,
10797
- expr,
10798
- config,
10799
- normalizeStack: true
10800
- }).signal;
10801
10923
  }
10802
10924
  }
10803
10925
 
10926
+ if ((isXorY(channel) || channel === THETA || channel === RADIUS) && stack && stack.fieldChannel === channel && stack.offset === 'normalize') {
10927
+ const {
10928
+ format,
10929
+ formatType
10930
+ } = getFormatMixins(fieldDef);
10931
+ value = formatSignalRef({
10932
+ fieldOrDatumDef: fieldDef,
10933
+ format,
10934
+ formatType,
10935
+ expr,
10936
+ config,
10937
+ normalizeStack: true
10938
+ }).signal;
10939
+ }
10940
+
10804
10941
  (_value = value) !== null && _value !== void 0 ? _value : value = textRef(fieldDef, config, expr).signal;
10805
10942
  tuples.push({
10806
10943
  channel,
@@ -11576,9 +11713,15 @@
11576
11713
  const scaleType = scale.get('type');
11577
11714
 
11578
11715
  if (scaleType === 'band') {
11716
+ let bandWidth = "bandwidth('".concat(scaleName, "')");
11717
+
11718
+ if (bandSize.band !== 1) {
11719
+ bandWidth = "".concat(bandSize.band, " * ").concat(bandWidth);
11720
+ } // TODO(#8351): make 0.25 here configurable
11721
+
11722
+
11579
11723
  return {
11580
- scale: scaleName,
11581
- band: bandSize.band
11724
+ signal: "max(0.25, ".concat(bandWidth, ")")
11582
11725
  };
11583
11726
  } else if (bandSize.band !== 1) {
11584
11727
  warn(cannotUseRelativeBandSizeWithNonBandScale(scaleType));
@@ -11649,8 +11792,9 @@
11649
11792
  } else {
11650
11793
  warn(cannotApplySizeToNonOrientedMark(markDef.type));
11651
11794
  }
11652
- } // Otherwise, apply default value
11795
+ }
11653
11796
 
11797
+ const hasSizeFromMarkOrEncoding = !!sizeMixins; // Otherwise, apply default value
11654
11798
 
11655
11799
  const bandSize = getBandSize({
11656
11800
  channel,
@@ -11671,7 +11815,7 @@
11671
11815
  If band is 0.6, the the x/y position in such case should be `(1 - band) / 2` = 0.2
11672
11816
  */
11673
11817
 
11674
- const defaultBandAlign = (scale === null || scale === void 0 ? void 0 : scale.get('type')) !== 'band' || !('band' in sizeMixins[vgSizeChannel]) ? 'middle' : 'top';
11818
+ const defaultBandAlign = (scale === null || scale === void 0 ? void 0 : scale.get('type')) === 'band' && isRelativeBandSize(bandSize) && !hasSizeFromMarkOrEncoding ? 'top' : 'middle';
11675
11819
  const vgChannel = vgAlignedPositionChannel(channel, markDef, config, defaultBandAlign);
11676
11820
  const center = vgChannel === 'xc' || vgChannel === 'yc';
11677
11821
  const {
@@ -11991,9 +12135,12 @@
11991
12135
  const scaleComponent = model.getScaleComponent(channel);
11992
12136
 
11993
12137
  if (scaleComponent) {
12138
+ var _model$stack;
12139
+
11994
12140
  const scaleType = scaleComponent.get('type');
11995
12141
  const field = model.vgField(channel, {
11996
- expr: 'datum'
12142
+ expr: 'datum',
12143
+ binSuffix: (_model$stack = model.stack) !== null && _model$stack !== void 0 && _model$stack.impute ? 'mid' : undefined
11997
12144
  }); // While discrete domain scales can handle invalid values, continuous scales can't.
11998
12145
 
11999
12146
  if (field && hasContinuousDomain(scaleType)) {
@@ -12577,7 +12724,7 @@
12577
12724
  var _model$component$sele;
12578
12725
 
12579
12726
  return vals((_model$component$sele = model.component.selection) !== null && _model$component$sele !== void 0 ? _model$component$sele : {}).reduce((identifier, selCmpt) => {
12580
- return identifier || selCmpt.project.items.some(proj => proj.field === SELECTION_ID);
12727
+ return identifier || selCmpt.project.hasSelectionId;
12581
12728
  }, false);
12582
12729
  } // Binding a point selection to query widgets or legends disables default direct manipulation interaction.
12583
12730
  // A user can choose to re-enable it by explicitly specifying triggering input events.
@@ -12747,7 +12894,9 @@
12747
12894
  }
12748
12895
  }
12749
12896
 
12750
- const test = "vlSelectionTest(".concat(store, ", ").concat(datum).concat(selCmpt.resolve === 'global' ? ')' : ", ".concat(vega.stringValue(selCmpt.resolve), ")"));
12897
+ const fn = selCmpt.project.hasSelectionId ? 'vlSelectionIdTest(' : 'vlSelectionTest(';
12898
+ const resolve = selCmpt.resolve === 'global' ? ')' : ", ".concat(vega.stringValue(selCmpt.resolve), ")");
12899
+ const test = "".concat(fn).concat(store, ", ").concat(datum).concat(resolve);
12751
12900
  const length = "length(data(".concat(store, "))");
12752
12901
  return pred.empty === false ? "".concat(length, " && ").concat(test) : "!".concat(length, " || ").concat(test);
12753
12902
  }
@@ -14194,13 +14343,36 @@
14194
14343
  format,
14195
14344
  formatType
14196
14345
  } = legend;
14197
- const text = isCustomFormatType(formatType) ? formatCustomType({
14198
- fieldOrDatumDef,
14199
- field: 'datum.value',
14200
- format,
14201
- formatType,
14202
- config
14203
- }) : undefined;
14346
+ let text = undefined;
14347
+
14348
+ if (isCustomFormatType(formatType)) {
14349
+ text = formatCustomType({
14350
+ fieldOrDatumDef,
14351
+ field: 'datum.value',
14352
+ format,
14353
+ formatType,
14354
+ config
14355
+ });
14356
+ } else if (format === undefined && formatType === undefined && config.customFormatTypes) {
14357
+ if (fieldOrDatumDef.type === 'quantitative' && config.numberFormatType) {
14358
+ text = formatCustomType({
14359
+ fieldOrDatumDef,
14360
+ field: 'datum.value',
14361
+ format: config.numberFormat,
14362
+ formatType: config.numberFormatType,
14363
+ config
14364
+ });
14365
+ } else if (fieldOrDatumDef.type === 'temporal' && config.timeFormatType && isFieldDef(fieldOrDatumDef) && fieldOrDatumDef.timeUnit === undefined) {
14366
+ text = formatCustomType({
14367
+ fieldOrDatumDef,
14368
+ field: 'datum.value',
14369
+ format: config.timeFormat,
14370
+ formatType: config.timeFormatType,
14371
+ config
14372
+ });
14373
+ }
14374
+ }
14375
+
14204
14376
  const labelsSpec = { ...(opacity ? {
14205
14377
  opacity
14206
14378
  } : {}),
@@ -20152,7 +20324,11 @@
20152
20324
  this.transform = duplicate(transform); // duplicate to prevent side effects
20153
20325
 
20154
20326
  const specifiedAs = (_this$transform$as = this.transform.as) !== null && _this$transform$as !== void 0 ? _this$transform$as : [undefined, undefined];
20155
- this.transform.as = [(_specifiedAs$ = specifiedAs[0]) !== null && _specifiedAs$ !== void 0 ? _specifiedAs$ : 'value', (_specifiedAs$2 = specifiedAs[1]) !== null && _specifiedAs$2 !== void 0 ? _specifiedAs$2 : 'density'];
20327
+ this.transform.as = [(_specifiedAs$ = specifiedAs[0]) !== null && _specifiedAs$ !== void 0 ? _specifiedAs$ : 'value', (_specifiedAs$2 = specifiedAs[1]) !== null && _specifiedAs$2 !== void 0 ? _specifiedAs$2 : 'density']; // set steps when we are grouping so that we get consitent sampling points for imputing and grouping
20328
+
20329
+ if (transform.groupby && transform.minsteps == null && transform.maxsteps == null && transform.steps == null) {
20330
+ this.transform.steps = 200;
20331
+ }
20156
20332
  }
20157
20333
 
20158
20334
  dependentFields() {
@@ -22543,6 +22719,45 @@
22543
22719
  }),
22544
22720
  ...specifiedLabelsSpec
22545
22721
  };
22722
+ } else if (format === undefined && formatType === undefined && config.customFormatTypes) {
22723
+ if (channelDefType(fieldOrDatumDef) === 'quantitative') {
22724
+ if (isPositionFieldOrDatumDef(fieldOrDatumDef) && fieldOrDatumDef.stack === 'normalize' && config.normalizedNumberFormatType) {
22725
+ return {
22726
+ text: formatCustomType({
22727
+ fieldOrDatumDef,
22728
+ field: 'datum.value',
22729
+ format: config.normalizedNumberFormat,
22730
+ formatType: config.normalizedNumberFormatType,
22731
+ config
22732
+ }),
22733
+ ...specifiedLabelsSpec
22734
+ };
22735
+ } else if (config.numberFormatType) {
22736
+ return {
22737
+ text: formatCustomType({
22738
+ fieldOrDatumDef,
22739
+ field: 'datum.value',
22740
+ format: config.numberFormat,
22741
+ formatType: config.numberFormatType,
22742
+ config
22743
+ }),
22744
+ ...specifiedLabelsSpec
22745
+ };
22746
+ }
22747
+ }
22748
+
22749
+ if (channelDefType(fieldOrDatumDef) === 'temporal' && config.timeFormatType && isFieldDef(fieldOrDatumDef) && !fieldOrDatumDef.timeUnit) {
22750
+ return {
22751
+ text: formatCustomType({
22752
+ fieldOrDatumDef,
22753
+ field: 'datum.value',
22754
+ format: config.timeFormat,
22755
+ formatType: config.timeFormatType,
22756
+ config
22757
+ }),
22758
+ ...specifiedLabelsSpec
22759
+ };
22760
+ }
22546
22761
  }
22547
22762
 
22548
22763
  return specifiedLabelsSpec;