@ggts-sh/spec 0.43.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/LICENSE +21 -0
- package/README.md +75 -0
- package/dist/artifact.d.ts +11 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +71 -0
- package/dist/artifact.js.map +1 -0
- package/dist/builder-core.d.ts +100 -0
- package/dist/builder-core.d.ts.map +1 -0
- package/dist/builder-core.js +176 -0
- package/dist/builder-core.js.map +1 -0
- package/dist/builder-data.d.ts +36 -0
- package/dist/builder-data.d.ts.map +1 -0
- package/dist/builder-data.js +123 -0
- package/dist/builder-data.js.map +1 -0
- package/dist/builder-geoms.d.ts +128 -0
- package/dist/builder-geoms.d.ts.map +1 -0
- package/dist/builder-geoms.js +221 -0
- package/dist/builder-geoms.js.map +1 -0
- package/dist/builder-options.d.ts +323 -0
- package/dist/builder-options.d.ts.map +1 -0
- package/dist/builder-options.js +2 -0
- package/dist/builder-options.js.map +1 -0
- package/dist/builder-scales.d.ts +160 -0
- package/dist/builder-scales.d.ts.map +1 -0
- package/dist/builder-scales.js +322 -0
- package/dist/builder-scales.js.map +1 -0
- package/dist/builder.d.ts +242 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +42 -0
- package/dist/builder.js.map +1 -0
- package/dist/capabilities-data.d.ts +72 -0
- package/dist/capabilities-data.d.ts.map +1 -0
- package/dist/capabilities-data.js +337 -0
- package/dist/capabilities-data.js.map +1 -0
- package/dist/capabilities-helpers.d.ts +31 -0
- package/dist/capabilities-helpers.d.ts.map +1 -0
- package/dist/capabilities-helpers.js +41 -0
- package/dist/capabilities-helpers.js.map +1 -0
- package/dist/capabilities.d.ts +22 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +154 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/coord-helpers.d.ts +102 -0
- package/dist/coord-helpers.d.ts.map +1 -0
- package/dist/coord-helpers.js +90 -0
- package/dist/coord-helpers.js.map +1 -0
- package/dist/coord-reference-build.d.ts +50 -0
- package/dist/coord-reference-build.d.ts.map +1 -0
- package/dist/coord-reference-build.js +211 -0
- package/dist/coord-reference-build.js.map +1 -0
- package/dist/coord-reference.d.ts +52 -0
- package/dist/coord-reference.d.ts.map +1 -0
- package/dist/coord-reference.js +27 -0
- package/dist/coord-reference.js.map +1 -0
- package/dist/error-catalog.d.ts +258 -0
- package/dist/error-catalog.d.ts.map +1 -0
- package/dist/error-catalog.js +235 -0
- package/dist/error-catalog.js.map +1 -0
- package/dist/error-prose-shared.d.ts +100 -0
- package/dist/error-prose-shared.d.ts.map +1 -0
- package/dist/error-prose-shared.js +95 -0
- package/dist/error-prose-shared.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +52 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/coord-reference-data.d.ts +189 -0
- package/dist/generated/coord-reference-data.d.ts.map +1 -0
- package/dist/generated/coord-reference-data.js +212 -0
- package/dist/generated/coord-reference-data.js.map +1 -0
- package/dist/generated/geom-param-keys.d.ts +58 -0
- package/dist/generated/geom-param-keys.d.ts.map +1 -0
- package/dist/generated/geom-param-keys.js +223 -0
- package/dist/generated/geom-param-keys.js.map +1 -0
- package/dist/generated/geom-reference-data.d.ts +2377 -0
- package/dist/generated/geom-reference-data.d.ts.map +1 -0
- package/dist/generated/geom-reference-data.js +2790 -0
- package/dist/generated/geom-reference-data.js.map +1 -0
- package/dist/generated/guide-reference-data.d.ts +219 -0
- package/dist/generated/guide-reference-data.d.ts.map +1 -0
- package/dist/generated/guide-reference-data.js +253 -0
- package/dist/generated/guide-reference-data.js.map +1 -0
- package/dist/generated/plot-spec-validator.d.ts +2 -0
- package/dist/generated/plot-spec-validator.d.ts.map +1 -0
- package/dist/generated/plot-spec-validator.js +6274 -0
- package/dist/generated/plot-spec-validator.js.map +1 -0
- package/dist/generated/position-reference-data.d.ts +82 -0
- package/dist/generated/position-reference-data.d.ts.map +1 -0
- package/dist/generated/position-reference-data.js +181 -0
- package/dist/generated/position-reference-data.js.map +1 -0
- package/dist/generated/scale-reference-data.d.ts +8366 -0
- package/dist/generated/scale-reference-data.d.ts.map +1 -0
- package/dist/generated/scale-reference-data.js +9821 -0
- package/dist/generated/scale-reference-data.js.map +1 -0
- package/dist/generated/stat-reference-data.d.ts +241 -0
- package/dist/generated/stat-reference-data.d.ts.map +1 -0
- package/dist/generated/stat-reference-data.js +311 -0
- package/dist/generated/stat-reference-data.js.map +1 -0
- package/dist/geom-params-build.d.ts +3 -0
- package/dist/geom-params-build.d.ts.map +1 -0
- package/dist/geom-params-build.js +80 -0
- package/dist/geom-params-build.js.map +1 -0
- package/dist/geom-params.d.ts +13 -0
- package/dist/geom-params.d.ts.map +1 -0
- package/dist/geom-params.js +7 -0
- package/dist/geom-params.js.map +1 -0
- package/dist/geom-reference-build.d.ts +29 -0
- package/dist/geom-reference-build.d.ts.map +1 -0
- package/dist/geom-reference-build.js +221 -0
- package/dist/geom-reference-build.js.map +1 -0
- package/dist/geom-reference.d.ts +52 -0
- package/dist/geom-reference.d.ts.map +1 -0
- package/dist/geom-reference.js +72 -0
- package/dist/geom-reference.js.map +1 -0
- package/dist/guide-helpers.d.ts +20 -0
- package/dist/guide-helpers.d.ts.map +1 -0
- package/dist/guide-helpers.js +25 -0
- package/dist/guide-helpers.js.map +1 -0
- package/dist/guide-reference-build.d.ts +42 -0
- package/dist/guide-reference-build.d.ts.map +1 -0
- package/dist/guide-reference-build.js +180 -0
- package/dist/guide-reference-build.js.map +1 -0
- package/dist/guide-reference.d.ts +48 -0
- package/dist/guide-reference.d.ts.map +1 -0
- package/dist/guide-reference.js +32 -0
- package/dist/guide-reference.js.map +1 -0
- package/dist/hue-grey-palettes.d.ts +15 -0
- package/dist/hue-grey-palettes.d.ts.map +1 -0
- package/dist/hue-grey-palettes.js +77 -0
- package/dist/hue-grey-palettes.js.map +1 -0
- package/dist/index.d.ts +364 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +225 -0
- package/dist/index.js.map +1 -0
- package/dist/lint-catalog.d.ts +47 -0
- package/dist/lint-catalog.d.ts.map +1 -0
- package/dist/lint-catalog.js +39 -0
- package/dist/lint-catalog.js.map +1 -0
- package/dist/lint-layer-rules.d.ts +18 -0
- package/dist/lint-layer-rules.d.ts.map +1 -0
- package/dist/lint-layer-rules.js +145 -0
- package/dist/lint-layer-rules.js.map +1 -0
- package/dist/lint-scale-rules.d.ts +8 -0
- package/dist/lint-scale-rules.d.ts.map +1 -0
- package/dist/lint-scale-rules.js +254 -0
- package/dist/lint-scale-rules.js.map +1 -0
- package/dist/lint.d.ts +62 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +57 -0
- package/dist/lint.js.map +1 -0
- package/dist/normalize-coord.d.ts +8 -0
- package/dist/normalize-coord.d.ts.map +1 -0
- package/dist/normalize-coord.js +123 -0
- package/dist/normalize-coord.js.map +1 -0
- package/dist/normalize-input-layers-marks.d.ts +208 -0
- package/dist/normalize-input-layers-marks.d.ts.map +1 -0
- package/dist/normalize-input-layers-marks.js +2 -0
- package/dist/normalize-input-layers-marks.js.map +1 -0
- package/dist/normalize-input-layers-special.d.ts +131 -0
- package/dist/normalize-input-layers-special.d.ts.map +1 -0
- package/dist/normalize-input-layers-special.js +2 -0
- package/dist/normalize-input-layers-special.js.map +1 -0
- package/dist/normalize-input.d.ts +81 -0
- package/dist/normalize-input.d.ts.map +1 -0
- package/dist/normalize-input.js +2 -0
- package/dist/normalize-input.js.map +1 -0
- package/dist/normalize-paint.d.ts +8 -0
- package/dist/normalize-paint.d.ts.map +1 -0
- package/dist/normalize-paint.js +83 -0
- package/dist/normalize-paint.js.map +1 -0
- package/dist/normalize-scales.d.ts +7 -0
- package/dist/normalize-scales.d.ts.map +1 -0
- package/dist/normalize-scales.js +90 -0
- package/dist/normalize-scales.js.map +1 -0
- package/dist/normalize.d.ts +46 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +279 -0
- package/dist/normalize.js.map +1 -0
- package/dist/paint-helpers.d.ts +45 -0
- package/dist/paint-helpers.d.ts.map +1 -0
- package/dist/paint-helpers.js +48 -0
- package/dist/paint-helpers.js.map +1 -0
- package/dist/pipeline-error-catalog.d.ts +319 -0
- package/dist/pipeline-error-catalog.d.ts.map +1 -0
- package/dist/pipeline-error-catalog.js +260 -0
- package/dist/pipeline-error-catalog.js.map +1 -0
- package/dist/portability-check.d.ts +35 -0
- package/dist/portability-check.d.ts.map +1 -0
- package/dist/portability-check.js +121 -0
- package/dist/portability-check.js.map +1 -0
- package/dist/portability-lossy.d.ts +19 -0
- package/dist/portability-lossy.d.ts.map +1 -0
- package/dist/portability-lossy.js +65 -0
- package/dist/portability-lossy.js.map +1 -0
- package/dist/portability.d.ts +23 -0
- package/dist/portability.d.ts.map +1 -0
- package/dist/portability.js +23 -0
- package/dist/portability.js.map +1 -0
- package/dist/portable-builder.d.ts +215 -0
- package/dist/portable-builder.d.ts.map +1 -0
- package/dist/portable-builder.js +27 -0
- package/dist/portable-builder.js.map +1 -0
- package/dist/portable-entry.d.ts +16 -0
- package/dist/portable-entry.d.ts.map +1 -0
- package/dist/portable-entry.js +14 -0
- package/dist/portable-entry.js.map +1 -0
- package/dist/position-reference-build.d.ts +29 -0
- package/dist/position-reference-build.d.ts.map +1 -0
- package/dist/position-reference-build.js +115 -0
- package/dist/position-reference-build.js.map +1 -0
- package/dist/position-reference.d.ts +34 -0
- package/dist/position-reference.d.ts.map +1 -0
- package/dist/position-reference.js +19 -0
- package/dist/position-reference.js.map +1 -0
- package/dist/runtime.d.ts +139 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scale-color-helpers.d.ts +121 -0
- package/dist/scale-color-helpers.d.ts.map +1 -0
- package/dist/scale-color-helpers.js +188 -0
- package/dist/scale-color-helpers.js.map +1 -0
- package/dist/scale-color-hue-grey.d.ts +52 -0
- package/dist/scale-color-hue-grey.d.ts.map +1 -0
- package/dist/scale-color-hue-grey.js +60 -0
- package/dist/scale-color-hue-grey.js.map +1 -0
- package/dist/scale-color-stops.d.ts +85 -0
- package/dist/scale-color-stops.d.ts.map +1 -0
- package/dist/scale-color-stops.js +87 -0
- package/dist/scale-color-stops.js.map +1 -0
- package/dist/scale-color-viridis.d.ts +52 -0
- package/dist/scale-color-viridis.d.ts.map +1 -0
- package/dist/scale-color-viridis.js +68 -0
- package/dist/scale-color-viridis.js.map +1 -0
- package/dist/scale-helpers.d.ts +20 -0
- package/dist/scale-helpers.d.ts.map +1 -0
- package/dist/scale-helpers.js +20 -0
- package/dist/scale-helpers.js.map +1 -0
- package/dist/scale-multi-helpers.d.ts +61 -0
- package/dist/scale-multi-helpers.d.ts.map +1 -0
- package/dist/scale-multi-helpers.js +147 -0
- package/dist/scale-multi-helpers.js.map +1 -0
- package/dist/scale-position-helpers.d.ts +81 -0
- package/dist/scale-position-helpers.d.ts.map +1 -0
- package/dist/scale-position-helpers.js +133 -0
- package/dist/scale-position-helpers.js.map +1 -0
- package/dist/scale-reference-build.d.ts +50 -0
- package/dist/scale-reference-build.d.ts.map +1 -0
- package/dist/scale-reference-build.js +147 -0
- package/dist/scale-reference-build.js.map +1 -0
- package/dist/scale-reference-classify-color.d.ts +11 -0
- package/dist/scale-reference-classify-color.d.ts.map +1 -0
- package/dist/scale-reference-classify-color.js +292 -0
- package/dist/scale-reference-classify-color.js.map +1 -0
- package/dist/scale-reference-classify-position.d.ts +10 -0
- package/dist/scale-reference-classify-position.d.ts.map +1 -0
- package/dist/scale-reference-classify-position.js +137 -0
- package/dist/scale-reference-classify-position.js.map +1 -0
- package/dist/scale-reference-classify-style.d.ts +10 -0
- package/dist/scale-reference-classify-style.d.ts.map +1 -0
- package/dist/scale-reference-classify-style.js +194 -0
- package/dist/scale-reference-classify-style.js.map +1 -0
- package/dist/scale-reference-classify-support.d.ts +37 -0
- package/dist/scale-reference-classify-support.d.ts.map +1 -0
- package/dist/scale-reference-classify-support.js +206 -0
- package/dist/scale-reference-classify-support.js.map +1 -0
- package/dist/scale-reference.d.ts +80 -0
- package/dist/scale-reference.d.ts.map +1 -0
- package/dist/scale-reference.js +85 -0
- package/dist/scale-reference.js.map +1 -0
- package/dist/scale-style-helpers.d.ts +158 -0
- package/dist/scale-style-helpers.d.ts.map +1 -0
- package/dist/scale-style-helpers.js +197 -0
- package/dist/scale-style-helpers.js.map +1 -0
- package/dist/schema-catalog.d.ts +62 -0
- package/dist/schema-catalog.d.ts.map +1 -0
- package/dist/schema-catalog.js +208 -0
- package/dist/schema-catalog.js.map +1 -0
- package/dist/schema-declarations.d.ts +1585 -0
- package/dist/schema-declarations.d.ts.map +1 -0
- package/dist/schema-declarations.js +51 -0
- package/dist/schema-declarations.js.map +1 -0
- package/dist/schema-decls-data.d.ts +58 -0
- package/dist/schema-decls-data.d.ts.map +1 -0
- package/dist/schema-decls-data.js +151 -0
- package/dist/schema-decls-data.js.map +1 -0
- package/dist/schema-decls-guides-theme.d.ts +166 -0
- package/dist/schema-decls-guides-theme.d.ts.map +1 -0
- package/dist/schema-decls-guides-theme.js +251 -0
- package/dist/schema-decls-guides-theme.js.map +1 -0
- package/dist/schema-decls-layers-col-boxplot.d.ts +118 -0
- package/dist/schema-decls-layers-col-boxplot.d.ts.map +1 -0
- package/dist/schema-decls-layers-col-boxplot.js +239 -0
- package/dist/schema-decls-layers-col-boxplot.js.map +1 -0
- package/dist/schema-decls-layers-count-pointrange.d.ts +89 -0
- package/dist/schema-decls-layers-count-pointrange.d.ts.map +1 -0
- package/dist/schema-decls-layers-count-pointrange.js +190 -0
- package/dist/schema-decls-layers-count-pointrange.js.map +1 -0
- package/dist/schema-decls-layers-crossbar-jitter.d.ts +129 -0
- package/dist/schema-decls-layers-crossbar-jitter.d.ts.map +1 -0
- package/dist/schema-decls-layers-crossbar-jitter.js +255 -0
- package/dist/schema-decls-layers-crossbar-jitter.js.map +1 -0
- package/dist/schema-decls-layers-point-path.d.ts +49 -0
- package/dist/schema-decls-layers-point-path.d.ts.map +1 -0
- package/dist/schema-decls-layers-point-path.js +156 -0
- package/dist/schema-decls-layers-point-path.js.map +1 -0
- package/dist/schema-decls-layers-sf-blank.d.ts +89 -0
- package/dist/schema-decls-layers-sf-blank.d.ts.map +1 -0
- package/dist/schema-decls-layers-sf-blank.js +254 -0
- package/dist/schema-decls-layers-sf-blank.js.map +1 -0
- package/dist/schema-decls-layers-text-map.d.ts +80 -0
- package/dist/schema-decls-layers-text-map.d.ts.map +1 -0
- package/dist/schema-decls-layers-text-map.js +151 -0
- package/dist/schema-decls-layers-text-map.js.map +1 -0
- package/dist/schema-decls-paint.d.ts +39 -0
- package/dist/schema-decls-paint.d.ts.map +1 -0
- package/dist/schema-decls-paint.js +95 -0
- package/dist/schema-decls-paint.js.map +1 -0
- package/dist/schema-decls-params-area-abline.d.ts +85 -0
- package/dist/schema-decls-params-area-abline.d.ts.map +1 -0
- package/dist/schema-decls-params-area-abline.js +259 -0
- package/dist/schema-decls-params-area-abline.js.map +1 -0
- package/dist/schema-decls-params-col-contour.d.ts +61 -0
- package/dist/schema-decls-params-col-contour.d.ts.map +1 -0
- package/dist/schema-decls-params-col-contour.js +202 -0
- package/dist/schema-decls-params-col-contour.js.map +1 -0
- package/dist/schema-decls-params-curve-label.d.ts +64 -0
- package/dist/schema-decls-params-curve-label.d.ts.map +1 -0
- package/dist/schema-decls-params-curve-label.js +204 -0
- package/dist/schema-decls-params-curve-label.js.map +1 -0
- package/dist/schema-decls-params-errorbar-position.d.ts +83 -0
- package/dist/schema-decls-params-errorbar-position.d.ts.map +1 -0
- package/dist/schema-decls-params-errorbar-position.js +264 -0
- package/dist/schema-decls-params-errorbar-position.js.map +1 -0
- package/dist/schema-decls-params-point-path.d.ts +61 -0
- package/dist/schema-decls-params-point-path.d.ts.map +1 -0
- package/dist/schema-decls-params-point-path.js +240 -0
- package/dist/schema-decls-params-point-path.js.map +1 -0
- package/dist/schema-decls-params-violin-summary.d.ts +78 -0
- package/dist/schema-decls-params-violin-summary.d.ts.map +1 -0
- package/dist/schema-decls-params-violin-summary.js +272 -0
- package/dist/schema-decls-params-violin-summary.js.map +1 -0
- package/dist/schema-decls-plot.d.ts +80 -0
- package/dist/schema-decls-plot.d.ts.map +1 -0
- package/dist/schema-decls-plot.js +222 -0
- package/dist/schema-decls-plot.js.map +1 -0
- package/dist/schema-decls-scales-guides.d.ts +291 -0
- package/dist/schema-decls-scales-guides.d.ts.map +1 -0
- package/dist/schema-decls-scales-guides.js +189 -0
- package/dist/schema-decls-scales-guides.js.map +1 -0
- package/dist/schema-decls-scales.d.ts +124 -0
- package/dist/schema-decls-scales.d.ts.map +1 -0
- package/dist/schema-decls-scales.js +279 -0
- package/dist/schema-decls-scales.js.map +1 -0
- package/dist/schema-imports.d.ts +1679 -0
- package/dist/schema-imports.d.ts.map +1 -0
- package/dist/schema-imports.js +104 -0
- package/dist/schema-imports.js.map +1 -0
- package/dist/schema-name-schemas.d.ts +18 -0
- package/dist/schema-name-schemas.d.ts.map +1 -0
- package/dist/schema-name-schemas.js +13 -0
- package/dist/schema-name-schemas.js.map +1 -0
- package/dist/schema-names.d.ts +53 -0
- package/dist/schema-names.d.ts.map +1 -0
- package/dist/schema-names.js +229 -0
- package/dist/schema-names.js.map +1 -0
- package/dist/schema-types.d.ts +336 -0
- package/dist/schema-types.d.ts.map +1 -0
- package/dist/schema-types.js +10 -0
- package/dist/schema-types.js.map +1 -0
- package/dist/schema.d.ts +38 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +34 -0
- package/dist/schema.js.map +1 -0
- package/dist/stat-reference-build.d.ts +24 -0
- package/dist/stat-reference-build.d.ts.map +1 -0
- package/dist/stat-reference-build.js +86 -0
- package/dist/stat-reference-build.js.map +1 -0
- package/dist/stat-reference.d.ts +33 -0
- package/dist/stat-reference.d.ts.map +1 -0
- package/dist/stat-reference.js +19 -0
- package/dist/stat-reference.js.map +1 -0
- package/dist/structural-gate.d.ts +15 -0
- package/dist/structural-gate.d.ts.map +1 -0
- package/dist/structural-gate.js +34 -0
- package/dist/structural-gate.js.map +1 -0
- package/dist/temporal-column.d.ts +33 -0
- package/dist/temporal-column.d.ts.map +1 -0
- package/dist/temporal-column.js +247 -0
- package/dist/temporal-column.js.map +1 -0
- package/dist/temporal-guides.d.ts +11 -0
- package/dist/temporal-guides.d.ts.map +1 -0
- package/dist/temporal-guides.js +11 -0
- package/dist/temporal-guides.js.map +1 -0
- package/dist/temporal-interval-schema.d.ts +9 -0
- package/dist/temporal-interval-schema.d.ts.map +1 -0
- package/dist/temporal-interval-schema.js +25 -0
- package/dist/temporal-interval-schema.js.map +1 -0
- package/dist/temporal-interval.d.ts +29 -0
- package/dist/temporal-interval.d.ts.map +1 -0
- package/dist/temporal-interval.js +122 -0
- package/dist/temporal-interval.js.map +1 -0
- package/dist/temporal-parse-core.d.ts +96 -0
- package/dist/temporal-parse-core.d.ts.map +1 -0
- package/dist/temporal-parse-core.js +235 -0
- package/dist/temporal-parse-core.js.map +1 -0
- package/dist/temporal-parse-format.d.ts +13 -0
- package/dist/temporal-parse-format.d.ts.map +1 -0
- package/dist/temporal-parse-format.js +180 -0
- package/dist/temporal-parse-format.js.map +1 -0
- package/dist/temporal-parse-schema.d.ts +11 -0
- package/dist/temporal-parse-schema.d.ts.map +1 -0
- package/dist/temporal-parse-schema.js +23 -0
- package/dist/temporal-parse-schema.js.map +1 -0
- package/dist/temporal-parse.d.ts +18 -0
- package/dist/temporal-parse.d.ts.map +1 -0
- package/dist/temporal-parse.js +183 -0
- package/dist/temporal-parse.js.map +1 -0
- package/dist/temporal-polyfill.d.ts +3 -0
- package/dist/temporal-polyfill.d.ts.map +1 -0
- package/dist/temporal-polyfill.js +25 -0
- package/dist/temporal-polyfill.js.map +1 -0
- package/dist/temporal-ticks.d.ts +20 -0
- package/dist/temporal-ticks.d.ts.map +1 -0
- package/dist/temporal-ticks.js +246 -0
- package/dist/temporal-ticks.js.map +1 -0
- package/dist/temporal.d.ts +109 -0
- package/dist/temporal.d.ts.map +1 -0
- package/dist/temporal.js +73 -0
- package/dist/temporal.js.map +1 -0
- package/dist/validate-data-checks-color-temporal.d.ts +58 -0
- package/dist/validate-data-checks-color-temporal.d.ts.map +1 -0
- package/dist/validate-data-checks-color-temporal.js +168 -0
- package/dist/validate-data-checks-color-temporal.js.map +1 -0
- package/dist/validate-data-checks-color.d.ts +28 -0
- package/dist/validate-data-checks-color.d.ts.map +1 -0
- package/dist/validate-data-checks-color.js +296 -0
- package/dist/validate-data-checks-color.js.map +1 -0
- package/dist/validate-data-checks-layer.d.ts +37 -0
- package/dist/validate-data-checks-layer.d.ts.map +1 -0
- package/dist/validate-data-checks-layer.js +343 -0
- package/dist/validate-data-checks-layer.js.map +1 -0
- package/dist/validate-data-checks-position.d.ts +45 -0
- package/dist/validate-data-checks-position.d.ts.map +1 -0
- package/dist/validate-data-checks-position.js +204 -0
- package/dist/validate-data-checks-position.js.map +1 -0
- package/dist/validate-data-checks-style-finite.d.ts +24 -0
- package/dist/validate-data-checks-style-finite.d.ts.map +1 -0
- package/dist/validate-data-checks-style-finite.js +40 -0
- package/dist/validate-data-checks-style-finite.js.map +1 -0
- package/dist/validate-data-checks-style-numeric.d.ts +26 -0
- package/dist/validate-data-checks-style-numeric.d.ts.map +1 -0
- package/dist/validate-data-checks-style-numeric.js +327 -0
- package/dist/validate-data-checks-style-numeric.js.map +1 -0
- package/dist/validate-data-checks-style.d.ts +14 -0
- package/dist/validate-data-checks-style.d.ts.map +1 -0
- package/dist/validate-data-checks-style.js +14 -0
- package/dist/validate-data-checks-style.js.map +1 -0
- package/dist/validate-data-checks-temporal.d.ts +57 -0
- package/dist/validate-data-checks-temporal.d.ts.map +1 -0
- package/dist/validate-data-checks-temporal.js +83 -0
- package/dist/validate-data-checks-temporal.js.map +1 -0
- package/dist/validate-data-checks.d.ts +31 -0
- package/dist/validate-data-checks.d.ts.map +1 -0
- package/dist/validate-data-checks.js +110 -0
- package/dist/validate-data-checks.js.map +1 -0
- package/dist/validate-data-evidence.d.ts +69 -0
- package/dist/validate-data-evidence.d.ts.map +1 -0
- package/dist/validate-data-evidence.js +329 -0
- package/dist/validate-data-evidence.js.map +1 -0
- package/dist/validate-data.d.ts +73 -0
- package/dist/validate-data.d.ts.map +1 -0
- package/dist/validate-data.js +30 -0
- package/dist/validate-data.js.map +1 -0
- package/dist/validate-map-errors.d.ts +32 -0
- package/dist/validate-map-errors.d.ts.map +1 -0
- package/dist/validate-map-errors.js +76 -0
- package/dist/validate-map-errors.js.map +1 -0
- package/dist/validate-map-forms.d.ts +43 -0
- package/dist/validate-map-forms.d.ts.map +1 -0
- package/dist/validate-map-forms.js +125 -0
- package/dist/validate-map-forms.js.map +1 -0
- package/dist/validate-map-path-keywords.d.ts +11 -0
- package/dist/validate-map-path-keywords.d.ts.map +1 -0
- package/dist/validate-map-path-keywords.js +95 -0
- package/dist/validate-map-path-keywords.js.map +1 -0
- package/dist/validate-map-path-unions.d.ts +27 -0
- package/dist/validate-map-path-unions.d.ts.map +1 -0
- package/dist/validate-map-path-unions.js +200 -0
- package/dist/validate-map-path-unions.js.map +1 -0
- package/dist/validate-schema-shape.d.ts +69 -0
- package/dist/validate-schema-shape.d.ts.map +1 -0
- package/dist/validate-schema-shape.js +156 -0
- package/dist/validate-schema-shape.js.map +1 -0
- package/dist/validate-schema-walk.d.ts +34 -0
- package/dist/validate-schema-walk.d.ts.map +1 -0
- package/dist/validate-schema-walk.js +216 -0
- package/dist/validate-schema-walk.js.map +1 -0
- package/dist/validate-structure-facet.d.ts +8 -0
- package/dist/validate-structure-facet.d.ts.map +1 -0
- package/dist/validate-structure-facet.js +67 -0
- package/dist/validate-structure-facet.js.map +1 -0
- package/dist/validate-structure-layer-computed-y.d.ts +14 -0
- package/dist/validate-structure-layer-computed-y.d.ts.map +1 -0
- package/dist/validate-structure-layer-computed-y.js +70 -0
- package/dist/validate-structure-layer-computed-y.js.map +1 -0
- package/dist/validate-structure-layer-ribbon.d.ts +8 -0
- package/dist/validate-structure-layer-ribbon.d.ts.map +1 -0
- package/dist/validate-structure-layer-ribbon.js +36 -0
- package/dist/validate-structure-layer-ribbon.js.map +1 -0
- package/dist/validate-structure-layer-rule.d.ts +14 -0
- package/dist/validate-structure-layer-rule.d.ts.map +1 -0
- package/dist/validate-structure-layer-rule.js +90 -0
- package/dist/validate-structure-layer-rule.js.map +1 -0
- package/dist/validate-structure-layer-shared.d.ts +12 -0
- package/dist/validate-structure-layer-shared.d.ts.map +1 -0
- package/dist/validate-structure-layer-shared.js +17 -0
- package/dist/validate-structure-layer-shared.js.map +1 -0
- package/dist/validate-structure-layers.d.ts +12 -0
- package/dist/validate-structure-layers.d.ts.map +1 -0
- package/dist/validate-structure-layers.js +292 -0
- package/dist/validate-structure-layers.js.map +1 -0
- package/dist/validate-structure-paint.d.ts +12 -0
- package/dist/validate-structure-paint.d.ts.map +1 -0
- package/dist/validate-structure-paint.js +87 -0
- package/dist/validate-structure-paint.js.map +1 -0
- package/dist/validate-structure-scales.d.ts +10 -0
- package/dist/validate-structure-scales.d.ts.map +1 -0
- package/dist/validate-structure-scales.js +242 -0
- package/dist/validate-structure-scales.js.map +1 -0
- package/dist/validate-structure-style-bins.d.ts +17 -0
- package/dist/validate-structure-style-bins.d.ts.map +1 -0
- package/dist/validate-structure-style-bins.js +150 -0
- package/dist/validate-structure-style-bins.js.map +1 -0
- package/dist/validate-structure.d.ts +16 -0
- package/dist/validate-structure.d.ts.map +1 -0
- package/dist/validate-structure.js +16 -0
- package/dist/validate-structure.js.map +1 -0
- package/dist/validate.d.ts +24 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +178 -0
- package/dist/validate.js.map +1 -0
- package/package.json +59 -0
- package/schema/v0.json +9618 -0
- package/src/artifact.ts +81 -0
- package/src/builder-core.ts +276 -0
- package/src/builder-data.ts +156 -0
- package/src/builder-geoms.ts +290 -0
- package/src/builder-options.ts +428 -0
- package/src/builder-scales.ts +443 -0
- package/src/builder.ts +125 -0
- package/src/capabilities-data.ts +336 -0
- package/src/capabilities-helpers.ts +54 -0
- package/src/capabilities.ts +159 -0
- package/src/coord-helpers.ts +177 -0
- package/src/coord-reference-build.ts +283 -0
- package/src/coord-reference.ts +75 -0
- package/src/error-catalog.ts +253 -0
- package/src/error-prose-shared.ts +106 -0
- package/src/errors.ts +87 -0
- package/src/generated/coord-reference-data.ts +235 -0
- package/src/generated/geom-param-keys.ts +222 -0
- package/src/generated/geom-reference-data.ts +3024 -0
- package/src/generated/guide-reference-data.ts +284 -0
- package/src/generated/plot-spec-validator.ts +7335 -0
- package/src/generated/position-reference-data.ts +191 -0
- package/src/generated/scale-reference-data.ts +10665 -0
- package/src/generated/stat-reference-data.ts +339 -0
- package/src/geom-params-build.ts +92 -0
- package/src/geom-params.ts +14 -0
- package/src/geom-reference-build.ts +292 -0
- package/src/geom-reference.ts +127 -0
- package/src/guide-helpers.ts +44 -0
- package/src/guide-reference-build.ts +249 -0
- package/src/guide-reference.ts +76 -0
- package/src/hue-grey-palettes.ts +82 -0
- package/src/index.ts +400 -0
- package/src/lint-catalog.ts +57 -0
- package/src/lint-layer-rules.ts +175 -0
- package/src/lint-scale-rules.ts +285 -0
- package/src/lint.ts +126 -0
- package/src/normalize-coord.ts +126 -0
- package/src/normalize-input-layers-marks.ts +276 -0
- package/src/normalize-input-layers-special.ts +252 -0
- package/src/normalize-input.ts +154 -0
- package/src/normalize-paint.ts +98 -0
- package/src/normalize-scales.ts +108 -0
- package/src/normalize.ts +403 -0
- package/src/paint-helpers.ts +98 -0
- package/src/pipeline-error-catalog.ts +278 -0
- package/src/portability-check.ts +155 -0
- package/src/portability-lossy.ts +81 -0
- package/src/portability.ts +31 -0
- package/src/portable-builder.ts +35 -0
- package/src/portable-entry.ts +37 -0
- package/src/position-reference-build.ts +164 -0
- package/src/position-reference.ts +41 -0
- package/src/runtime.ts +198 -0
- package/src/scale-color-helpers.ts +263 -0
- package/src/scale-color-hue-grey.ts +95 -0
- package/src/scale-color-stops.ts +177 -0
- package/src/scale-color-viridis.ts +99 -0
- package/src/scale-helpers.ts +264 -0
- package/src/scale-multi-helpers.ts +220 -0
- package/src/scale-position-helpers.ts +231 -0
- package/src/scale-reference-build.ts +222 -0
- package/src/scale-reference-classify-color.ts +334 -0
- package/src/scale-reference-classify-position.ts +164 -0
- package/src/scale-reference-classify-style.ts +229 -0
- package/src/scale-reference-classify-support.ts +298 -0
- package/src/scale-reference.ts +165 -0
- package/src/scale-style-helpers.ts +316 -0
- package/src/schema-catalog.ts +222 -0
- package/src/schema-declarations.ts +51 -0
- package/src/schema-decls-data.ts +272 -0
- package/src/schema-decls-guides-theme.ts +395 -0
- package/src/schema-decls-layers-col-boxplot.ts +410 -0
- package/src/schema-decls-layers-count-pointrange.ts +321 -0
- package/src/schema-decls-layers-crossbar-jitter.ts +443 -0
- package/src/schema-decls-layers-point-path.ts +246 -0
- package/src/schema-decls-layers-sf-blank.ts +408 -0
- package/src/schema-decls-layers-text-map.ts +259 -0
- package/src/schema-decls-paint.ts +124 -0
- package/src/schema-decls-params-area-abline.ts +440 -0
- package/src/schema-decls-params-col-contour.ts +333 -0
- package/src/schema-decls-params-curve-label.ts +343 -0
- package/src/schema-decls-params-errorbar-position.ts +446 -0
- package/src/schema-decls-params-point-path.ts +394 -0
- package/src/schema-decls-params-violin-summary.ts +447 -0
- package/src/schema-decls-plot.ts +385 -0
- package/src/schema-decls-scales-guides.ts +233 -0
- package/src/schema-decls-scales.ts +432 -0
- package/src/schema-imports.ts +116 -0
- package/src/schema-name-schemas.ts +37 -0
- package/src/schema-names.ts +243 -0
- package/src/schema-types.ts +400 -0
- package/src/schema.ts +287 -0
- package/src/stat-reference-build.ts +145 -0
- package/src/stat-reference.ts +38 -0
- package/src/structural-gate.ts +42 -0
- package/src/temporal-column.ts +323 -0
- package/src/temporal-guides.ts +32 -0
- package/src/temporal-interval-schema.ts +40 -0
- package/src/temporal-interval.ts +151 -0
- package/src/temporal-parse-core.ts +331 -0
- package/src/temporal-parse-format.ts +222 -0
- package/src/temporal-parse-schema.ts +38 -0
- package/src/temporal-parse.ts +259 -0
- package/src/temporal-polyfill.ts +27 -0
- package/src/temporal-ticks.ts +312 -0
- package/src/temporal.ts +112 -0
- package/src/validate-data-checks-color-temporal.ts +261 -0
- package/src/validate-data-checks-color.ts +395 -0
- package/src/validate-data-checks-layer.ts +492 -0
- package/src/validate-data-checks-position.ts +275 -0
- package/src/validate-data-checks-style-finite.ts +55 -0
- package/src/validate-data-checks-style-numeric.ts +455 -0
- package/src/validate-data-checks-style.ts +13 -0
- package/src/validate-data-checks-temporal.ts +129 -0
- package/src/validate-data-checks.ts +157 -0
- package/src/validate-data-evidence.ts +419 -0
- package/src/validate-data.ts +114 -0
- package/src/validate-map-errors.ts +126 -0
- package/src/validate-map-forms.ts +148 -0
- package/src/validate-map-path-keywords.ts +129 -0
- package/src/validate-map-path-unions.ts +281 -0
- package/src/validate-schema-shape.ts +232 -0
- package/src/validate-schema-walk.ts +219 -0
- package/src/validate-structure-facet.ts +76 -0
- package/src/validate-structure-layer-computed-y.ts +94 -0
- package/src/validate-structure-layer-ribbon.ts +61 -0
- package/src/validate-structure-layer-rule.ts +98 -0
- package/src/validate-structure-layer-shared.ts +29 -0
- package/src/validate-structure-layers.ts +395 -0
- package/src/validate-structure-paint.ts +101 -0
- package/src/validate-structure-scales.ts +278 -0
- package/src/validate-structure-style-bins.ts +167 -0
- package/src/validate-structure.ts +16 -0
- package/src/validate.ts +212 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule / hline / vline annotation vs data-driven form checks.
|
|
3
|
+
* Orchestrated by validate-structure-layers.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { SpecError } from "./errors.js";
|
|
6
|
+
import type { Aes } from "./schema.js";
|
|
7
|
+
import { isRecord } from "./validate-structure-layer-shared.js";
|
|
8
|
+
|
|
9
|
+
/** Asymmetric intercept presence for rule / hline / vline form checks. */
|
|
10
|
+
export function hasGeomIntercepts(geom: string, layer: Record<string, unknown>): boolean {
|
|
11
|
+
const params = layer["params"];
|
|
12
|
+
if (!isRecord(params)) return false;
|
|
13
|
+
if (geom === "hline") return params["yintercept"] !== undefined;
|
|
14
|
+
if (geom === "vline") return params["xintercept"] !== undefined;
|
|
15
|
+
return params["xintercept"] !== undefined || params["yintercept"] !== undefined;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Structural errors for rule-family geoms. Caller returns these immediately
|
|
20
|
+
* (no further layer checks apply to the rule family).
|
|
21
|
+
*/
|
|
22
|
+
export function ruleFamilyStructuralErrors(
|
|
23
|
+
layer: Record<string, unknown>,
|
|
24
|
+
geom: string,
|
|
25
|
+
layerPath: string,
|
|
26
|
+
layerAes: Aes | undefined,
|
|
27
|
+
mapped: (channel: "x" | "y") => unknown,
|
|
28
|
+
): SpecError[] {
|
|
29
|
+
const errors: SpecError[] = [];
|
|
30
|
+
const intercepts = hasGeomIntercepts(geom, layer);
|
|
31
|
+
// The annotation form inherits NO plot aes (normalize drops it, matching
|
|
32
|
+
// ggplot2's inherit.aes = FALSE) — only the layer's OWN x/y mappings
|
|
33
|
+
// conflict with intercepts. Data-driven hline/vline sugar also nulls the
|
|
34
|
+
// orthogonal axis during normalize; pre-normalize validation still sees
|
|
35
|
+
// raw layer aes here.
|
|
36
|
+
const own = (channel: "x" | "y") => layerAes?.[channel] ?? undefined;
|
|
37
|
+
let x = intercepts ? own("x") : mapped("x");
|
|
38
|
+
let y = intercepts ? own("y") : mapped("y");
|
|
39
|
+
// Pre-normalize data-driven aliases: orthogonal axis is not part of the form.
|
|
40
|
+
if (!intercepts && geom === "hline") x = undefined;
|
|
41
|
+
if (!intercepts && geom === "vline") y = undefined;
|
|
42
|
+
const { interceptHint, dataHint } = ruleHints(geom);
|
|
43
|
+
if (intercepts && (x !== undefined || y !== undefined)) {
|
|
44
|
+
errors.push({
|
|
45
|
+
code: "rule-form-ambiguous",
|
|
46
|
+
path: layerPath,
|
|
47
|
+
message: `This ${geom} layer mixes the annotation form (${interceptHint}) with mapped ${dataHint}. Use fixed intercepts OR a data mapping, never both.`,
|
|
48
|
+
fix: {
|
|
49
|
+
description:
|
|
50
|
+
"Remove the intercept params (data-driven form), or unset the position aes with null (annotation form).",
|
|
51
|
+
example: ruleExample(geom),
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
} else if (!intercepts && x === undefined && y === undefined) {
|
|
55
|
+
errors.push({
|
|
56
|
+
code: "rule-form-missing",
|
|
57
|
+
path: layerPath,
|
|
58
|
+
message: `This ${geom} layer has neither fixed intercepts (${interceptHint}) nor a mapped ${dataHint} — nothing to draw.`,
|
|
59
|
+
fix: {
|
|
60
|
+
description: missingRuleDescription(geom),
|
|
61
|
+
example: ruleExample(geom),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
} else if (!intercepts && x !== undefined && y !== undefined) {
|
|
65
|
+
errors.push({
|
|
66
|
+
code: "rule-both-axes",
|
|
67
|
+
path: layerPath,
|
|
68
|
+
message:
|
|
69
|
+
"This rule layer maps BOTH aes.x and aes.y; a data-driven rule is either vertical (map x) or horizontal (map y). Unset the other channel with null.",
|
|
70
|
+
fix: {
|
|
71
|
+
description: "Keep one direction and unset the other channel with null.",
|
|
72
|
+
example: { geom: "rule", aes: { y: null } },
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return errors;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function ruleHints(geom: string): { interceptHint: string; dataHint: string } {
|
|
80
|
+
if (geom === "hline") return { interceptHint: "params.yintercept", dataHint: "aes.y" };
|
|
81
|
+
if (geom === "vline") return { interceptHint: "params.xintercept", dataHint: "aes.x" };
|
|
82
|
+
return { interceptHint: "params.xintercept/yintercept", dataHint: "aes.x/aes.y" };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function ruleExample(geom: string) {
|
|
86
|
+
if (geom === "vline") return { geom: "vline", params: { xintercept: 0 } };
|
|
87
|
+
return { geom: geom === "hline" ? "hline" : "rule", params: { yintercept: 0 } };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function missingRuleDescription(geom: string): string {
|
|
91
|
+
if (geom === "hline") {
|
|
92
|
+
return "Set params.yintercept for an annotation, or map aes.y for data-driven rules.";
|
|
93
|
+
}
|
|
94
|
+
if (geom === "vline") {
|
|
95
|
+
return "Set params.xintercept for an annotation, or map aes.x for data-driven rules.";
|
|
96
|
+
}
|
|
97
|
+
return "Set params.yintercept (or xintercept) for an annotation, or map aes.x/aes.y to a field for data-driven rules.";
|
|
98
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for layer structural grammar checks.
|
|
3
|
+
*/
|
|
4
|
+
import type { SpecError } from "./errors.js";
|
|
5
|
+
import type { ChannelName } from "./schema.js";
|
|
6
|
+
|
|
7
|
+
/** Same shape as sibling validate-structure-* modules (local, not schema-walk). */
|
|
8
|
+
export function isRecord(v: unknown): v is Record<string, unknown> {
|
|
9
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const CHANNEL_FIX_EXAMPLE = { field: "column_name" };
|
|
13
|
+
|
|
14
|
+
export function pushMissingChannel(
|
|
15
|
+
errors: SpecError[],
|
|
16
|
+
layerPath: string,
|
|
17
|
+
channel: ChannelName,
|
|
18
|
+
message: string,
|
|
19
|
+
): void {
|
|
20
|
+
errors.push({
|
|
21
|
+
code: "missing-required-channel",
|
|
22
|
+
path: `${layerPath}/aes/${channel}`,
|
|
23
|
+
message,
|
|
24
|
+
fix: {
|
|
25
|
+
description: `Map "${channel}" to a data field.`,
|
|
26
|
+
example: { [channel]: CHANNEL_FIX_EXAMPLE },
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data-free structural grammar checks for layers (required channels, rule forms,
|
|
3
|
+
* computed-y bans, bin center/boundary, errorbar stat channels).
|
|
4
|
+
* Color-scheme rules: validate-structure-scales.ts. Facet form: validate-structure-facet.ts.
|
|
5
|
+
* Form families: validate-structure-layer-{rule,ribbon,computed-y,shared}.ts.
|
|
6
|
+
* Barrel: validate-structure.ts.
|
|
7
|
+
*/
|
|
8
|
+
import type { SpecError } from "./errors.js";
|
|
9
|
+
import type { Aes, ChannelName, GeomName } from "./schema.js";
|
|
10
|
+
import { GEOM_DEFAULTS } from "./schema-catalog.js";
|
|
11
|
+
import { STYLE_AESTHETIC_GEOMS, type StyleAesthetic } from "./capabilities.js";
|
|
12
|
+
import { effectiveChannel } from "./validate-data.js";
|
|
13
|
+
import { paintStructuralErrors } from "./validate-structure-paint.js";
|
|
14
|
+
import { computedYMappedErrors } from "./validate-structure-layer-computed-y.js";
|
|
15
|
+
import { hasGeomIntercepts, ruleFamilyStructuralErrors } from "./validate-structure-layer-rule.js";
|
|
16
|
+
import { ribbonStructuralErrors } from "./validate-structure-layer-ribbon.js";
|
|
17
|
+
import {
|
|
18
|
+
CHANNEL_FIX_EXAMPLE,
|
|
19
|
+
isRecord,
|
|
20
|
+
pushMissingChannel,
|
|
21
|
+
} from "./validate-structure-layer-shared.js";
|
|
22
|
+
|
|
23
|
+
type MappedChannel = (channel: ChannelName) => ReturnType<typeof effectiveChannel>;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Channels every geom needs mapped (after plot-aes inheritance).
|
|
27
|
+
* Total over GeomName — a missing geom is a type error, not a silent `?? []`
|
|
28
|
+
* (#1078). Empty lists are deliberate (form-checked elsewhere or annotation-only).
|
|
29
|
+
*/
|
|
30
|
+
const REQUIRED_CHANNELS: Record<GeomName, readonly ChannelName[]> = {
|
|
31
|
+
point: ["x", "y"],
|
|
32
|
+
count: ["x", "y"],
|
|
33
|
+
jitter: ["x", "y"],
|
|
34
|
+
line: ["x", "y"],
|
|
35
|
+
path: ["x", "y"], // data-order polylines (#788); same channels as line
|
|
36
|
+
step: ["x", "y"],
|
|
37
|
+
col: ["x", "y"],
|
|
38
|
+
bar: ["x"],
|
|
39
|
+
histogram: ["x"],
|
|
40
|
+
freqpoly: ["x"],
|
|
41
|
+
area: ["x", "y"],
|
|
42
|
+
rule: [], // form-checked separately
|
|
43
|
+
hline: [], // form-checked like rule (yintercept / aes.y)
|
|
44
|
+
vline: [], // form-checked like rule (xintercept / aes.x)
|
|
45
|
+
text: ["x", "y", "label"],
|
|
46
|
+
label: ["x", "y", "label"], // same contract as text (#1078)
|
|
47
|
+
sf_text: ["label"], // x/y come from stat_sf_coordinates (#809 phase 2)
|
|
48
|
+
sf_label: ["label"],
|
|
49
|
+
sf: [], // geometry column, not aes
|
|
50
|
+
smooth: ["x", "y"],
|
|
51
|
+
boxplot: ["x", "y"],
|
|
52
|
+
density: ["x"],
|
|
53
|
+
errorbar: ["x"], // ymin/ymax vs y are stat-dependent, checked separately
|
|
54
|
+
linerange: ["x"],
|
|
55
|
+
pointrange: ["x"],
|
|
56
|
+
crossbar: ["x"],
|
|
57
|
+
rect: ["xmin", "xmax", "ymin", "ymax"],
|
|
58
|
+
segment: ["x", "y", "xend", "yend"],
|
|
59
|
+
violin: ["x", "y"],
|
|
60
|
+
function: [], // domain from xlim / peer / optional x; y is after_stat
|
|
61
|
+
polygon: ["x", "y"],
|
|
62
|
+
spoke: ["x", "y"], // angle/radius: aes or params — checked below
|
|
63
|
+
curve: ["x", "y", "xend", "yend"],
|
|
64
|
+
rug: [], // sides-dependent; checked separately
|
|
65
|
+
tile: ["x", "y"],
|
|
66
|
+
raster: ["x", "y"],
|
|
67
|
+
ribbon: [], // orientation-dependent; checked separately
|
|
68
|
+
contour: ["x", "y", "z"],
|
|
69
|
+
quantile: ["x", "y"],
|
|
70
|
+
density_2d: ["x", "y"],
|
|
71
|
+
density_2d_filled: ["x", "y"],
|
|
72
|
+
hex: ["x", "y"],
|
|
73
|
+
bin_2d: ["x", "y"],
|
|
74
|
+
abline: [], // annotation-only: slope/intercept in params
|
|
75
|
+
qq: ["sample"],
|
|
76
|
+
qq_line: ["sample"],
|
|
77
|
+
dotplot: ["x"],
|
|
78
|
+
map: ["map_id"],
|
|
79
|
+
blank: [], // trains whatever is mapped; nothing required
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** Grammar checks for one schema-valid layer. */
|
|
83
|
+
export function layerStructuralErrors(
|
|
84
|
+
layer: Record<string, unknown>,
|
|
85
|
+
geom: string,
|
|
86
|
+
index: number,
|
|
87
|
+
plotAes: Aes | undefined,
|
|
88
|
+
): SpecError[] {
|
|
89
|
+
const errors: SpecError[] = [];
|
|
90
|
+
const layerAes = isRecord(layer["aes"]) ? (layer["aes"] as Aes) : undefined;
|
|
91
|
+
const layerPath = `/layers/${index}`;
|
|
92
|
+
const mapped = (channel: ChannelName) => effectiveChannel(plotAes, layerAes, channel);
|
|
93
|
+
// Annotation-form rules / hline / vline (fixed intercepts) inherit NO plot
|
|
94
|
+
// aes — normalize drops it — so a plot-level style meant for other layers
|
|
95
|
+
// must not trip the geom-capability check here. Match the rule-form x/y
|
|
96
|
+
// handling below by consulting only the layer's OWN aes for these layers.
|
|
97
|
+
const isRuleFamily = geom === "rule" || geom === "hline" || geom === "vline";
|
|
98
|
+
const annotationRule = isRuleFamily && hasGeomIntercepts(geom, layer);
|
|
99
|
+
|
|
100
|
+
errors.push(...styleAestheticErrors(layerAes, geom, annotationRule, mapped, layerPath));
|
|
101
|
+
|
|
102
|
+
if (isRuleFamily) {
|
|
103
|
+
// Keep unsupported-geom-aesthetic errors already pushed above; rule form
|
|
104
|
+
// checks append. Returning only the form-check array would drop them.
|
|
105
|
+
errors.push(...ruleFamilyStructuralErrors(layer, geom, layerPath, layerAes, mapped));
|
|
106
|
+
return errors;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const stat =
|
|
110
|
+
typeof layer["stat"] === "string"
|
|
111
|
+
? layer["stat"]
|
|
112
|
+
: (GEOM_DEFAULTS[geom as keyof typeof GEOM_DEFAULTS]?.stat ?? "identity");
|
|
113
|
+
|
|
114
|
+
errors.push(
|
|
115
|
+
...computedYMappedErrors(geom, stat, layerPath, mapped),
|
|
116
|
+
...binAlignmentErrors(layer, geom, stat, layerPath),
|
|
117
|
+
...intervalChannelErrors(geom, stat, layerPath, mapped),
|
|
118
|
+
...(geom === "ribbon" ? ribbonStructuralErrors(layer, layerPath, mapped) : []),
|
|
119
|
+
...statParameterErrors(layer, stat, layerPath),
|
|
120
|
+
...spokeStructuralErrors(layer, geom, layerPath, mapped),
|
|
121
|
+
...rugStructuralErrors(layer, geom, layerPath, mapped),
|
|
122
|
+
...paintStructuralErrors(layer, layerPath, plotAes),
|
|
123
|
+
...requiredChannelErrors(geom, stat, layerPath, mapped),
|
|
124
|
+
);
|
|
125
|
+
return errors;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function binAlignmentErrors(
|
|
129
|
+
layer: Record<string, unknown>,
|
|
130
|
+
geom: string,
|
|
131
|
+
stat: string,
|
|
132
|
+
layerPath: string,
|
|
133
|
+
): SpecError[] {
|
|
134
|
+
const binnedGeom = ["bar", "histogram", "freqpoly", "dotplot"].includes(geom);
|
|
135
|
+
const binnedLayer =
|
|
136
|
+
binnedGeom ||
|
|
137
|
+
(geom === "line" && (stat === "bin" || stat === "summary_bin")) ||
|
|
138
|
+
((geom === "point" || geom === "errorbar") && stat === "summary_bin") ||
|
|
139
|
+
stat === "summary_bin" ||
|
|
140
|
+
stat === "bindot";
|
|
141
|
+
if (!binnedLayer) return [];
|
|
142
|
+
const params = isRecord(layer["params"]) ? layer["params"] : {};
|
|
143
|
+
const binStat =
|
|
144
|
+
["histogram", "freqpoly", "dotplot"].includes(geom) ||
|
|
145
|
+
["bin", "summary_bin", "bindot"].includes(stat);
|
|
146
|
+
if (!binStat || params["center"] === undefined || params["boundary"] === undefined) return [];
|
|
147
|
+
return [
|
|
148
|
+
{
|
|
149
|
+
code: "bin-center-and-boundary",
|
|
150
|
+
path: `${layerPath}/params`,
|
|
151
|
+
message: `The ${stat === "summary_bin" ? "summary_bin" : "bin"} stat accepts params.center OR params.boundary (both align the bin grid), never both.`,
|
|
152
|
+
fix: {
|
|
153
|
+
description: "Keep one alignment parameter and remove the other.",
|
|
154
|
+
example: { params: { binwidth: 1, boundary: 0 } },
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function intervalChannelErrors(
|
|
161
|
+
geom: string,
|
|
162
|
+
stat: string,
|
|
163
|
+
layerPath: string,
|
|
164
|
+
mapped: MappedChannel,
|
|
165
|
+
): SpecError[] {
|
|
166
|
+
if (!["errorbar", "linerange", "pointrange", "crossbar"].includes(geom)) return [];
|
|
167
|
+
const needed: ChannelName[] =
|
|
168
|
+
stat === "summary" || stat === "summary_bin"
|
|
169
|
+
? ["y"]
|
|
170
|
+
: geom === "pointrange" || geom === "crossbar"
|
|
171
|
+
? ["y", "ymin", "ymax"]
|
|
172
|
+
: ["ymin", "ymax"];
|
|
173
|
+
return needed.flatMap((channel) =>
|
|
174
|
+
mapped(channel) === undefined
|
|
175
|
+
? [
|
|
176
|
+
{
|
|
177
|
+
code: "missing-required-channel" as const,
|
|
178
|
+
path: `${layerPath}/aes/${channel}`,
|
|
179
|
+
message: `The ${geom} geom with the ${stat} stat requires a "${channel}" channel; map it in the layer's aes or the plot-level aes.`,
|
|
180
|
+
fix: {
|
|
181
|
+
description: `Map "${channel}" to a data field.`,
|
|
182
|
+
example: { [channel]: CHANNEL_FIX_EXAMPLE },
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
]
|
|
186
|
+
: [],
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function statParameterErrors(
|
|
191
|
+
layer: Record<string, unknown>,
|
|
192
|
+
stat: string,
|
|
193
|
+
layerPath: string,
|
|
194
|
+
): SpecError[] {
|
|
195
|
+
const errors: SpecError[] = [];
|
|
196
|
+
const params = isRecord(layer["params"]) ? layer["params"] : {};
|
|
197
|
+
const fun = params["fun"];
|
|
198
|
+
if (
|
|
199
|
+
["summary", "summary_bin", "summary_rolling"].includes(stat) &&
|
|
200
|
+
(fun === "first" || fun === "last")
|
|
201
|
+
) {
|
|
202
|
+
errors.push({
|
|
203
|
+
code: "summary-fun-unsupported",
|
|
204
|
+
path: `${layerPath}/params/fun`,
|
|
205
|
+
message: `The ${stat} stat summarizes with the registry funs mean|median|sum|min|max; params.fun "${fun}" is a manual-stat keep transform and has no meaning here.`,
|
|
206
|
+
fix: {
|
|
207
|
+
description:
|
|
208
|
+
"Use mean, median, or sum for the center summary (min/max via funMin/funMax where supported).",
|
|
209
|
+
example: { params: { fun: "median" } },
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
const window = params["window"];
|
|
214
|
+
if (stat === "summary_rolling" && (window === undefined || window === null || window === "")) {
|
|
215
|
+
errors.push({
|
|
216
|
+
code: "summary-rolling-window-required",
|
|
217
|
+
path: `${layerPath}/params/window`,
|
|
218
|
+
message:
|
|
219
|
+
"The summary_rolling stat requires params.window (rolling-window width in x data units, greater than 0). There is no silent default width.",
|
|
220
|
+
fix: {
|
|
221
|
+
description:
|
|
222
|
+
"Set params.window to the window width in x units (e.g. 30 for a 30-year running summary).",
|
|
223
|
+
example: { params: { window: 30 } },
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
if (stat === "manual" && (fun === undefined || fun === null || fun === "")) {
|
|
228
|
+
errors.push({
|
|
229
|
+
code: "manual-fun-required",
|
|
230
|
+
path: `${layerPath}/params/fun`,
|
|
231
|
+
message:
|
|
232
|
+
"The manual stat requires params.fun (one of first|last|mean|median|min|max|sum). There is no silent identity default (ggplot2 divergence; #814).",
|
|
233
|
+
fix: {
|
|
234
|
+
description: "Set params.fun to a registered portable transform name.",
|
|
235
|
+
example: { params: { fun: "mean" } },
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return errors;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function spokeStructuralErrors(
|
|
243
|
+
layer: Record<string, unknown>,
|
|
244
|
+
geom: string,
|
|
245
|
+
layerPath: string,
|
|
246
|
+
mapped: MappedChannel,
|
|
247
|
+
): SpecError[] {
|
|
248
|
+
if (geom !== "spoke") return [];
|
|
249
|
+
const errors: SpecError[] = [];
|
|
250
|
+
const params = isRecord(layer["params"]) ? layer["params"] : {};
|
|
251
|
+
for (const channel of ["angle", "radius"] as const) {
|
|
252
|
+
const fromAes = mapped(channel);
|
|
253
|
+
const fromParams = params[channel];
|
|
254
|
+
if (fromAes === undefined && fromParams === undefined) {
|
|
255
|
+
errors.push(spokeChannelError(channel, layerPath, false));
|
|
256
|
+
}
|
|
257
|
+
if (fromAes !== undefined && !("field" in fromAes) && fromParams === undefined) {
|
|
258
|
+
errors.push(spokeChannelError(channel, layerPath, true));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return errors;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function spokeChannelError(
|
|
265
|
+
channel: "angle" | "radius",
|
|
266
|
+
layerPath: string,
|
|
267
|
+
invalidAesConstant: boolean,
|
|
268
|
+
): SpecError {
|
|
269
|
+
const message = invalidAesConstant
|
|
270
|
+
? `The spoke geom requires aes.${channel} to map a data field (not a constant or stat). Use params.${channel} for a fixed value.`
|
|
271
|
+
: `The spoke geom requires "${channel}" via aes.${channel} or params.${channel}.`;
|
|
272
|
+
return {
|
|
273
|
+
code: "missing-required-channel",
|
|
274
|
+
path: `${layerPath}/aes/${channel}`,
|
|
275
|
+
message,
|
|
276
|
+
fix: {
|
|
277
|
+
description: `Map aes.${channel} to a field, or set params.${channel} to a constant.`,
|
|
278
|
+
example:
|
|
279
|
+
channel === "angle"
|
|
280
|
+
? { geom: "spoke", params: { angle: 0, radius: 1 } }
|
|
281
|
+
: { geom: "spoke", params: { radius: 1, angle: 0 } },
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function rugStructuralErrors(
|
|
287
|
+
layer: Record<string, unknown>,
|
|
288
|
+
geom: string,
|
|
289
|
+
layerPath: string,
|
|
290
|
+
mapped: MappedChannel,
|
|
291
|
+
): SpecError[] {
|
|
292
|
+
if (geom !== "rug") return [];
|
|
293
|
+
const errors: SpecError[] = [];
|
|
294
|
+
const params = isRecord(layer["params"]) ? layer["params"] : {};
|
|
295
|
+
const sides = typeof params["sides"] === "string" ? params["sides"] : "bl";
|
|
296
|
+
if (/[bt]/.test(sides) && mapped("x") === undefined) {
|
|
297
|
+
pushMissingChannel(
|
|
298
|
+
errors,
|
|
299
|
+
layerPath,
|
|
300
|
+
"x",
|
|
301
|
+
`The rug geom with sides "${sides}" requires an "x" channel for bottom/top ticks; map aes.x or narrow params.sides.`,
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
if (/[lr]/.test(sides) && mapped("y") === undefined) {
|
|
305
|
+
pushMissingChannel(
|
|
306
|
+
errors,
|
|
307
|
+
layerPath,
|
|
308
|
+
"y",
|
|
309
|
+
`The rug geom with sides "${sides}" requires a "y" channel for left/right ticks; map aes.y or narrow params.sides.`,
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
return errors;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function styleAestheticErrors(
|
|
316
|
+
layerAes: Aes | undefined,
|
|
317
|
+
geom: string,
|
|
318
|
+
annotationRule: boolean,
|
|
319
|
+
mapped: MappedChannel,
|
|
320
|
+
layerPath: string,
|
|
321
|
+
): SpecError[] {
|
|
322
|
+
const errors: SpecError[] = [];
|
|
323
|
+
for (const aesthetic of Object.keys(STYLE_AESTHETIC_GEOMS) as StyleAesthetic[]) {
|
|
324
|
+
const value = annotationRule ? (layerAes?.[aesthetic] ?? undefined) : mapped(aesthetic);
|
|
325
|
+
if (value === undefined) continue;
|
|
326
|
+
const compatible = STYLE_AESTHETIC_GEOMS[aesthetic] as readonly string[];
|
|
327
|
+
if (compatible.includes(geom)) continue;
|
|
328
|
+
errors.push({
|
|
329
|
+
code: "unsupported-geom-aesthetic",
|
|
330
|
+
path: `${layerPath}/aes/${aesthetic}`,
|
|
331
|
+
message: `The ${geom} geom does not consume aes.${aesthetic}; supported geoms: ${compatible.join(", ")}.`,
|
|
332
|
+
fix: {
|
|
333
|
+
description: `Remove aes.${aesthetic} or move it to a compatible ${compatible[0]} layer.`,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return errors;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function requiredChannelErrors(
|
|
341
|
+
geom: string,
|
|
342
|
+
stat: string,
|
|
343
|
+
layerPath: string,
|
|
344
|
+
mapped: MappedChannel,
|
|
345
|
+
): SpecError[] {
|
|
346
|
+
const errors: SpecError[] = [];
|
|
347
|
+
for (const channel of REQUIRED_CHANNELS[geom as GeomName]) {
|
|
348
|
+
if (computedPositionChannel(geom, stat, channel)) continue;
|
|
349
|
+
const value = mapped(channel);
|
|
350
|
+
if (value === undefined) {
|
|
351
|
+
errors.push(missingChannelError(geom, layerPath, channel));
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
if (requiresFieldMapping(geom, channel) && !("field" in value)) {
|
|
355
|
+
errors.push({
|
|
356
|
+
code: "missing-required-channel",
|
|
357
|
+
path: `${layerPath}/aes/${channel}`,
|
|
358
|
+
message: `The ${geom} geom requires aes.${channel} to map a data field (not a constant or stat).`,
|
|
359
|
+
fix: {
|
|
360
|
+
description: `Map "${channel}" to a data field.`,
|
|
361
|
+
example: { [channel]: CHANNEL_FIX_EXAMPLE },
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return errors;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function computedPositionChannel(geom: string, stat: string, channel: ChannelName): boolean {
|
|
370
|
+
if (channel === "x") return false;
|
|
371
|
+
return (
|
|
372
|
+
["bar", "histogram", "freqpoly", "density", "dotplot"].includes(geom) ||
|
|
373
|
+
(geom === "line" && stat === "bin")
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function requiresFieldMapping(geom: string, channel: ChannelName): boolean {
|
|
378
|
+
const endpoint = channel === "x" || channel === "y" || channel === "xend" || channel === "yend";
|
|
379
|
+
return (
|
|
380
|
+
((geom === "segment" || geom === "curve") && endpoint) ||
|
|
381
|
+
(geom === "spoke" && (channel === "x" || channel === "y"))
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function missingChannelError(geom: string, layerPath: string, channel: ChannelName): SpecError {
|
|
386
|
+
return {
|
|
387
|
+
code: "missing-required-channel",
|
|
388
|
+
path: `${layerPath}/aes/${channel}`,
|
|
389
|
+
message: `The ${geom} geom requires a "${channel}" channel; map it in the layer's aes or the plot-level aes.`,
|
|
390
|
+
fix: {
|
|
391
|
+
description: `Map "${channel}" to a data field.`,
|
|
392
|
+
example: { [channel]: CHANNEL_FIX_EXAMPLE },
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural validation for within-mark paint (#591): stop order and
|
|
3
|
+
* data-mapped fill/color conflicts. Schema already rejects empty stops,
|
|
4
|
+
* out-of-range offsets, non-hex colors, and excessive glow radii.
|
|
5
|
+
*/
|
|
6
|
+
import type { SpecError } from "./errors.js";
|
|
7
|
+
import type { Aes, ChannelValue } from "./schema.js";
|
|
8
|
+
import { effectiveChannel } from "./validate-data.js";
|
|
9
|
+
|
|
10
|
+
function isRecord(v: unknown): v is Record<string, unknown> {
|
|
11
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function isDataMapped(channel: ChannelValue | undefined): boolean {
|
|
15
|
+
if (channel === undefined || channel === null) return false;
|
|
16
|
+
if ("field" in channel) return true;
|
|
17
|
+
if ("value" in channel && channel.scale === true) return true;
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function stopOrderErrors(paint: unknown, path: string): SpecError[] {
|
|
22
|
+
if (!isRecord(paint) || !Array.isArray(paint["stops"])) return [];
|
|
23
|
+
const stops = paint["stops"] as unknown[];
|
|
24
|
+
let prev = -Infinity;
|
|
25
|
+
for (let i = 0; i < stops.length; i++) {
|
|
26
|
+
const stop = stops[i];
|
|
27
|
+
if (!isRecord(stop) || typeof stop["offset"] !== "number") continue;
|
|
28
|
+
const offset = stop["offset"];
|
|
29
|
+
if (offset < prev) {
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
code: "paint-stops-unordered",
|
|
33
|
+
path: `${path}/stops/${String(i)}/offset`,
|
|
34
|
+
message: `Gradient stop offsets must be non-decreasing; stop ${String(i)} has offset ${String(offset)} after ${String(prev)}.`,
|
|
35
|
+
fix: {
|
|
36
|
+
description: "Sort stops by offset ascending (each between 0 and 1).",
|
|
37
|
+
example: {
|
|
38
|
+
stops: [
|
|
39
|
+
{ offset: 0, color: "#000000" },
|
|
40
|
+
{ offset: 1, color: "#ffffff" },
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
prev = offset;
|
|
48
|
+
}
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Paint structural checks for one layer (opt-in tier-2 via validate options).
|
|
54
|
+
*/
|
|
55
|
+
export function paintStructuralErrors(
|
|
56
|
+
layer: Record<string, unknown>,
|
|
57
|
+
layerPath: string,
|
|
58
|
+
plotAes: Aes | undefined,
|
|
59
|
+
): SpecError[] {
|
|
60
|
+
const errors: SpecError[] = [];
|
|
61
|
+
const params = isRecord(layer["params"]) ? layer["params"] : null;
|
|
62
|
+
if (params === null) return errors;
|
|
63
|
+
|
|
64
|
+
const layerAes = isRecord(layer["aes"]) ? (layer["aes"] as Aes) : undefined;
|
|
65
|
+
const fill = effectiveChannel(plotAes, layerAes, "fill");
|
|
66
|
+
const color = effectiveChannel(plotAes, layerAes, "color");
|
|
67
|
+
|
|
68
|
+
if (params["fillPaint"] !== undefined) {
|
|
69
|
+
errors.push(...stopOrderErrors(params["fillPaint"], `${layerPath}/params/fillPaint`));
|
|
70
|
+
if (isDataMapped(fill)) {
|
|
71
|
+
errors.push({
|
|
72
|
+
code: "paint-scale-conflict",
|
|
73
|
+
path: `${layerPath}/params/fillPaint`,
|
|
74
|
+
message:
|
|
75
|
+
"params.fillPaint cannot combine with a data-mapped fill channel (field or scaled constant).",
|
|
76
|
+
fix: {
|
|
77
|
+
description: "Remove aes.fill field mapping, or remove fillPaint and keep the scale.",
|
|
78
|
+
example: { params: { fillPaint: { type: "linear" } } },
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (params["strokePaint"] !== undefined) {
|
|
85
|
+
errors.push(...stopOrderErrors(params["strokePaint"], `${layerPath}/params/strokePaint`));
|
|
86
|
+
if (isDataMapped(color)) {
|
|
87
|
+
errors.push({
|
|
88
|
+
code: "paint-scale-conflict",
|
|
89
|
+
path: `${layerPath}/params/strokePaint`,
|
|
90
|
+
message:
|
|
91
|
+
"params.strokePaint cannot combine with a data-mapped color channel (field or scaled constant).",
|
|
92
|
+
fix: {
|
|
93
|
+
description: "Remove aes.color field mapping, or remove strokePaint and keep the scale.",
|
|
94
|
+
example: { params: { strokePaint: { type: "linear" } } },
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return errors;
|
|
101
|
+
}
|