From 206b40d895dcb4b0b25537356662bff6b32a833c Mon Sep 17 00:00:00 2001 From: Kanit Wongsuphasawat Date: Mon, 6 Mar 2017 22:34:40 -0800 Subject: [PATCH] Release 2.0.0-alpha.6 f202c9026ac5fa7e3e251c07d64c64c8cb5db985 --- build/examples/examples.test.d.ts | 0 build/examples/examples.test.js | 53 + build/package.json | 115 + build/src/aggregate.d.ts | 8 + build/src/aggregate.js | 45 + build/src/axis.d.ts | 71 + build/src/axis.js | 10 + build/src/bin.d.ts | 40 + build/src/bin.js | 18 + build/src/channel.d.ts | 70 + build/src/channel.js | 156 + build/src/compile/axis/encode.d.ts | 4 + build/src/compile/axis/encode.js | 64 + build/src/compile/axis/parse.d.ts | 10 + build/src/compile/axis/parse.js | 127 + build/src/compile/axis/rules.d.ts | 23 + build/src/compile/axis/rules.js | 125 + build/src/compile/common.d.ts | 31 + build/src/compile/common.js | 105 + build/src/compile/compile.d.ts | 36 + build/src/compile/compile.js | 87 + build/src/compile/data/base.d.ts | 21 + build/src/compile/data/base.js | 3 + build/src/compile/data/bin.d.ts | 4 + build/src/compile/data/bin.js | 86 + build/src/compile/data/data.d.ts | 59 + build/src/compile/data/data.js | 115 + build/src/compile/data/filter.d.ts | 2 + build/src/compile/data/filter.js | 61 + build/src/compile/data/formatparse.d.ts | 3 + build/src/compile/data/formatparse.js | 96 + build/src/compile/data/formula.d.ts | 4 + build/src/compile/data/formula.js | 40 + build/src/compile/data/nonpositivefilter.d.ts | 3 + build/src/compile/data/nonpositivefilter.js | 55 + build/src/compile/data/nullfilter.d.ts | 4 + build/src/compile/data/nullfilter.js | 75 + build/src/compile/data/pathorder.d.ts | 3 + build/src/compile/data/pathorder.js | 84 + build/src/compile/data/source.d.ts | 11 + build/src/compile/data/source.js | 101 + build/src/compile/data/stack.d.ts | 39 + build/src/compile/data/stack.js | 134 + build/src/compile/data/summary.d.ts | 15 + build/src/compile/data/summary.js | 164 + build/src/compile/data/timeunit.d.ts | 4 + build/src/compile/data/timeunit.js | 48 + build/src/compile/facet.d.ts | 69 + build/src/compile/facet.js | 481 + build/src/compile/layer.d.ts | 64 + build/src/compile/layer.js | 199 + build/src/compile/layout.d.ts | 24 + build/src/compile/layout.js | 164 + build/src/compile/legend/encode.d.ts | 5 + build/src/compile/legend/encode.js | 94 + build/src/compile/legend/parse.d.ts | 6 + build/src/compile/legend/parse.js | 72 + build/src/compile/legend/rules.d.ts | 8 + build/src/compile/legend/rules.js | 36 + build/src/compile/mark/area.d.ts | 2 + build/src/compile/mark/area.js | 13 + build/src/compile/mark/bar.d.ts | 2 + build/src/compile/mark/bar.js | 90 + build/src/compile/mark/base.d.ts | 17 + build/src/compile/mark/base.js | 3 + build/src/compile/mark/init.d.ts | 13 + build/src/compile/mark/init.js | 149 + build/src/compile/mark/line.d.ts | 2 + build/src/compile/mark/line.js | 14 + build/src/compile/mark/mark.d.ts | 2 + build/src/compile/mark/mark.js | 108 + build/src/compile/mark/mixins.d.ts | 40 + build/src/compile/mark/mixins.js | 141 + build/src/compile/mark/point.d.ts | 7 + build/src/compile/mark/point.js | 39 + build/src/compile/mark/rect.d.ts | 2 + build/src/compile/mark/rect.js | 59 + build/src/compile/mark/rule.d.ts | 2 + build/src/compile/mark/rule.js | 14 + build/src/compile/mark/text.d.ts | 2 + build/src/compile/mark/text.js | 37 + build/src/compile/mark/tick.d.ts | 2 + build/src/compile/mark/tick.js | 39 + build/src/compile/mark/valueref.d.ts | 30 + build/src/compile/mark/valueref.js | 234 + build/src/compile/model.d.ts | 136 + build/src/compile/model.js | 241 + build/src/compile/scale/domain.d.ts | 23 + build/src/compile/scale/domain.js | 267 + build/src/compile/scale/init.d.ts | 18 + build/src/compile/scale/init.js | 92 + build/src/compile/scale/parse.d.ts | 14 + build/src/compile/scale/parse.js | 53 + build/src/compile/scale/range.d.ts | 19 + build/src/compile/scale/range.js | 193 + build/src/compile/scale/rules.d.ts | 9 + build/src/compile/scale/rules.js | 83 + build/src/compile/scale/type.d.ts | 10 + build/src/compile/scale/type.js | 128 + build/src/compile/selection/interval.d.ts | 8 + build/src/compile/selection/interval.js | 135 + build/src/compile/selection/multi.d.ts | 3 + build/src/compile/selection/multi.js | 27 + build/src/compile/selection/selection.d.ts | 44 + build/src/compile/selection/selection.js | 177 + build/src/compile/selection/single.d.ts | 3 + build/src/compile/selection/single.js | 28 + .../compile/selection/transforms/inputs.d.ts | 3 + .../compile/selection/transforms/inputs.js | 35 + .../compile/selection/transforms/nearest.d.ts | 3 + .../compile/selection/transforms/nearest.js | 39 + .../compile/selection/transforms/project.d.ts | 3 + .../compile/selection/transforms/project.js | 21 + .../compile/selection/transforms/scales.d.ts | 6 + .../compile/selection/transforms/scales.js | 53 + .../compile/selection/transforms/toggle.d.ts | 3 + .../compile/selection/transforms/toggle.js | 24 + .../selection/transforms/transforms.d.ts | 14 + .../selection/transforms/transforms.js | 20 + .../selection/transforms/translate.d.ts | 3 + .../compile/selection/transforms/translate.js | 64 + .../compile/selection/transforms/zoom.d.ts | 3 + .../src/compile/selection/transforms/zoom.js | 60 + build/src/compile/unit.d.ts | 76 + build/src/compile/unit.js | 268 + build/src/compositemark.d.ts | 11 + build/src/compositemark.js | 49 + build/src/config.d.ts | 147 + build/src/config.js | 56 + build/src/data.d.ts | 65 + build/src/data.js | 22 + build/src/datetime.d.ts | 101 + build/src/datetime.js | 180 + build/src/encoding.d.ts | 73 + build/src/encoding.js | 132 + build/src/facet.d.ts | 11 + build/src/facet.js | 3 + build/src/fielddef.d.ts | 125 + build/src/fielddef.js | 190 + build/src/filter.d.ts | 53 + build/src/filter.js | 79 + build/src/legend.d.ts | 51 + build/src/legend.js | 7 + build/src/log.d.ts | 78 + build/src/log.js | 234 + build/src/mark.d.ts | 130 + build/src/mark.js | 55 + build/src/scale.d.ts | 257 + build/src/scale.js | 169 + build/src/selection.d.ts | 25 + build/src/selection.js | 13 + build/src/sort.d.ts | 14 + build/src/sort.js | 7 + build/src/spec.d.ts | 101 + build/src/spec.js | 210 + build/src/stack.d.ts | 29 + build/src/stack.js | 90 + build/src/timeunit.d.ts | 48 + build/src/timeunit.js | 275 + build/src/transform.d.ts | 31 + build/src/transform.js | 3 + build/src/type.d.ts | 19 + build/src/type.js | 43 + build/src/util.d.ts | 49 + build/src/util.js | 202 + build/src/validate.d.ts | 32 + build/src/validate.js | 69 + build/src/vega.schema.d.ts | 540 + build/src/vega.schema.js | 33 + build/src/vl.d.ts | 24 + build/src/vl.js | 28 + build/test/babel.d.ts | 0 build/test/babel.js | 6 + build/test/channel.test.d.ts | 0 build/test/channel.test.js | 120 + build/test/compile/axis/encode.test.d.ts | 0 build/test/compile/axis/encode.test.js | 62 + build/test/compile/axis/parse.test.d.ts | 0 build/test/compile/axis/parse.test.js | 95 + build/test/compile/axis/rules.test.d.ts | 0 build/test/compile/axis/rules.test.js | 142 + build/test/compile/common.test.d.ts | 0 build/test/compile/common.test.js | 59 + build/test/compile/compile.test.d.ts | 0 build/test/compile/compile.test.js | 90 + build/test/compile/data/bin.test.d.ts | 0 build/test/compile/data/bin.test.js | 72 + build/test/compile/data/data.test.d.ts | 0 build/test/compile/data/data.test.js | 113 + build/test/compile/data/datatestutil.d.ts | 2 + build/test/compile/data/datatestutil.js | 20 + build/test/compile/data/filter.test.d.ts | 0 build/test/compile/data/filter.test.js | 53 + build/test/compile/data/formatparse.test.d.ts | 0 build/test/compile/data/formatparse.test.js | 99 + build/test/compile/data/formula.test.d.ts | 0 build/test/compile/data/formula.test.js | 48 + .../compile/data/nonpositivefilter.test.d.ts | 0 .../compile/data/nonpositivefilter.test.js | 45 + build/test/compile/data/nullfilter.test.d.ts | 0 build/test/compile/data/nullfilter.test.js | 85 + build/test/compile/data/pathorder.test.d.ts | 0 build/test/compile/data/pathorder.test.js | 164 + build/test/compile/data/source.test.d.ts | 0 build/test/compile/data/source.test.js | 129 + build/test/compile/data/stack.test.d.ts | 0 build/test/compile/data/stack.test.js | 304 + build/test/compile/data/summary.test.d.ts | 0 build/test/compile/data/summary.test.js | 123 + build/test/compile/data/timeunit.test.d.ts | 0 build/test/compile/data/timeunit.test.js | 37 + build/test/compile/facet.test.d.ts | 0 build/test/compile/facet.test.js | 367 + build/test/compile/layer.test.d.ts | 0 build/test/compile/layer.test.js | 69 + build/test/compile/layout.test.d.ts | 0 build/test/compile/layout.test.js | 148 + build/test/compile/legend/encode.test.d.ts | 0 build/test/compile/legend/encode.test.js | 73 + build/test/compile/legend/parse.test.d.ts | 0 build/test/compile/legend/parse.test.js | 40 + build/test/compile/legend/rules.test.d.ts | 0 build/test/compile/legend/rules.test.js | 52 + build/test/compile/mark/area.test.d.ts | 0 build/test/compile/mark/area.test.js | 191 + build/test/compile/mark/bar.test.d.ts | 0 build/test/compile/mark/bar.test.js | 409 + build/test/compile/mark/init.test.d.ts | 0 build/test/compile/mark/init.test.js | 208 + build/test/compile/mark/line.test.d.ts | 0 build/test/compile/mark/line.test.js | 110 + build/test/compile/mark/mark.test.d.ts | 0 build/test/compile/mark/mark.test.js | 99 + build/test/compile/mark/mixins.test.d.ts | 0 build/test/compile/mark/mixins.test.js | 50 + build/test/compile/mark/point.test.d.ts | 0 build/test/compile/mark/point.test.js | 260 + build/test/compile/mark/rect.test.d.ts | 0 build/test/compile/mark/rect.test.js | 114 + build/test/compile/mark/rule.test.d.ts | 0 build/test/compile/mark/rule.test.js | 166 + build/test/compile/mark/text.test.d.ts | 0 build/test/compile/mark/text.test.js | 133 + build/test/compile/mark/tick.test.d.ts | 0 build/test/compile/mark/tick.test.js | 138 + build/test/compile/model.test.d.ts | 0 build/test/compile/model.test.js | 90 + build/test/compile/scale/domain.test.d.ts | 0 build/test/compile/scale/domain.test.js | 272 + build/test/compile/scale/init.test.d.ts | 0 build/test/compile/scale/init.test.js | 28 + build/test/compile/scale/parse.test.d.ts | 0 build/test/compile/scale/parse.test.js | 151 + build/test/compile/scale/range.test.d.ts | 0 build/test/compile/scale/range.test.js | 223 + build/test/compile/scale/rules.test.d.ts | 0 build/test/compile/scale/rules.test.js | 108 + build/test/compile/scale/type.test.d.ts | 0 build/test/compile/scale/type.test.js | 190 + build/test/compile/selection/inputs.test.d.ts | 0 build/test/compile/selection/inputs.test.js | 160 + .../test/compile/selection/interval.test.d.ts | 0 build/test/compile/selection/interval.test.js | 347 + build/test/compile/selection/multi.test.d.ts | 0 build/test/compile/selection/multi.test.js | 112 + .../test/compile/selection/nearest.test.d.ts | 0 build/test/compile/selection/nearest.test.js | 158 + build/test/compile/selection/parse.test.d.ts | 0 build/test/compile/selection/parse.test.js | 106 + .../compile/selection/predicate.test.d.ts | 0 .../test/compile/selection/predicate.test.js | 78 + build/test/compile/selection/single.test.d.ts | 0 build/test/compile/selection/single.test.js | 123 + .../compile/selection/translate.test.d.ts | 0 .../test/compile/selection/translate.test.js | 167 + build/test/compile/selection/zoom.test.d.ts | 0 build/test/compile/selection/zoom.test.js | 176 + build/test/compile/unit.test.d.ts | 0 build/test/compile/unit.test.js | 165 + build/test/datetime.test.d.ts | 0 build/test/datetime.test.js | 117 + build/test/fielddef.test.d.ts | 0 build/test/fielddef.test.js | 130 + build/test/filter.test.d.ts | 0 build/test/filter.test.js | 99 + build/test/scale.test.d.ts | 0 build/test/scale.test.js | 31 + build/test/schema.test.d.ts | 0 build/test/schema.test.js | 23 + build/test/spec.test.d.ts | 0 build/test/spec.test.js | 633 ++ build/test/stack.test.d.ts | 0 build/test/stack.test.js | 383 + build/test/timeunit.test.d.ts | 0 build/test/timeunit.test.js | 141 + build/test/type.test.d.ts | 0 build/test/type.test.js | 30 + build/test/util.d.ts | 9 + build/test/util.js | 25 + build/test/validate.test.d.ts | 0 build/test/validate.test.js | 70 + build/vega-lite.js | 9656 +++++++++++++++++ build/vega-lite.js.map | 191 + build/vega-lite.min.js | 6 + build/vega-lite.min.js.map | 1 + 305 files changed, 29983 insertions(+) create mode 100644 build/examples/examples.test.d.ts create mode 100644 build/examples/examples.test.js create mode 100644 build/package.json create mode 100644 build/src/aggregate.d.ts create mode 100644 build/src/aggregate.js create mode 100644 build/src/axis.d.ts create mode 100644 build/src/axis.js create mode 100644 build/src/bin.d.ts create mode 100644 build/src/bin.js create mode 100644 build/src/channel.d.ts create mode 100644 build/src/channel.js create mode 100644 build/src/compile/axis/encode.d.ts create mode 100644 build/src/compile/axis/encode.js create mode 100644 build/src/compile/axis/parse.d.ts create mode 100644 build/src/compile/axis/parse.js create mode 100644 build/src/compile/axis/rules.d.ts create mode 100644 build/src/compile/axis/rules.js create mode 100644 build/src/compile/common.d.ts create mode 100644 build/src/compile/common.js create mode 100644 build/src/compile/compile.d.ts create mode 100644 build/src/compile/compile.js create mode 100644 build/src/compile/data/base.d.ts create mode 100644 build/src/compile/data/base.js create mode 100644 build/src/compile/data/bin.d.ts create mode 100644 build/src/compile/data/bin.js create mode 100644 build/src/compile/data/data.d.ts create mode 100644 build/src/compile/data/data.js create mode 100644 build/src/compile/data/filter.d.ts create mode 100644 build/src/compile/data/filter.js create mode 100644 build/src/compile/data/formatparse.d.ts create mode 100644 build/src/compile/data/formatparse.js create mode 100644 build/src/compile/data/formula.d.ts create mode 100644 build/src/compile/data/formula.js create mode 100644 build/src/compile/data/nonpositivefilter.d.ts create mode 100644 build/src/compile/data/nonpositivefilter.js create mode 100644 build/src/compile/data/nullfilter.d.ts create mode 100644 build/src/compile/data/nullfilter.js create mode 100644 build/src/compile/data/pathorder.d.ts create mode 100644 build/src/compile/data/pathorder.js create mode 100644 build/src/compile/data/source.d.ts create mode 100644 build/src/compile/data/source.js create mode 100644 build/src/compile/data/stack.d.ts create mode 100644 build/src/compile/data/stack.js create mode 100644 build/src/compile/data/summary.d.ts create mode 100644 build/src/compile/data/summary.js create mode 100644 build/src/compile/data/timeunit.d.ts create mode 100644 build/src/compile/data/timeunit.js create mode 100644 build/src/compile/facet.d.ts create mode 100644 build/src/compile/facet.js create mode 100644 build/src/compile/layer.d.ts create mode 100644 build/src/compile/layer.js create mode 100644 build/src/compile/layout.d.ts create mode 100644 build/src/compile/layout.js create mode 100644 build/src/compile/legend/encode.d.ts create mode 100644 build/src/compile/legend/encode.js create mode 100644 build/src/compile/legend/parse.d.ts create mode 100644 build/src/compile/legend/parse.js create mode 100644 build/src/compile/legend/rules.d.ts create mode 100644 build/src/compile/legend/rules.js create mode 100644 build/src/compile/mark/area.d.ts create mode 100644 build/src/compile/mark/area.js create mode 100644 build/src/compile/mark/bar.d.ts create mode 100644 build/src/compile/mark/bar.js create mode 100644 build/src/compile/mark/base.d.ts create mode 100644 build/src/compile/mark/base.js create mode 100644 build/src/compile/mark/init.d.ts create mode 100644 build/src/compile/mark/init.js create mode 100644 build/src/compile/mark/line.d.ts create mode 100644 build/src/compile/mark/line.js create mode 100644 build/src/compile/mark/mark.d.ts create mode 100644 build/src/compile/mark/mark.js create mode 100644 build/src/compile/mark/mixins.d.ts create mode 100644 build/src/compile/mark/mixins.js create mode 100644 build/src/compile/mark/point.d.ts create mode 100644 build/src/compile/mark/point.js create mode 100644 build/src/compile/mark/rect.d.ts create mode 100644 build/src/compile/mark/rect.js create mode 100644 build/src/compile/mark/rule.d.ts create mode 100644 build/src/compile/mark/rule.js create mode 100644 build/src/compile/mark/text.d.ts create mode 100644 build/src/compile/mark/text.js create mode 100644 build/src/compile/mark/tick.d.ts create mode 100644 build/src/compile/mark/tick.js create mode 100644 build/src/compile/mark/valueref.d.ts create mode 100644 build/src/compile/mark/valueref.js create mode 100644 build/src/compile/model.d.ts create mode 100644 build/src/compile/model.js create mode 100644 build/src/compile/scale/domain.d.ts create mode 100644 build/src/compile/scale/domain.js create mode 100644 build/src/compile/scale/init.d.ts create mode 100644 build/src/compile/scale/init.js create mode 100644 build/src/compile/scale/parse.d.ts create mode 100644 build/src/compile/scale/parse.js create mode 100644 build/src/compile/scale/range.d.ts create mode 100644 build/src/compile/scale/range.js create mode 100644 build/src/compile/scale/rules.d.ts create mode 100644 build/src/compile/scale/rules.js create mode 100644 build/src/compile/scale/type.d.ts create mode 100644 build/src/compile/scale/type.js create mode 100644 build/src/compile/selection/interval.d.ts create mode 100644 build/src/compile/selection/interval.js create mode 100644 build/src/compile/selection/multi.d.ts create mode 100644 build/src/compile/selection/multi.js create mode 100644 build/src/compile/selection/selection.d.ts create mode 100644 build/src/compile/selection/selection.js create mode 100644 build/src/compile/selection/single.d.ts create mode 100644 build/src/compile/selection/single.js create mode 100644 build/src/compile/selection/transforms/inputs.d.ts create mode 100644 build/src/compile/selection/transforms/inputs.js create mode 100644 build/src/compile/selection/transforms/nearest.d.ts create mode 100644 build/src/compile/selection/transforms/nearest.js create mode 100644 build/src/compile/selection/transforms/project.d.ts create mode 100644 build/src/compile/selection/transforms/project.js create mode 100644 build/src/compile/selection/transforms/scales.d.ts create mode 100644 build/src/compile/selection/transforms/scales.js create mode 100644 build/src/compile/selection/transforms/toggle.d.ts create mode 100644 build/src/compile/selection/transforms/toggle.js create mode 100644 build/src/compile/selection/transforms/transforms.d.ts create mode 100644 build/src/compile/selection/transforms/transforms.js create mode 100644 build/src/compile/selection/transforms/translate.d.ts create mode 100644 build/src/compile/selection/transforms/translate.js create mode 100644 build/src/compile/selection/transforms/zoom.d.ts create mode 100644 build/src/compile/selection/transforms/zoom.js create mode 100644 build/src/compile/unit.d.ts create mode 100644 build/src/compile/unit.js create mode 100644 build/src/compositemark.d.ts create mode 100644 build/src/compositemark.js create mode 100644 build/src/config.d.ts create mode 100644 build/src/config.js create mode 100644 build/src/data.d.ts create mode 100644 build/src/data.js create mode 100644 build/src/datetime.d.ts create mode 100644 build/src/datetime.js create mode 100644 build/src/encoding.d.ts create mode 100644 build/src/encoding.js create mode 100644 build/src/facet.d.ts create mode 100644 build/src/facet.js create mode 100644 build/src/fielddef.d.ts create mode 100644 build/src/fielddef.js create mode 100644 build/src/filter.d.ts create mode 100644 build/src/filter.js create mode 100644 build/src/legend.d.ts create mode 100644 build/src/legend.js create mode 100644 build/src/log.d.ts create mode 100644 build/src/log.js create mode 100644 build/src/mark.d.ts create mode 100644 build/src/mark.js create mode 100644 build/src/scale.d.ts create mode 100644 build/src/scale.js create mode 100644 build/src/selection.d.ts create mode 100644 build/src/selection.js create mode 100644 build/src/sort.d.ts create mode 100644 build/src/sort.js create mode 100644 build/src/spec.d.ts create mode 100644 build/src/spec.js create mode 100644 build/src/stack.d.ts create mode 100644 build/src/stack.js create mode 100644 build/src/timeunit.d.ts create mode 100644 build/src/timeunit.js create mode 100644 build/src/transform.d.ts create mode 100644 build/src/transform.js create mode 100644 build/src/type.d.ts create mode 100644 build/src/type.js create mode 100644 build/src/util.d.ts create mode 100644 build/src/util.js create mode 100644 build/src/validate.d.ts create mode 100644 build/src/validate.js create mode 100644 build/src/vega.schema.d.ts create mode 100644 build/src/vega.schema.js create mode 100644 build/src/vl.d.ts create mode 100644 build/src/vl.js create mode 100644 build/test/babel.d.ts create mode 100644 build/test/babel.js create mode 100644 build/test/channel.test.d.ts create mode 100644 build/test/channel.test.js create mode 100644 build/test/compile/axis/encode.test.d.ts create mode 100644 build/test/compile/axis/encode.test.js create mode 100644 build/test/compile/axis/parse.test.d.ts create mode 100644 build/test/compile/axis/parse.test.js create mode 100644 build/test/compile/axis/rules.test.d.ts create mode 100644 build/test/compile/axis/rules.test.js create mode 100644 build/test/compile/common.test.d.ts create mode 100644 build/test/compile/common.test.js create mode 100644 build/test/compile/compile.test.d.ts create mode 100644 build/test/compile/compile.test.js create mode 100644 build/test/compile/data/bin.test.d.ts create mode 100644 build/test/compile/data/bin.test.js create mode 100644 build/test/compile/data/data.test.d.ts create mode 100644 build/test/compile/data/data.test.js create mode 100644 build/test/compile/data/datatestutil.d.ts create mode 100644 build/test/compile/data/datatestutil.js create mode 100644 build/test/compile/data/filter.test.d.ts create mode 100644 build/test/compile/data/filter.test.js create mode 100644 build/test/compile/data/formatparse.test.d.ts create mode 100644 build/test/compile/data/formatparse.test.js create mode 100644 build/test/compile/data/formula.test.d.ts create mode 100644 build/test/compile/data/formula.test.js create mode 100644 build/test/compile/data/nonpositivefilter.test.d.ts create mode 100644 build/test/compile/data/nonpositivefilter.test.js create mode 100644 build/test/compile/data/nullfilter.test.d.ts create mode 100644 build/test/compile/data/nullfilter.test.js create mode 100644 build/test/compile/data/pathorder.test.d.ts create mode 100644 build/test/compile/data/pathorder.test.js create mode 100644 build/test/compile/data/source.test.d.ts create mode 100644 build/test/compile/data/source.test.js create mode 100644 build/test/compile/data/stack.test.d.ts create mode 100644 build/test/compile/data/stack.test.js create mode 100644 build/test/compile/data/summary.test.d.ts create mode 100644 build/test/compile/data/summary.test.js create mode 100644 build/test/compile/data/timeunit.test.d.ts create mode 100644 build/test/compile/data/timeunit.test.js create mode 100644 build/test/compile/facet.test.d.ts create mode 100644 build/test/compile/facet.test.js create mode 100644 build/test/compile/layer.test.d.ts create mode 100644 build/test/compile/layer.test.js create mode 100644 build/test/compile/layout.test.d.ts create mode 100644 build/test/compile/layout.test.js create mode 100644 build/test/compile/legend/encode.test.d.ts create mode 100644 build/test/compile/legend/encode.test.js create mode 100644 build/test/compile/legend/parse.test.d.ts create mode 100644 build/test/compile/legend/parse.test.js create mode 100644 build/test/compile/legend/rules.test.d.ts create mode 100644 build/test/compile/legend/rules.test.js create mode 100644 build/test/compile/mark/area.test.d.ts create mode 100644 build/test/compile/mark/area.test.js create mode 100644 build/test/compile/mark/bar.test.d.ts create mode 100644 build/test/compile/mark/bar.test.js create mode 100644 build/test/compile/mark/init.test.d.ts create mode 100644 build/test/compile/mark/init.test.js create mode 100644 build/test/compile/mark/line.test.d.ts create mode 100644 build/test/compile/mark/line.test.js create mode 100644 build/test/compile/mark/mark.test.d.ts create mode 100644 build/test/compile/mark/mark.test.js create mode 100644 build/test/compile/mark/mixins.test.d.ts create mode 100644 build/test/compile/mark/mixins.test.js create mode 100644 build/test/compile/mark/point.test.d.ts create mode 100644 build/test/compile/mark/point.test.js create mode 100644 build/test/compile/mark/rect.test.d.ts create mode 100644 build/test/compile/mark/rect.test.js create mode 100644 build/test/compile/mark/rule.test.d.ts create mode 100644 build/test/compile/mark/rule.test.js create mode 100644 build/test/compile/mark/text.test.d.ts create mode 100644 build/test/compile/mark/text.test.js create mode 100644 build/test/compile/mark/tick.test.d.ts create mode 100644 build/test/compile/mark/tick.test.js create mode 100644 build/test/compile/model.test.d.ts create mode 100644 build/test/compile/model.test.js create mode 100644 build/test/compile/scale/domain.test.d.ts create mode 100644 build/test/compile/scale/domain.test.js create mode 100644 build/test/compile/scale/init.test.d.ts create mode 100644 build/test/compile/scale/init.test.js create mode 100644 build/test/compile/scale/parse.test.d.ts create mode 100644 build/test/compile/scale/parse.test.js create mode 100644 build/test/compile/scale/range.test.d.ts create mode 100644 build/test/compile/scale/range.test.js create mode 100644 build/test/compile/scale/rules.test.d.ts create mode 100644 build/test/compile/scale/rules.test.js create mode 100644 build/test/compile/scale/type.test.d.ts create mode 100644 build/test/compile/scale/type.test.js create mode 100644 build/test/compile/selection/inputs.test.d.ts create mode 100644 build/test/compile/selection/inputs.test.js create mode 100644 build/test/compile/selection/interval.test.d.ts create mode 100644 build/test/compile/selection/interval.test.js create mode 100644 build/test/compile/selection/multi.test.d.ts create mode 100644 build/test/compile/selection/multi.test.js create mode 100644 build/test/compile/selection/nearest.test.d.ts create mode 100644 build/test/compile/selection/nearest.test.js create mode 100644 build/test/compile/selection/parse.test.d.ts create mode 100644 build/test/compile/selection/parse.test.js create mode 100644 build/test/compile/selection/predicate.test.d.ts create mode 100644 build/test/compile/selection/predicate.test.js create mode 100644 build/test/compile/selection/single.test.d.ts create mode 100644 build/test/compile/selection/single.test.js create mode 100644 build/test/compile/selection/translate.test.d.ts create mode 100644 build/test/compile/selection/translate.test.js create mode 100644 build/test/compile/selection/zoom.test.d.ts create mode 100644 build/test/compile/selection/zoom.test.js create mode 100644 build/test/compile/unit.test.d.ts create mode 100644 build/test/compile/unit.test.js create mode 100644 build/test/datetime.test.d.ts create mode 100644 build/test/datetime.test.js create mode 100644 build/test/fielddef.test.d.ts create mode 100644 build/test/fielddef.test.js create mode 100644 build/test/filter.test.d.ts create mode 100644 build/test/filter.test.js create mode 100644 build/test/scale.test.d.ts create mode 100644 build/test/scale.test.js create mode 100644 build/test/schema.test.d.ts create mode 100644 build/test/schema.test.js create mode 100644 build/test/spec.test.d.ts create mode 100644 build/test/spec.test.js create mode 100644 build/test/stack.test.d.ts create mode 100644 build/test/stack.test.js create mode 100644 build/test/timeunit.test.d.ts create mode 100644 build/test/timeunit.test.js create mode 100644 build/test/type.test.d.ts create mode 100644 build/test/type.test.js create mode 100644 build/test/util.d.ts create mode 100644 build/test/util.js create mode 100644 build/test/validate.test.d.ts create mode 100644 build/test/validate.test.js create mode 100644 build/vega-lite.js create mode 100644 build/vega-lite.js.map create mode 100644 build/vega-lite.min.js create mode 100644 build/vega-lite.min.js.map diff --git a/build/examples/examples.test.d.ts b/build/examples/examples.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/examples/examples.test.js b/build/examples/examples.test.js new file mode 100644 index 0000000000..68d6cfb5cb --- /dev/null +++ b/build/examples/examples.test.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var compile_1 = require("../src/compile/compile"); +var Ajv = require("ajv"); +var inspect = require('util').inspect; +var fs = require('fs'); +var path = require('path'); +var vlSchema = require('../../build/vega-lite-schema.json'); +var vgSchema = require('vega/build/vega-schema.json'); +var ajv = new Ajv({ + validateSchema: false, + extendRefs: true, + allErrors: true +}); +var validateVl = ajv.compile(vlSchema); +var validateVg = ajv.compile(vgSchema); +function validateVL(spec) { + var valid = validateVl(spec); + var errors = validateVl.errors; + if (!valid) { + console.log(inspect(errors, { depth: 10, colors: true })); + } + chai_1.assert(valid, errors && errors.map(function (err) { return err.message; }).join(', ')); + chai_1.assert.equal(spec.$schema, 'https://vega.github.io/schema/vega-lite/v2.json'); +} +function validateVega(spec) { + var vegaSpec = compile_1.compile(spec).spec; + var valid = validateVg(vegaSpec); + var errors = validateVg.errors; + if (!valid) { + console.log(inspect(errors, { depth: 10, colors: true })); + } + chai_1.assert(valid, errors && errors.map(function (err) { return err.message; }).join(', ')); +} +describe('Examples', function () { + var examples = fs.readdirSync('examples/specs'); + examples.forEach(function (example) { + if (path.extname(example) !== '.json') { + return; + } + var jsonSpec = JSON.parse(fs.readFileSync('examples/specs/' + example)); + describe(example, function () { + it('should be valid vega-lite with proper $schema', function () { + validateVL(jsonSpec); + }); + it('should produce valid vega', function () { + validateVega(jsonSpec); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhhbXBsZXMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2V4YW1wbGVzL2V4YW1wbGVzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFDNUIsa0RBQStDO0FBRS9DLHlCQUEyQjtBQUUzQixJQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDO0FBQ3hDLElBQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6QixJQUFNLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7QUFFN0IsSUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFDOUQsSUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLDZCQUE2QixDQUFDLENBQUM7QUFFeEQsSUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDbEIsY0FBYyxFQUFFLEtBQUs7SUFDckIsVUFBVSxFQUFFLElBQUk7SUFDaEIsU0FBUyxFQUFFLElBQUk7Q0FDaEIsQ0FBQyxDQUFDO0FBQ0gsSUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUN6QyxJQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBRXpDLG9CQUFvQixJQUFrQjtJQUNwQyxJQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDL0IsSUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQztJQUNqQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDWCxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUNELGFBQU0sQ0FBQyxLQUFLLEVBQUUsTUFBTSxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBQyxHQUFvQixJQUFLLE9BQUEsR0FBRyxDQUFDLE9BQU8sRUFBWCxDQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUV0RixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaURBQWlELENBQUMsQ0FBQztBQUNoRixDQUFDO0FBRUQsc0JBQXNCLElBQWtCO0lBQ3RDLElBQU0sUUFBUSxHQUFHLGlCQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDO0lBRXBDLElBQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxJQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO0lBQ2pDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNYLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBQ0QsYUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFDLEdBQW9CLElBQUssT0FBQSxHQUFHLENBQUMsT0FBTyxFQUFYLENBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3hGLENBQUM7QUFFRCxRQUFRLENBQUMsVUFBVSxFQUFFO0lBQ25CLElBQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUVsRCxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQVMsT0FBZTtRQUN2QyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFBQSxNQUFNLENBQUM7UUFBQSxDQUFDO1FBQ2hELElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRTFFLFFBQVEsQ0FBQyxPQUFPLEVBQUU7WUFDaEIsRUFBRSxDQUFDLCtDQUErQyxFQUFFO2dCQUNsRCxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkIsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsMkJBQTJCLEVBQUU7Z0JBQzlCLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN6QixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/package.json b/build/package.json new file mode 100644 index 0000000000..3a259e105a --- /dev/null +++ b/build/package.json @@ -0,0 +1,115 @@ +{ + "name": "vega-lite", + "author": "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat", + "version": "2.0.0-alpha.6", + "collaborators": [ + "Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)", + "Dominik Moritz (https://www.domoritz.de)", + "Jeffrey Heer (http://jheer.org)" + ], + "homepage": "https://vega.github.io/vega-lite/", + "description": "Vega-lite provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.", + "main": "build/src/vl.js", + "types": "build/src/vl.d.ts", + "bin": { + "vl2png": "./bin/vl2png", + "vl2svg": "./bin/vl2svg", + "vl2vg": "./bin/vl2vg" + }, + "directories": { + "test": "test" + }, + "scripts": { + "prebuild": "mkdir -p build/site build/examples/images build/test-gallery", + "build": "tsc && cp package.json build && browserify src/vl.ts -p tsify -g [ babelify ] -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js", + "postbuild": "uglifyjs build/vega-lite.js -cm --in-source-map build/vega-lite.js.map --source-map build/vega-lite.min.js.map > build/vega-lite.min.js && npm run schema", + "build:images": "npm run data && scripts/generate-images.sh", + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "browserify site/static/main.ts -p [tsify -p site] -d > build/site/main.js", + "build:versions": "scripts/update-version.sh", + "build:test-gallery": "browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js", + "checkschema": "scripts/check-schema.sh", + "clean": "rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\.(js|js.map|d.ts)' -delete & rm -rf examples/_diff examples/_original examples/_output examples/images && rm -rf data", + "data": "rsync -r node_modules/vega-datasets/data/* data", + + "deploy": "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + + "prestart": "npm run data && npm run build && scripts/index-examples", + "start": "nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'", + "poststart": "rm examples/all-examples.json", + + "preschema": "npm run prebuild", + "schema": "typescript-json-schema --required true --noExtraProps true src/spec.ts ExtendedSpec > build/vega-lite-schema.json", + + "presite": "npm run build && npm run data && npm run build:site && npm run build:toc && npm run build:versions", + "site": "bundle exec jekyll serve", + + "lint": "tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'", + + "test": "tsc && npm run schema && npm run data && npm run test:nocompile", + "test:nocompile": "npm run test:only && npm run lint && npm run mocha:examples", + "test:only": "nyc --reporter=html --reporter=text-summary npm run mocha:test", + "test:debug": "tsc && npm run schema && npm run data && mocha --recursive --require ./test/babel.ts --debug-brk build/test build/examples", + "mocha:test": "mocha --reporter dot --recursive build/test", + "mocha:examples": "mocha --require ./test/babel.ts --reporter dot --recursive build/examples", + + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json", + "watch:build": "watchify src/vl.ts -p tsify -g [ babelify ] -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'", + "watch:test": "nodemon -x 'npm test'", + "watch": "nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build", + "x-compile": "./scripts/examples-compile.sh", + "x-diff": "./scripts/examples-diff.sh" + }, + "repository": { + "type": "git", + "url": "https://github.com/vega/vega-lite.git" + }, + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/vega/vega-lite/issues" + }, + "devDependencies": { + "@types/chai": "^3.4.35", + "@types/highlight.js": "^9.1.9", + "@types/d3": "^4.5.0", + "@types/json-stable-stringify": "^1.0.30", + "@types/mocha": "^2.2.39", + "@types/node": "^7.0.5", + "ajv": "5.0.1-beta.1", + "babel-preset-es2015": "^6.22.0", + "babelify": "^7.3.0", + "browser-sync": "~2.18.8", + "browserify": "~14.1.0", + "browserify-shim": "^3.8.13", + "chai": "~3.5.0", + "cheerio": "~0.22.0", + "codecov": "~1.0.1", + "d3": "^4.7.0", + "exorcist": "~0.4.0", + "highlight.js": "^9.9.0", + "mocha": "~3.2.0", + "nodemon": "~1.11.0", + "nyc": "~10.1.2", + "source-map-support": "~0.4.11", + "tsify": "~3.0.1", + "tslint": "~4.5.1", + "tslint-eslint-rules": "^3.4.0", + "typescript": "^2.2.1", + "typescript-json-schema": "^0.10.0", + "uglify-js": "~2.8.4", + "vega": "3.0.0-beta.25", + "vega-datasets": "vega/vega-datasets#gh-pages", + "vega-embed": "3.0.0-beta.5", + "vega-parser": "^1.0.0-beta.38", + "watchify": "~3.9.0", + "yaml-front-matter": "~3.4.0" + }, + "dependencies": { + "json-stable-stringify": "~1.0.1", + "tslib": "^1.6.0", + "vega-util": "~1.1.4", + "yargs": "~6.6.0" + } +} diff --git a/build/src/aggregate.d.ts b/build/src/aggregate.d.ts new file mode 100644 index 0000000000..d6bfe2d151 --- /dev/null +++ b/build/src/aggregate.d.ts @@ -0,0 +1,8 @@ +export declare type AggregateOp = 'argmax' | 'argmin' | 'average' | 'count' | 'distinct' | 'max' | 'mean' | 'median' | 'min' | 'missing' | 'modeskew' | 'q1' | 'q3' | 'stdev' | 'stdevp' | 'sum' | 'valid' | 'values' | 'variance' | 'variancep'; +export declare const AGGREGATE_OPS: AggregateOp[]; +/** Additive-based aggregation operations. These can be applied to stack. */ +export declare const SUM_OPS: AggregateOp[]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +export declare const SHARED_DOMAIN_OPS: AggregateOp[]; diff --git a/build/src/aggregate.js b/build/src/aggregate.js new file mode 100644 index 0000000000..f5a7c056d3 --- /dev/null +++ b/build/src/aggregate.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AGGREGATE_OPS = [ + 'values', + 'count', + 'valid', + 'missing', + 'distinct', + 'sum', + 'mean', + 'average', + 'variance', + 'variancep', + 'stdev', + 'stdevp', + 'median', + 'q1', + 'q3', + 'modeskew', + 'min', + 'max', + 'argmin', + 'argmax', +]; +/** Additive-based aggregation operations. These can be applied to stack. */ +exports.SUM_OPS = [ + 'count', + 'sum', + 'distinct', + 'valid', + 'missing' +]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +exports.SHARED_DOMAIN_OPS = [ + 'mean', + 'average', + 'median', + 'q1', + 'q3', + 'min', + 'max', +]; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FnZ3JlZ2F0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU1hLFFBQUEsYUFBYSxHQUFrQjtJQUN4QyxRQUFRO0lBQ1IsT0FBTztJQUNQLE9BQU87SUFDUCxTQUFTO0lBQ1QsVUFBVTtJQUNWLEtBQUs7SUFDTCxNQUFNO0lBQ04sU0FBUztJQUNULFVBQVU7SUFDVixXQUFXO0lBQ1gsT0FBTztJQUNQLFFBQVE7SUFDUixRQUFRO0lBQ1IsSUFBSTtJQUNKLElBQUk7SUFDSixVQUFVO0lBQ1YsS0FBSztJQUNMLEtBQUs7SUFDTCxRQUFRO0lBQ1IsUUFBUTtDQUNYLENBQUM7QUFFRiw2RUFBNkU7QUFDaEUsUUFBQSxPQUFPLEdBQWtCO0lBQ2xDLE9BQU87SUFDUCxLQUFLO0lBQ0wsVUFBVTtJQUNWLE9BQU87SUFDUCxTQUFTO0NBQ1osQ0FBQztBQUVGOztHQUVHO0FBQ1UsUUFBQSxpQkFBaUIsR0FBa0I7SUFDNUMsTUFBTTtJQUNOLFNBQVM7SUFDVCxRQUFRO0lBQ1IsSUFBSTtJQUNKLElBQUk7SUFDSixLQUFLO0lBQ0wsS0FBSztDQUNSLENBQUMifQ== \ No newline at end of file diff --git a/build/src/axis.d.ts b/build/src/axis.d.ts new file mode 100644 index 0000000000..9e68f70d9f --- /dev/null +++ b/build/src/axis.d.ts @@ -0,0 +1,71 @@ +import { DateTime } from './datetime'; +import { VgAxisEncode, VgAxisBase, VgAxisConfig } from './vega.schema'; +export declare type AxisOrient = 'top' | 'right' | 'left' | 'bottom'; +export interface AxisConfig extends VgAxisConfig, VlOnlyAxisBase { + /** + * Whether month names and weekday names should be abbreviated. + */ + shortTimeLabels?: boolean; +} +export declare const defaultAxisConfig: AxisConfig; +export interface Axis extends VgAxisBase, VlOnlyAxisBase { + /** + * The padding, in pixels, between axis and text labels. + */ + labelPadding?: number; + /** + * The formatting pattern for axis labels. + */ + format?: string; + /** + * The orientation of the axis. One of top, bottom, left or right. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart). + */ + orient?: AxisOrient; + /** + * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle. + */ + offset?: number; + /** + * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate. + * + * __Default value__: `0` + */ + position?: number; + /** + * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are "nice" (multiples of 2, 5, 10) and lie within the underlying scale's range. + * @minimum 0 + * @TJS-type integer + */ + tickCount?: number; + /** + * A title for the axis. Shows field name and its function by default. + */ + title?: string; + values?: number[] | DateTime[]; + /** + * A non-positive integer indicating z-index of the axis. + * If zindex is 0, axes should be drawn behind all chart elements. + * To put them in front, use zindex = 1. + * @TJS-type integer + * @minimum 0 + */ + zindex?: number; + /** + * Optional mark definitions for custom axis encoding. + */ + encode?: VgAxisEncode; +} +/** + * Base object for properties that are shared between Axis and Axis Config. + * These properties are not in Vega Axis and Axis Config. + */ +export interface VlOnlyAxisBase { + /** + * Truncate labels that are too long. + * @minimum 1 + * @TJS-type integer + */ + labelMaxLength?: number; +} +export declare const AXIS_PROPERTIES: (keyof Axis)[]; +export declare const VL_ONLY_AXIS_PROPERTIES: (keyof VlOnlyAxisBase)[]; diff --git a/build/src/axis.js b/build/src/axis.js new file mode 100644 index 0000000000..bf685c02cc --- /dev/null +++ b/build/src/axis.js @@ -0,0 +1,10 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultAxisConfig = { + labelMaxLength: 25, +}; +exports.AXIS_PROPERTIES = [ + 'domain', 'format', 'grid', 'labelPadding', 'labels', 'maxExtent', 'minExtent', 'offset', 'orient', 'position', 'tickCount', 'ticks', 'tickSize', 'title', 'titlePadding', 'values', 'zindex' +]; +exports.VL_ONLY_AXIS_PROPERTIES = ['labelMaxLength']; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9heGlzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBWWEsUUFBQSxpQkFBaUIsR0FBZTtJQUMzQyxjQUFjLEVBQUUsRUFBRTtDQUNuQixDQUFDO0FBeUVXLFFBQUEsZUFBZSxHQUFrQjtJQUM1QyxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsUUFBUTtDQUM5TCxDQUFDO0FBRVcsUUFBQSx1QkFBdUIsR0FBNEIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/src/bin.d.ts b/build/src/bin.d.ts new file mode 100644 index 0000000000..37d66681dd --- /dev/null +++ b/build/src/bin.d.ts @@ -0,0 +1,40 @@ +import { Channel } from './channel'; +/** + * Binning properties or boolean flag for determining whether to bin data or not. + */ +export interface Bin { + /** + * A two-element (`[min, max]`) array indicating the range of desired bin values. + * @minItems 2 + * @maxItems 2 + */ + extent?: number[]; + /** + * The number base to use for automatic bin determination (default is base 10). + */ + base?: number; + /** + * An exact step size to use between bins. If provided, options such as maxbins will be ignored. + */ + step?: number; + /** + * An array of allowable step sizes to choose from. + * @minItems 1 + */ + steps?: number[]; + /** + * A minimum allowable step size (particularly useful for integer values). + */ + minstep?: number; + /** + * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints. + * @minItems 1 + */ + divide?: number[]; + /** + * Maximum number of bins. + * @minimum 2 + */ + maxbins?: number; +} +export declare function autoMaxBins(channel: Channel): number; diff --git a/build/src/bin.js b/build/src/bin.js new file mode 100644 index 0000000000..b50ad5672b --- /dev/null +++ b/build/src/bin.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +function autoMaxBins(channel) { + switch (channel) { + case channel_1.ROW: + case channel_1.COLUMN: + case channel_1.SIZE: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule + case channel_1.SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } +} +exports.autoMaxBins = autoMaxBins; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFDQUE0RDtBQTBDNUQscUJBQTRCLE9BQWdCO0lBQzFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDaEIsS0FBSyxhQUFHLENBQUM7UUFDVCxLQUFLLGdCQUFNLENBQUM7UUFDWixLQUFLLGNBQUksQ0FBQztRQUNSLCtDQUErQztRQUMvQyw4Q0FBOEM7UUFDaEQsS0FBSyxlQUFLO1lBQ1IsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLHVDQUF1QztRQUNuRDtZQUNFLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQztBQVpELGtDQVlDIn0= \ No newline at end of file diff --git a/build/src/channel.d.ts b/build/src/channel.d.ts new file mode 100644 index 0000000000..2d3fdb859b --- /dev/null +++ b/build/src/channel.d.ts @@ -0,0 +1,70 @@ +import { Encoding } from './encoding'; +import { Facet } from './facet'; +import { Mark } from './mark'; +import { RangeType } from './compile/scale/type'; +import { ScaleType } from './scale'; +export declare namespace Channel { + const ROW: 'row'; + const COLUMN: 'column'; + const X: 'x'; + const Y: 'y'; + const X2: 'x2'; + const Y2: 'y2'; + const COLOR: 'color'; + const SHAPE: 'shape'; + const SIZE: 'size'; + const OPACITY: 'opacity'; + const TEXT: 'text'; + const ORDER: 'order'; + const DETAIL: 'detail'; +} +export declare type Channel = keyof Encoding | keyof Facet; +export declare const X: "x"; +export declare const Y: "y"; +export declare const X2: "x2"; +export declare const Y2: "y2"; +export declare const ROW: "row"; +export declare const COLUMN: "column"; +export declare const SHAPE: "shape"; +export declare const SIZE: "size"; +export declare const COLOR: "color"; +export declare const TEXT: "text"; +export declare const DETAIL: "detail"; +export declare const ORDER: "order"; +export declare const OPACITY: "opacity"; +export declare const CHANNELS: Channel[]; +export declare const UNIT_CHANNELS: ("text" | "x" | "y" | "x2" | "y2" | "color" | "opacity" | "size" | "shape" | "detail" | "order")[]; +export declare const UNIT_SCALE_CHANNELS: ("x" | "y" | "color" | "opacity" | "size" | "shape")[]; +export declare const SCALE_CHANNELS: ("x" | "y" | "color" | "opacity" | "size" | "shape" | "row" | "column")[]; +export declare const NONSPATIAL_CHANNELS: ("text" | "color" | "opacity" | "size" | "shape" | "detail" | "order")[]; +export declare const NONSPATIAL_SCALE_CHANNELS: ("color" | "opacity" | "size" | "shape")[]; +/** Channels that can serve as groupings for stacked charts. */ +export declare const STACK_GROUP_CHANNELS: ("color" | "opacity" | "size" | "detail" | "order")[]; +export interface SupportedMark { + point?: boolean; + tick?: boolean; + rule?: boolean; + circle?: boolean; + square?: boolean; + bar?: boolean; + rect?: boolean; + line?: boolean; + area?: boolean; + text?: boolean; +} +/** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ +export declare function supportMark(channel: Channel, mark: Mark): boolean; +/** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to boolean values. + */ +export declare function getSupportedMark(channel: Channel): SupportedMark; +export declare function hasScale(channel: Channel): boolean; +export declare function supportScaleType(channel: Channel, scaleType: ScaleType): boolean; +export declare function rangeType(channel: Channel): RangeType; diff --git a/build/src/channel.js b/build/src/channel.js new file mode 100644 index 0000000000..e5172edb9e --- /dev/null +++ b/build/src/channel.js @@ -0,0 +1,156 @@ +/* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("./scale"); +var util_1 = require("./util"); +var Channel; +(function (Channel) { + // Facet + Channel.ROW = 'row'; + Channel.COLUMN = 'column'; + // Position + Channel.X = 'x'; + Channel.Y = 'y'; + Channel.X2 = 'x2'; + Channel.Y2 = 'y2'; + // Mark property with scale + Channel.COLOR = 'color'; + Channel.SHAPE = 'shape'; + Channel.SIZE = 'size'; + Channel.OPACITY = 'opacity'; + // Non-scale channel + Channel.TEXT = 'text'; + Channel.ORDER = 'order'; + Channel.DETAIL = 'detail'; +})(Channel = exports.Channel || (exports.Channel = {})); +exports.X = Channel.X; +exports.Y = Channel.Y; +exports.X2 = Channel.X2; +exports.Y2 = Channel.Y2; +exports.ROW = Channel.ROW; +exports.COLUMN = Channel.COLUMN; +exports.SHAPE = Channel.SHAPE; +exports.SIZE = Channel.SIZE; +exports.COLOR = Channel.COLOR; +exports.TEXT = Channel.TEXT; +exports.DETAIL = Channel.DETAIL; +exports.ORDER = Channel.ORDER; +exports.OPACITY = Channel.OPACITY; +exports.CHANNELS = [exports.X, exports.Y, exports.X2, exports.Y2, exports.ROW, exports.COLUMN, exports.SIZE, exports.SHAPE, exports.COLOR, exports.ORDER, exports.OPACITY, exports.TEXT, exports.DETAIL]; +// CHANNELS without COLUMN, ROW +exports.UNIT_CHANNELS = [exports.X, exports.Y, exports.X2, exports.Y2, exports.SIZE, exports.SHAPE, exports.COLOR, exports.ORDER, exports.OPACITY, exports.TEXT, exports.DETAIL]; +// UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT +exports.UNIT_SCALE_CHANNELS = [exports.X, exports.Y, exports.SIZE, exports.SHAPE, exports.COLOR, exports.OPACITY]; +// UNIT_SCALE_CHANNELS with ROW, COLUMN +exports.SCALE_CHANNELS = [exports.X, exports.Y, exports.SIZE, exports.SHAPE, exports.COLOR, exports.OPACITY, exports.ROW, exports.COLUMN]; +// UNIT_CHANNELS without X, Y, X2, Y2; +exports.NONSPATIAL_CHANNELS = [exports.SIZE, exports.SHAPE, exports.COLOR, exports.ORDER, exports.OPACITY, exports.TEXT, exports.DETAIL]; +// UNIT_SCALE_CHANNELS without X, Y; +exports.NONSPATIAL_SCALE_CHANNELS = [exports.SIZE, exports.SHAPE, exports.COLOR, exports.OPACITY]; +/** Channels that can serve as groupings for stacked charts. */ +exports.STACK_GROUP_CHANNELS = [exports.COLOR, exports.DETAIL, exports.ORDER, exports.OPACITY, exports.SIZE]; +; +/** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ +function supportMark(channel, mark) { + return mark in getSupportedMark(channel); +} +exports.supportMark = supportMark; +/** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to boolean values. + */ +function getSupportedMark(channel) { + switch (channel) { + case exports.X: + case exports.Y: + case exports.COLOR: + case exports.DETAIL: + case exports.ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case exports.OPACITY: + case exports.ROW: + case exports.COLUMN: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, area: true, text: true + }; + case exports.X2: + case exports.Y2: + return { + rule: true, bar: true, rect: true, area: true + }; + case exports.SIZE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, text: true, line: true + }; + case exports.SHAPE: + return { point: true }; + case exports.TEXT: + return { text: true }; + } + return {}; +} +exports.getSupportedMark = getSupportedMark; +function hasScale(channel) { + return !util_1.contains([exports.DETAIL, exports.TEXT, exports.ORDER], channel); +} +exports.hasScale = hasScale; +// Position does not work with ordinal (lookup) scale and sequential (which is only for color) +var POSITION_SCALE_TYPE_INDEX = util_1.toSet(util_1.without(scale_1.SCALE_TYPES, ['ordinal', 'sequential'])); +function supportScaleType(channel, scaleType) { + switch (channel) { + case exports.ROW: + case exports.COLUMN: + return scaleType === 'band'; // row / column currently supports band only + case exports.X: + case exports.Y: + case exports.SIZE: // TODO: size and opacity can support ordinal with more modification + case exports.OPACITY: + // Although it generally doesn't make sense to use band with size and opacity, + // it can also work since we use band: 0.5 to get midpoint. + return scaleType in POSITION_SCALE_TYPE_INDEX; + case exports.COLOR: + return scaleType !== 'band'; // band does not make sense with color + case exports.SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; +} +exports.supportScaleType = supportScaleType; +function rangeType(channel) { + switch (channel) { + case exports.X: + case exports.Y: + case exports.SIZE: + case exports.OPACITY: + return 'continuous'; + case exports.ROW: + case exports.COLUMN: + case exports.SHAPE: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case exports.COLOR: + return 'flexible'; + // No scale, no range type. + case exports.X2: + case exports.Y2: + case exports.DETAIL: + case exports.TEXT: + case exports.ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('getSupportedRole not implemented for ' + channel); +} +exports.rangeType = rangeType; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jaGFubmVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRzs7O0FBTUgsaUNBQStDO0FBQy9DLCtCQUFnRDtBQUVoRCxJQUFpQixPQUFPLENBcUJ2QjtBQXJCRCxXQUFpQixPQUFPO0lBQ3RCLFFBQVE7SUFDSyxXQUFHLEdBQVUsS0FBSyxDQUFDO0lBQ25CLGNBQU0sR0FBYSxRQUFRLENBQUM7SUFFekMsV0FBVztJQUNFLFNBQUMsR0FBUSxHQUFHLENBQUM7SUFDYixTQUFDLEdBQVEsR0FBRyxDQUFDO0lBQ2IsVUFBRSxHQUFTLElBQUksQ0FBQztJQUNoQixVQUFFLEdBQVMsSUFBSSxDQUFDO0lBRTdCLDJCQUEyQjtJQUNkLGFBQUssR0FBWSxPQUFPLENBQUM7SUFDekIsYUFBSyxHQUFZLE9BQU8sQ0FBQztJQUN6QixZQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLGVBQU8sR0FBYyxTQUFTLENBQUM7SUFFNUMsb0JBQW9CO0lBQ1AsWUFBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixhQUFLLEdBQVksT0FBTyxDQUFDO0lBQ3pCLGNBQU0sR0FBYSxRQUFRLENBQUM7QUFDM0MsQ0FBQyxFQXJCZ0IsT0FBTyxHQUFQLGVBQU8sS0FBUCxlQUFPLFFBcUJ2QjtBQUlZLFFBQUEsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDZCxRQUFBLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ2QsUUFBQSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQztBQUNoQixRQUFBLEVBQUUsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDO0FBQ2hCLFFBQUEsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7QUFDbEIsUUFBQSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUN4QixRQUFBLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFD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 \ No newline at end of file diff --git a/build/src/compile/axis/encode.d.ts b/build/src/compile/axis/encode.d.ts new file mode 100644 index 0000000000..05dda907f1 --- /dev/null +++ b/build/src/compile/axis/encode.d.ts @@ -0,0 +1,4 @@ +import { Channel } from '../../channel'; +import { VgAxis } from '../../vega.schema'; +import { Model } from '../model'; +export declare function labels(model: Model, channel: Channel, labelsSpec: any, def: VgAxis): any; diff --git a/build/src/compile/axis/encode.js b/build/src/compile/axis/encode.js new file mode 100644 index 0000000000..c888b93ea3 --- /dev/null +++ b/build/src/compile/axis/encode.js @@ -0,0 +1,64 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function labels(model, channel, labelsSpec, def) { + var fieldDef = model.fieldDef(channel); + var axis = model.axis(channel); + var config = model.config; + // Text + if (util_1.contains([type_1.NOMINAL, type_1.ORDINAL], fieldDef.type) && axis.labelMaxLength) { + // TODO replace this with Vega's labelMaxLength once it is introduced + labelsSpec = util_1.extend({ + text: { + signal: "truncate(datum.value, " + axis.labelMaxLength + ")" + } + }, labelsSpec || {}); + } + else if (fieldDef.type === type_1.TEMPORAL) { + labelsSpec = util_1.extend({ + text: { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat) + } + }, labelsSpec); + } + // Label Angle + if (axis.labelAngle !== undefined) { + labelsSpec.angle = { value: axis.labelAngle }; + } + else { + // auto rotate for X + if (channel === channel_1.X && (util_1.contains([type_1.NOMINAL, type_1.ORDINAL], fieldDef.type) || !!fieldDef.bin || fieldDef.type === type_1.TEMPORAL)) { + labelsSpec.angle = { value: 270 }; + } + } + // Auto set align if rotated + // TODO: consider other value besides 270, 90 + if (labelsSpec.angle) { + if (labelsSpec.angle.value === 270) { + labelsSpec.align = { + value: def.orient === 'top' ? 'left' : + (channel === channel_1.X || channel === channel_1.COLUMN) ? 'right' : + 'center' + }; + } + else if (labelsSpec.angle.value === 90) { + labelsSpec.align = { value: 'center' }; + } + } + if (labelsSpec.angle) { + // Auto set baseline if rotated + // TODO: consider other value besides 270, 90 + if (labelsSpec.angle.value === 270) { + labelsSpec.baseline = { value: (channel === channel_1.X || channel === channel_1.COLUMN) ? 'middle' : 'bottom' }; + } + else if (labelsSpec.angle.value === 90) { + labelsSpec.baseline = { value: 'bottom' }; + } + } + return util_1.keys(labelsSpec).length === 0 ? undefined : labelsSpec; +} +exports.labels = labels; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvYXhpcy9lbmNvZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBaUQ7QUFDakQsbUNBQXNEO0FBQ3RELG1DQUFrRDtBQUdsRCxvQ0FBK0M7QUFHL0MsZ0JBQXVCLEtBQVksRUFBRSxPQUFnQixFQUFFLFVBQWUsRUFBRSxHQUFXO0lBQ2pGLElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekMsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBRTVCLE9BQU87SUFDUCxFQUFFLENBQUMsQ0FBQyxlQUFRLENBQUMsQ0FBQyxjQUFPLEVBQUUsY0FBTyxDQUFDLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLHFFQUFxRTtRQUNyRSxVQUFVLEdBQUcsYUFBTSxDQUFDO1lBQ2xCLElBQUksRUFBRTtnQkFDSixNQUFNLEVBQUUsMkJBQXlCLElBQUksQ0FBQyxjQUFjLE1BQUc7YUFDeEQ7U0FDRixFQUFFLFVBQVUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN2QixDQUFDO0lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssZUFBUSxDQUFDLENBQUMsQ0FBQztRQUN0QyxVQUFVLEdBQUcsYUFBTSxDQUFDO1lBQ2xCLElBQUksRUFBRTtnQkFDSixNQUFNLEVBQUUsNkJBQW9CLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDO2FBQzVIO1NBQ0YsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNqQixDQUFDO0lBRUQsY0FBYztJQUNkLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNsQyxVQUFVLENBQUMsS0FBSyxHQUFHLEVBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixvQkFBb0I7UUFDcEIsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLFdBQUMsSUFBSSxDQUFDLGVBQVEsQ0FBQyxDQUFDLGNBQU8sRUFBRSxjQUFPLENBQUMsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxlQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkgsVUFBVSxDQUFDLEtBQUssR0FBRyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUVELDRCQUE0QjtJQUM1Qiw2Q0FBNkM7SUFDN0MsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckIsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNuQyxVQUFVLENBQUMsS0FBSyxHQUFHO2dCQUNqQixLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sS0FBSyxLQUFLLEdBQUcsTUFBTTtvQkFDNUIsQ0FBQyxPQUFPLEtBQUssV0FBQyxJQUFJLE9BQU8sS0FBSyxnQkFBTSxDQUFDLEdBQUcsT0FBTzt3QkFDL0MsUUFBUTthQUNqQixDQUFDO1FBQ0osQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNyQiwrQkFBK0I7UUFDL0IsNkNBQTZDO1FBQzdDLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbkMsVUFBVSxDQUFDLFFBQVEsR0FBRyxFQUFDLEtBQUssRUFBRSxDQUFDLE9BQU8sS0FBSyxXQUFDLElBQUksT0FBTyxLQUFLLGdCQUFNLENBQUMsR0FBRyxRQUFRLEdBQUcsUUFBUSxFQUFDLENBQUM7UUFDN0YsQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLFVBQVUsQ0FBQyxRQUFRLEdBQUcsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLENBQUM7UUFDMUMsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsV0FBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEdBQUcsU0FBUyxHQUFHLFVBQVUsQ0FBQztBQUNoRSxDQUFDO0FBeERELHdCQXdEQyJ9 \ No newline at end of file diff --git a/build/src/compile/axis/parse.d.ts b/build/src/compile/axis/parse.d.ts new file mode 100644 index 0000000000..362bffee8e --- /dev/null +++ b/build/src/compile/axis/parse.d.ts @@ -0,0 +1,10 @@ +import { Channel } from '../../channel'; +import { VgAxis } from '../../vega.schema'; +import { Model } from '../model'; +import { Dict } from '../../util'; +export declare function parseAxisComponent(model: Model, axisChannels: Channel[]): Dict; +/** + * Make an inner axis for showing grid for shared axis. + */ +export declare function parseGridAxis(channel: Channel, model: Model): VgAxis; +export declare function parseMainAxis(channel: Channel, model: Model): any; diff --git a/build/src/compile/axis/parse.js b/build/src/compile/axis/parse.js new file mode 100644 index 0000000000..2279ef75a0 --- /dev/null +++ b/build/src/compile/axis/parse.js @@ -0,0 +1,127 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var axis_1 = require("../../axis"); +var encode = require("./encode"); +var rules = require("./rules"); +var util_1 = require("../../util"); +var AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title']; +function parseAxisComponent(model, axisChannels) { + return axisChannels.reduce(function (axis, channel) { + var vgAxes = []; + if (model.axis(channel)) { + var main = parseMainAxis(channel, model); + if (main && isVisibleAxis(main)) { + vgAxes.push(main); + } + var grid = parseGridAxis(channel, model); + if (grid && isVisibleAxis(grid)) { + vgAxes.push(grid); + } + if (vgAxes.length > 0) { + axis[channel] = vgAxes; + } + } + return axis; + }, {}); +} +exports.parseAxisComponent = parseAxisComponent; +function isFalseOrNull(v) { + return v === false || v === null; +} +/** + * Return if an axis is visible (shows at least one part of the axis). + */ +function isVisibleAxis(axis) { + return util_1.some(AXIS_PARTS, function (part) { return hasAxisPart(axis, part); }); +} +function hasAxisPart(axis, part) { + // FIXME this method can be wrong if users use a Vega theme. + // (Not sure how to correctly handle that yet.). + if (part === 'grid' || part === 'title') { + return !!axis[part]; + } + // Other parts are enabled by default, so they should not be false or null. + return !isFalseOrNull(axis[part]); +} +/** + * Make an inner axis for showing grid for shared axis. + */ +function parseGridAxis(channel, model) { + // FIXME: support adding ticks for grid axis that are inner axes of faceted plots. + return parseAxis(channel, model, true); +} +exports.parseGridAxis = parseGridAxis; +function parseMainAxis(channel, model) { + return parseAxis(channel, model, false); +} +exports.parseMainAxis = parseMainAxis; +function parseAxis(channel, model, isGridAxis) { + var axis = model.axis(channel); + var vgAxis = { + scale: model.scaleName(channel) + }; + // 1.2. Add properties + axis_1.AXIS_PROPERTIES.forEach(function (property) { + var value = getSpecifiedOrDefaultValue(property, axis, channel, model, isGridAxis); + if (value !== undefined) { + vgAxis[property] = value; + } + }); + // Special case for gridScale since gridScale is not a Vega-Lite Axis property. + var gridScale = getSpecifiedOrDefaultValue('gridScale', axis, channel, model, isGridAxis); + if (gridScale !== undefined) { + vgAxis.gridScale = gridScale; + } + // 2) Add guide encode definition groups + var encodeSpec = axis.encode || {}; + AXIS_PARTS.forEach(function (part) { + if (!hasAxisPart(vgAxis, part)) { + // No need to create encode for a disabled part. + return; + } + // TODO(@yuhanlu): instead of calling encode[part], break this line based on part type + // as different require different parameters. + var value; + if (part === 'labels') { + value = encode.labels(model, channel, encodeSpec.labels || {}, vgAxis); + } + else { + value = encodeSpec[part] || {}; + } + if (value !== undefined && util_1.keys(value).length > 0) { + vgAxis.encode = vgAxis.encode || {}; + vgAxis.encode[part] = { update: value }; + } + }); + return vgAxis; +} +function getSpecifiedOrDefaultValue(property, specifiedAxis, channel, model, isGridAxis) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'labels': + return isGridAxis ? false : specifiedAxis[property]; + case 'domain': + return rules.domain(property, specifiedAxis, isGridAxis, channel); + case 'ticks': + return rules.ticks(property, specifiedAxis, isGridAxis, channel); + case 'format': + return rules.format(specifiedAxis, channel, fieldDef, model.config); + case 'grid': + return rules.grid(model, channel, isGridAxis); // FIXME: refactor this + case 'gridScale': + return rules.gridScale(model, channel, isGridAxis); + case 'orient': + return rules.orient(specifiedAxis, channel); + case 'tickCount': + return rules.tickCount(specifiedAxis, channel, fieldDef); // TODO: scaleType + case 'title': + return rules.title(specifiedAxis, fieldDef, model.config, isGridAxis); + case 'values': + return rules.values(specifiedAxis); + case 'zindex': + return rules.zindex(specifiedAxis, isGridAxis); + } + // Otherwise, return specified property. + return specifiedAxis[property]; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9heGlzL3BhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQWlEO0FBSWpELGlDQUFtQztBQUNuQywrQkFBaUM7QUFHakMsbUNBQTRDO0FBRzVDLElBQU0sVUFBVSxHQUFlLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBRTlFLDRCQUFtQyxLQUFZLEVBQUUsWUFBdUI7SUFDdEUsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBUyxJQUFJLEVBQUUsT0FBTztRQUMvQyxJQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFDNUIsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEIsSUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQixDQUFDO1lBRUQsSUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMzQyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQixDQUFDO1lBRUQsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDO1lBQ3pCLENBQUM7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 \ No newline at end of file diff --git a/build/src/compile/axis/rules.d.ts b/build/src/compile/axis/rules.d.ts new file mode 100644 index 0000000000..95515ee086 --- /dev/null +++ b/build/src/compile/axis/rules.d.ts @@ -0,0 +1,23 @@ +import { Axis } from '../../axis'; +import { VgAxis } from '../../vega.schema'; +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { DateTime } from '../../datetime'; +import { FieldDef } from '../../fielddef'; +import { Model } from '../model'; +export declare function format(specifiedAxis: Axis, channel: Channel, fieldDef: FieldDef, config: Config): string; +/** + * Default rules for whether to show a grid should be shown for a channel. + * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned + */ +export declare function gridShow(model: Model, channel: Channel): boolean; +export declare function grid(model: Model, channel: Channel, isGridAxis: boolean): boolean; +export declare function gridScale(model: Model, channel: Channel, isGridAxis: boolean): string; +export declare function orient(specifiedAxis: Axis, channel: Channel): "top" | "bottom" | "left" | "right"; +export declare function tickCount(specifiedAxis: Axis, channel: Channel, fieldDef: FieldDef): number; +export declare function title(specifiedAxis: Axis, fieldDef: FieldDef, config: Config, isGridAxis: boolean): string; +export declare function values(specifiedAxis: Axis): number[] | DateTime[]; +export declare function zindex(specifiedAxis: Axis, isGridAxis: boolean): number; +export declare function domainAndTicks(property: keyof VgAxis, specifiedAxis: Axis, isGridAxis: boolean, channel: Channel): any; +export declare const domain: typeof domainAndTicks; +export declare const ticks: typeof domainAndTicks; diff --git a/build/src/compile/axis/rules.js b/build/src/compile/axis/rules.js new file mode 100644 index 0000000000..04d5bf0970 --- /dev/null +++ b/build/src/compile/axis/rules.js @@ -0,0 +1,125 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function format(specifiedAxis, channel, fieldDef, config) { + return common_1.numberFormat(fieldDef, specifiedAxis.format, config, channel); +} +exports.format = format; +// TODO: we need to refactor this method after we take care of config refactoring +/** + * Default rules for whether to show a grid should be shown for a channel. + * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned + */ +function gridShow(model, channel) { + var grid = model.axis(channel).grid; + if (grid !== undefined) { + return grid; + } + return !model.hasDiscreteScale(channel) && !model.fieldDef(channel).bin; +} +exports.gridShow = gridShow; +function grid(model, channel, isGridAxis) { + if (channel === channel_1.ROW || channel === channel_1.COLUMN) { + // never apply grid for ROW and COLUMN since we manually create rule-group for them + return false; + } + if (!isGridAxis) { + return undefined; + } + return gridShow(model, channel); +} +exports.grid = grid; +function gridScale(model, channel, isGridAxis) { + if (isGridAxis) { + var gridChannel = channel === 'x' ? 'y' : 'x'; + if (model.scale(gridChannel)) { + return model.scaleName(gridChannel); + } + } + return undefined; +} +exports.gridScale = gridScale; +function orient(specifiedAxis, channel) { + var orient = specifiedAxis.orient; + if (orient) { + return orient; + } + switch (channel) { + case channel_1.COLUMN: + // FIXME test and decide + return 'top'; + case channel_1.X: + return 'bottom'; + case channel_1.ROW: + case channel_1.Y: + return 'left'; + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS); +} +exports.orient = orient; +function tickCount(specifiedAxis, channel, fieldDef) { + var count = specifiedAxis.tickCount; + if (count !== undefined) { + return count; + } + // FIXME depends on scale type too + if (channel === channel_1.X && !fieldDef.bin) { + // Vega's default tickCount often lead to a lot of label occlusion on X without 90 degree rotation + return 5; + } + return undefined; +} +exports.tickCount = tickCount; +function title(specifiedAxis, fieldDef, config, isGridAxis) { + if (isGridAxis) { + return undefined; + } + if (specifiedAxis.title !== undefined) { + return specifiedAxis.title; + } + // if not defined, automatically determine axis title from field def + var fieldTitle = fielddef_1.title(fieldDef, config); + var maxLength = specifiedAxis.titleMaxLength; + return maxLength ? util_1.truncate(fieldTitle, maxLength) : fieldTitle; +} +exports.title = title; +function values(specifiedAxis) { + var vals = specifiedAxis.values; + if (specifiedAxis.values && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return datetime_1.timestamp(dt, true); + }); + } + return vals; +} +exports.values = values; +function zindex(specifiedAxis, isGridAxis) { + var z = specifiedAxis.zindex; + if (z !== undefined) { + return z; + } + if (isGridAxis) { + // if grid is true, need to put layer on the back so that grid is behind marks + return 0; + } + return 1; // otherwise return undefined and use Vega's default. +} +exports.zindex = zindex; +; +function domainAndTicks(property, specifiedAxis, isGridAxis, channel) { + if (isGridAxis || channel === channel_1.ROW || channel === channel_1.COLUMN) { + return false; + } + return specifiedAxis[property]; +} +exports.domainAndTicks = domainAndTicks; +exports.domain = domainAndTicks; +exports.ticks = domainAndTicks; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9heGlzL3J1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQWlDO0FBSWpDLHlDQUF5RDtBQUV6RCwyQ0FBK0Q7QUFDL0QsMkNBQWdFO0FBQ2hFLG1DQUFvQztBQUVwQyxvQ0FBdUM7QUFHdkMsZ0JBQXVCLGFBQW1CLEVBQUUsT0FBZ0IsRUFBRSxRQUFrQixFQUFFLE1BQWM7SUFDOUYsTUFBTSxDQUFDLHFCQUFZLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFGRCx3QkFFQztBQUVELGlGQUFpRjtBQUNqRjs7O0dBR0c7QUFDSCxrQkFBeUIsS0FBWSxFQUFFLE9BQWdCO0lBQ3JELElBQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3RDLEVBQUUsQ0FBQyxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUM7QUFDMUUsQ0FBQztBQVBELDRCQU9DO0FBRUQsY0FBcUIsS0FBWSxFQUFFLE9BQWdCLEVBQUUsVUFBbUI7SUFDdEUsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLGFBQUcsSUFBSSxPQUFPLEtBQUssZ0JBQU0sQ0FBQyxDQUFDLENBQUM7UUFDMUMsbUZBQW1GO1FBQ25GLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2hC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 \ No newline at end of file diff --git a/build/src/compile/common.d.ts b/build/src/compile/common.d.ts new file mode 100644 index 0000000000..4ec619f542 --- /dev/null +++ b/build/src/compile/common.d.ts @@ -0,0 +1,31 @@ +import { Channel } from '../channel'; +import { Config, CellConfig } from '../config'; +import { FieldDef, OrderFieldDef } from '../fielddef'; +import { Mark, MarkConfig, TextConfig } from '../mark'; +import { TimeUnit } from '../timeunit'; +import { Model } from './model'; +import { UnitModel } from './unit'; +import { Spec } from '../spec'; +import { VgEncodeEntry, VgSort } from '../vega.schema'; +export declare function buildModel(spec: Spec, parent: Model, parentGivenName: string): Model; +export declare function applyConfig(e: VgEncodeEntry, config: CellConfig | MarkConfig | TextConfig, propsList: string[]): any; +export declare function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]): any; +/** + * Return value mark specific config property if exists. + * Otherwise, return general mark specific config. + */ +export declare function getMarkConfig

(prop: P, mark: Mark, config: Config): MarkConfig[P]; +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +export declare function numberFormat(fieldDef: FieldDef, format: string, config: Config, channel: Channel): string; +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +export declare function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string): string; +/** + * Return Vega sort parameters (tuple of field and order). + */ +export declare function sortParams(orderDef: OrderFieldDef | OrderFieldDef[]): VgSort; diff --git a/build/src/compile/common.js b/build/src/compile/common.js new file mode 100644 index 0000000000..529bdd700c --- /dev/null +++ b/build/src/compile/common.js @@ -0,0 +1,105 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var channel_1 = require("../channel"); +var fielddef_1 = require("../fielddef"); +var type_1 = require("../type"); +var util_1 = require("../util"); +var facet_1 = require("./facet"); +var layer_1 = require("./layer"); +var timeunit_1 = require("../timeunit"); +var unit_1 = require("./unit"); +var spec_1 = require("../spec"); +function buildModel(spec, parent, parentGivenName) { + if (spec_1.isFacetSpec(spec)) { + return new facet_1.FacetModel(spec, parent, parentGivenName); + } + if (spec_1.isLayerSpec(spec)) { + return new layer_1.LayerModel(spec, parent, parentGivenName); + } + if (spec_1.isUnitSpec(spec)) { + return new unit_1.UnitModel(spec, parent, parentGivenName); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.buildModel = buildModel; +function applyConfig(e, config, // TODO(#1842): consolidate MarkConfig | TextConfig? + propsList) { + propsList.forEach(function (property) { + var value = config[property]; + if (value !== undefined) { + e[property] = { value: value }; + } + }); + return e; +} +exports.applyConfig = applyConfig; +function applyMarkConfig(e, model, propsList) { + propsList.forEach(function (property) { + var value = getMarkConfig(property, model.mark(), model.config); + if (value !== undefined) { + e[property] = { value: value }; + } + }); + return e; +} +exports.applyMarkConfig = applyMarkConfig; +/** + * Return value mark specific config property if exists. + * Otherwise, return general mark specific config. + */ +function getMarkConfig(prop, mark, config) { + var markSpecificConfig = config[mark]; + if (markSpecificConfig[prop] !== undefined) { + return markSpecificConfig[prop]; + } + return config.mark[prop]; +} +exports.getMarkConfig = getMarkConfig; +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +function numberFormat(fieldDef, format, config, channel) { + if (fieldDef.type === type_1.QUANTITATIVE) { + // add number format for quantitative type only + if (format) { + return format; + } + else if (fieldDef.aggregate === 'count' && channel === channel_1.TEXT) { + // FIXME: need a more holistic way to deal with this. + return 'd'; + } + // TODO: need to make this work correctly for numeric ordinal / nominal type + return config.numberFormat; + } + return undefined; +} +exports.numberFormat = numberFormat; +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +function timeFormatExpression(field, timeUnit, format, shortTimeLabels, timeFormatConfig) { + if (!timeUnit || format) { + // If there is not time unit, or if user explicitly specify format for axis/legend/text. + var _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit. + return "timeFormat(" + field + ", '" + _format + "')"; + } + else { + return timeunit_1.formatExpression(timeUnit, field, shortTimeLabels); + } +} +exports.timeFormatExpression = timeFormatExpression; +/** + * Return Vega sort parameters (tuple of field and order). + */ +function sortParams(orderDef) { + return (util_1.isArray(orderDef) ? orderDef : [orderDef]).reduce(function (s, orderChannelDef) { + s.field.push(fielddef_1.field(orderChannelDef, { binSuffix: 'start' })); + s.order.push(orderChannelDef.sort || 'ascending'); + return s; + }, { field: [], order: [] }); +} +exports.sortParams = sortParams; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGUvY29tbW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNEJBQThCO0FBRTlCLHNDQUF5QztBQUV6Qyx3Q0FBMkQ7QUFHM0QsZ0NBQXFDO0FBQ3JDLGdDQUFnQztBQUVoQyxpQ0FBbUM7QUFDbkMsaUNBQW1DO0FBRW5DLHdDQUE2QztBQUM3QywrQkFBaUM7QUFDakMsZ0NBQW1FO0FBR25FLG9CQUEyQixJQUFVLEVBQUUsTUFBYSxFQUFFLGVBQXVCO0lBQzNFLEVBQUUsQ0FBQyxDQUFDLGtCQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sQ0FBQyxJQUFJLGtCQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxlQUFlLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsa0JBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLElBQUksa0JBQVUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxpQkFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsSUFBSSxnQkFBUyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBZEQsZ0NBY0M7QUFFRCxxQkFBNEIsQ0FBZ0IsRUFDeEMsTUFBNEMsRUFBRSxvREFBb0Q7SUFDbEcsU0FBbUI7SUFDckIsU0FBUyxDQUFDLE9BQU8sQ0FBQyxVQUFDLFFBQVE7UUFDekIsSUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FB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 \ No newline at end of file diff --git a/build/src/compile/compile.d.ts b/build/src/compile/compile.d.ts new file mode 100644 index 0000000000..d56848a57a --- /dev/null +++ b/build/src/compile/compile.d.ts @@ -0,0 +1,36 @@ +import * as log from '../log'; +import { Model } from './model'; +import { ExtendedSpec } from '../spec'; +export declare function compile(inputSpec: ExtendedSpec, logger?: log.LoggerInterface): { + spec: { + $schema: string; + } & { + padding: number | { + top?: number; + bottom?: number; + left?: number; + right?: number; + }; + } & { + autosize: string; + } & {} & {} & { + signals: { + name: string; + update: string; + }[]; + } & { + data: any[]; + marks: any[]; + }; +}; +export declare function topLevelBasicProperties(model: Model): { + padding: number | { + top?: number; + bottom?: number; + left?: number; + right?: number; + }; +} & { + autosize: string; +} & {} & {}; +export declare function assembleRootGroup(model: Model): any; diff --git a/build/src/compile/compile.js b/build/src/compile/compile.js new file mode 100644 index 0000000000..3457d2d940 --- /dev/null +++ b/build/src/compile/compile.js @@ -0,0 +1,87 @@ +/** + * Module for compiling Vega-lite spec into Vega spec. + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../data"); +var log = require("../log"); +var spec_1 = require("../spec"); +var util_1 = require("../util"); +var selection_1 = require("./selection/selection"); +var common_1 = require("./common"); +function compile(inputSpec, logger) { + if (logger) { + // set the singleton logger to the provided logger + log.set(logger); + } + try { + // 1. Convert input spec into a normal form + // (Decompose all extended unit specs into composition of unit spec.) + var spec = spec_1.normalize(inputSpec); + // 2. Instantiate the model with default properties + var model = common_1.buildModel(spec, null, ''); + // 3. Parse each part of the model to produce components that will be assembled later + // We traverse the whole tree to parse once for each type of components + // (e.g., data, layout, mark, scale). + // Please see inside model.parse() for order for compilation. + model.parse(); + // 4. Assemble a Vega Spec from the parsed components in 3. + return assemble(model); + } + finally { + // Reset the singleton logger if a logger is provided + if (logger) { + log.reset(); + } + } +} +exports.compile = compile; +function assemble(model) { + // TODO: change type to become VgSpec + var output = util_1.extend({ + $schema: 'http://vega.github.io/schema/vega/v3.0.json', + }, topLevelBasicProperties(model), { + // Map calculated layout width and height to width and height signals. + signals: [ + { + name: 'width', + update: "data('layout')[0].width" + }, + { + name: 'height', + update: "data('layout')[0].height" + } + ].concat(selection_1.assembleTopLevelSignals(model)) + }, { + data: [].concat(model.assembleData([]), model.assembleLayout([]), model.assembleSelectionData([])), + marks: [assembleRootGroup(model)] + }); + return { + spec: output + // TODO: add warning / errors here + }; +} +function topLevelBasicProperties(model) { + var config = model.config; + return util_1.extend( + // TODO: Add other top-level basic properties (#1778) + { padding: model.padding || config.padding }, { autosize: 'pad' }, config.viewport ? { viewport: config.viewport } : {}, config.background ? { background: config.background } : {}); +} +exports.topLevelBasicProperties = topLevelBasicProperties; +function assembleRootGroup(model) { + var rootGroup = util_1.extend({ + name: model.getName('main'), + type: 'group', + }, model.description ? { description: model.description } : {}, { + from: { data: model.getName(data_1.LAYOUT + '') }, + encode: { + update: util_1.extend({ + width: { field: model.getName('width') }, + height: { field: model.getName('height') } + }, model.assembleParentGroupProperties(model.config.cell)) + } + }); + return util_1.extend(rootGroup, model.assembleGroup()); +} +exports.assembleRootGroup = assembleRootGroup; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL2NvbXBpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7OztBQUVILGdDQUErQjtBQUMvQiw0QkFBOEI7QUFFOUIsZ0NBQWdEO0FBQ2hELGdDQUErQjtBQUMvQixtREFBOEQ7QUFDOUQsbUNBQW9DO0FBRXBDLGlCQUF3QixTQUF1QixFQUFFLE1BQTRCO0lBQzNFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDWCxrREFBa0Q7UUFDbEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsQixDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0gsMkNBQTJDO1FBQzNDLHFFQUFxRTtRQUNyRSxJQUFNLElBQUksR0FBRyxnQkFBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWxDLG1EQUFtRDtRQUNuRCxJQUFNLEtBQUssR0FBRyxtQkFBVSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFekMscUZBQXFGO1FBQ3JGLHVFQUF1RTtRQUN2RSxxQ0FBcUM7UUFDckMsNkRBQTZEO1FBQzdELEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUVkLDJEQUEyRDtRQUMzRCxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pCLENBQUM7WUFBUyxDQUFDO1FBQ1QscURBQXFEO1FBQ3JELEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDWCxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUE1QkQsMEJBNEJDO0FBRUQsa0JBQWtCLEtBQVk7SUFDNUIscUNBQXFDO0lBQ3JDLElBQU0sTUFBTSxHQUFHLGFBQU0sQ0FDbkI7UUFDRSxPQUFPLEVBQUUsNkNBQTZDO0tBQ3ZELEVBQ0QsdUJBQXVCLENBQUMsS0FBSyxDQUFDLEVBQzlCO1FBQ0Usc0VBQXNFO1FBQ3RFLE9BQU8sRUFBRTtZQUNQO2dCQUNFLElBQUksRUFBRSxPQUFPO2dCQUNiLE1BQU0sRUFBRSx5QkFBeUI7YUFDbEM7WUFDRDtnQkFDRSxJQUFJLEVBQUUsUUFBUTtnQkFDZCxNQUFNLEVBQUUsMEJBQTBCO2FBQ25DO1NBQ0YsQ0FBQyxNQUFNLENBQUMsbUNBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDekMsRUFBQztRQUNBLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxDQUNiLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEVBQ3RCLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLEVBQ3hCLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLENBQUMsQ0FDaEM7UUFDRCxLQUFLLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNsQyxDQUFDLENBQUM7SUFFTCxNQUFNLENBQUM7UUFDTCxJQUFJLEVBQUUsTUFBTTtRQUNaLGtDQUFrQztLQUNuQyxDQUFDO0FBQ0osQ0FBQztBQUVELGlDQUF3QyxLQUFZO0lBQ2xELElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDNUIsTUFBTSxDQUFDLGFBQU07SUFDWCxxREFBcUQ7SUFDckQsRUFBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFDLEVBQzFDLEVBQUMsUUFBUSxFQUFFLEtBQUssRUFBQyxFQUNqQixNQUFNLENBQUMsUUFBUSxHQUFHLEVBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUMsR0FBRyxFQUFFLEVBQ2xELE1BQU0sQ0FBQyxVQUFVLEdBQUcsRUFBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVUsRUFBQyxHQUFHLEVBQUUsQ0FDekQsQ0FBQztBQUNKLENBQUM7QUFURCwwREFTQztBQUVELDJCQUFrQyxLQUFZO0lBQzVDLElBQUksU0FBUyxHQUFPLGFBQU0sQ0FDeEI7UUFDRSxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDM0IsSUFBSSxFQUFFLE9BQU87S0FDZCxFQUNELEtBQUssQ0FBQyxXQUFXLEdBQUcsRUFBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBQyxHQUFHLEVBQUUsRUFDekQ7UUFDRSxJQUFJLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxhQUFNLEdBQUUsRUFBRSxDQUFDLEVBQUM7UUFDdkMsTUFBTSxFQUFFO1lBQ04sTUFBTSxFQUFFLGFBQU0sQ0FDWjtnQkFDRSxLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBQztnQkFDdEMsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUM7YUFDekMsRUFDRCxLQUFLLENBQUMsNkJBQTZCLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FDdkQ7U0FDRjtLQUNGLENBQUMsQ0FBQztJQUVMLE1BQU0sQ0FBQyxhQUFNLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO0FBQ2xELENBQUM7QUFyQkQsOENBcUJDIn0= \ No newline at end of file diff --git a/build/src/compile/data/base.d.ts b/build/src/compile/data/base.d.ts new file mode 100644 index 0000000000..986dad75a3 --- /dev/null +++ b/build/src/compile/data/base.d.ts @@ -0,0 +1,21 @@ +import { FacetModel } from './../facet'; +import { LayerModel } from './../layer'; +import { UnitModel } from './../unit'; +/** + * Abstract interface for implementing a data component compiler + * that produces a part of a data source. + * + * Each type of data component compiler should have a common data component (T), + * which stores minimal set of properties that can be merged + * and assembled into the desired output. + * + * For some data component type, the component might simply be the desired output + * if the desired output is already easy to merge. However, that is not the + * case for all types of data components. + */ +export interface DataComponentCompiler { + parseUnit: (model: UnitModel) => T; + parseLayer: (model: LayerModel) => T; + parseFacet: (model: FacetModel) => T; + assemble: (component: T) => any; +} diff --git a/build/src/compile/data/base.js b/build/src/compile/data/base.js new file mode 100644 index 0000000000..9e5274dfac --- /dev/null +++ b/build/src/compile/data/base.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0= \ No newline at end of file diff --git a/build/src/compile/data/bin.d.ts b/build/src/compile/data/bin.d.ts new file mode 100644 index 0000000000..6d0e9b1d83 --- /dev/null +++ b/build/src/compile/data/bin.d.ts @@ -0,0 +1,4 @@ +import { DataComponentCompiler } from './base'; +import { Dict } from '../../util'; +import { VgTransform } from '../../vega.schema'; +export declare const bin: DataComponentCompiler>; diff --git a/build/src/compile/data/bin.js b/build/src/compile/data/bin.js new file mode 100644 index 0000000000..aaf18c0db9 --- /dev/null +++ b/build/src/compile/data/bin.js @@ -0,0 +1,86 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bin_1 = require("../../bin"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var scale_1 = require("../../scale"); +function numberFormatExpr(expr, format) { + return "format(" + expr + ", '" + format + "')"; +} +function parse(model) { + return model.reduceFieldDef(function (binComponent, fieldDef, channel) { + var bin = model.fieldDef(channel).bin; + if (bin) { + var binTrans = util_1.extend({ + type: 'bin', + field: fieldDef.field, + as: [fielddef_1.field(fieldDef, { binSuffix: 'start' }), fielddef_1.field(fieldDef, { binSuffix: 'end' })], + signal: model.getName(fieldDef.field + '_bins') + }, + // if bin is an object, load parameter here! + typeof bin === 'boolean' ? {} : bin); + var transform = []; + if (!binTrans.extent) { + var extentSignal = model.getName(fieldDef.field + '_extent'); + transform.push({ + type: 'extent', + field: fieldDef.field, + signal: extentSignal + }); + binTrans.extent = { signal: extentSignal }; + } + if (!binTrans.maxbins && !binTrans.step) { + // if both maxbins and step are not specified, need to automatically determine bin + binTrans.maxbins = bin_1.autoMaxBins(channel); + } + transform.push(binTrans); + var discreteDomain = scale_1.hasDiscreteDomain(model.scale(channel).type); + if (discreteDomain) { + // read format from axis or legend, if there is no format then use config.numberFormat + var format = (model.axis(channel) || model.legend(channel) || {}).format || + model.config.numberFormat; + var startField = fielddef_1.field(fieldDef, { datum: true, binSuffix: 'start' }); + var endField = fielddef_1.field(fieldDef, { datum: true, binSuffix: 'end' }); + transform.push({ + type: 'formula', + as: fielddef_1.field(fieldDef, { binSuffix: 'range' }), + expr: numberFormatExpr(startField, format) + " + ' - ' + " + numberFormatExpr(endField, format) + }); + } + // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color + var key = util_1.hash(bin) + '_' + fieldDef.field + 'oc:' + discreteDomain; + binComponent[key] = transform; + } + return binComponent; + }, {}); +} +exports.bin = { + parseUnit: parse, + parseFacet: function (model) { + var binComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color + util_1.extend(binComponent, childDataComponent.bin); + delete childDataComponent.bin; + } + return binComponent; + }, + parseLayer: function (model) { + var binComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(binComponent, childDataComponent.bin); + delete childDataComponent.bin; + } + }); + return binComponent; + }, + assemble: function (component) { + return util_1.flatten(util_1.vals(component)); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9iaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxpQ0FBc0M7QUFFdEMsMkNBQStDO0FBQy9DLG1DQUE2RDtBQUU3RCxxQ0FBOEM7QUFPOUMsMEJBQTBCLElBQVksRUFBRSxNQUFjO0lBQ3BELE1BQU0sQ0FBQyxZQUFVLElBQUksV0FBTSxNQUFNLE9BQUksQ0FBQztBQUN4QyxDQUFDO0FBRUQsZUFBZSxLQUFZO0lBQ3pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLFVBQVMsWUFBaUMsRUFBRSxRQUFrQixFQUFFLE9BQWdCO1FBQzFHLElBQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3hDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFUixJQUFJLFFBQVEsR0FBZ0IsYUFBTSxDQUFDO2dCQUNqQyxJQUFJLEVBQUUsS0FBSztnQkFDWCxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUs7Z0JBQ3JCLEVBQUUsRUFBRSxDQUFDLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDLEVBQUUsZ0JBQUssQ0FBQyxRQUFRLEVBQUUsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztnQkFDaEYsTUFBTSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUM7YUFDaEQ7WUFDQyw0Q0FBNEM7WUFDNUMsT0FBTyxHQUFHLEtBQUssU0FBUyxHQUFHLEVBQUUsR0FBRyxHQUFHLENBQ3BDLENBQUM7WUFFRixJQUFNLFNBQVMsR0FBa0IsRUFBRSxDQUFDO1lBQ3BDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ3JC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 \ No newline at end of file diff --git a/build/src/compile/data/data.d.ts b/build/src/compile/data/data.d.ts new file mode 100644 index 0000000000..0435f63e79 --- /dev/null +++ b/build/src/compile/data/data.d.ts @@ -0,0 +1,59 @@ +import { FieldDef } from '../../fielddef'; +import { Formula } from '../../transform'; +import { Dict, StringSet } from '../../util'; +import { VgData, VgSort, VgTransform } from '../../vega.schema'; +import { FacetModel } from './../facet'; +import { LayerModel } from './../layer'; +import { Model } from './../model'; +import { UnitModel } from './../unit'; +import { StackComponent } from './stack'; +/** + * Composable component instance of a model's data. + */ +export interface DataComponent { + source: VgData; + /** Mapping from field name to primitive data type. */ + formatParse: Dict; + /** String set of fields for null filtering */ + nullFilter: Dict; + /** Hashset of a formula object */ + calculate: Dict; + /** Filter test expression */ + filter: string; + /** Dictionary mapping a bin parameter hash to transforms of the binned field */ + bin: Dict; + /** Dictionary mapping an output field name (hash) to the time unit transform */ + timeUnit: Dict; + /** String set of fields to be filtered */ + nonPositiveFilter: Dict; + /** Sort order to apply at the end */ + pathOrder: VgSort; + /** + * Stack transforms to be applied. + */ + stack: StackComponent; + /** Array of summary component object for producing summary (aggregate) data source */ + summary: SummaryComponent[]; +} +/** + * Composable component for a model's summary data + */ +export interface SummaryComponent { + /** Name of the summary data source */ + name: string; + /** String set for all dimension fields */ + dimensions: StringSet; + /** dictionary mapping field name to string set of aggregate ops */ + measures: Dict; +} +export declare function parseUnitData(model: UnitModel): DataComponent; +export declare function parseFacetData(model: FacetModel): DataComponent; +export declare function parseLayerData(model: LayerModel): DataComponent; +/** + * Creates Vega Data array from a given compiled model and append all of them to the given array + * + * @param model + * @param data array + * @return modified data array + */ +export declare function assembleData(model: Model, data: VgData[]): VgData[]; diff --git a/build/src/compile/data/data.js b/build/src/compile/data/data.js new file mode 100644 index 0000000000..b27f073512 --- /dev/null +++ b/build/src/compile/data/data.js @@ -0,0 +1,115 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var source_1 = require("./source"); +var formatparse_1 = require("./formatparse"); +var nullfilter_1 = require("./nullfilter"); +var filter_1 = require("./filter"); +var bin_1 = require("./bin"); +var formula_1 = require("./formula"); +var pathorder_1 = require("./pathorder"); +var nonpositivefilter_1 = require("./nonpositivefilter"); +var summary_1 = require("./summary"); +var stack_1 = require("./stack"); +var timeunit_1 = require("./timeunit"); +// TODO: split this file into multiple files and remove this linter flag +/* tslint:disable:no-use-before-declare */ +function parseUnitData(model) { + return { + formatParse: formatparse_1.formatParse.parseUnit(model), + nullFilter: nullfilter_1.nullFilter.parseUnit(model), + filter: filter_1.filter.parseUnit(model), + nonPositiveFilter: nonpositivefilter_1.nonPositiveFilter.parseUnit(model), + pathOrder: pathorder_1.pathOrder.parseUnit(model), + source: source_1.source.parseUnit(model), + bin: bin_1.bin.parseUnit(model), + calculate: formula_1.formula.parseUnit(model), + timeUnit: timeunit_1.timeUnit.parseUnit(model), + summary: summary_1.summary.parseUnit(model), + stack: stack_1.stack.parseUnit(model) + }; +} +exports.parseUnitData = parseUnitData; +function parseFacetData(model) { + return { + formatParse: formatparse_1.formatParse.parseFacet(model), + nullFilter: nullfilter_1.nullFilter.parseFacet(model), + filter: filter_1.filter.parseFacet(model), + nonPositiveFilter: nonpositivefilter_1.nonPositiveFilter.parseFacet(model), + pathOrder: pathorder_1.pathOrder.parseFacet(model), + source: source_1.source.parseFacet(model), + bin: bin_1.bin.parseFacet(model), + calculate: formula_1.formula.parseFacet(model), + timeUnit: timeunit_1.timeUnit.parseFacet(model), + summary: summary_1.summary.parseFacet(model), + stack: stack_1.stack.parseFacet(model) + }; +} +exports.parseFacetData = parseFacetData; +function parseLayerData(model) { + return { + // filter and formatParse could cause us to not be able to merge into parent + // so let's parse them first + filter: filter_1.filter.parseLayer(model), + formatParse: formatparse_1.formatParse.parseLayer(model), + nullFilter: nullfilter_1.nullFilter.parseLayer(model), + nonPositiveFilter: nonpositivefilter_1.nonPositiveFilter.parseLayer(model), + pathOrder: pathorder_1.pathOrder.parseLayer(model), + // everything after here does not affect whether we can merge child data into parent or not + source: source_1.source.parseLayer(model), + bin: bin_1.bin.parseLayer(model), + calculate: formula_1.formula.parseLayer(model), + timeUnit: timeunit_1.timeUnit.parseLayer(model), + summary: summary_1.summary.parseLayer(model), + stack: stack_1.stack.parseLayer(model) + }; +} +exports.parseLayerData = parseLayerData; +/* tslint:enable:no-use-before-declare */ +/** + * Creates Vega Data array from a given compiled model and append all of them to the given array + * + * @param model + * @param data array + * @return modified data array + */ +function assembleData(model, data) { + var dataComponent = model.component.data; + var sourceData = source_1.source.assemble(dataComponent); + if (sourceData) { + data.push(sourceData); + } + summary_1.summary.assemble(dataComponent.summary || [], model.dataName(data_1.SOURCE)).forEach(function (summaryData) { + data.push(summaryData); + }); + // nonPositiveFilter + var nonPositiveFilterTransform = nonpositivefilter_1.nonPositiveFilter.assemble(dataComponent.nonPositiveFilter); + if (nonPositiveFilterTransform.length > 0) { + if (data.length > 0) { + var dataTable = data[data.length - 1]; + dataTable.transform = (dataTable.transform || []).concat(nonPositiveFilterTransform); + } + else { + throw new Error('Invalid nonPositiveFilter not merged'); + } + } + // stack + var stackData = stack_1.stack.assemble(dataComponent.stack); + if (stackData) { + data.push(stackData); + } + // Path Order + var pathOrderCollectTransform = pathorder_1.pathOrder.assemble(dataComponent.pathOrder); + if (pathOrderCollectTransform) { + var dataTable = data[data.length - 1]; + if (data.length > 0) { + dataTable.transform = (dataTable.transform || []).concat([pathOrderCollectTransform]); + } + else { + throw new Error('Invalid path order collect transform not added'); + } + } + return data; +} +exports.assembleData = assembleData; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQUFrQztBQVdsQyxtQ0FBZ0M7QUFDaEMsNkNBQTBDO0FBQzFDLDJDQUF3QztBQUN4QyxtQ0FBZ0M7QUFDaEMsNkJBQTBCO0FBQzFCLHFDQUFrQztBQUNsQyx5Q0FBc0M7QUFDdEMseURBQXNEO0FBQ3RELHFDQUFrQztBQUNsQyxpQ0FBOEM7QUFDOUMsdUNBQW9DO0FBdURwQyx3RUFBd0U7QUFDeEUsMENBQTBDO0FBRTFDLHVCQUE4QixLQUFnQjtJQUM1QyxNQUFNLENBQUM7UUFDTCxXQUFXLEVBQUUseUJBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ3pDLFVBQVUsRUFBRSx1QkFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDdkMsTUFBTSxFQUFFLGVBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQy9CLGlCQUFpQixFQUFFLHFDQUFpQixDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDckQsU0FBUyxFQUFFLHFCQUFTLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUVyQyxNQUFNLEVBQUUsZUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDL0IsR0FBRyxFQUFFLFNBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ3pCLFNBQVMsRUFBRSxpQkFBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDbkMsUUFBUSxFQUFFLG1CQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztRQUNuQyxPQUFPLEVBQUUsaUJBQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ2pDLEtBQUssRUFBRSxhQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztLQUM5QixDQUFDO0FBQ0osQ0FBQztBQWZELHNDQWVDO0FBRUQsd0JBQStCLEtB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 \ No newline at end of file diff --git a/build/src/compile/data/filter.d.ts b/build/src/compile/data/filter.d.ts new file mode 100644 index 0000000000..89c06b1667 --- /dev/null +++ b/build/src/compile/data/filter.d.ts @@ -0,0 +1,2 @@ +import { DataComponentCompiler } from './base'; +export declare const filter: DataComponentCompiler; diff --git a/build/src/compile/data/filter.js b/build/src/compile/data/filter.js new file mode 100644 index 0000000000..fa69b97767 --- /dev/null +++ b/build/src/compile/data/filter.js @@ -0,0 +1,61 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var filter_1 = require("../../filter"); +var util_1 = require("../../util"); +/** + * @param v value to be converted into Vega Expression + * @param timeUnit + * @return Vega Expression of the value v. This could be one of: + * - a timestamp value of datetime object + * - a timestamp value of casted single time unit value + * - stringified value + */ +function parse(model) { + var filter = model.filter(); + if (util_1.isArray(filter)) { + return '(' + + filter.map(function (f) { return filter_1.expression(f); }) + .filter(function (f) { return f !== undefined; }) + .join(') && (') + + ')'; + } + else if (filter) { + return filter_1.expression(filter); + } + return undefined; +} +exports.filter = { + parseUnit: parse, + parseFacet: function (model) { + var filterComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source but has filter, then merge + if (!childDataComponent.source && childDataComponent.filter) { + // merge by adding && + filterComponent = + (filterComponent ? filterComponent + ' && ' : '') + + childDataComponent.filter; + delete childDataComponent.filter; + } + return filterComponent; + }, + parseLayer: function (model) { + // Note that this `filter.parseLayer` method is called before `source.parseLayer` + var filterComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && childDataComponent.filter && childDataComponent.filter === filterComponent) { + // same filter in child so we can just delete it + delete childDataComponent.filter; + } + }); + return filterComponent; + }, + assemble: function (filterComponent) { + return filterComponent ? [{ + type: 'filter', + expr: filterComponent + }] : []; + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9maWx0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSx1Q0FBd0M7QUFDeEMsbUNBQW1DO0FBTW5DOzs7Ozs7O0dBT0c7QUFFSCxlQUFlLEtBQVk7SUFDekIsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzlCLEVBQUUsQ0FBQyxDQUFDLGNBQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsTUFBTSxDQUFDLEdBQUc7WUFDUixNQUFNLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsbUJBQVUsQ0FBQyxDQUFDLENBQUMsRUFBYixDQUFhLENBQUM7aUJBQzdCLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsS0FBSSxTQUFTLEVBQWQsQ0FBYyxDQUFDO2lCQUM3QixJQUFJLENBQUMsUUFBUSxDQUFDO1lBQ2pCLEdBQUcsQ0FBQztJQUNSLENBQUM7SUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNsQixNQUFNLENBQUMsbUJBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBQ0QsTUFBTSxDQUFDLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRVksUUFBQSxNQUFNLEdBQWtDO0lBQ25ELFNBQVMsRUFBRSxLQUFLO0lBRWhCLFVBQVUsRUFBRSxVQUFTLEtBQWlCO1FBQ3BDLElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVuQyxJQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQztRQUV0RCx1RUFBdUU7UUFDdkUsRUFBRSxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLElBQUksa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUM1RCxxQkFBcUI7WUFDckIsZUFBZTtnQkFDYixDQUFDLGVBQWUsR0FBRyxlQUFlLEdBQUcsTUFBTSxHQUFHLEVBQUUsQ0FBQztvQkFDakQsa0JBQWtCLENBQUMsTUFBTSxDQUFDO1lBQzVCLE9BQU8sa0JBQWtCLENBQUMsTUFBTSxDQUFDO1FBQ25DLENBQUM7UUFDRCxNQUFNLENBQUMsZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxVQUFVLEVBQUUsVUFBUyxLQUFpQjtRQUNwQyxpRkFBaUY7UUFDakYsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25DLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUMzQixJQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2hELEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxNQUFNLElBQUksa0JBQWtCLENBQUMsTUFBTSxLQUFLLGVBQWUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hILGdEQUFnRDtnQkFDaEQsT0FBTyxrQkFBa0IsQ0FBQyxNQUFNLENBQUM7WUFDbkMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLGVBQWUsQ0FBQztJQUN6QixDQUFDO0lBRUQsUUFBUSxFQUFFLFVBQVMsZUFBdUI7UUFDeEMsTUFBTSxDQUFDLGVBQWUsR0FBRyxDQUFDO2dCQUN4QixJQUFJLEVBQUUsUUFBUTtnQkFDZCxJQUFJLEVBQUUsZUFBZTthQUN0QixDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ1YsQ0FBQztDQUNGLENBQUMifQ== \ No newline at end of file diff --git a/build/src/compile/data/formatparse.d.ts b/build/src/compile/data/formatparse.d.ts new file mode 100644 index 0000000000..693ea93932 --- /dev/null +++ b/build/src/compile/data/formatparse.d.ts @@ -0,0 +1,3 @@ +import { DataComponentCompiler } from './base'; +import { Dict } from '../../util'; +export declare const formatParse: DataComponentCompiler>; diff --git a/build/src/compile/data/formatparse.js b/build/src/compile/data/formatparse.js new file mode 100644 index 0000000000..a45d0a9bf5 --- /dev/null +++ b/build/src/compile/data/formatparse.js @@ -0,0 +1,96 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("../../datetime"); +var data_1 = require("../../data"); +var fielddef_1 = require("../../fielddef"); +var filter_1 = require("../../filter"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function parse(model) { + var calcFieldMap = (model.calculate() || []).reduce(function (fieldMap, formula) { + fieldMap[formula.as] = true; + return fieldMap; + }, {}); + var parseComponent = {}; + // Parse filter fields + var filter = model.filter(); + if (!util_1.isArray(filter)) { + filter = [filter]; + } + filter.forEach(function (f) { + var val = null; + // For EqualFilter, just use the equal property. + // For RangeFilter and OneOfFilter, all array members should have + // the same type, so we only use the first one. + if (filter_1.isEqualFilter(f)) { + val = f.equal; + } + else if (filter_1.isRangeFilter(f)) { + val = f.range[0]; + } + else if (filter_1.isOneOfFilter(f)) { + val = (f.oneOf || f['in'])[0]; + } // else -- for filter expression, we can't infer anything + if (!!val) { + if (datetime_1.isDateTime(val)) { + parseComponent[f['field']] = 'date'; + } + else if (util_1.isNumber(val)) { + parseComponent[f['field']] = 'number'; + } + else if (util_1.isString(val)) { + parseComponent[f['field']] = 'string'; + } + } + }); + // Parse encoded fields + model.forEachFieldDef(function (fieldDef) { + if (fieldDef.type === type_1.TEMPORAL) { + parseComponent[fieldDef.field] = 'date'; + } + else if (fieldDef.type === type_1.QUANTITATIVE) { + if (fielddef_1.isCount(fieldDef) || calcFieldMap[fieldDef.field]) { + return; + } + parseComponent[fieldDef.field] = 'number'; + } + }); + // Custom parse should override inferred parse + var data = model.data; + if (data && data_1.isUrlData(data) && data.format && data.format.parse) { + var parse_1 = data.format.parse; + util_1.keys(parse_1).forEach(function (field) { + parseComponent[field] = parse_1[field]; + }); + } + return parseComponent; +} +exports.formatParse = { + parseUnit: parse, + parseFacet: function (model) { + var parseComponent = parse(model); + // If child doesn't have its own data source, but has its own parse, then merge + var childDataComponent = model.child.component.data; + if (!childDataComponent.source && childDataComponent.formatParse) { + util_1.extend(parseComponent, childDataComponent.formatParse); + delete childDataComponent.formatParse; + } + return parseComponent; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + var parseComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && !util_1.differ(childDataComponent.formatParse, parseComponent)) { + // merge parse up if the child does not have an incompatible parse + util_1.extend(parseComponent, childDataComponent.formatParse); + delete childDataComponent.formatParse; + } + }); + return parseComponent; + }, + // identity function + assemble: function (x) { return x; } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0cGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL2Zvcm1hdHBhcnNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsMkNBQW9EO0FBQ3BELG1DQUFxQztBQUNyQywyQ0FBaUQ7QUFDakQsdUNBQXlFO0FBQ3pFLG1DQUFrRDtBQUNsRCxtQ0FBbUY7QUFNbkYsZUFBZSxLQUFZO0lBQ3pCLElBQU0sWUFBWSxHQUFHLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFTLFFBQVEsRUFBRSxPQUFPO1FBQzlFLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDbEIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRVAsSUFBSSxjQUFjLEdBQWlCLEVBQUUsQ0FBQztJQUV0QyxzQkFBc0I7SUFDdEIsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzVCLEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNwQixDQUFDO0lBQ0QsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFBLENBQUM7UUFDZCxJQUFJLEdBQUcsR0FBeUMsSUFBSSxDQUFDO1FBQ3JELGdEQUFnRDtRQUNoRCxpRUFBaUU7UUFDakUsK0NBQStDO1FBQy9DLEVBQUUsQ0FBQyxDQUFDLHNCQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLEdBQUcsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ2hCLENBQUM7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsc0JBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFD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 \ No newline at end of file diff --git a/build/src/compile/data/formula.d.ts b/build/src/compile/data/formula.d.ts new file mode 100644 index 0000000000..9767eec7d4 --- /dev/null +++ b/build/src/compile/data/formula.d.ts @@ -0,0 +1,4 @@ +import { DataComponentCompiler } from './base'; +import { Formula } from '../../transform'; +import { Dict } from '../../util'; +export declare const formula: DataComponentCompiler>; diff --git a/build/src/compile/data/formula.js b/build/src/compile/data/formula.js new file mode 100644 index 0000000000..94c59706fb --- /dev/null +++ b/build/src/compile/data/formula.js @@ -0,0 +1,40 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +function parse(model) { + return (model.calculate() || []).reduce(function (formulaComponent, formula) { + formulaComponent[util_1.hash(formula)] = formula; + return formulaComponent; + }, {}); +} +exports.formula = { + parseUnit: parse, + parseFacet: function (model) { + var formulaComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(formulaComponent, childDataComponent.calculate); + delete childDataComponent.calculate; + } + return formulaComponent; + }, + parseLayer: function (model) { + var formulaComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (!childDataComponent.source && childDataComponent.calculate) { + util_1.extend(formulaComponent || {}, childDataComponent.calculate); + delete childDataComponent.calculate; + } + }); + return formulaComponent; + }, + assemble: function (component) { + return util_1.vals(component).reduce(function (transform, f) { + transform.push(util_1.extend({ type: 'formula' }, f)); + return transform; + }, []); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybXVsYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvZm9ybXVsYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUdBLG1DQUFvRDtBQU1wRCxlQUFlLEtBQVk7SUFDekIsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFTLGdCQUFnQixFQUFFLE9BQU87UUFDeEUsZ0JBQWdCLENBQUMsV0FBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztJQUMxQixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDVCxDQUFDO0FBRVksUUFBQSxPQUFPLEdBQXlDO0lBQzNELFNBQVMsRUFBRSxLQUFLO0lBRWhCLFVBQVUsRUFBRSxVQUFTLEtBQWlCO1FBQ3BDLElBQUksZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXBDLElBQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1FBRXRELHdEQUF3RDtRQUN4RCxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDL0IsYUFBTSxDQUFDLGdCQUFnQixFQUFFLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3ZELE9BQU8sa0JBQWtCLENBQUMsU0FBUyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxNQUFNLENBQUMsZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQztJQUVELFVBQVUsRUFBRSxVQUFTLEtBQWlCO1FBQ3BDLElBQUksZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUMzQixJQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2hELEVBQUUsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsTUFBTSxJQUFJLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9ELGFBQU0sQ0FBQyxnQkFBZ0IsSUFBSSxFQUFFLEVBQUUsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQzdELE9BQU8sa0JBQWtCLENBQUMsU0FBUyxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztJQUMxQixDQUFDO0lBRUQsUUFBUSxFQUFFLFVBQVMsU0FBd0I7UUFDekMsTUFBTSxDQUFDLFdBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBUyxTQUFjLEVBQUUsQ0FBTTtZQUMzRCxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQU0sQ0FBQyxFQUFDLElBQUksRUFBRSxTQUFTLEVBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDbkIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1QsQ0FBQztDQUNGLENBQUMifQ== \ No newline at end of file diff --git a/build/src/compile/data/nonpositivefilter.d.ts b/build/src/compile/data/nonpositivefilter.d.ts new file mode 100644 index 0000000000..9764ce9670 --- /dev/null +++ b/build/src/compile/data/nonpositivefilter.d.ts @@ -0,0 +1,3 @@ +import { DataComponentCompiler } from './base'; +import { Dict } from '../../util'; +export declare const nonPositiveFilter: DataComponentCompiler>; diff --git a/build/src/compile/data/nonpositivefilter.js b/build/src/compile/data/nonpositivefilter.js new file mode 100644 index 0000000000..23993f583c --- /dev/null +++ b/build/src/compile/data/nonpositivefilter.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +exports.nonPositiveFilter = { + parseUnit: function (model) { + return model.channels().reduce(function (nonPositiveComponent, channel) { + var scale = model.scale(channel); + if (!model.field(channel) || !scale) { + // don't set anything + return nonPositiveComponent; + } + nonPositiveComponent[model.field(channel)] = scale.type === scale_1.ScaleType.LOG; + return nonPositiveComponent; + }, {}); + }, + parseFacet: function (model) { + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then consider merging + if (!childDataComponent.source) { + // For now, let's assume it always has union scale + var nonPositiveFilterComponent = childDataComponent.nonPositiveFilter; + delete childDataComponent.nonPositiveFilter; + return nonPositiveFilterComponent; + } + return {}; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + var nonPositiveFilterComponent = {}; + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && !util_1.differ(childDataComponent.nonPositiveFilter, nonPositiveFilterComponent)) { + util_1.extend(nonPositiveFilterComponent, childDataComponent.nonPositiveFilter); + delete childDataComponent.nonPositiveFilter; + } + }); + return nonPositiveFilterComponent; + }, + assemble: function (nonPositiveFilterComponent) { + if (nonPositiveFilterComponent) { + return util_1.keys(nonPositiveFilterComponent).filter(function (field) { + // Only filter fields (keys) with value = true + return nonPositiveFilterComponent[field]; + }).map(function (field) { + return { + type: 'filter', + expr: 'datum["' + field + '"] > 0' + }; + }); + } + return []; + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9ucG9zaXRpdmVmaWx0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL25vbnBvc2l0aXZlZmlsdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEscUNBQXNDO0FBQ3RDLG1DQUFzRDtBQU96QyxRQUFBLGlCQUFpQixHQUF5QztJQUNyRSxTQUFTLEVBQUUsVUFBUyxLQUFZO1FBQzlCLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVMsb0JBQW9CLEVBQUUsT0FBTztZQUNuRSxJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ25DLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLHFCQUFxQjtnQkFDckIsTUFBTSxDQUFDLG9CQUFvQixDQUFDO1lBQzlCLENBQUM7WUFDRCxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksS0FBSyxpQkFBUyxDQUFDLEdBQUcsQ0FBQztZQUMxRSxNQUFNLENBQUMsb0JBQW9CLENBQUM7UUFDOUIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1QsQ0FBQztJQUVELFVBQVUsRUFBRSxVQUFTLEtBQWlCO1FBQ3BDLElBQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1FBRXRELG1FQUFtRTtRQUNuRSxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDL0Isa0RBQWtEO1lBQ2xELElBQU0sMEJBQTBCLEdBQUcsa0JBQWtCLENBQUMsaUJBQWlCLENBQUM7WUFDeEUsT0FBTyxrQkFBa0IsQ0FBQyxpQkFBaUIsQ0FBQztZQUM1QyxNQUFNLENBQUMsMEJBQTBCLENBQUM7UUFDcEMsQ0FBQztRQUNELE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsVUFBVSxFQUFFLFVBQVMsS0FBaUI7UUFDcEMsaURBQWlEO1FBQ2pELElBQUksMEJBQTBCLEdBQUcsRUFBRSxDQUFDO1FBRXBDLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUMzQixJQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2hELEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQU0sQ0FBQyxrQkFBa0IsQ0FBQyxpQkFBaUIsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDL0csYUFBTSxDQUFDLDBCQUEwQixFQUFFLGtCQUFrQixDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0JBQ3pFLE9BQU8sa0JBQWtCLENBQUMsaUJBQWlCLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLDBCQUEwQixDQUFDO0lBQ3BDLENBQUM7SUFFRCxRQUFRLEVBQUUsVUFBUywwQkFBeUM7UUFDMUQsRUFBRSxDQUFDLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sQ0FBQyxXQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxNQUFNLENBQUMsVUFBQyxLQUFLO2dCQUNuRCw4Q0FBOEM7Z0JBQzlDLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBUyxLQUFLO2dCQUNuQixNQUFNLENBQUM7b0JBQ0wsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsSUFBSSxFQUFFLFNBQVMsR0FBRyxLQUFLLEdBQUcsUUFBUTtpQkFDbkMsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDWixDQUFDO0NBQ0YsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/compile/data/nullfilter.d.ts b/build/src/compile/data/nullfilter.d.ts new file mode 100644 index 0000000000..7c2296b0e1 --- /dev/null +++ b/build/src/compile/data/nullfilter.d.ts @@ -0,0 +1,4 @@ +import { DataComponentCompiler } from './base'; +import { FieldDef } from '../../fielddef'; +import { Dict } from '../../util'; +export declare const nullFilter: DataComponentCompiler>; diff --git a/build/src/compile/data/nullfilter.js b/build/src/compile/data/nullfilter.js new file mode 100644 index 0000000000..6161abef4d --- /dev/null +++ b/build/src/compile/data/nullfilter.js @@ -0,0 +1,75 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var DEFAULT_NULL_FILTERS = { + nominal: false, + ordinal: false, + quantitative: true, + temporal: true +}; +/** Return Hashset of fields for null filtering (key=field, value = true). */ +function parse(model) { + var filterInvalid = model.filterInvalid(); + return model.reduceFieldDef(function (aggregator, fieldDef) { + if (fieldDef.field !== '*') { + if (filterInvalid || + (filterInvalid === undefined && fieldDef.field && DEFAULT_NULL_FILTERS[fieldDef.type])) { + aggregator[fieldDef.field] = fieldDef; + } + else { + // define this so we know that we don't filter nulls for this field + // this makes it easier to merge into parents + aggregator[fieldDef.field] = null; + } + } + return aggregator; + }, {}); +} +exports.nullFilter = { + parseUnit: parse, + parseFacet: function (model) { + var nullFilterComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(nullFilterComponent, childDataComponent.nullFilter); + delete childDataComponent.nullFilter; + } + return nullFilterComponent; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + // FIXME: null filters are not properly propagated right now + var nullFilterComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && !util_1.differ(childDataComponent.nullFilter, nullFilterComponent)) { + util_1.extend(nullFilterComponent, childDataComponent.nullFilter); + delete childDataComponent.nullFilter; + } + }); + return nullFilterComponent; + }, + assemble: function (component) { + var filters = util_1.keys(component).reduce(function (_filters, field) { + var fieldDef = component[field]; + if (fieldDef !== null) { + _filters.push('datum["' + fieldDef.field + '"] !== null'); + if (util_1.contains([type_1.QUANTITATIVE, type_1.TEMPORAL], fieldDef.type)) { + // TODO(https://github.com/vega/vega-lite/issues/1436): + // We can be even smarter and add NaN filter for N,O that are numbers + // based on the `parse` property once we have it. + _filters.push('!isNaN(datum["' + fieldDef.field + '"])'); + } + } + return _filters; + }, []); + return filters.length > 0 ? + [{ + type: 'filter', + expr: filters.join(' && ') + }] : []; + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVsbGZpbHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvbnVsbGZpbHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUdBLG1DQUFrRDtBQUNsRCxtQ0FBZ0U7QUFNaEUsSUFBTSxvQkFBb0IsR0FBRztJQUMzQixPQUFPLEVBQUUsS0FBSztJQUNkLE9BQU8sRUFBRSxLQUFLO0lBQ2QsWUFBWSxFQUFFLElBQUk7SUFDbEIsUUFBUSxFQUFFLElBQUk7Q0FDZixDQUFDO0FBRUYsNkVBQTZFO0FBQzdFLGVBQWUsS0FBWTtJQUN6QixJQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7SUFFNUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsVUFBUyxVQUEwQixFQUFFLFFBQWtCO1FBQ2pGLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztZQUMzQixFQUFFLENBQUMsQ0FBQyxhQUFhO2dCQUNmLENBQUMsYUFBYSxLQUFLLFNBQVMsSUFBSSxRQUFRLENBQUMsS0FBSyxJQUFJLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDekYsVUFBVSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxRQUFRLENBQUM7WUFDeEMsQ0FBQztZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNOLG1FQUFtRTtnQkFDbkUsNkNBQTZDO2dCQUM3QyxVQUFVLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQztZQUNwQyxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sQ0FBQyxVQUFVLENBQUM7SUFDcEIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ1QsQ0FBQztBQUVZLFFBQUEsVUFBVSxHQUEwQztJQUMvRCxTQUFTLEVBQUUsS0FBSztJQUVoQixVQUFVLEVB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 \ No newline at end of file diff --git a/build/src/compile/data/pathorder.d.ts b/build/src/compile/data/pathorder.d.ts new file mode 100644 index 0000000000..f040be79c7 --- /dev/null +++ b/build/src/compile/data/pathorder.d.ts @@ -0,0 +1,3 @@ +import { DataComponentCompiler } from './base'; +import { VgSort } from '../../vega.schema'; +export declare const pathOrder: DataComponentCompiler; diff --git a/build/src/compile/data/pathorder.js b/build/src/compile/data/pathorder.js new file mode 100644 index 0000000000..04c5fd0c87 --- /dev/null +++ b/build/src/compile/data/pathorder.js @@ -0,0 +1,84 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var sort_1 = require("../../sort"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +exports.pathOrder = { + parseUnit: function (model) { + if (util_1.contains(['line', 'area'], model.mark())) { + if (model.mark() === 'line' && model.channelHasField('order')) { + // For only line, sort by the order field if it is specified. + return common_1.sortParams(model.encoding.order); + } + else { + // For both line and area, we sort values based on dimension by default + var dimensionChannel = model.markDef.orient === 'horizontal' ? 'y' : 'x'; + var sort = model.sort(dimensionChannel); + var sortField = sort_1.isSortField(sort) ? + fielddef_1.field({ + // FIXME: this op might not already exist? + // FIXME: what if dimensionChannel (x or y) contains custom domain? + aggregate: encoding_1.isAggregate(model.encoding) ? sort.op : undefined, + field: sort.field + }) : + model.field(dimensionChannel, { binSuffix: 'start' }); + return { + field: sortField, + order: 'descending' + }; + } + } + return null; + }, + parseFacet: function (model) { + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then consider merging + if (!childDataComponent.source) { + // For now, let's assume it always has union scale + var pathOrderComponent = childDataComponent.pathOrder; + delete childDataComponent.pathOrder; + return pathOrderComponent; + } + return null; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + var pathOrderComponent = null; + var stringifiedPathOrder = null; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && childDataComponent.pathOrder !== null) { + if (pathOrderComponent === null) { + pathOrderComponent = childDataComponent.pathOrder; + stringifiedPathOrder = stringify(pathOrderComponent); + } + else if (stringifiedPathOrder !== stringify(childDataComponent.pathOrder)) { + pathOrderComponent = null; + break; + } + } + } + if (pathOrderComponent !== null) { + // If we merge pathOrderComponent, remove them from children. + for (var _b = 0, _c = model.children; _b < _c.length; _b++) { + var child = _c[_b]; + delete child.component.data.pathOrder; + } + } + return pathOrderComponent; + }, + assemble: function (pathOrderComponent) { + if (pathOrderComponent) { + return { + type: 'collect', + sort: pathOrderComponent + }; + } + return null; + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aG9yZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9wYXRob3JkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpREFBbUQ7QUFJbkQsMkNBQTJDO0FBQzNDLDJDQUFxQztBQUNyQyxtQ0FBdUM7QUFFdkMsbUNBQW9DO0FBRXBDLG9DQUFxQztBQUt4QixRQUFBLFNBQVMsR0FBa0M7SUFDdEQsU0FBUyxFQUFFLFVBQVMsS0FBZ0I7UUFDbEMsRUFBRSxDQUFDLENBQUMsZUFBUSxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssTUFBTSxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM5RCw2REFBNkQ7Z0JBQzdELE1BQU0sQ0FBQyxtQkFBVSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUMsQ0FBQztZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNOLHVFQUF1RTtnQkFDdkUsSUFBTSxnQkFBZ0IsR0FBYyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxZQUFZLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQztnQkFDdEYsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUMxQyxJQUFNLFNBQVMsR0FBRyxrQkFBVyxDQUFDLElBQUksQ0FBQztvQkFDakMsZ0JBQUssQ0FBQzt3QkFDSiwwQ0FBMEM7d0JBQzFDLG1FQUFtRTt3QkFDbkUsU0FBUyxFQUFFLHNCQUFXLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsU0FBUzt3QkFDNUQsS0FB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 \ No newline at end of file diff --git a/build/src/compile/data/source.d.ts b/build/src/compile/data/source.d.ts new file mode 100644 index 0000000000..c8d48dfae0 --- /dev/null +++ b/build/src/compile/data/source.d.ts @@ -0,0 +1,11 @@ +import { VgData } from '../../vega.schema'; +import { FacetModel } from '../facet'; +import { LayerModel } from '../layer'; +import { Model } from './../model'; +import { DataComponent } from './data'; +export declare namespace source { + const parseUnit: (model: Model) => VgData; + function parseFacet(model: FacetModel): VgData; + function parseLayer(model: LayerModel): VgData; + function assemble(component: DataComponent): VgData; +} diff --git a/build/src/compile/data/source.js b/build/src/compile/data/source.js new file mode 100644 index 0000000000..e90399028a --- /dev/null +++ b/build/src/compile/data/source.js @@ -0,0 +1,101 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var nullfilter_1 = require("./nullfilter"); +var filter_1 = require("./filter"); +var bin_1 = require("./bin"); +var formula_1 = require("./formula"); +var timeunit_1 = require("./timeunit"); +var source; +(function (source) { + function parse(model) { + var data = model.data; + if (data) { + // If data is explicitly provided + var sourceData = { name: model.dataName(data_1.SOURCE) }; + if (data_1.isInlineData(data)) { + sourceData.values = data.values; + sourceData.format = { type: 'json' }; + } + else if (data_1.isUrlData(data)) { + sourceData.url = data.url; + // Extract extension from URL using snippet from + // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript + var defaultExtension = /(?:\.([^.]+))?$/.exec(sourceData.url)[1]; + if (!util_1.contains(['json', 'csv', 'tsv', 'topojson'], defaultExtension)) { + defaultExtension = 'json'; + } + var dataFormat = data.format || {}; + // For backward compatibility for former `data.formatType` property + var formatType = dataFormat.type || data['formatType']; + sourceData.format = + util_1.extend({ type: formatType ? formatType : defaultExtension }, dataFormat.property ? { property: dataFormat.property } : {}, + // Feature and mesh are two mutually exclusive properties + dataFormat.feature ? + { feature: dataFormat.feature } : + dataFormat.mesh ? + { mesh: dataFormat.mesh } : + {}); + } + else if (data_1.isNamedData(data)) { + return { name: data.name }; + } + return sourceData; + } + else if (!model.parent) { + // If data is not explicitly provided but the model is a root, + // need to produce a source as well + return { name: model.dataName(data_1.SOURCE) }; + } + return undefined; + } + source.parseUnit = parse; + function parseFacet(model) { + var sourceData = parse(model); + if (!model.child.component.data.source) { + // If the child does not have its own source, have to rename its source. + model.child.renameData(model.child.dataName(data_1.SOURCE), model.dataName(data_1.SOURCE)); + } + return sourceData; + } + source.parseFacet = parseFacet; + function parseLayer(model) { + var sourceData = parse(model); + model.children.forEach(function (child) { + var childData = child.component.data; + if (model.compatibleSource(child)) { + // we cannot merge if the child has filters defined even after we tried to move them up + var canMerge = !childData.filter && !childData.formatParse && !childData.nullFilter; + if (canMerge) { + // rename source because we can just remove it + child.renameData(child.dataName(data_1.SOURCE), model.dataName(data_1.SOURCE)); + delete childData.source; + } + else { + // child does not have data defined or the same source so just use the parents source + childData.source = { + name: child.dataName(data_1.SOURCE), + source: model.dataName(data_1.SOURCE) + }; + } + } + }); + return sourceData; + } + source.parseLayer = parseLayer; + function assemble(component) { + if (component.source) { + var sourceData = component.source; + if (component.formatParse) { + component.source.format = component.source.format || {}; + component.source.format.parse = component.formatParse; + } + sourceData.transform = [].concat(formula_1.formula.assemble(component.calculate), nullfilter_1.nullFilter.assemble(component.nullFilter), filter_1.filter.assemble(component.filter), bin_1.bin.assemble(component.bin), timeunit_1.timeUnit.assemble(component.timeUnit)); + return sourceData; + } + return null; + } + source.assemble = assemble; +})(source = exports.source || (exports.source = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvZGF0YS9zb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxtQ0FBb0Y7QUFDcEYsbUNBQTRDO0FBUTVDLDJDQUF3QztBQUN4QyxtQ0FBZ0M7QUFDaEMsNkJBQTBCO0FBQzFCLHFDQUFrQztBQUNsQyx1Q0FBb0M7QUFFcEMsSUFBaUIsTUFBTSxDQXlHdEI7QUF6R0QsV0FBaUIsTUFBTTtJQUNyQixlQUFlLEtBQVk7UUFDekIsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztRQUV0QixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ1QsaUNBQWlDO1lBRWpDLElBQUksVUFBVSxHQUFXLEVBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsYUFBTSxDQUFDLEVBQUMsQ0FBQztZQUN4RCxFQUFFLENBQUMsQ0FBQyxtQkFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdkIsVUFBVSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUNoQyxVQUFVLENBQUMsTUFBTSxHQUFHLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBQyxDQUFDO1lBQ3JDLENBQUM7WUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsZ0JBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNCLFVBQVUsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztnQkFFMUIsZ0RBQWdEO2dCQUNoRCx3R0FBd0c7Z0JBQ3hHLElBQUksZ0JBQWdCLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakUsRUFBRSxDQUFDLENBQUMsQ0FBQyxlQUFRLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxF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 \ No newline at end of file diff --git a/build/src/compile/data/stack.d.ts b/build/src/compile/data/stack.d.ts new file mode 100644 index 0000000000..fe941f22e4 --- /dev/null +++ b/build/src/compile/data/stack.d.ts @@ -0,0 +1,39 @@ +import { DataComponentCompiler } from './base'; +import { StackOffset } from '../../stack'; +import { VgSort } from '../../vega.schema'; +export interface StackComponent { + /** + * Name of the output stacked data source + */ + name: string; + /** + * Name of the input source data for stacked data source + */ + source: string; + /** + * Grouping fields for stacked charts. This includes one of x- or 'y-field and may include faceted field. + */ + groupby: string[]; + /** + * Stack measure's field + */ + field: string; + /** + * Level of detail fields for each level in the stacked charts such as color or detail. + */ + stackby: string[]; + /** + * Field that determines order of levels in the stacked charts. + */ + sort: VgSort; + /** Mode for stacking marks. */ + offset: StackOffset; + /** + * Whether to impute the data before stacking. + */ + impute: boolean; +} +/** + * Stack data compiler + */ +export declare const stack: DataComponentCompiler; diff --git a/build/src/compile/data/stack.js b/build/src/compile/data/stack.js new file mode 100644 index 0000000000..419f1df65a --- /dev/null +++ b/build/src/compile/data/stack.js @@ -0,0 +1,134 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("../common"); +var data_1 = require("../../data"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +function getStackByFields(model) { + return model.stack.stackBy.reduce(function (fields, by) { + var channel = by.channel; + var fieldDef = by.fieldDef; + var scale = model.scale(channel); + var _field = fielddef_1.field(fieldDef, { + binSuffix: scale && scale_1.hasDiscreteDomain(scale.type) ? 'range' : 'start' + }); + if (!!_field) { + fields.push(_field); + } + return fields; + }, []); +} +/** + * Stack data compiler + */ +exports.stack = { + parseUnit: function (model) { + var stackProperties = model.stack; + if (!stackProperties) { + return undefined; + } + var groupby = []; + if (stackProperties.groupbyChannel) { + var groupbyFieldDef = model.fieldDef(stackProperties.groupbyChannel); + if (groupbyFieldDef.bin) { + // For Bin, we need to add both start and end to ensure that both get imputed + // and included in the stack output (https://github.com/vega/vega-lite/issues/1805). + groupby.push(model.field(stackProperties.groupbyChannel, { binSuffix: 'start' })); + groupby.push(model.field(stackProperties.groupbyChannel, { binSuffix: 'end' })); + } + else { + groupby.push(model.field(stackProperties.groupbyChannel)); + } + } + var stackby = getStackByFields(model); + var orderDef = model.encoding.order; + var sort; + if (orderDef) { + sort = common_1.sortParams(orderDef); + } + else { + // default = descending by stackFields + // FIXME is the default here correct for binned fields? + sort = stackby.reduce(function (s, field) { + s.field.push(field); + s.order.push('descending'); + return s; + }, { field: [], order: [] }); + } + return { + name: model.dataName(data_1.STACKED), + source: model.dataName(data_1.SUMMARY), + groupby: groupby, + field: model.field(stackProperties.fieldChannel), + stackby: stackby, + sort: sort, + offset: stackProperties.offset, + impute: util_1.contains(['area', 'line'], model.mark()) + }; + }, + parseLayer: function (model) { + // FIXME: merge if identical + // FIXME: Correctly support facet of layer of stack. + return undefined; + }, + parseFacet: function (model) { + var child = model.child; + var childDataComponent = child.component.data; + // FIXME: Correctly support facet of layer of stack. + if (childDataComponent.stack) { + var stackComponent = childDataComponent.stack; + var newName = model.dataName(data_1.STACKED); + child.renameData(stackComponent.name, newName); + stackComponent.name = newName; + // Refer to facet's summary instead (always summary because stacked only works with aggregation) + stackComponent.source = model.dataName(data_1.SUMMARY); + // Add faceted field to groupby + stackComponent.groupby = model.reduceFieldDef(function (groupby, fieldDef) { + var facetedField = fielddef_1.field(fieldDef, { binSuffix: 'start' }); + if (!util_1.contains(groupby, facetedField)) { + groupby.push(facetedField); + } + return groupby; + }, stackComponent.groupby); + delete childDataComponent.stack; + return stackComponent; + } + return undefined; + }, + assemble: function (stackComponent) { + if (!stackComponent) { + return undefined; + } + var transform = []; + // Impute + if (stackComponent.impute) { + transform.push({ + type: 'impute', + field: stackComponent.field, + groupby: stackComponent.stackby, + orderby: stackComponent.groupby, + method: 'value', + value: 0 + }); + } + // Stack + transform.push({ + type: 'stack', + groupby: stackComponent.groupby, + field: stackComponent.field, + sort: stackComponent.sort, + as: [ + stackComponent.field + '_start', + stackComponent.field + '_end' + ], + offset: stackComponent.offset + }); + return { + name: stackComponent.name, + source: stackComponent.source, + transform: transform + }; + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3N0YWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBTUEsb0NBQXFDO0FBQ3JDLG1DQUE0QztBQUM1QywyQ0FBK0M7QUFDL0MscUNBQThDO0FBRTlDLG1DQUFvQztBQTRDcEMsMEJBQTBCLEtBQWdCO0lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQyxNQUFNLEVBQUUsRUFBRTtRQUMzQyxJQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDO1FBQzNCLElBQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUM7UUFFN0IsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxJQUFNLE1BQU0sR0FBRyxnQkFBSyxDQUFDLFFBQVEsRUFBRTtZQUM3QixTQUFTLEVBQUUsS0FBSyxJQUFJLHlCQUFpQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLEdBQUcsT0FBTztTQUN0RSxDQUFDLENBQUM7UUFDSCxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNiLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEIsQ0FBQztRQUNELE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDaEIsQ0FBQyxFQUFFLEVBQWMsQ0FBQyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7R0FFRztBQUNVLFFBQUEsS0FBSyxHQUEwQztJQUUxRCxTQUFTLEVBQUUsVUFBUyxLQUFnQjtRQUNsQyxJQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQ3BDLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztZQUNyQixNQUFNLENBQUMsU0FBUyxDQUFDO1FB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 \ No newline at end of file diff --git a/build/src/compile/data/summary.d.ts b/build/src/compile/data/summary.d.ts new file mode 100644 index 0000000000..34a4b812c8 --- /dev/null +++ b/build/src/compile/data/summary.d.ts @@ -0,0 +1,15 @@ +import { VgData } from '../../vega.schema'; +import { FacetModel } from './../facet'; +import { LayerModel } from './../layer'; +import { Model } from './../model'; +import { SummaryComponent } from './data'; +export declare namespace summary { + function parseUnit(model: Model): SummaryComponent[]; + function parseFacet(model: FacetModel): SummaryComponent[]; + function parseLayer(model: LayerModel): SummaryComponent[]; + /** + * Assemble the summary. Needs a rename function because we cannot guarantee that the + * parent data before the children data. + */ + function assemble(component: SummaryComponent[], sourceName: string): VgData[]; +} diff --git a/build/src/compile/data/summary.js b/build/src/compile/data/summary.js new file mode 100644 index 0000000000..00a25608c2 --- /dev/null +++ b/build/src/compile/data/summary.js @@ -0,0 +1,164 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var summary; +(function (summary) { + function addDimension(dims, fieldDef) { + if (fieldDef.bin) { + dims[fielddef_1.field(fieldDef, { binSuffix: 'start' })] = true; + dims[fielddef_1.field(fieldDef, { binSuffix: 'end' })] = true; + // const scale = model.scale(channel); + // if (scaleType(scale, fieldDef, channel, model.mark()) === ScaleType.ORDINAL) { + // also produce bin_range if the binned field use ordinal scale + dims[fielddef_1.field(fieldDef, { binSuffix: 'range' })] = true; + // } + } + else { + dims[fielddef_1.field(fieldDef)] = true; + } + return dims; + } + function parseUnit(model) { + /* string set for dimensions */ + var dims = {}; + /* dictionary mapping field name => dict set of aggregation functions */ + var meas = {}; + model.forEachFieldDef(function (fieldDef, channel) { + if (fieldDef.aggregate) { + if (fieldDef.aggregate === 'count') { + meas['*'] = meas['*'] || {}; + /* tslint:disable:no-string-literal */ + meas['*']['count'] = true; + /* tslint:enable:no-string-literal */ + } + else { + meas[fieldDef.field] = meas[fieldDef.field] || {}; + meas[fieldDef.field][fieldDef.aggregate] = true; + // add min/max so we can use their union as unaggregated domain + var scale = model.scale(channel); + if (scale && scale.domain === 'unaggregated') { + meas[fieldDef.field]['min'] = true; + meas[fieldDef.field]['max'] = true; + } + } + } + else { + addDimension(dims, fieldDef); + } + ; + }); + return [{ + name: model.dataName(data_1.SUMMARY), + dimensions: dims, + measures: meas + }]; + } + summary.parseUnit = parseUnit; + function parseFacet(model) { + var childDataComponent = model.child.component.data; + // FIXME: this could be incorrect for faceted layer charts. + // If child doesn't have its own data source but has a summary data source, merge + if (!childDataComponent.source && childDataComponent.summary) { + var summaryComponents = childDataComponent.summary.map(function (summaryComponent) { + // add facet fields as dimensions + summaryComponent.dimensions = model.reduceFieldDef(addDimension, summaryComponent.dimensions); + var summaryNameWithoutPrefix = summaryComponent.name.substr(model.child.getName('').length); + model.child.renameData(summaryComponent.name, summaryNameWithoutPrefix); + summaryComponent.name = summaryNameWithoutPrefix; + return summaryComponent; + }); + delete childDataComponent.summary; + return summaryComponents; + } + return []; + } + summary.parseFacet = parseFacet; + function mergeMeasures(parentMeasures, childMeasures) { + for (var field_1 in childMeasures) { + if (childMeasures.hasOwnProperty(field_1)) { + // when we merge a measure, we either have to add an aggregation operator or even a new field + var ops = childMeasures[field_1]; + for (var op in ops) { + if (ops.hasOwnProperty(op)) { + if (field_1 in parentMeasures) { + // add operator to existing measure field + parentMeasures[field_1][op] = true; + } + else { + parentMeasures[field_1] = { op: true }; + } + } + } + } + } + } + function parseLayer(model) { + // Index by the fields we are grouping by + var summaries = {}; + // Combine summaries for children that don't have a distinct source + // (either having its own data source, or its own tranformation of the same data source). + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (!childDataComponent.source && childDataComponent.summary) { + // Merge the summaries if we can + childDataComponent.summary.forEach(function (childSummary) { + // The key is a hash based on the dimensions; + // we use it to find out whether we have a summary that uses the same group by fields. + var key = util_1.hash(childSummary.dimensions); + if (key in summaries) { + // yes, there is a summary hat we need to merge into + // we know that the dimensions are the same so we only need to merge the measures + mergeMeasures(summaries[key].measures, childSummary.measures); + } + else { + // give the summary a new name + childSummary.name = model.dataName(data_1.SUMMARY) + '_' + util_1.keys(summaries).length; + summaries[key] = childSummary; + } + // remove summary from child + child.renameData(child.dataName(data_1.SUMMARY), summaries[key].name); + delete childDataComponent.summary; + }); + } + }); + return util_1.vals(summaries); + } + summary.parseLayer = parseLayer; + /** + * Assemble the summary. Needs a rename function because we cannot guarantee that the + * parent data before the children data. + */ + function assemble(component, sourceName) { + return component.reduce(function (summaryData, summaryComponent) { + var dims = summaryComponent.dimensions; + var meas = summaryComponent.measures; + if (util_1.keys(meas).length > 0) { + var groupby = util_1.keys(dims); + var transform = util_1.reduce(meas, function (t, fnDictSet, field) { + var ops = util_1.keys(fnDictSet); + for (var _i = 0, ops_1 = ops; _i < ops_1.length; _i++) { + var op = ops_1[_i]; + t.fields.push(field); + t.ops.push(op); + } + return t; + }, { + type: 'aggregate', + groupby: groupby, + fields: [], + ops: [] + }); + summaryData.push({ + name: summaryComponent.name, + source: sourceName, + transform: [transform] + }); + } + return summaryData; + }, []); + } + summary.assemble = assemble; +})(summary = exports.summary || (exports.summary = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VtbWFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL2RhdGEvc3VtbWFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQUFtQztBQUNuQywyQ0FBK0M7QUFDL0MsbUNBQXFFO0FBVXJFLElBQWlCLE9BQU8sQ0FvS3ZCO0FBcEtELFdBQWlCLE9BQU87SUFDdEIsc0JBQXNCLElBQWdDLEVBQUUsUUFBa0I7UUFDeEUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDakIsSUFBSSxDQUFDLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDbkQsSUFBSSxDQUFDLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFFakQsc0NBQXNDO1lBQ3RDLGlGQUFpRjtZQUNqRiwrREFBK0Q7WUFDL0QsSUFBSSxDQUFDLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsU0FBUyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDbkQsSUFBSTtRQUNOLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLElBQUksQ0FBQyxnQkFBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQy9CLENBQUM7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELG1CQUEwQixLQUFZO1FBQ3BDLCtCQUErQjtRQUMvQixJQUFNLElBQUksR0FBYyxFQUFFLENBQUM7UUFFM0Isd0VBQXdFO1FBQ3hFLElBQU0sSUFBSSxHQUFvQixFQUFFLENBQUM7UUFFakMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFTLFFBQVEsRUFBRSxPQUFPO1lBQzlDLEVBQUUsQ0FBQyxD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 \ No newline at end of file diff --git a/build/src/compile/data/timeunit.d.ts b/build/src/compile/data/timeunit.d.ts new file mode 100644 index 0000000000..1d73bdbe19 --- /dev/null +++ b/build/src/compile/data/timeunit.d.ts @@ -0,0 +1,4 @@ +import { DataComponentCompiler } from './base'; +import { Dict } from '../../util'; +import { VgFormulaTransform } from '../../vega.schema'; +export declare const timeUnit: DataComponentCompiler>; diff --git a/build/src/compile/data/timeunit.js b/build/src/compile/data/timeunit.js new file mode 100644 index 0000000000..e3fa52b650 --- /dev/null +++ b/build/src/compile/data/timeunit.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../../fielddef"); +var timeunit_1 = require("../../timeunit"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function parse(model) { + return model.reduceFieldDef(function (timeUnitComponent, fieldDef) { + if (fieldDef.type === type_1.TEMPORAL && fieldDef.timeUnit) { + var f = fielddef_1.field(fieldDef); + timeUnitComponent[f] = { + type: 'formula', + as: f, + expr: timeunit_1.fieldExpr(fieldDef.timeUnit, fieldDef.field) + }; + } + return timeUnitComponent; + }, {}); +} +exports.timeUnit = { + parseUnit: parse, + parseFacet: function (model) { + var timeUnitComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(timeUnitComponent, childDataComponent.timeUnit); + delete childDataComponent.timeUnit; + } + return timeUnitComponent; + }, + parseLayer: function (model) { + var timeUnitComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (!childDataComponent.source) { + util_1.extend(timeUnitComponent, childDataComponent.timeUnit); + delete childDataComponent.timeUnit; + } + }); + return timeUnitComponent; + }, + assemble: function (component) { + // just join the values, which are already transforms + return util_1.vals(component); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9kYXRhL3RpbWV1bml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsMkNBQStDO0FBQy9DLDJDQUF5QztBQUN6QyxtQ0FBb0M7QUFDcEMsbUNBQThDO0FBTzlDLGVBQWUsS0FBWTtJQUN6QixNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxVQUFTLGlCQUEyQyxFQUFFLFFBQWtCO1FBQ2xHLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssZUFBUSxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBRXBELElBQU0sQ0FBQyxHQUFHLGdCQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDMUIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEdBQUc7Z0JBQ3JCLElBQUksRUFBRSxTQUFTO2dCQUNmLEVBQUUsRUFBRSxDQUFDO2dCQUNMLElBQUksRUFBRSxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQzthQUNuRCxDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDVCxDQUFDO0FBRVksUUFBQSxRQUFRLEdBQW9EO0lBQ3ZFLFNBQVMsRUFBRSxLQUFLO0lBRWhCLFVBQVUsRUFBRSxVQUFVLEtBQWlCO1FBQ3JDLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXJDLElBQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1FBRXRELHdEQUF3RDtRQUN4RCxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDL0IsYUFBTSxDQUFDLGlCQUFpQixFQUFFLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZELE9BQU8sa0JBQWtCLENBQUMsUUFBUSxDQUFDO1FBQ3JDLENBQUM7UUFDRCxNQUFNLENBQUMsaUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUVELFVBQVUsRUFBRSxVQUFTLEtBQWlCO1FBQ3BDLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLEtBQUssQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUMzQixJQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2hELEVBQUUsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDL0IsYUFBTSxDQUFDLGlCQUFpQixFQUFFLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN2RCxPQUFPLGtCQUFrQixDQUFDLFFBQVEsQ0FBQztZQUNyQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsaUJBQWlCLENBQUM7SUFDM0IsQ0FBQztJQUNELFFBQVEsRUFBRSxVQUFTLFNBQW1DO1FBQ3BELHFEQUFxRDtRQUNyRCxNQUFNLENBQUMsV0FBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7Q0FDRixDQUFDIn0= \ No newline at end of file diff --git a/build/src/compile/facet.d.ts b/build/src/compile/facet.d.ts new file mode 100644 index 0000000000..3de85008c3 --- /dev/null +++ b/build/src/compile/facet.d.ts @@ -0,0 +1,69 @@ +import { Axis } from '../axis'; +import { Channel } from '../channel'; +import { Config } from '../config'; +import { Facet } from '../facet'; +import { FieldDef } from '../fielddef'; +import { Legend } from '../legend'; +import { Scale } from '../scale'; +import { FacetSpec } from '../spec'; +import { Dict } from '../util'; +import { VgData, VgEncodeEntry } from '../vega.schema'; +import { StackProperties } from '../stack'; +import { Model } from './model'; +/** + * Prefix for special data sources for driving column's axis group. + */ +export declare const COLUMN_AXES_DATA_PREFIX = "column-"; +/** + * Prefix for special data sources for driving row's axis group. + */ +export declare const ROW_AXES_DATA_PREFIX = "row-"; +export declare class FacetModel extends Model { + readonly facet: Facet; + readonly child: Model; + readonly children: Model[]; + protected readonly scales: Dict; + protected readonly axes: Dict; + protected readonly legends: Dict; + readonly config: Config; + readonly stack: StackProperties; + private readonly _spacing; + constructor(spec: FacetSpec, parent: Model, parentGivenName: string); + private initConfig(specConfig, parent); + private initFacet(facet); + private initScalesAndSpacing(facet, config); + private initAxis(facet, config, child); + channelHasField(channel: Channel): boolean; + private hasSummary(); + facetedTable(): string; + dataTable(): string; + fieldDef(channel: Channel): FieldDef; + parseData(): void; + parseSelection(): void; + parseLayoutData(): void; + parseScale(): void; + parseMark(): void; + parseAxis(): void; + parseAxisGroup(): void; + parseGridGroup(): void; + parseLegend(): void; + assembleParentGroupProperties(): any; + assembleSignals(signals: any): any[]; + assembleSelectionData(data: VgData[]): VgData[]; + assembleData(data: VgData[]): VgData[]; + assembleLayout(layoutData: VgData[]): VgData[]; + assembleMarks(): any[]; + channels(): ("row" | "column")[]; + protected getMapping(): Facet; + spacing(channel: Channel): any; + isFacet(): boolean; +} +export declare function hasSubPlotWithXy(model: FacetModel): boolean; +export declare function spacing(scale: Scale, model: FacetModel, config: Config): number; +/** + * Add data for driving row/column axes when there are both row and column + * Note that we don't have to deal with these in the parse step at all + * because these items never get merged with any other items. + */ +export declare function assembleAxesGroupData(model: FacetModel, data: VgData[]): VgData[]; +export declare function getSharedAxisGroup(model: FacetModel, channel: 'x' | 'y'): VgEncodeEntry; diff --git a/build/src/compile/facet.js b/build/src/compile/facet.js new file mode 100644 index 0000000000..a4bfc8eceb --- /dev/null +++ b/build/src/compile/facet.js @@ -0,0 +1,481 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var log = require("../log"); +var axis_1 = require("../axis"); +var channel_1 = require("../channel"); +var config_1 = require("../config"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var rules_1 = require("./axis/rules"); +var common_1 = require("./common"); +var data_1 = require("./data/data"); +var layout_1 = require("./layout"); +var model_1 = require("./model"); +var init_1 = require("./scale/init"); +var parse_2 = require("./scale/parse"); +/** + * Prefix for special data sources for driving column's axis group. + */ +exports.COLUMN_AXES_DATA_PREFIX = 'column-'; +/** + * Prefix for special data sources for driving row's axis group. + */ +exports.ROW_AXES_DATA_PREFIX = 'row-'; +var FacetModel = (function (_super) { + tslib_1.__extends(FacetModel, _super); + function FacetModel(spec, parent, parentGivenName) { + var _this = _super.call(this, spec, parent, parentGivenName) || this; + _this.scales = {}; + _this.axes = {}; + _this.legends = {}; + _this.stack = null; + _this._spacing = {}; + // Config must be initialized before child as it gets cascaded to the child + var config = _this.config = _this.initConfig(spec.config, parent); + var child = _this.child = common_1.buildModel(spec.spec, _this, _this.getName('child')); + _this.children = [child]; + var facet = _this.facet = _this.initFacet(spec.facet); + _this.scales = _this.initScalesAndSpacing(facet, config); + _this.axes = _this.initAxis(facet, config, child); + _this.legends = {}; + return _this; + } + FacetModel.prototype.initConfig = function (specConfig, parent) { + return util_1.mergeDeep(util_1.duplicate(config_1.defaultConfig), parent ? parent.config : {}, specConfig); + }; + FacetModel.prototype.initFacet = function (facet) { + // clone to prevent side effect to the original spec + facet = util_1.duplicate(facet); + encoding_1.forEach(facet, function (fieldDef, channel) { + if (!util_1.contains([channel_1.ROW, channel_1.COLUMN], channel)) { + // Drop unsupported channel + log.warn(log.message.incompatibleChannel(channel, 'facet')); + delete facet[channel]; + return; + } + // TODO: array of row / column ? + if (fieldDef.field === undefined) { + log.warn(log.message.emptyFieldDef(fieldDef, channel)); + delete facet[channel]; + return; + } + // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + fielddef_1.normalize(fieldDef, channel); + }); + return facet; + }; + FacetModel.prototype.initScalesAndSpacing = function (facet, config) { + var model = this; + return [channel_1.ROW, channel_1.COLUMN].reduce(function (_scale, channel) { + if (facet[channel]) { + _scale[channel] = init_1.default(channel, facet[channel], config, undefined, // Facet doesn't have one single mark + undefined, // TODO(#1647): support width / height here + [] // There is no xyRangeSteps here and there is no need to input + ); + model._spacing[channel] = spacing(facet[channel].scale || {}, model, config); + } + return _scale; + }, {}); + }; + FacetModel.prototype.initAxis = function (facet, config, child) { + var model = this; + return [channel_1.ROW, channel_1.COLUMN].reduce(function (_axis, channel) { + if (facet[channel]) { + var axisSpec = facet[channel].axis; + if (axisSpec !== false) { + var vlOnlyAxisProperties_1 = {}; + axis_1.VL_ONLY_AXIS_PROPERTIES.forEach(function (property) { + if (config.facet.axis[property] !== undefined) { + vlOnlyAxisProperties_1[property] = config.facet.axis[property]; + } + }); + var modelAxis = _axis[channel] = tslib_1.__assign({}, vlOnlyAxisProperties_1, axisSpec); + if (channel === channel_1.ROW) { + var yAxis = child.axis(channel_1.Y); + if (yAxis && yAxis.orient !== 'right' && !modelAxis.orient) { + modelAxis.orient = 'right'; + } + if (model.hasDescendantWithFieldOnChannel(channel_1.X) && !modelAxis.labelAngle) { + modelAxis.labelAngle = modelAxis.orient === 'right' ? 90 : 270; + } + } + } + } + return _axis; + }, {}); + }; + FacetModel.prototype.channelHasField = function (channel) { + return !!this.facet[channel]; + }; + FacetModel.prototype.hasSummary = function () { + var summary = this.component.data.summary; + for (var _i = 0, summary_1 = summary; _i < summary_1.length; _i++) { + var s = summary_1[_i]; + if (util_1.keys(s.measures).length > 0) { + return true; + } + } + return false; + }; + FacetModel.prototype.facetedTable = function () { + // FIXME: revise if the suffix should be 'data' + return 'faceted-' + this.getName('data'); + }; + FacetModel.prototype.dataTable = function () { + // FIXME: shouldn't we apply data renaming here? + if (this.component.data.stack) { + return 'stacked'; + } + if (this.hasSummary()) { + return 'summary'; + } + return 'source'; + }; + FacetModel.prototype.fieldDef = function (channel) { + return this.facet[channel]; + }; + FacetModel.prototype.parseData = function () { + this.child.parseData(); + this.component.data = data_1.parseFacetData(this); + }; + FacetModel.prototype.parseSelection = function () { + // TODO: @arvind can write this + // We might need to split this into compileSelectionData and compileSelectionSignals? + }; + FacetModel.prototype.parseLayoutData = function () { + this.child.parseLayoutData(); + this.component.layout = layout_1.parseFacetLayout(this); + }; + FacetModel.prototype.parseScale = function () { + var child = this.child; + var model = this; + child.parseScale(); + // TODO: support scales for field reference of parent data (e.g., for SPLOM) + // First, add scale for row and column. + var scaleComponent = this.component.scales = parse_2.default(this); + // Then, move shared/union from its child spec. + util_1.keys(child.component.scales).forEach(function (channel) { + // TODO: correctly implement independent scale + if (true) { + var scale = scaleComponent[channel] = child.component.scales[channel]; + var scaleNameWithoutPrefix = scale.name.substr(child.getName('').length); + var newName = model.scaleName(scaleNameWithoutPrefix, true); + child.renameScale(scale.name, newName); + // Once put in parent, just remove the child's scale. + delete child.component.scales[channel]; + } + }); + }; + FacetModel.prototype.parseMark = function () { + this.child.parseMark(); + this.component.mark = util_1.extend({ + name: this.getName('cell'), + type: 'group', + from: util_1.extend({ + facet: { + name: this.facetedTable(), + data: this.dataTable(), + groupby: [].concat(this.channelHasField(channel_1.ROW) ? [this.field(channel_1.ROW)] : [], this.channelHasField(channel_1.COLUMN) ? [this.field(channel_1.COLUMN)] : []) + } + }), + encode: { + update: getFacetGroupProperties(this) + } + }, + // FIXME: move this call to assembleMarks() + // Call child's assembleGroup to add marks, scales, axes, and legends. + // Note that we can call child's assembleGroup() here because parseMark() + // is the last method in compile() and thus the child is completely compiled + // at this point. + this.child.assembleGroup()); + }; + FacetModel.prototype.parseAxis = function () { + this.child.parseAxis(); + this.component.axes = parse_1.parseAxisComponent(this, [channel_1.ROW, channel_1.COLUMN]); + }; + FacetModel.prototype.parseAxisGroup = function () { + // TODO: with nesting, we might need to consider calling child + // this.child.parseAxisGroup(); + var xAxisGroup = parseAxisGroups(this, channel_1.X); + var yAxisGroup = parseAxisGroups(this, channel_1.Y); + this.component.axisGroups = util_1.extend(xAxisGroup ? { x: xAxisGroup } : {}, yAxisGroup ? { y: yAxisGroup } : {}); + }; + FacetModel.prototype.parseGridGroup = function () { + // TODO: with nesting, we might need to consider calling child + // this.child.parseGridGroup(); + var child = this.child; + this.component.gridGroups = util_1.extend(!child.channelHasField(channel_1.X) && this.channelHasField(channel_1.COLUMN) ? { column: getColumnGridGroups(this) } : {}, !child.channelHasField(channel_1.Y) && this.channelHasField(channel_1.ROW) ? { row: getRowGridGroups(this) } : {}); + }; + FacetModel.prototype.parseLegend = function () { + this.child.parseLegend(); + // TODO: support legend for independent non-position scale across facets + // TODO: support legend for field reference of parent data (e.g., for SPLOM) + // For now, assuming that non-positional scales are always shared across facets + // Thus, just move all legends from its child + this.component.legends = this.child.component.legends; + this.child.component.legends = {}; + }; + FacetModel.prototype.assembleParentGroupProperties = function () { + return null; + }; + FacetModel.prototype.assembleSignals = function (signals) { + return []; + }; + FacetModel.prototype.assembleSelectionData = function (data) { + return []; + }; + FacetModel.prototype.assembleData = function (data) { + // Prefix traversal – parent data might be referred by children data + data_1.assembleData(this, data); + this.child.assembleData(data); + assembleAxesGroupData(this, data); + return data; + }; + FacetModel.prototype.assembleLayout = function (layoutData) { + // Postfix traversal – layout is assembled bottom-up + this.child.assembleLayout(layoutData); + return layout_1.assembleLayout(this, layoutData); + }; + FacetModel.prototype.assembleMarks = function () { + return [].concat( + // axisGroup is a mapping to VgMarkGroup + util_1.vals(this.component.axisGroups), util_1.flatten(util_1.vals(this.component.gridGroups)), this.component.mark); + }; + FacetModel.prototype.channels = function () { + return [channel_1.ROW, channel_1.COLUMN]; + }; + FacetModel.prototype.getMapping = function () { + return this.facet; + }; + FacetModel.prototype.spacing = function (channel) { + return this._spacing[channel]; + }; + FacetModel.prototype.isFacet = function () { + return true; + }; + return FacetModel; +}(model_1.Model)); +exports.FacetModel = FacetModel; +function hasSubPlotWithXy(model) { + return model.hasDescendantWithFieldOnChannel('x') || + model.hasDescendantWithFieldOnChannel('y'); +} +exports.hasSubPlotWithXy = hasSubPlotWithXy; +function spacing(scale, model, config) { + if (scale.spacing !== undefined) { + return scale.spacing; + } + if (!hasSubPlotWithXy(model)) { + // If there is no subplot with x/y, it's a simple table so there should be no spacing. + return 0; + } + return config.scale.facetSpacing; +} +exports.spacing = spacing; +function getFacetGroupProperties(model) { + var child = model.child; + var mergedCellConfig = util_1.extend({}, child.config.cell, child.config.facet.cell); + return util_1.extend({ + x: model.channelHasField(channel_1.COLUMN) ? { + scale: model.scaleName(channel_1.COLUMN), + field: model.field(channel_1.COLUMN), + // offset by the spacing / 2 + offset: model.spacing(channel_1.COLUMN) / 2 + } : { value: model.config.scale.facetSpacing / 2 }, + y: model.channelHasField(channel_1.ROW) ? { + scale: model.scaleName(channel_1.ROW), + field: model.field(channel_1.ROW), + // offset by the spacing / 2 + offset: model.spacing(channel_1.ROW) / 2 + } : { value: model.config.scale.facetSpacing / 2 }, + width: { field: { parent: model.child.sizeName('width') } }, + height: { field: { parent: model.child.sizeName('height') } } + }, hasSubPlotWithXy(model) ? child.assembleParentGroupProperties(mergedCellConfig) : {}); +} +// TODO: move the rest of the file src/compile/facet/*.ts +/** + * Add data for driving row/column axes when there are both row and column + * Note that we don't have to deal with these in the parse step at all + * because these items never get merged with any other items. + */ +function assembleAxesGroupData(model, data) { + if (model.facet.column) { + data.push({ + name: exports.COLUMN_AXES_DATA_PREFIX + model.dataTable(), + source: model.dataTable(), + transform: [{ + type: 'aggregate', + groupby: [model.field(channel_1.COLUMN)] + }] + }); + } + if (model.facet.row) { + data.push({ + name: exports.ROW_AXES_DATA_PREFIX + model.dataTable(), + source: model.dataTable(), + transform: [{ + type: 'aggregate', + groupby: [model.field(channel_1.ROW)] + }] + }); + } + return data; +} +exports.assembleAxesGroupData = assembleAxesGroupData; +function parseAxisGroups(model, channel) { + // TODO: add a case where inner spec is not a unit (facet/layer/concat) + var axisGroup = null; + var child = model.child; + if (child.channelHasField(channel)) { + if (child.axis(channel)) { + if (true) { + // add a group for the shared axes + axisGroup = getSharedAxisGroup(model, channel); + if (child.axis(channel) && rules_1.gridShow(child, channel)) { + // add inner axis (aka axis that shows only grid to ) + child.component.axes[channel] = [parse_1.parseGridAxis(channel, child)]; + } + else { + // Delete existing child axes + delete child.component.axes[channel]; + } + } + else { + // TODO: implement independent axes support + } + } + } + return axisGroup; +} +function getSharedAxisGroup(model, channel) { + var isX = channel === 'x'; + var facetChannel = isX ? 'column' : 'row'; + var hasFacet = !!model.facet[facetChannel]; + var dataPrefix = isX ? exports.COLUMN_AXES_DATA_PREFIX : exports.ROW_AXES_DATA_PREFIX; + var axesGroup = { + name: model.getName(channel + '-axes'), + type: 'group' + }; + if (hasFacet) { + // Need to drive this with special data source that has one item for each column/row value. + // TODO: We might only need to drive this with special data source if there are both row and column + // However, it might be slightly difficult as we have to merge this with the main group. + axesGroup.from = { data: dataPrefix + model.dataTable() }; + } + if (isX) { + axesGroup.encode = { + update: { + width: { field: { parent: model.child.sizeName('width') } }, + height: { field: { group: 'height' } }, + x: hasFacet ? { + scale: model.scaleName(channel_1.COLUMN), + field: model.field(channel_1.COLUMN), + // offset by the spacing + offset: model.spacing(channel_1.COLUMN) / 2 + } : { + // TODO: support custom spacing here + // offset by the spacing + value: model.config.scale.facetSpacing / 2 + } + } + }; + } + else { + axesGroup.encode = { + update: { + width: { field: { group: 'width' } }, + height: { field: { parent: model.child.sizeName('height') } }, + y: hasFacet ? { + scale: model.scaleName(channel_1.ROW), + field: model.field(channel_1.ROW), + // offset by the spacing + offset: model.spacing(channel_1.ROW) / 2 + } : { + // offset by the spacing + value: model.config.scale.facetSpacing / 2 + } + } + }; + } + axesGroup.axes = [parse_1.parseMainAxis(channel, model.child)]; + return axesGroup; +} +exports.getSharedAxisGroup = getSharedAxisGroup; +function getRowGridGroups(model) { + var facetGridConfig = model.config.facet.grid; + var rowGrid = { + name: model.getName('row-grid'), + type: 'rule', + from: { + data: exports.ROW_AXES_DATA_PREFIX + model.dataTable() + }, + encode: { + update: { + y: { + scale: model.scaleName(channel_1.ROW), + field: model.field(channel_1.ROW) + }, + x: { value: 0, offset: -facetGridConfig.offset }, + x2: { field: { group: 'width' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }; + return [rowGrid, { + name: model.getName('row-grid-end'), + type: 'rule', + encode: { + update: { + y: { field: { group: 'height' } }, + x: { value: 0, offset: -facetGridConfig.offset }, + x2: { field: { group: 'width' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }]; +} +function getColumnGridGroups(model) { + var facetGridConfig = model.config.facet.grid; + var columnGrid = { + name: model.getName('column-grid'), + type: 'rule', + from: { + data: exports.COLUMN_AXES_DATA_PREFIX + model.dataTable() + }, + encode: { + update: { + x: { + scale: model.scaleName(channel_1.COLUMN), + field: model.field(channel_1.COLUMN) + }, + y: { value: 0, offset: -facetGridConfig.offset }, + y2: { field: { group: 'height' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }; + return [columnGrid, { + name: model.getName('column-grid-end'), + type: 'rule', + encode: { + update: { + x: { field: { group: 'width' } }, + y: { value: 0, offset: -facetGridConfig.offset }, + y2: { field: { group: 'height' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }]; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9mYWNldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0QkFBOEI7QUFFOUIsZ0NBQXNFO0FBQ3RFLHNDQUFzRDtBQUN0RCxvQ0FBZ0Q7QUFFaEQsd0NBQW9DO0FBQ3BDLHdDQUFnRDtBQUloRCxnQ0FBMEY7QUFJMUYsc0NBQThFO0FBQzlFLHNDQUFzQztBQUN0QyxtQ0FBb0M7QUFDcEMsb0NBQXlEO0FBQ3pELG1DQUEwRDtBQUMxRCxpQ0FBOEI7QUFFOUIscUNBQXFDO0FBQ3JDLHVDQUFnRDtBQUVoRDs7R0FFRztBQUVVLFFBQUEsdUJBQXVCLEdBQUcsU0FBUyxDQUFDO0FBRWpEOztHQUVHO0FBQ1UsUUFBQSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFFM0M7SUFBZ0Msc0NBQUs7SUFxQm5DLG9CQUFZLElBQWUsRUFBRSxNQUFhLEVBQUUsZUFBdUI7UUFBbkUsWUFDRSxrQkFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxTQVlyQztRQTVCa0IsWUFBTSxHQUFnQixFQUFFLENBQUM7UUFFekIsVUFBSSxHQUFlLEVBQUUsQ0FBQztRQUV0QixhQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUk5QixXQUFLLEdBQW9CLElBQUksQ0FBQztRQUU3QixjQUFRLEdBR3JCLEVBQUUsQ0FBQztRQUtMLDJFQUEyRTtRQUMzRSxJQUFNLE1BQU0sR0FBRyxLQUFJLENBQUMsTUFBTSxHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVsRSxJQUFNLEtBQUssR0FBSSxLQUFJLENBQUMsS0FBSyxHQUFHLG1CQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFJLEVBQUUsS0FBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQy9FLEtBQUksQ0FBQyxRQUFRLEdBQUcs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 \ No newline at end of file diff --git a/build/src/compile/layer.d.ts b/build/src/compile/layer.d.ts new file mode 100644 index 0000000000..82313deb22 --- /dev/null +++ b/build/src/compile/layer.d.ts @@ -0,0 +1,64 @@ +import { Channel } from '../channel'; +import { CellConfig, Config } from '../config'; +import { FieldDef } from '../fielddef'; +import { Legend } from '../legend'; +import { Scale } from '../scale'; +import { Axis } from '../axis'; +import { LayerSpec } from '../spec'; +import { StackProperties } from '../stack'; +import { Dict } from '../util'; +import { VgData, VgEncodeEntry, VgScale } from '../vega.schema'; +import { Model } from './model'; +import { UnitModel } from './unit'; +export declare class LayerModel extends Model { + readonly children: UnitModel[]; + protected readonly scales: Dict; + protected readonly axes: Dict; + protected readonly legends: Dict; + readonly config: Config; + readonly stack: StackProperties; + /** + * Fixed width for the unit visualization. + * If undefined (e.g., for ordinal scale), the width of the + * visualization will be calculated dynamically. + */ + readonly width: number; + /** + * Fixed height for the unit visualization. + * If undefined (e.g., for ordinal scale), the height of the + * visualization will be calculated dynamically. + */ + readonly height: number; + constructor(spec: LayerSpec, parent: Model, parentGivenName: string); + private initConfig(specConfig, parent); + channelHasField(channel: Channel): boolean; + hasDiscreteScale(channel: Channel): boolean; + dataTable(): string; + fieldDef(channel: Channel): FieldDef; + parseData(): void; + parseSelection(): void; + parseLayoutData(): void; + parseScale(this: LayerModel): void; + parseMark(): void; + parseAxis(): void; + parseAxisGroup(): void; + parseGridGroup(): void; + parseLegend(): void; + assembleParentGroupProperties(cellConfig: CellConfig): VgEncodeEntry; + assembleSignals(signals: any[]): any[]; + assembleSelectionData(data: VgData[]): VgData[]; + assembleScales(): VgScale[]; + assembleData(data: VgData[]): VgData[]; + assembleLayout(layoutData: VgData[]): VgData[]; + assembleMarks(): any[]; + channels(): Channel[]; + protected getMapping(): any; + isLayer(): boolean; + /** + * Returns true if the child either has no source defined or uses the same url. + * This is useful if you want to know whether it is possible to move a filter up. + * + * This function can only be called once th child has been parsed. + */ + compatibleSource(child: UnitModel): boolean; +} diff --git a/build/src/compile/layer.js b/build/src/compile/layer.js new file mode 100644 index 0000000000..9a218b351b --- /dev/null +++ b/build/src/compile/layer.js @@ -0,0 +1,199 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var config_1 = require("../config"); +var mark_1 = require("../mark"); +var util_1 = require("../util"); +var vega_schema_1 = require("../vega.schema"); +var data_1 = require("../data"); +var data_2 = require("./data/data"); +var common_1 = require("./common"); +var layout_1 = require("./layout"); +var model_1 = require("./model"); +var domain_1 = require("./scale/domain"); +var LayerModel = (function (_super) { + tslib_1.__extends(LayerModel, _super); + function LayerModel(spec, parent, parentGivenName) { + var _this = _super.call(this, spec, parent, parentGivenName) || this; + _this.scales = {}; + _this.axes = {}; + _this.legends = {}; + _this.stack = null; + _this.width = spec.width; + _this.height = spec.height; + _this.config = _this.initConfig(spec.config, parent); + _this.children = spec.layer.map(function (layer, i) { + // we know that the model has to be a unit model because we pass in a unit spec + return common_1.buildModel(layer, _this, _this.getName('layer_' + i)); + }); + return _this; + } + LayerModel.prototype.initConfig = function (specConfig, parent) { + return util_1.mergeDeep(util_1.duplicate(config_1.defaultConfig), specConfig, parent ? parent.config : {}); + }; + LayerModel.prototype.channelHasField = function (channel) { + // layer does not have any channels + return false; + }; + LayerModel.prototype.hasDiscreteScale = function (channel) { + // since we assume shared scales we can just ask the first child + return this.children[0].hasDiscreteScale(channel); + }; + LayerModel.prototype.dataTable = function () { + // FIXME: don't just use the first child + return this.children[0].dataTable(); + }; + LayerModel.prototype.fieldDef = function (channel) { + return null; // layer does not have field defs + }; + LayerModel.prototype.parseData = function () { + this.children.forEach(function (child) { + child.parseData(); + }); + this.component.data = data_2.parseLayerData(this); + }; + LayerModel.prototype.parseSelection = function () { + // TODO: @arvind can write this + // We might need to split this into compileSelectionData and compileSelectionSignals? + }; + LayerModel.prototype.parseLayoutData = function () { + // TODO: correctly union ordinal scales rather than just using the layout of the first child + this.children.forEach(function (child) { + child.parseLayoutData(); + }); + this.component.layout = layout_1.parseLayerLayout(this); + }; + LayerModel.prototype.parseScale = function () { + var model = this; + var scaleComponent = this.component.scales = {}; + this.children.forEach(function (child) { + child.parseScale(); + // FIXME(#1602): correctly implement independent scale + // Also need to check whether the scales are actually compatible, e.g. use the same sort or throw error + if (true) { + util_1.keys(child.component.scales).forEach(function (channel) { + var childScale = child.component.scales[channel]; + var modelScale = scaleComponent[channel]; + if (!childScale || vega_schema_1.isSignalRefDomain(childScale.domain) || (modelScale && vega_schema_1.isSignalRefDomain(modelScale.domain))) { + // TODO: merge signal ref domains + return; + } + if (modelScale) { + modelScale.domain = domain_1.unionDomains(modelScale.domain, childScale.domain); + } + else { + scaleComponent[channel] = childScale; + } + // rename child scale to parent scales + var scaleNameWithoutPrefix = childScale.name.substr(child.getName('').length); + var newName = model.scaleName(scaleNameWithoutPrefix, true); + child.renameScale(childScale.name, newName); + // remove merged scales from children + delete child.component.scales[channel]; + }); + } + }); + }; + LayerModel.prototype.parseMark = function () { + this.children.forEach(function (child) { + child.parseMark(); + }); + }; + LayerModel.prototype.parseAxis = function () { + var axisComponent = this.component.axes = {}; + this.children.forEach(function (child) { + child.parseAxis(); + // TODO: correctly implement independent axes + if (true) { + util_1.keys(child.component.axes).forEach(function (channel) { + // TODO: support multiple axes for shared scale + // just use the first axis definition for each channel + if (!axisComponent[channel]) { + axisComponent[channel] = child.component.axes[channel]; + } + }); + } + }); + }; + LayerModel.prototype.parseAxisGroup = function () { + return null; + }; + LayerModel.prototype.parseGridGroup = function () { + return null; + }; + LayerModel.prototype.parseLegend = function () { + var legendComponent = this.component.legends = {}; + this.children.forEach(function (child) { + child.parseLegend(); + // TODO: correctly implement independent axes + if (true) { + util_1.keys(child.component.legends).forEach(function (channel) { + // just use the first legend definition for each channel + if (!legendComponent[channel]) { + legendComponent[channel] = child.component.legends[channel]; + } + }); + } + }); + }; + LayerModel.prototype.assembleParentGroupProperties = function (cellConfig) { + return common_1.applyConfig({}, cellConfig, mark_1.FILL_STROKE_CONFIG.concat(['clip'])); + }; + LayerModel.prototype.assembleSignals = function (signals) { + return []; + }; + LayerModel.prototype.assembleSelectionData = function (data) { + return []; + }; + LayerModel.prototype.assembleScales = function () { + // combine with scales from children + return this.children.reduce(function (scales, c) { + return scales.concat(c.assembleScales()); + }, _super.prototype.assembleScales.call(this)); + }; + LayerModel.prototype.assembleData = function (data) { + // Prefix traversal – parent data might be referred to by children data + data_2.assembleData(this, data); + this.children.forEach(function (child) { + child.assembleData(data); + }); + return data; + }; + LayerModel.prototype.assembleLayout = function (layoutData) { + // Postfix traversal – layout is assembled bottom-up + this.children.forEach(function (child) { + child.assembleLayout(layoutData); + }); + return layout_1.assembleLayout(this, layoutData); + }; + LayerModel.prototype.assembleMarks = function () { + // only children have marks + return util_1.flatten(this.children.map(function (child) { + return child.assembleMarks(); + })); + }; + LayerModel.prototype.channels = function () { + return []; + }; + LayerModel.prototype.getMapping = function () { + return null; + }; + LayerModel.prototype.isLayer = function () { + return true; + }; + /** + * Returns true if the child either has no source defined or uses the same url. + * This is useful if you want to know whether it is possible to move a filter up. + * + * This function can only be called once th child has been parsed. + */ + LayerModel.prototype.compatibleSource = function (child) { + var data = this.data; + var childData = child.component.data; + var compatible = !childData.source || (data && data_1.isUrlData(data) && data.url === childData.source.url); + return compatible; + }; + return LayerModel; +}(model_1.Model)); +exports.LayerModel = LayerModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9sYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxvQ0FBNEQ7QUFPNUQsZ0NBQTJDO0FBQzNDLGdDQUFrRTtBQUNsRSw4Q0FBaUY7QUFDakYsZ0NBQWtDO0FBRWxDLG9DQUF5RDtBQUN6RCxtQ0FBaUQ7QUFDakQsbUNBQTBEO0FBQzFELGlDQUE4QjtBQUc5Qix5Q0FBNEM7QUFHNUM7SUFBZ0Msc0NBQUs7SUEyQm5DLG9CQUFZLElBQWUsRUFBRSxNQUFhLEVBQUUsZUFBdUI7UUFBbkUsWUFDRSxrQkFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxTQVVyQztRQW5Da0IsWUFBTSxHQUFnQixFQUFFLENBQUM7UUFFekIsVUFBSSxHQUFlLEVBQUUsQ0FBQztRQUV0QixhQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUk5QixXQUFLLEdBQW9CLElBQUksQ0FBQztRQW1CNUMsS0FBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3hCLEtBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUUxQixLQUFJLENBQUMsTUFBTSxHQUFHLEtBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNuRCxLQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEMsK0VBQStFO1lBQy9FLE1BQU0sQ0FBQyxtQkFBVSxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQWMsQ0FBQztRQUMxRSxDQUFDLENBQUMsQ0FBQzs7SUFDTCxDQUFDO0lBRU8sK0JBQVUsR0FBbEIsVUFBbUIsVUFBa0IsRUFBRSxNQUFhO1FBQ2xE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 \ No newline at end of file diff --git a/build/src/compile/layout.d.ts b/build/src/compile/layout.d.ts new file mode 100644 index 0000000000..85833d1e46 --- /dev/null +++ b/build/src/compile/layout.d.ts @@ -0,0 +1,24 @@ +import { Channel } from '../channel'; +import { Formula } from '../transform'; +import { StringSet } from '../util'; +import { VgData } from '../vega.schema'; +import { FacetModel } from './facet'; +import { LayerModel } from './layer'; +import { Model } from './model'; +import { UnitModel } from './unit'; +export interface LayoutComponent { + width: SizeComponent; + height: SizeComponent; +} +export interface SizeComponent { + /** Field that we need to calculate distinct */ + distinct: StringSet; + /** Array of formulas */ + formula: Formula[]; +} +export declare function assembleLayout(model: Model, layoutData: VgData[]): VgData[]; +export declare function parseUnitLayout(model: UnitModel): LayoutComponent; +export declare function unitSizeExpr(model: UnitModel, channel: Channel): string; +export declare function parseFacetLayout(model: FacetModel): LayoutComponent; +export declare function parseLayerLayout(model: LayerModel): LayoutComponent; +export declare function cardinalityExpr(model: Model, channel: Channel): string; diff --git a/build/src/compile/layout.js b/build/src/compile/layout.js new file mode 100644 index 0000000000..1d41287772 --- /dev/null +++ b/build/src/compile/layout.js @@ -0,0 +1,164 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var data_1 = require("../data"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +function assembleLayout(model, layoutData) { + var layoutComponent = model.component.layout; + if (!layoutComponent.width && !layoutComponent.height) { + return layoutData; // Do nothing + } + if (true) { + var distinctFields = util_1.keys(util_1.extend(layoutComponent.width.distinct, layoutComponent.height.distinct)); + var formula = layoutComponent.width.formula.concat(layoutComponent.height.formula) + .map(function (f) { return util_1.extend({ type: 'formula' }, f); }); + return [ + distinctFields.length > 0 ? { + name: model.dataName(data_1.LAYOUT), + source: model.dataTable(), + transform: [{ + type: 'aggregate', + fields: distinctFields, + ops: distinctFields.map(function () { return 'distinct'; }) + }].concat(formula) + } : { + name: model.dataName(data_1.LAYOUT), + values: [{}], + transform: formula + } + ]; + } + // FIXME: implement + // otherwise, we need to join width and height (cross) +} +exports.assembleLayout = assembleLayout; +// FIXME: for nesting x and y, we need to declare x,y layout separately before joining later +// For now, let's always assume shared scale +function parseUnitLayout(model) { + return { + width: parseUnitSizeLayout(model, channel_1.X), + height: parseUnitSizeLayout(model, channel_1.Y) + }; +} +exports.parseUnitLayout = parseUnitLayout; +function parseUnitSizeLayout(model, channel) { + return { + distinct: getDistinct(model, channel), + formula: [{ + as: model.channelSizeName(channel), + expr: unitSizeExpr(model, channel) + }] + }; +} +function unitSizeExpr(model, channel) { + var scale = model.scale(channel); + if (scale) { + if (scale_1.hasDiscreteDomain(scale.type) && scale.rangeStep) { + // If the spec has top level size or specified rangeStep = fit, it will be undefined here. + var cardinality = cardinalityExpr(model, channel); + var paddingOuter = scale.paddingOuter !== undefined ? scale.paddingOuter : scale.padding; + var paddingInner = scale.type === 'band' ? + // only band has real paddingInner + (scale.paddingInner !== undefined ? scale.paddingInner : scale.padding) : + // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128, + // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points. + 1; + var space = cardinality + + (paddingInner ? " - " + paddingInner : '') + + (paddingOuter ? " + 2*" + paddingOuter : ''); + // This formula is equivalent to + // space = count - inner + outer * 2 + // range = rangeStep * (space > 0 ? space : 0) + // in https://github.com/vega/vega-encode/blob/master/src/Scale.js#L112 + return "max(" + space + ", 0) * " + scale.rangeStep; + } + } + return (channel === channel_1.X ? model.width : model.height) + ''; +} +exports.unitSizeExpr = unitSizeExpr; +function parseFacetLayout(model) { + return { + width: parseFacetSizeLayout(model, channel_1.COLUMN), + height: parseFacetSizeLayout(model, channel_1.ROW) + }; +} +exports.parseFacetLayout = parseFacetLayout; +function parseFacetSizeLayout(model, channel) { + var childLayoutComponent = model.child.component.layout; + var sizeType = channel === channel_1.ROW ? 'height' : 'width'; + var childSizeComponent = childLayoutComponent[sizeType]; + if (true) { + // For shared scale, we can simply merge the layout into one data source + var distinct = util_1.extend(getDistinct(model, channel), childSizeComponent.distinct); + var formula = childSizeComponent.formula.concat([{ + as: model.channelSizeName(channel), + expr: facetSizeFormula(model, channel, model.child.channelSizeName(channel)) + }]); + delete childLayoutComponent[sizeType]; + return { + distinct: distinct, + formula: formula + }; + } + // FIXME implement independent scale as well + // TODO: - also consider when children have different data source +} +function facetSizeFormula(model, channel, innerSize) { + if (model.channelHasField(channel)) { + return '(datum["' + innerSize + '"] + ' + model.spacing(channel) + ')' + ' * ' + cardinalityExpr(model, channel); + } + else { + return 'datum["' + innerSize + '"] + ' + model.config.scale.facetSpacing; // need to add outer padding for facet + } +} +function parseLayerLayout(model) { + return { + width: parseLayerSizeLayout(model, channel_1.X), + height: parseLayerSizeLayout(model, channel_1.Y) + }; +} +exports.parseLayerLayout = parseLayerLayout; +function parseLayerSizeLayout(model, channel) { + if (true) { + // For shared scale, we can simply merge the layout into one data source + // TODO: don't just take the layout from the first child + var childLayoutComponent = model.children[0].component.layout; + var sizeType_1 = channel === channel_1.Y ? 'height' : 'width'; + var childSizeComponent = childLayoutComponent[sizeType_1]; + var distinct = childSizeComponent.distinct; + var formula = [{ + as: model.channelSizeName(channel), + expr: childSizeComponent.formula[0].expr + }]; + model.children.forEach(function (child) { + delete child.component.layout[sizeType_1]; + }); + return { + distinct: distinct, + formula: formula + }; + } +} +function getDistinct(model, channel) { + if (model.channelHasField(channel) && model.hasDiscreteScale(channel)) { + var scale = model.scale(channel); + if (scale_1.hasDiscreteDomain(scale.type) && !(scale.domain instanceof Array)) { + // if explicit domain is declared, use array length + var distinctField = model.field(channel); + var distinct = {}; + distinct[distinctField] = true; + return distinct; + } + } + return {}; +} +function cardinalityExpr(model, channel) { + var scale = model.scale(channel); + if (scale.domain instanceof Array) { + return scale.domain.length + ''; + } + return model.field(channel, { datum: true, prefix: 'distinct' }); +} +exports.cardinalityExpr = cardinalityExpr; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5b3V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGF5b3V0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esc0NBQXNEO0FBQ3RELGdDQUErQjtBQUMvQixrQ0FBMkM7QUFFM0MsZ0NBQWdEO0FBdUJoRCx3QkFBK0IsS0FBWSxFQUFFLFVBQW9CO0lBQy9ELElBQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQy9DLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxhQUFhO0lBQ2xDLENBQUM7SUFFRCxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ1QsSUFBTSxjQUFjLEdBQUcsV0FBSSxDQUFDLGFBQU0sQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDckcsSUFBTSxPQUFPLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO2FBQ2pGLEdBQUcsQ0FBQyxVQUFBLENBQUMsSUFBSSxPQUFBLGFBQU0sQ0FBQyxFQUFDLElBQUksRUFBRSxTQUFTLEVBQUMsRUFBRSxDQUFDLENBQUMsRUFBNUIsQ0FBNEIsQ0FBQyxDQUFDO1FBRTFDLE1BQU0sQ0FBQztZQUNMLGNBQWMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHO2dCQUMxQixJQUFJLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxhQUFNLENBQUM7Z0JBQzVCLE1BQU0sRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFO2dCQUN6QixTQUFTLEVBQUUsQ0FBQzt3QkFDVixJQUFJLEVBQUUs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 \ No newline at end of file diff --git a/build/src/compile/legend/encode.d.ts b/build/src/compile/legend/encode.d.ts new file mode 100644 index 0000000000..ffbfb1c842 --- /dev/null +++ b/build/src/compile/legend/encode.d.ts @@ -0,0 +1,5 @@ +import { Channel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { UnitModel } from '../unit'; +export declare function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel): any; +export declare function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: Channel): any; diff --git a/build/src/compile/legend/encode.js b/build/src/compile/legend/encode.js new file mode 100644 index 0000000000..f75dd6bf1d --- /dev/null +++ b/build/src/compile/legend/encode.js @@ -0,0 +1,94 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var mark_1 = require("../../mark"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function symbols(fieldDef, symbolsSpec, model, channel) { + var symbols = {}; + var mark = model.mark(); + switch (mark) { + case mark_1.BAR: + case mark_1.TICK: + case mark_1.TEXT: + symbols.shape = { value: 'square' }; + break; + case mark_1.CIRCLE: + case mark_1.SQUARE: + symbols.shape = { value: mark }; + break; + case mark_1.POINT: + case mark_1.LINE: + case mark_1.AREA: + // use default circle + break; + } + var cfg = model.config; + var filled = model.markDef.filled; + var config = channel === channel_1.COLOR ? + /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */ + util_1.without(mark_1.FILL_STROKE_CONFIG, [filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) : + /* For other legend, no need to omit. */ + mark_1.FILL_STROKE_CONFIG; + config = util_1.without(config, ['strokeDash', 'strokeDashOffset']); + common_1.applyMarkConfig(symbols, model, config); + if (filled) { + symbols.strokeWidth = { value: 0 }; + } + var value; + var colorDef = model.encoding.color; + if (fielddef_1.isValueDef(colorDef)) { + value = { value: colorDef.value }; + } + if (value !== undefined) { + // apply the value + if (filled) { + symbols.fill = value; + } + else { + symbols.stroke = value; + } + } + else if (channel !== channel_1.COLOR) { + // For non-color legend, apply color config if there is no fill / stroke config. + // (For color, do not override scale specified!) + symbols[filled ? 'fill' : 'stroke'] = symbols[filled ? 'fill' : 'stroke'] || + { value: cfg.mark.color }; + } + if (symbols.fill === undefined) { + // fall back to mark config colors for legend fill + if (cfg.mark.fill !== undefined) { + symbols.fill = { value: cfg.mark.fill }; + } + else if (cfg.mark.stroke !== undefined) { + symbols.stroke = { value: cfg.mark.stroke }; + } + } + var shapeDef = model.encoding.shape; + if (channel !== channel_1.SHAPE) { + if (fielddef_1.isValueDef(shapeDef)) { + symbols.shape = { value: shapeDef.value }; + } + } + symbols = util_1.extend(symbols, symbolsSpec || {}); + return util_1.keys(symbols).length > 0 ? symbols : undefined; +} +exports.symbols = symbols; +function labels(fieldDef, labelsSpec, model, channel) { + var legend = model.legend(channel); + var config = model.config; + var labels = {}; + if (fieldDef.type === type_1.TEMPORAL) { + labelsSpec = util_1.extend({ + text: { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat) + } + }, labelsSpec || {}); + } + labels = util_1.extend(labels, labelsSpec || {}); + return util_1.keys(labels).length > 0 ? labels : undefined; +} +exports.labels = labels; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbGVnZW5kL2VuY29kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUFvRDtBQUNwRCwyQ0FBb0Q7QUFDcEQsbUNBQWtHO0FBQ2xHLG1DQUFvQztBQUNwQyxtQ0FBaUQ7QUFJakQsb0NBQWdFO0FBR2hFLGlCQUF3QixRQUFrQixFQUFFLFdBQWdCLEVBQUUsS0FBZ0IsRUFBRSxPQUFnQjtJQUM5RixJQUFJLE9BQU8sR0FBTyxFQUFFLENBQUM7SUFDckIsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBRTFCLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDYixLQUFLLFVBQUcsQ0FBQztRQUNULEtBQUssV0FBSSxDQUFDO1FBQ1YsS0FBSyxXQUFJO1lBQ1AsT0FBTyxDQUFDLEtBQUssR0FBRyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQztZQUNsQyxLQUFLLENBQUM7UUFDUixLQUFLLGFBQU0sQ0FBQztRQUNaLEtBQUssYUFBTTtZQUNULE9BQU8sQ0FBQyxLQUFLLEdBQUcsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUM7WUFDOUIsS0FBSyxDQUFDO1FBQ1IsS0FBSyxZQUFLLENBQUM7UUFDWCxLQUFLLFdBQUksQ0FBQztRQUNWLEtBQUssV0FBSTtZQUNQLHFCQUFxQjtZQUNyQixLQUFLLENBQUM7SUFDVixDQUFDO0lBRUQsSUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztJQUN6QixJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUVwQyxJQUFJLE1BQU0sR0FBRyxPQUFPLEtBQUssZUFBSztRQUMxQiwyS0FBMks7UUFDM0ssY0FBTyxDQUFDLHlCQUFrQixFQUFFLENBQUUsTUFBTSxHQUFHLE1BQU0sR0FBRyxRQUFRLEVB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 \ No newline at end of file diff --git a/build/src/compile/legend/parse.d.ts b/build/src/compile/legend/parse.d.ts new file mode 100644 index 0000000000..a2aa7f2e88 --- /dev/null +++ b/build/src/compile/legend/parse.d.ts @@ -0,0 +1,6 @@ +import { Channel } from '../../channel'; +import { Dict } from '../../util'; +import { VgLegend } from '../../vega.schema'; +import { UnitModel } from '../unit'; +export declare function parseLegendComponent(model: UnitModel): Dict; +export declare function parseLegend(model: UnitModel, channel: Channel): VgLegend; diff --git a/build/src/compile/legend/parse.js b/build/src/compile/legend/parse.js new file mode 100644 index 0000000000..f15f60e289 --- /dev/null +++ b/build/src/compile/legend/parse.js @@ -0,0 +1,72 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var util_1 = require("../../util"); +var legend_1 = require("../../legend"); +var common_1 = require("../common"); +var encode = require("./encode"); +var rules = require("./rules"); +function parseLegendComponent(model) { + return [channel_1.COLOR, channel_1.SIZE, channel_1.SHAPE, channel_1.OPACITY].reduce(function (legendComponent, channel) { + if (model.legend(channel)) { + legendComponent[channel] = parseLegend(model, channel); + } + return legendComponent; + }, {}); +} +exports.parseLegendComponent = parseLegendComponent; +function getLegendDefWithScale(model, channel) { + // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels + switch (channel) { + case channel_1.COLOR: + var scale = model.scaleName(channel_1.COLOR); + return model.markDef.filled ? { fill: scale } : { stroke: scale }; + case channel_1.SIZE: + return { size: model.scaleName(channel_1.SIZE) }; + case channel_1.SHAPE: + return { shape: model.scaleName(channel_1.SHAPE) }; + case channel_1.OPACITY: + return { opacity: model.scaleName(channel_1.OPACITY) }; + } + return null; +} +function parseLegend(model, channel) { + var fieldDef = model.fieldDef(channel); + var legend = model.legend(channel); + var def = getLegendDefWithScale(model, channel); + legend_1.LEGEND_PROPERTIES.forEach(function (property) { + var value = getSpecifiedOrDefaultValue(property, legend, channel, model); + if (value !== undefined) { + def[property] = value; + } + }); + // 2) Add mark property definition groups + var encodeSpec = legend.encode || {}; + ['labels', 'legend', 'title', 'symbols'].forEach(function (part) { + var value = encode[part] ? + encode[part](fieldDef, encodeSpec[part], model, channel) : + encodeSpec[part]; // no rule -- just default values + if (value !== undefined && util_1.keys(value).length > 0) { + def.encode = def.encode || {}; + def.encode[part] = { update: value }; + } + }); + return def; +} +exports.parseLegend = parseLegend; +function getSpecifiedOrDefaultValue(property, specifiedLegend, channel, model) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'format': + return common_1.numberFormat(fieldDef, specifiedLegend.format, model.config, channel); + case 'title': + return rules.title(specifiedLegend, fieldDef, model.config); + case 'values': + return rules.values(specifiedLegend); + case 'type': + rules.type(specifiedLegend, fieldDef, channel); + } + // Otherwise, return specified property. + return specifiedLegend[property]; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9sZWdlbmQvcGFyc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBbUU7QUFDbkUsbUNBQXNDO0FBRXRDLHVDQUF1RDtBQUd2RCxvQ0FBdUM7QUFHdkMsaUNBQW1DO0FBQ25DLCtCQUFpQztBQUVqQyw4QkFBcUMsS0FBZ0I7SUFDbkQsTUFBTSxDQUFDLENBQUMsZUFBSyxFQUFFLGNBQUksRUFBRSxlQUFLLEVBQUUsaUJBQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFTLGVBQWUsRUFBRSxPQUFPO1FBQzNFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLGVBQWUsQ0FBQyxPQUFPLENBQUMsR0FBRyxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3pELENBQUM7UUFDRCxNQUFNLENBQUMsZUFBZSxDQUFDO0lBQ3pCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNULENBQUM7QUFQRCxvREFPQztBQUVELCtCQUErQixLQUFnQixFQUFFLE9BQWdCO0lBQy9ELDRHQUE0RztJQUM1RyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2hCLEtBQUssZUFBSztZQUNSLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsZUFBSyxDQUFDLENBQUM7WUFDckMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxHQUFHLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDO1FBQ2hFLEtBQUssY0FBSTtZQUNQLE1BQU0sQ0FBQyxFQUFDLElBQUksRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLGNBQUksQ0FBQyxFQUFDLENBQUM7UUFDdkMsS0FBSyxlQUFL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 \ No newline at end of file diff --git a/build/src/compile/legend/rules.d.ts b/build/src/compile/legend/rules.d.ts new file mode 100644 index 0000000000..1d81fc8132 --- /dev/null +++ b/build/src/compile/legend/rules.d.ts @@ -0,0 +1,8 @@ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { DateTime } from '../../datetime'; +import { FieldDef } from '../../fielddef'; +import { Legend } from '../../legend'; +export declare function title(legend: Legend, fieldDef: FieldDef, config: Config): string; +export declare function values(legend: Legend): string[] | number[] | DateTime[]; +export declare function type(legend: Legend, fieldDef: FieldDef, channel: Channel): "symbol" | "gradient"; diff --git a/build/src/compile/legend/rules.js b/build/src/compile/legend/rules.js new file mode 100644 index 0000000000..5053c12aff --- /dev/null +++ b/build/src/compile/legend/rules.js @@ -0,0 +1,36 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function title(legend, fieldDef, config) { + if (legend.title !== undefined) { + return legend.title; + } + return fielddef_1.title(fieldDef, config); +} +exports.title = title; +function values(legend) { + var vals = legend.values; + if (vals && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return datetime_1.timestamp(dt, true); + }); + } + return vals; +} +exports.values = values; +function type(legend, fieldDef, channel) { + if (legend.type) { + return legend.type; + } + if (channel === channel_1.COLOR && !fieldDef.bin && !fieldDef.timeUnit && util_1.contains([type_1.QUANTITATIVE, type_1.TEMPORAL], fieldDef.type)) { + return 'gradient'; + } + return undefined; +} +exports.type = type; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9sZWdlbmQvcnVsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBNkM7QUFFN0MsMkNBQStEO0FBRy9ELDJDQUFtRDtBQUNuRCxtQ0FBa0Q7QUFDbEQsbUNBQW9DO0FBRXBDLGVBQXNCLE1BQWMsRUFBRSxRQUFrQixFQUFFLE1BQWM7SUFDdEUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxNQUFNLENBQUMsZ0JBQVUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQU5ELHNCQU1DO0FBRUQsZ0JBQXVCLE1BQWM7SUFDbkMsSUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUMzQixFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUkscUJBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDaEMsTUFBTSxDQUFFLElBQW1CLENBQUMsR0FBRyxDQUFDLFVBQUMsRUFBRTtZQUNqQyxxREFBcUQ7WUFDckQsTUFBTSxDQUFDLG9CQUFTLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBVEQsd0JBU0M7QUFFRCxjQUFxQixNQUFjLEVBQUUsUUFBa0IsRUFBRSxPQUFnQjtJQUN2RSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNoQixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNyQixDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLGVBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLGVBQVEsQ0FBQyxDQUFDLG1CQUFZLEVBQUUsZUFBUSxDQUFDLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsSCxNQUFNLENBQUMsVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFDRCxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFURCxvQkFTQyJ9 \ No newline at end of file diff --git a/build/src/compile/mark/area.d.ts b/build/src/compile/mark/area.d.ts new file mode 100644 index 0000000000..92ee281df3 --- /dev/null +++ b/build/src/compile/mark/area.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const area: MarkCompiler; diff --git a/build/src/compile/mark/area.js b/build/src/compile/mark/area.js new file mode 100644 index 0000000000..3b3cf0ecf9 --- /dev/null +++ b/build/src/compile/mark/area.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +exports.area = { + vgMark: 'area', + role: undefined, + encodeEntry: function (model) { + var orient = model.markDef.orient; + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin'), mixins.color(model), mixins.nonPosition('opacity', model), mixins.markDefProperties(model.markDef, ['orient', 'interpolate', 'tension'])); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJlYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvYXJlYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpQ0FBbUM7QUFLdEIsUUFBQSxJQUFJLEdBQWlCO0lBQ2hDLE1BQU0sRUFBRSxNQUFNO0lBQ2QsSUFBSSxFQUFFLFNBQVM7SUFDZixXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUM1QixJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUVwQyxNQUFNLHNCQUNELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsRUFDN0MsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUM3QyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsRUFFekMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFDbkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3BDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUNoRjtJQUNKLENBQUM7Q0FDRixDQUFDIn0= \ No newline at end of file diff --git a/build/src/compile/mark/bar.d.ts b/build/src/compile/mark/bar.d.ts new file mode 100644 index 0000000000..577df12005 --- /dev/null +++ b/build/src/compile/mark/bar.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const bar: MarkCompiler; diff --git a/build/src/compile/mark/bar.js b/build/src/compile/mark/bar.js new file mode 100644 index 0000000000..ee20f5fc9d --- /dev/null +++ b/build/src/compile/mark/bar.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var log = require("../../log"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.bar = { + vgMark: 'rect', + role: 'bar', + encodeEntry: function (model) { + var stack = model.stack; + return tslib_1.__assign({}, x(model, stack), y(model, stack), mixins.color(model), mixins.nonPosition('opacity', model)); + } +}; +function x(model, stack) { + var config = model.config; + var orient = model.markDef.orient; + var sizeDef = model.encoding.size; + var xDef = model.encoding.x; + var xScaleName = model.scaleName(channel_1.X); + var xScale = model.scale(channel_1.X); + // x, x2, and width -- we must specify two of these in all conditions + if (orient === 'horizontal') { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(xDef)) { + if (!sizeDef && scale_1.isBinScale(xScale.type)) { + return mixins.binnedPosition('x', model, config.bar.binSpacing); + } + else if (xScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('x', model); + } + } + // sized bin, normal point-ordinal axis, quantitative x-axis, or no x + return mixins.centeredBandPosition('x', model, tslib_1.__assign({}, ref.midX(config), { offset: 1 }), // TODO: config.singleBarOffset, + defaultSizeRef(xScaleName, model.scale(channel_1.X), config)); + } +} +function y(model, stack) { + var config = model.config, encoding = model.encoding; + var orient = model.markDef.orient; + var sizeDef = encoding.size; + var yDef = encoding.y; + var yScaleName = model.scaleName(channel_1.Y); + var yScale = model.scale(channel_1.Y); + // y, y2 & height -- we must specify two of these in all conditions + if (orient === 'vertical') { + return tslib_1.__assign({}, mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(yDef)) { + if (yDef.bin && !sizeDef) { + return mixins.binnedPosition('y', model, config.bar.binSpacing); + } + else if (yScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('y', model); + } + } + return mixins.centeredBandPosition('y', model, ref.midY(config), defaultSizeRef(yScaleName, model.scale(channel_1.Y), config)); + } +} +function defaultSizeRef(scaleName, scale, config) { + if (config.bar.discreteBandSize) { + return { value: config.bar.discreteBandSize }; + } + if (scale) { + if (scale.type === scale_1.ScaleType.POINT) { + if (scale.rangeStep !== null) { + return { value: scale.rangeStep - 1 }; + } + log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL); + } + else if (scale.type === scale_1.ScaleType.BAND) { + return ref.band(scaleName); + } + else { + return { value: config.bar.continuousBandSize }; + } + } + if (config.scale.rangeStep && config.scale.rangeStep !== null) { + return { value: config.scale.rangeStep - 1 }; + } + // TODO: this should depends on cell's width / height? + return { value: 20 }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9iYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQW1DO0FBRW5DLDJDQUEwQztBQUMxQyxxQ0FBeUQ7QUFFekQsK0JBQWlDO0FBR2pDLGlDQUFtQztBQUtuQyxnQ0FBa0M7QUFFckIsUUFBQSxHQUFHLEdBQWlCO0lBQy9CLE1BQU0sRUFBRSxNQUFNO0lBQ2QsSUFBSSxFQUFFLEtBQUs7SUFDWCxXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUM1QixJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzFCLE1BQU0sc0JBQ0QsQ0FBQyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsRUFDZixDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQ25CLE1BQU0sQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUN2QztJQUNKLENBQUM7Q0FDRixDQUFDO0FBRUYsV0FBVyxLQUFnQixFQUFFLEtBQXNCO0lBQzFDLElBQUEscUJBQU0sQ0FBVTtJQUN2QixJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUNwQyxJQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztJQUVwQyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUM5QixJQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLFdBQUMsQ0FBQyxDQUFDO0lBQ3RDLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsV0FBQyxDQUFDLENBQUM7SUFDOUIscUVBQXFFO0lBQ3JFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzVC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 \ No newline at end of file diff --git a/build/src/compile/mark/base.d.ts b/build/src/compile/mark/base.d.ts new file mode 100644 index 0000000000..d66b8891ae --- /dev/null +++ b/build/src/compile/mark/base.d.ts @@ -0,0 +1,17 @@ +import { UnitModel } from '../unit'; +import { VgEncodeEntry } from '../../vega.schema'; +/** + * Abstract interface for compiling a Vega-Lite primitive mark type. + */ +export interface MarkCompiler { + /** + * Underlying vega Mark type for the Vega-Lite mark. + */ + vgMark: 'area' | 'line' | 'symbol' | 'rect' | 'rule' | 'text'; + /** + * Vega's Mark role, which enables use to use config..* in parser. + * Basically for marks that are not Vega marks, we output roles for all of them. + */ + role: 'bar' | 'point' | 'circle' | 'square' | 'tick' | undefined; + encodeEntry: (model: UnitModel) => VgEncodeEntry; +} diff --git a/build/src/compile/mark/base.js b/build/src/compile/mark/base.js new file mode 100644 index 0000000000..db1dbbe9de --- /dev/null +++ b/build/src/compile/mark/base.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0= \ No newline at end of file diff --git a/build/src/compile/mark/init.d.ts b/build/src/compile/mark/init.d.ts new file mode 100644 index 0000000000..c98813ea6a --- /dev/null +++ b/build/src/compile/mark/init.d.ts @@ -0,0 +1,13 @@ +import { Mark, MarkDef } from '../../mark'; +import { Encoding } from '../../encoding'; +import { Dict } from '../../util'; +import { Scale } from '../../scale'; +import { Config } from '../../config'; +import { StackProperties } from '../../stack'; +export declare function initMarkDef(mark: Mark | MarkDef, encoding: Encoding, scale: Dict, config: Config): MarkDef & { + filled: boolean; +}; +/** + * Initialize encoding's value with some special default values + */ +export declare function initEncoding(mark: Mark, encoding: Encoding, stacked: StackProperties, config: Config): Encoding; diff --git a/build/src/compile/mark/init.js b/build/src/compile/mark/init.js new file mode 100644 index 0000000000..d2c1ada236 --- /dev/null +++ b/build/src/compile/mark/init.js @@ -0,0 +1,149 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mark_1 = require("../../mark"); +var encoding_1 = require("../../encoding"); +var log = require("../../log"); +var util_1 = require("../../util"); +var scale_1 = require("../../scale"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var common_1 = require("../common"); +function initMarkDef(mark, encoding, scale, config) { + var markDef = mark_1.isMarkDef(mark) ? mark : { type: mark }; + var specifiedOrient = markDef.orient || common_1.getMarkConfig('orient', markDef.type, config); + markDef.orient = orient(markDef.type, encoding, scale, specifiedOrient); + if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) { + log.warn(log.message.orientOverridden(markDef.orient, specifiedOrient)); + } + return tslib_1.__assign({}, markDef, { + // TODO: filled could be injected to encoding too, but we don't have filled channel yet. + // Thus we inject it here for now. + filled: filled(markDef.type, config) }); +} +exports.initMarkDef = initMarkDef; +/** + * Initialize encoding's value with some special default values + */ +function initEncoding(mark, encoding, stacked, config) { + var opacityConfig = common_1.getMarkConfig('opacity', mark, config); + if (!encoding.opacity && opacityConfig === undefined) { + var opacity = defaultOpacity(mark, encoding, stacked); + if (opacity !== undefined) { + encoding.opacity = { value: opacity }; + } + } + return encoding; +} +exports.initEncoding = initEncoding; +function defaultOpacity(mark, encoding, stacked) { + if (util_1.contains([mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE], mark)) { + // point-based marks + if (!encoding_1.isAggregate(encoding) || encoding_1.channelHasField(encoding, 'detail')) { + return 0.7; + } + } + if (mark === mark_1.BAR && !stacked) { + if (encoding_1.channelHasField(encoding, 'color') || encoding_1.channelHasField(encoding, 'detail') || encoding_1.channelHasField(encoding, 'size')) { + return 0.7; + } + } + if (mark === mark_1.AREA) { + return 0.7; // inspired by Tableau + } + return undefined; +} +function filled(mark, config) { + var filledConfig = common_1.getMarkConfig('filled', mark, config); + return filledConfig !== undefined ? filledConfig : mark !== mark_1.POINT && mark !== mark_1.LINE && mark !== mark_1.RULE; +} +function orient(mark, encoding, scale, specifiedOrient) { + switch (mark) { + case mark_1.POINT: + case mark_1.CIRCLE: + case mark_1.SQUARE: + case mark_1.TEXT: + case mark_1.RECT: + // orient is meaningless for these marks. + return undefined; + } + var yIsRange = encoding.y && encoding.y2; + var xIsRange = encoding.x && encoding.x2; + switch (mark) { + case mark_1.TICK: + var xScaleType = scale['x'] ? scale['x'].type : null; + var yScaleType = scale['y'] ? scale['y'].type : null; + // Tick is opposite to bar, line, area and never have ranged mark. + if (!scale_1.hasDiscreteDomain(xScaleType) && (!encoding.y || + scale_1.hasDiscreteDomain(yScaleType) || + (fielddef_1.isFieldDef(encoding.y) && encoding.y.bin))) { + return 'vertical'; + } + // y:Q or Ambiguous case, return horizontal + return 'horizontal'; + case mark_1.RULE: + case mark_1.BAR: + case mark_1.AREA: + // If there are range for both x and y, y (vertical) has higher precedence. + if (yIsRange) { + return 'vertical'; + } + else if (xIsRange) { + return 'horizontal'; + } + else if (mark === mark_1.RULE) { + if (encoding.x && !encoding.y) { + return 'vertical'; + } + else if (encoding.y && !encoding.x) { + return 'horizontal'; + } + } + /* tslint:disable */ + case mark_1.LINE: + /* tslint:enable */ + var xIsContinuous = fielddef_1.isFieldDef(encoding.x) && fielddef_1.isContinuous(encoding.x); + var yIsContinuous = fielddef_1.isFieldDef(encoding.y) && fielddef_1.isContinuous(encoding.y); + if (xIsContinuous && !yIsContinuous) { + return 'horizontal'; + } + else if (!xIsContinuous && yIsContinuous) { + return 'vertical'; + } + else if (xIsContinuous && yIsContinuous) { + var xDef = encoding.x; // we can cast here since they are surely fieldDef + var yDef = encoding.y; + var xIsTemporal = xDef.type === type_1.TEMPORAL; + var yIsTemporal = yDef.type === type_1.TEMPORAL; + // temporal without timeUnit is considered continuous, but better serves as dimension + if (xIsTemporal && !yIsTemporal) { + return 'vertical'; + } + else if (!xIsTemporal && yIsTemporal) { + return 'horizontal'; + } + if (!xDef.aggregate && !!yDef.aggregate) { + return 'vertical'; + } + else if (!!xDef.aggregate && !yDef.aggregate) { + return 'horizontal'; + } + if (specifiedOrient) { + // When ambiguous, use user specified one. + return specifiedOrient; + } + if (!(mark === mark_1.LINE && encoding.order)) { + // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots. + log.warn(log.message.unclearOrientContinuous(mark)); + } + return 'vertical'; + } + else { + // For Discrete x Discrete case, return undefined. + log.warn(log.message.unclearOrientDiscreteOrEmpty(mark)); + return undefined; + } + } + return 'vertical'; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvaW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBNEg7QUFDNUgsMkNBQXNFO0FBQ3RFLCtCQUFpQztBQUNqQyxtQ0FBMEM7QUFDMUMscUNBQXFEO0FBQ3JELDJDQUFrRTtBQUNsRSxtQ0FBb0M7QUFFcEMsb0NBQXdDO0FBR3hDLHFCQUE0QixJQUFvQixFQUFFLFFBQWtCLEVBQUUsS0FBa0IsRUFBRSxNQUFjO0lBQ3RHLElBQU0sT0FBTyxHQUFHLGdCQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDO0lBRXRELElBQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksc0JBQWEsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN4RixPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDeEUsRUFBRSxDQUFDLENBQUMsZUFBZSxLQUFLLFNBQVMsSUFBSSxlQUFlLEtBQUssT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDeEUsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsTUFBTSxzQkFDRCxPQUFPO1FBRVYsd0ZBQXdGO1FBQ3hGLGtDQUFrQztRQUNsQyxNQUFNLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQ3BDO0FBQ0osQ0FBQztBQWhCRCxrQ0FnQkM7QUFFRDs7R0FFRztBQUNILHNCQUE2QixJQUFV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 \ No newline at end of file diff --git a/build/src/compile/mark/line.d.ts b/build/src/compile/mark/line.d.ts new file mode 100644 index 0000000000..1a1b8215a5 --- /dev/null +++ b/build/src/compile/mark/line.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const line: MarkCompiler; diff --git a/build/src/compile/mark/line.js b/build/src/compile/mark/line.js new file mode 100644 index 0000000000..82bed7d3bb --- /dev/null +++ b/build/src/compile/mark/line.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +exports.line = { + vgMark: 'line', + role: undefined, + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.color(model), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's line size is strokeWidth + }), mixins.markDefProperties(model.markDef, ['interpolate', 'tension'])); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvbGluZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpQ0FBbUM7QUFLdEIsUUFBQSxJQUFJLEdBQWlCO0lBQ2hDLE1BQU0sRUFBRSxNQUFNO0lBQ2QsSUFBSSxFQUFFLFNBQVM7SUFDZixXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUM1QixNQUFNLHNCQUNELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsRUFDN0MsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUM3QyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUNuQixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDcEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFO1lBQ25DLFNBQVMsRUFBRSxhQUFhLENBQUUsZ0NBQWdDO1NBQzNELENBQUMsRUFDQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUN0RTtJQUNKLENBQUM7Q0FDRixDQUFDIn0= \ No newline at end of file diff --git a/build/src/compile/mark/mark.d.ts b/build/src/compile/mark/mark.d.ts new file mode 100644 index 0000000000..556b38b39a --- /dev/null +++ b/build/src/compile/mark/mark.d.ts @@ -0,0 +1,2 @@ +import { UnitModel } from '../unit'; +export declare function parseMark(model: UnitModel): any[]; diff --git a/build/src/compile/mark/mark.js b/build/src/compile/mark/mark.js new file mode 100644 index 0000000000..dabb93e532 --- /dev/null +++ b/build/src/compile/mark/mark.js @@ -0,0 +1,108 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var mark_1 = require("../../mark"); +var util_1 = require("../../util"); +var area_1 = require("./area"); +var bar_1 = require("./bar"); +var line_1 = require("./line"); +var point_1 = require("./point"); +var rect_1 = require("./rect"); +var rule_1 = require("./rule"); +var text_1 = require("./text"); +var tick_1 = require("./tick"); +var markCompiler = { + area: area_1.area, + bar: bar_1.bar, + line: line_1.line, + point: point_1.point, + text: text_1.text, + tick: tick_1.tick, + rect: rect_1.rect, + rule: rule_1.rule, + circle: point_1.circle, + square: point_1.square +}; +function parseMark(model) { + if (util_1.contains([mark_1.LINE, mark_1.AREA], model.mark())) { + return parsePathMark(model); + } + else { + return parseNonPathMark(model); + } +} +exports.parseMark = parseMark; +// FIXME: maybe this should not be here. Need re-think and refactor, esp. after having all composition in. +function dataFrom(model) { + var parent = model.parent; + if (parent && parent.isFacet()) { + return parent.facetedTable(); + } + if (model.stack) { + return model.dataName('stacked'); + } + return model.dataTable(); +} +var FACETED_PATH_PREFIX = 'faceted-path-'; +function parsePathMark(model) { + var mark = model.mark(); + // FIXME: replace this with more general case for composition + var details = detailFields(model); + var pathMarks = [ + { + name: model.getName('marks'), + type: markCompiler[mark].vgMark, + // If has subfacet for line/area group, need to use faceted data from below. + // FIXME: support sorting path order (in connected scatterplot) + from: { data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + dataFrom(model) }, + encode: { update: markCompiler[mark].encodeEntry(model) } + } + ]; + if (details.length > 0) { + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + return [{ + name: model.getName('pathgroup'), + type: 'group', + from: { + facet: { + name: FACETED_PATH_PREFIX + dataFrom(model), + data: dataFrom(model), + groupby: details, + } + }, + encode: { + update: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } } + } + }, + marks: pathMarks + }]; + } + else { + return pathMarks; + } +} +function parseNonPathMark(model) { + var mark = model.mark(); + var role = markCompiler[mark].role; + var marks = []; // TODO: vgMarks + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + marks.push(tslib_1.__assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (role ? { role: role } : {}), { from: { data: dataFrom(model) }, encode: { update: markCompiler[mark].encodeEntry(model) } })); + return marks; +} +var NONSPATIAL_CHANNELS_EXCEPT_ORDER = util_1.without(channel_1.NONSPATIAL_CHANNELS, ['order']); +/** + * Returns list of detail (group-by) fields + * that the model's spec contains. + */ +function detailFields(model) { + return NONSPATIAL_CHANNELS_EXCEPT_ORDER.reduce(function (details, channel) { + if (model.channelHasField(channel) && !model.fieldDef(channel).aggregate) { + details.push(model.field(channel)); + } + return details; + }, []); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvbWFyay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBMkQ7QUFDM0QsbUNBQXNDO0FBQ3RDLG1DQUE2QztBQUc3QywrQkFBNEI7QUFDNUIsNkJBQTBCO0FBQzFCLCtCQUE0QjtBQUM1QixpQ0FBOEM7QUFDOUMsK0JBQTRCO0FBQzVCLCtCQUE0QjtBQUM1QiwrQkFBNEI7QUFDNUIsK0JBQTRCO0FBSzVCLElBQU0sWUFBWSxHQUFtQztJQUNuRCxJQUFJLEVBQUUsV0FBSTtJQUNWLEdBQUcsRUFBRSxTQUFHO0lBQ1IsSUFBSSxFQUFFLFdBQUk7SUFDVixLQUFLLEVBQUUsYUFBSztJQUNaLElBQUksRUFBRSxXQUFJO0lBQ1YsSUFBSSxFQUFFLFdBQUk7SUFDVixJQUFJLEVBQUUsV0FBSTtJQUNWLElBQUksRUFBRSxXQUFJO0lBQ1YsTUFBTSxFQUFFLGNBQU07SUFDZCxNQUFNLEVBQUUsY0FBTTtDQUNmLENBQUM7QUFFRixtQkFBMEIsS0FBZ0I7SUFDeEMsRUFBRSxDQUFDLENBQUMsZUFBUSxDQUFDLENBQUMsV0FBSSxFQUFFLFdBQUksQ0FBQyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0FBQ0gsQ0FBQztBQU5ELDhCQU1DO0FBRUQsMkdBQTJHO0FBQzNHLGtCQUFrQixLQUFnQjtJQUNoQyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQzVCLEVBQUUsQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFD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 \ No newline at end of file diff --git a/build/src/compile/mark/mixins.d.ts b/build/src/compile/mark/mixins.d.ts new file mode 100644 index 0000000000..79c6fdb09a --- /dev/null +++ b/build/src/compile/mark/mixins.d.ts @@ -0,0 +1,40 @@ +import { MarkDef } from '../../mark'; +import { VgEncodeEntry, VgValueRef } from '../../vega.schema'; +import { UnitModel } from '../unit'; +import { NONSPATIAL_SCALE_CHANNELS } from '../../channel'; +export declare function color(model: UnitModel): any; +export declare function markDefProperties(mark: MarkDef, props: (keyof MarkDef)[]): {}; +export declare function valueIfDefined(prop: string, value: VgValueRef): VgEncodeEntry; +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +export declare function nonPosition(channel: typeof NONSPATIAL_SCALE_CHANNELS[0], model: UnitModel, opt?: { + defaultValue?: number | string | boolean; + vgChannel?: string; + defaultRef?: VgValueRef; +}): VgEncodeEntry; +export declare function text(model: UnitModel): any; +export declare function bandPosition(channel: 'x' | 'y', model: UnitModel): { + [x: string]: VgValueRef; +}; +export declare function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef): any; +export declare function binnedPosition(channel: 'x' | 'y', model: UnitModel, spacing: number): { + x2: VgValueRef; + x: VgValueRef; +} | { + y2: VgValueRef; + y: VgValueRef; +}; +/** + * Return mixins for point (non-band) position channels. + */ +export declare function pointPosition(channel: 'x' | 'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x' | 'y' | 'xc' | 'yc'): { + [x: string]: VgValueRef; +}; +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +export declare function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel?: 'x2' | 'y2'): { + [x: string]: VgValueRef; +}; diff --git a/build/src/compile/mark/mixins.js b/build/src/compile/mark/mixins.js new file mode 100644 index 0000000000..231ac9bda4 --- /dev/null +++ b/build/src/compile/mark/mixins.js @@ -0,0 +1,141 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var util = require("../../util"); +var common_1 = require("../common"); +var ref = require("./valueref"); +var selection_1 = require("../selection/selection"); +function color(model) { + var config = model.config; + var filled = model.markDef.filled; + var e = nonPosition('color', model, { + vgChannel: filled ? 'fill' : 'stroke', + defaultValue: common_1.getMarkConfig('color', model.mark(), config) + }); + // If there is no fill, always fill symbols + // with transparent fills https://github.com/vega/vega-lite/issues/1316 + if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) { + e.fill = { value: 'transparent' }; + } + return e; +} +exports.color = color; +function markDefProperties(mark, props) { + return props.reduce(function (m, prop) { + if (mark[prop]) { + m[prop] = { value: mark[prop] }; + } + return m; + }, {}); +} +exports.markDefProperties = markDefProperties; +function valueIfDefined(prop, value) { + if (value !== undefined) { + return _a = {}, _a[prop] = { value: value }, _a; + } + return undefined; + var _a; +} +exports.valueIfDefined = valueIfDefined; +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +function nonPosition(channel, model, opt) { + // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + if (opt === void 0) { opt = {}; } + var defaultValue = opt.defaultValue, vgChannel = opt.vgChannel; + var defaultRef = opt.defaultRef || (defaultValue !== undefined ? { value: defaultValue } : undefined); + var channelDef = model.encoding[channel]; + var valueRef = ref.midPoint(channel, channelDef, model.scaleName(channel), model.scale(channel), defaultRef); + return wrapCondition(model, channelDef && channelDef.condition, vgChannel || channel, valueRef); +} +exports.nonPosition = nonPosition; +/** + * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition. + * or a simple mixin if channel def has no condition. + */ +function wrapCondition(model, condition, vgChannel, valueRef) { + if (condition) { + var selection = condition.selection, value = condition.value; + return _a = {}, + _a[vgChannel] = [ + { test: selectionTest(model, selection), value: value } + ].concat((valueRef !== undefined ? [valueRef] : [])), + _a; + } + else { + return valueRef !== undefined ? (_b = {}, _b[vgChannel] = valueRef, _b) : {}; + } + var _a, _b; +} +function selectionTest(model, selectionName) { + var negate = selectionName.charAt(0) === '!', name = negate ? selectionName.slice(1) : selectionName; + return (negate ? '!' : '') + selection_1.predicate(model.component.selection[name]); +} +function text(model) { + var channelDef = model.encoding.text; + return wrapCondition(model, channelDef && channelDef.condition, 'text', ref.text(channelDef, model.config)); +} +exports.text = text; +function bandPosition(channel, model) { + // TODO: band scale doesn't support size yet + var fieldDef = model.encoding[channel]; + var scaleName = model.scaleName(channel); + var sizeChannel = channel === 'x' ? 'width' : 'height'; + return _a = {}, + _a[channel] = ref.fieldRef(fieldDef, scaleName, {}), + _a[sizeChannel] = ref.band(scaleName), + _a; + var _a; +} +exports.bandPosition = bandPosition; +function centeredBandPosition(channel, model, defaultPosRef, defaultSizeRef) { + var centerChannel = channel === 'x' ? 'xc' : 'yc'; + var sizeChannel = channel === 'x' ? 'width' : 'height'; + return tslib_1.__assign({}, pointPosition(channel, model, defaultPosRef, centerChannel), nonPosition('size', model, { defaultRef: defaultSizeRef, vgChannel: sizeChannel })); +} +exports.centeredBandPosition = centeredBandPosition; +function binnedPosition(channel, model, spacing) { + var fieldDef = model.encoding[channel]; + var scaleName = model.scaleName(channel); + if (channel === 'x') { + return { + x2: ref.bin(fieldDef, scaleName, 'start', spacing), + x: ref.bin(fieldDef, scaleName, 'end') + }; + } + else { + return { + y2: ref.bin(fieldDef, scaleName, 'start'), + y: ref.bin(fieldDef, scaleName, 'end', spacing) + }; + } +} +exports.binnedPosition = binnedPosition; +/** + * Return mixins for point (non-band) position channels. + */ +function pointPosition(channel, model, defaultRef, vgChannel) { + // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + var encoding = model.encoding, stack = model.stack; + var valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.scale(channel), stack, defaultRef); + return _a = {}, + _a[vgChannel || channel] = valueRef, + _a; + var _a; +} +exports.pointPosition = pointPosition; +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +function pointPosition2(model, defaultRef, channel) { + var encoding = model.encoding, markDef = model.markDef, stack = model.stack; + channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2'); + var baseChannel = channel === 'x2' ? 'x' : 'y'; + var valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.scale(baseChannel), stack, defaultRef); + return _a = {}, _a[channel] = valueRef, _a; + var _a; +} +exports.pointPosition2 = pointPosition2; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWl4aW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvbWFyay9taXhpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsaUNBQW1DO0FBRW5DLG9DQUF3QztBQUd4QyxnQ0FBa0M7QUFJbEMsb0RBQWlEO0FBRWpELGVBQXNCLEtBQWdCO0lBQ3BDLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDNUIsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFFcEMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUU7UUFDbEMsU0FBUyxFQUFFLE1BQU0sR0FBRyxNQUFNLEdBQUcsUUFBUTtRQUNyQyxZQUFZLEVBQUUsc0JBQWEsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sQ0FBVztLQUNyRSxDQUFDLENBQUM7SUFFSCwyQ0FBMkM7SUFDM0MsdUVBQXVFO0lBQ3ZFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pGLENBQUMsQ0FBQyxJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFDLENBQUM7SUFDbEMsQ0FBQztJQUNELE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDWCxDQUFDO0FBZkQsc0JBZUM7QUFFRCwyQkFBa0MsSUFBYSxFQUFFLEtBQXdCO0lBQ3ZFLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBQyxFQUFFLElBQUk7UUFDMUIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FB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 \ No newline at end of file diff --git a/build/src/compile/mark/point.d.ts b/build/src/compile/mark/point.d.ts new file mode 100644 index 0000000000..2502d82ccd --- /dev/null +++ b/build/src/compile/mark/point.d.ts @@ -0,0 +1,7 @@ +import { UnitModel } from '../unit'; +import { MarkCompiler } from './base'; +import { Config } from '../../config'; +export declare function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square'): any; +export declare const point: MarkCompiler; +export declare const circle: MarkCompiler; +export declare const square: MarkCompiler; diff --git a/build/src/compile/mark/point.js b/build/src/compile/mark/point.js new file mode 100644 index 0000000000..204806ac90 --- /dev/null +++ b/build/src/compile/mark/point.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +var common_1 = require("../common"); +function encodeEntry(model, fixedShape) { + var config = model.config; + return tslib_1.__assign({}, mixins.pointPosition('x', model, ref.midX(config)), mixins.pointPosition('y', model, ref.midY(config)), mixins.color(model), mixins.nonPosition('size', model), shapeMixins(model, config, fixedShape), mixins.nonPosition('opacity', model)); +} +function shapeMixins(model, config, fixedShape) { + if (fixedShape) { + return { shape: { value: fixedShape } }; + } + return mixins.nonPosition('shape', model, { defaultValue: common_1.getMarkConfig('shape', 'point', config) }); +} +exports.shapeMixins = shapeMixins; +exports.point = { + vgMark: 'symbol', + role: 'point', + encodeEntry: function (model) { + return encodeEntry(model); + } +}; +exports.circle = { + vgMark: 'symbol', + role: 'circle', + encodeEntry: function (model) { + return encodeEntry(model, 'circle'); + } +}; +exports.square = { + vgMark: 'symbol', + role: 'square', + encodeEntry: function (model) { + return encodeEntry(model, 'square'); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9pbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL3BvaW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLGlDQUFtQztBQUluQyxnQ0FBa0M7QUFDbEMsb0NBQXdDO0FBR3hDLHFCQUFxQixLQUFnQixFQUFFLFVBQWdDO0lBQzlELElBQUEscUJBQU0sQ0FBVTtJQUV2QixNQUFNLHNCQUNELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ2xELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBRWxELE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQ25CLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUNqQyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFDdEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3ZDO0FBQ0osQ0FBQztBQUVELHFCQUE0QixLQUFnQixFQUFFLE1BQWMsRUFBRSxVQUFnQztJQUM1RixFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2YsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFVBQVUsRUFBQyxFQUFDLENBQUM7SUFDdEMsQ0FBQztJQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBQyxZQUFZLEVBQUUsc0JBQWEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBVyxFQUFDLENBQUMsQ0FBQztBQUMvRyxDQUFDO0FBTEQsa0NBS0M7QUFFWSxRQUFBLEtBQUssR0FBaUI7SUFDakMsTUFBTSxFQUFFLFFBQVE7SUFDaEIsSUFBSSxFQUFFLE9BQU87SUFDYixXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUM1QixNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVCLENBQUM7Q0FDRixDQUFDO0FBRVcsUUFBQSxNQUFNLEdBQWlCO0lBQ2xDLE1BQU0sRUFBRSxRQUFRO0lBQ2hCLElBQUksRUFBRSxRQUFRO0lBQ2QsV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDNUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdEMsQ0FBQztDQUNGLENBQUM7QUFFVyxRQUFBLE1BQU0sR0FBaUI7SUFDbEMsTUFBTSxFQUFFLFFBQVE7SUFDaEIsSUFBSSxFQUFFLFFBQVE7SUFDZCxXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUM1QixNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0QyxDQUFDO0NBQ0YsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/compile/mark/rect.d.ts b/build/src/compile/mark/rect.d.ts new file mode 100644 index 0000000000..58a147b1bb --- /dev/null +++ b/build/src/compile/mark/rect.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const rect: MarkCompiler; diff --git a/build/src/compile/mark/rect.js b/build/src/compile/mark/rect.js new file mode 100644 index 0000000000..8da3aaac31 --- /dev/null +++ b/build/src/compile/mark/rect.js @@ -0,0 +1,59 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var mark_1 = require("../../mark"); +var log = require("../../log"); +var mixins = require("./mixins"); +exports.rect = { + vgMark: 'rect', + role: undefined, + encodeEntry: function (model) { + return tslib_1.__assign({}, x(model), y(model), mixins.color(model), mixins.nonPosition('opacity', model)); + } +}; +function x(model) { + var xDef = model.encoding.x; + var x2Def = model.encoding.x2; + var xScale = model.scale(channel_1.X); + if (fielddef_1.isFieldDef(xDef) && xDef.bin && !x2Def) { + return mixins.binnedPosition('x', model, 0); + } + else if (xScale && scale_1.hasDiscreteDomain(xScale.type)) { + /* istanbul ignore else */ + if (xScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('x', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(log.message.scaleTypeNotWorkWithMark(mark_1.RECT, xScale.type)); + } + } + else { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'x2')); + } +} +function y(model) { + var yDef = model.encoding.y; + var y2Def = model.encoding.y2; + var yScale = model.scale(channel_1.Y); + if (fielddef_1.isFieldDef(yDef) && yDef.bin && !y2Def) { + return mixins.binnedPosition('y', model, 0); + } + else if (yScale && scale_1.hasDiscreteDomain(yScale.type)) { + /* istanbul ignore else */ + if (yScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('y', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(log.message.scaleTypeNotWorkWithMark(mark_1.RECT, yScale.type)); + } + } + else { + return tslib_1.__assign({}, mixins.pointPosition('y', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'y2')); + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvcmVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBbUM7QUFDbkMsMkNBQTBDO0FBQzFDLHFDQUF5RDtBQUN6RCxtQ0FBZ0M7QUFDaEMsK0JBQWlDO0FBRWpDLGlDQUFtQztBQUt0QixRQUFBLElBQUksR0FBaUI7SUFDaEMsTUFBTSxFQUFFLE1BQU07SUFDZCxJQUFJLEVBQUUsU0FBUztJQUNmLFdBQVcsRUFBRSxVQUFDLEtBQWdCO1FBQzVCLE1BQU0sc0JBQ0QsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUNSLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFDUixNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUNuQixNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsRUFDdkM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLFdBQVcsS0FBZ0I7SUFDekIsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUIsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7SUFDaEMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxXQUFDLENBQUMsQ0FBQztJQUU5QixFQUFFLENBQUMsQ0FBQyxxQkFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLElBQUkseUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRCwwQkFBMEI7UUFDMUIsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxpQkFBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLHNEQUFzRDtZQUN0RCxNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsV0FBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzNFLENBQUM7SUFDSCxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixNQUFNLHNCQUNELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsRUFDN0MsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxFQUNsRDtJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsV0FBVyxLQUFnQjtJQUN6QixJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUM5QixJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUNoQyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQUMsQ0FBQyxDQUFDO0lBRTlCLEVBQUUsQ0FBQyxDQUFDLHFCQUFVLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sSUFBSSx5QkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BELDBCQUEwQjtRQUMxQixFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLGlCQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sc0RBQXNEO1lBQ3RELE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxXQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDM0UsQ0FBQztJQUNILENBQUM7SUFBQyxJQUFJLENBQUMsQ0FBQztRQUNOLE1BQU0sc0JBQ0QsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUM3QyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLEVBQ2xEO0lBQ0osQ0FBQztBQUNILENBQUMifQ== \ No newline at end of file diff --git a/build/src/compile/mark/rule.d.ts b/build/src/compile/mark/rule.d.ts new file mode 100644 index 0000000000..4b4078e38f --- /dev/null +++ b/build/src/compile/mark/rule.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const rule: MarkCompiler; diff --git a/build/src/compile/mark/rule.js b/build/src/compile/mark/rule.js new file mode 100644 index 0000000000..e49ea16dae --- /dev/null +++ b/build/src/compile/mark/rule.js @@ -0,0 +1,14 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +exports.rule = { + vgMark: 'rule', + role: undefined, + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMax'), mixins.color(model), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's rule size is strokeWidth + })); + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpQ0FBbUM7QUFFdEIsUUFBQSxJQUFJLEdBQWlCO0lBQ2hDLE1BQU0sRUFBRSxNQUFNO0lBQ2QsSUFBSSxFQUFFLFNBQVM7SUFDZixXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUM1QixNQUFNLHNCQUNELE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsRUFDN0MsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxFQUM3QyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsRUFFekMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFDbkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3BDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtZQUNuQyxTQUFTLEVBQUUsYUFBYSxDQUFFLGdDQUFnQztTQUMzRCxDQUFDLEVBQ0Y7SUFDSixDQUFDO0NBQ0YsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/compile/mark/text.d.ts b/build/src/compile/mark/text.d.ts new file mode 100644 index 0000000000..3f8145da15 --- /dev/null +++ b/build/src/compile/mark/text.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const text: MarkCompiler; diff --git a/build/src/compile/mark/text.js b/build/src/compile/mark/text.js new file mode 100644 index 0000000000..9660468950 --- /dev/null +++ b/build/src/compile/mark/text.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var common_1 = require("../common"); +var mixins = require("./mixins"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var ref = require("./valueref"); +var encoding_1 = require("../../encoding"); +exports.text = { + vgMark: 'text', + role: undefined, + encodeEntry: function (model) { + var config = model.config, encoding = model.encoding; + var textDef = encoding.text; + return tslib_1.__assign({}, mixins.pointPosition('x', model, xDefault(config, textDef)), mixins.pointPosition('y', model, ref.midY(config)), mixins.text(model), mixins.color(model), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'fontSize' // VL's text size is fontSize + }), mixins.valueIfDefined('align', align(encoding, config))); + } +}; +function xDefault(config, textDef) { + if (fielddef_1.isFieldDef(textDef) && textDef.type === type_1.QUANTITATIVE) { + return { field: { group: 'width' }, offset: -5 }; + } + // TODO: allow this to fit (Be consistent with ref.midX()) + return { value: config.scale.textXRangeStep / 2 }; +} +function align(encoding, config) { + var alignConfig = common_1.getMarkConfig('align', 'text', config); + if (alignConfig === undefined) { + return encoding_1.channelHasField(encoding, channel_1.X) ? 'center' : 'right'; + } + // If there is a config, Vega-parser will process this already. + return undefined; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvdGV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBZ0M7QUFDaEMsb0NBQXdDO0FBRXhDLGlDQUFtQztBQUVuQywyQ0FBc0Q7QUFDdEQsbUNBQXdDO0FBS3hDLGdDQUFrQztBQUNsQywyQ0FBeUQ7QUFFNUMsUUFBQSxJQUFJLEdBQWlCO0lBQ2hDLE1BQU0sRUFBRSxNQUFNO0lBQ2QsSUFBSSxFQUFFLFNBQVM7SUFFZixXQUFXLEVBQUUsVUFBQyxLQUFnQjtRQUNyQixJQUFBLHFCQUFNLEVBQUUseUJBQVEsQ0FBVTtRQUNqQyxJQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBRTlCLE1BQU0sc0JBQ0QsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUMsRUFDM0QsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDbEQsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFDbEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFDbkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3BDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtZQUNuQyxTQUFTLEVBQUUsVUFBVSxDQUFFLDZCQUE2QjtTQUNyRCxDQUFDLEVBQ0MsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxFQUMxRDtJQUNKLENBQUM7Q0FDRixDQUFDO0FBRUYsa0JBQWtCLE1BQWMsRUFBRSxPQUFtQjtJQUNuRCxFQUFFLENBQUMsQ0FBQyxxQkFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssbUJBQVksQ0FBQyxDQUFDLENBQUM7UUFDekQsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBQyxDQUFDO0lBQy9DLENBQUM7SUFDRCwwREFBMEQ7SUFDMUQsTUFBTSxDQUFDLEVBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxHQUFHLENBQUMsRUFBQyxDQUFDO0FBQ2xELENBQUM7QUFFRCxlQUFlLFFBQWtCLEVBQUUsTUFBYztJQUMvQyxJQUFNLFdBQVcsR0FBRyxzQkFBYSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0QsRUFBRSxDQUFDLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLDBCQUFlLENBQUMsUUFBUSxFQUFFLFdBQUMsQ0FBQyxHQUFHLFFBQVEsR0FBRyxPQUFPLENBQUM7SUFDM0QsQ0FBQztJQUNELCtEQUErRDtJQUMvRCxNQUFNLENBQUMsU0FBUyxDQUFDO0FBQ25CLENBQUMifQ== \ No newline at end of file diff --git a/build/src/compile/mark/tick.d.ts b/build/src/compile/mark/tick.d.ts new file mode 100644 index 0000000000..9e01bb786c --- /dev/null +++ b/build/src/compile/mark/tick.d.ts @@ -0,0 +1,2 @@ +import { MarkCompiler } from './base'; +export declare const tick: MarkCompiler; diff --git a/build/src/compile/mark/tick.js b/build/src/compile/mark/tick.js new file mode 100644 index 0000000000..1ea09e9bd1 --- /dev/null +++ b/build/src/compile/mark/tick.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.tick = { + vgMark: 'rect', + role: 'tick', + encodeEntry: function (model) { + var config = model.config, markDef = model.markDef; + var orient = markDef.orient; + var vgSizeChannel = orient === 'horizontal' ? 'width' : 'height'; + var vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width'; + return tslib_1.__assign({}, mixins.pointPosition('x', model, ref.midX(config), 'xc'), mixins.pointPosition('y', model, ref.midY(config), 'yc'), mixins.nonPosition('size', model, { + defaultValue: defaultSize(model), + vgChannel: vgSizeChannel + }), (_a = {}, _a[vgThicknessChannel] = { value: config.tick.thickness }, _a), mixins.color(model), mixins.nonPosition('opacity', model)); + var _a; + } +}; +function defaultSize(model) { + var config = model.config; + var orient = model.markDef.orient; + var scaleRangeStep = (model.scale(orient === 'horizontal' ? 'x' : 'y') || {}).rangeStep; + if (config.tick.bandSize !== undefined) { + return config.tick.bandSize; + } + else { + var rangeStep = scaleRangeStep !== undefined ? + scaleRangeStep : + config.scale.rangeStep; + if (typeof rangeStep !== 'number') { + // FIXME consolidate this log + throw new Error('Function does not handle non-numeric rangeStep'); + } + return rangeStep / 1.5; + } +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGljay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL21hcmsvdGljay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpQ0FBbUM7QUFJbkMsZ0NBQWtDO0FBRXJCLFFBQUEsSUFBSSxHQUFpQjtJQUNoQyxNQUFNLEVBQUUsTUFBTTtJQUNkLElBQUksRUFBRSxNQUFNO0lBRVosV0FBVyxFQUFFLFVBQUMsS0FBZ0I7UUFDckIsSUFBQSxxQkFBTSxFQUFFLHVCQUFPLENBQVU7UUFDaEMsSUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUU5QixJQUFNLGFBQWEsR0FBRyxNQUFNLEtBQUssWUFBWSxHQUFHLE9BQU8sR0FBRyxRQUFRLENBQUM7UUFDbkUsSUFBTSxrQkFBa0IsR0FBRyxNQUFNLEtBQUssWUFBWSxHQUFHLFFBQVEsR0FBRyxPQUFPLENBQUM7UUFFeEUsTUFBTSxzQkFDRCxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsRUFDeEQsTUFBTSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBR3hELE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRTtZQUNuQyxZQUFZLEVBQUUsV0FBVyxDQUFDLEtBQUssQ0FBQztZQUNoQyxTQUFTLEVBQUUsYUFBYTtTQUN6QixDQUFDLGVBQ0Qsa0JBQWtCLElBQUcsRUFBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsT0FFakQsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFDbkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3ZDOztJQUNKLENBQUM7Q0FDRixDQUFDO0FBRUYscUJBQXFCLEtBQWdCO0lBQzVCLElBQUEscUJBQU0sQ0FBVTtJQUN2QixJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztJQUVwQyxJQUFNLGNBQWMsR0FBa0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxZQUFZLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUV6RyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUM5QixDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixJQUFNLFNBQVMsR0FBRyxjQUFjLEtBQUssU0FBUztZQUM1QyxjQUFjO1lBQ2QsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDekIsRUFBRSxDQUFDLENBQUMsT0FBTyxTQUFTLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNsQyw2QkFBNkI7WUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxNQUFNLENBQUMsU0FBUyxHQUFHLEdBQUcsQ0FBQztJQUN6QixDQUFDO0FBQ0gsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/compile/mark/valueref.d.ts b/build/src/compile/mark/valueref.d.ts new file mode 100644 index 0000000000..fb3c90f441 --- /dev/null +++ b/build/src/compile/mark/valueref.d.ts @@ -0,0 +1,30 @@ +/** + * Utility files for producing Vega ValueRef for marks + */ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { ChannelDef, FieldDef, FieldRefOption, TextFieldDef, ValueDef } from '../../fielddef'; +import { Scale } from '../../scale'; +import { StackProperties } from '../../stack'; +import { VgValueRef } from '../../vega.schema'; +/** + * @return Vega ValueRef for stackable x or y + */ +export declare function stackable(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: Scale, stack: StackProperties, defaultRef: VgValueRef): VgValueRef; +/** + * @return Vega ValueRef for stackable x2 or y2 + */ +export declare function stackable2(channel: 'x2' | 'y2', aFieldDef: FieldDef, a2fieldDef: FieldDef, scaleName: string, scale: Scale, stack: StackProperties, defaultRef: VgValueRef): VgValueRef; +/** + * Value Ref for binned fields + */ +export declare function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number): VgValueRef; +export declare function fieldRef(fieldDef: FieldDef, scaleName: string, opt: FieldRefOption, offset?: number | VgValueRef): VgValueRef; +export declare function band(scaleName: string, band?: number | boolean): VgValueRef; +/** + * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels. + */ +export declare function midPoint(channel: Channel, channelDef: ChannelDef, scaleName: string, scale: Scale, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): VgValueRef; +export declare function text(textDef: TextFieldDef | ValueDef, config: Config): VgValueRef; +export declare function midX(config: Config): VgValueRef; +export declare function midY(config: Config): VgValueRef; diff --git a/build/src/compile/mark/valueref.js b/build/src/compile/mark/valueref.js new file mode 100644 index 0000000000..0773a95d12 --- /dev/null +++ b/build/src/compile/mark/valueref.js @@ -0,0 +1,234 @@ +/** + * Utility files for producing Vega ValueRef for marks + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +// TODO: we need to find a way to refactor these so that scaleName is a part of scale +// but that's complicated. For now, this is a huge step moving forward. +/** + * @return Vega ValueRef for stackable x or y + */ +function stackable(channel, channelDef, scaleName, scale, stack, defaultRef) { + if (channelDef && stack && channel === stack.fieldChannel) { + // x or y use stack_end so that stacked line's point mark use stack_end too. + return fieldRef(channelDef, scaleName, { suffix: 'end' }); + } + return midPoint(channel, channelDef, scaleName, scale, defaultRef); +} +exports.stackable = stackable; +/** + * @return Vega ValueRef for stackable x2 or y2 + */ +function stackable2(channel, aFieldDef, a2fieldDef, scaleName, scale, stack, defaultRef) { + if (aFieldDef && stack && + // If fieldChannel is X and channel is X2 (or Y and Y2) + channel.charAt(0) === stack.fieldChannel.charAt(0)) { + return fieldRef(aFieldDef, scaleName, { suffix: 'start' }); + } + return midPoint(channel, a2fieldDef, scaleName, scale, defaultRef); +} +exports.stackable2 = stackable2; +/** + * Value Ref for binned fields + */ +function bin(fieldDef, scaleName, side, offset) { + return fieldRef(fieldDef, scaleName, { binSuffix: side }, offset); +} +exports.bin = bin; +function fieldRef(fieldDef, scaleName, opt, offset) { + var ref = { + scale: scaleName, + field: fielddef_1.field(fieldDef, opt), + }; + if (offset) { + ref.offset = offset; + } + return ref; +} +exports.fieldRef = fieldRef; +function band(scaleName, band) { + if (band === void 0) { band = true; } + return { + scale: scaleName, + band: band + }; +} +exports.band = band; +function binMidSignal(fieldDef, scaleName) { + return { + signal: "(" + + ("scale(\"" + scaleName + "\", " + fielddef_1.field(fieldDef, { binSuffix: 'start', datum: true }) + ")") + + " + " + + ("scale(\"" + scaleName + "\", " + fielddef_1.field(fieldDef, { binSuffix: 'end', datum: true }) + ")") + + ")/2" + }; +} +/** + * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels. + */ +function midPoint(channel, channelDef, scaleName, scale, defaultRef) { + // TODO: datum support + if (channelDef) { + /* istanbul ignore else */ + if (fielddef_1.isFieldDef(channelDef)) { + if (scale.type === 'bin-linear') { + return binMidSignal(channelDef, scaleName); + } + else if (scale.type === 'bin-ordinal') { + return fieldRef(channelDef, scaleName, { binSuffix: 'start' }); + } + if (scale_1.hasDiscreteDomain(scale.type)) { + if (scale.type === 'band') { + // For band, to get mid point, need to offset by half of the band + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }, band(scaleName, 0.5)); + } + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }); + } + else { + return fieldRef(channelDef, scaleName, {}); // no need for bin suffix + } + } + else if (channelDef.value) { + return { value: channelDef.value }; + } + else { + throw new Error('FieldDef without field or value.'); // FIXME add this to log.message + } + } + if (defaultRef === 'zeroOrMin') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMinX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMinY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + else if (defaultRef === 'zeroOrMax') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMaxX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMaxY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + return defaultRef; +} +exports.midPoint = midPoint; +function text(textDef, config) { + // text + if (textDef) { + if (fielddef_1.isFieldDef(textDef)) { + if (textDef.type === 'quantitative') { + // FIXME: what happens if we have bin? + var format = common_1.numberFormat(textDef, textDef.format, config, 'text'); + return { + signal: "format(" + fielddef_1.field(textDef, { datum: true }) + ", '" + format + "')" + }; + } + else if (textDef.type === 'temporal') { + return { + signal: common_1.timeFormatExpression(fielddef_1.field(textDef, { datum: true }), textDef.timeUnit, textDef.format, config.text.shortTimeLabels, config.timeFormat) + }; + } + else { + return { field: textDef.field }; + } + } + else if (textDef.value) { + return { value: textDef.value }; + } + } + return { value: config.text.text }; +} +exports.text = text; +function midX(config) { + if (typeof config.scale.rangeStep === 'string') { + // TODO: For fit-mode, use middle of the width + throw new Error('midX can not handle string rangeSteps'); + } + return { value: config.scale.rangeStep / 2 }; +} +exports.midX = midX; +function midY(config) { + if (typeof config.scale.rangeStep === 'string') { + // TODO: For fit-mode, use middle of the width + throw new Error('midX can not handle string rangeSteps'); + } + return { value: config.scale.rangeStep / 2 }; +} +exports.midY = midY; +function zeroOrMinX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the x-axis + return { value: 0 }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + return { field: { group: 'width' } }; +} +function zeroOrMinY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { field: { group: 'height' } }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { value: 0 }; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsdWVyZWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9tYXJrL3ZhbHVlcmVmLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHOzs7QUFFSCx5Q0FBb0Q7QUFFcEQsMkNBQStHO0FBQy9HLHFDQUFnRTtBQUVoRSxtQ0FBb0M7QUFFcEMsb0NBQTZEO0FBRTdELHFGQUFxRjtBQUNyRix3RUFBd0U7QUFFeEU7O0dBRUc7QUFDSCxtQkFBMEIsT0FBa0IsRUFBRSxVQUFzQixFQUFFLFNBQWlCLEVBQUUsS0FBWSxFQUNqRyxLQUFzQixFQUFFLFVBQXNCO0lBQ2hELEVBQUUsQ0FBQyxDQUFDLFVBQVUsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQzFELDRFQUE0RTtRQUM1RSxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDckUsQ0FBQztBQVBELDhCQU9DO0FBRUQ7O0dBRUc7QUFDSCxvQkFBMkIsT0FBb0IsRUFBRSxTQUFtQixFQUFFLFVBQW9CLEVBQUUsU0FBaUIsRUFBRSxLQUFZLEVBQ3ZILEtBQXNCLEVBQUUsVUFBc0I7SUFDaEQsRUFBRSxDQUFDLENBQUMsU0FBUyxJQUFJLEtBQUs7UUFDbEIsdURBQXVEO1FBQ3ZELE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUNqRCxDQUFDLENBQUMsQ0FBQztRQUNMLE1BQU0sQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxFQUFDLE1BQU0s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 \ No newline at end of file diff --git a/build/src/compile/model.d.ts b/build/src/compile/model.d.ts new file mode 100644 index 0000000000..3d6d61e964 --- /dev/null +++ b/build/src/compile/model.d.ts @@ -0,0 +1,136 @@ +import { Axis } from '../axis'; +import { Channel } from '../channel'; +import { Config, CellConfig } from '../config'; +import { Data, DataSourceType } from '../data'; +import { FieldDef, FieldRefOption } from '../fielddef'; +import { Legend } from '../legend'; +import { Scale } from '../scale'; +import { SortField, SortOrder } from '../sort'; +import { BaseSpec, Padding } from '../spec'; +import { Transform } from '../transform'; +import { Dict } from '../util'; +import { VgData, VgEncodeEntry, VgScale, VgAxis, VgLegend } from '../vega.schema'; +import { Formula } from '../transform'; +import { OneOfFilter, EqualFilter, RangeFilter } from '../filter'; +import { DataComponent } from './data/data'; +import { LayoutComponent } from './layout'; +import { StackProperties } from '../stack'; +import { SelectionComponent } from './selection/selection'; +/** + * Composable Components that are intermediate results of the parsing phase of the + * compilations. These composable components will be assembled in the last + * compilation step. + */ +export interface Component { + data: DataComponent; + layout: LayoutComponent; + scales: Dict; + selection: Dict; + /** Dictionary mapping channel to VgAxis definition */ + axes: Dict; + /** Dictionary mapping channel to VgLegend definition */ + legends: Dict; + /** Dictionary mapping channel to axis mark group for facet and concat */ + axisGroups: Dict; + /** Dictionary mapping channel to grid mark group for facet (and concat?) */ + gridGroups: Dict; + mark: VgEncodeEntry[]; +} +export declare class NameMap implements NameMapInterface { + private nameMap; + constructor(); + rename(oldName: string, newName: string): void; + has(name: string): boolean; + get(name: string): string; +} +export interface NameMapInterface { + rename(oldname: string, newName: string): void; + has(name: string): boolean; + get(name: string): string; +} +export declare abstract class Model { + readonly parent: Model; + protected readonly name: string; + readonly description: string; + readonly padding: Padding; + readonly data: Data; + /** Name map for data sources, which can be renamed by a model's parent. */ + protected dataNameMap: NameMapInterface; + /** Name map for scales, which can be renamed by a model's parent. */ + protected scaleNameMap: NameMapInterface; + /** Name map for size, which can be renamed by a model's parent. */ + protected sizeNameMap: NameMapInterface; + protected readonly transform: Transform; + protected readonly abstract scales: Dict; + protected readonly abstract axes: Dict; + protected readonly abstract legends: Dict; + readonly abstract config: Config; + component: Component; + readonly abstract children: Model[]; + abstract stack: StackProperties; + constructor(spec: BaseSpec, parent: Model, parentGivenName: string); + parse(): void; + abstract parseData(): void; + abstract parseSelection(): void; + abstract parseLayoutData(): void; + abstract parseScale(): void; + abstract parseMark(): void; + abstract parseAxis(): void; + abstract parseLegend(): void; + abstract parseAxisGroup(): void; + abstract parseGridGroup(): void; + abstract assembleSignals(signals: any[]): any[]; + abstract assembleSelectionData(data: VgData[]): VgData[]; + abstract assembleData(data: VgData[]): VgData[]; + abstract assembleLayout(layoutData: VgData[]): VgData[]; + assembleScales(): VgScale[]; + abstract assembleMarks(): any[]; + assembleAxes(): VgAxis[]; + assembleLegends(): any[]; + assembleGroup(): any; + abstract assembleParentGroupProperties(cellConfig: CellConfig): VgEncodeEntry; + abstract channels(): Channel[]; + protected abstract getMapping(): { + [key: string]: any; + }; + reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any): any; + forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any): void; + hasDescendantWithFieldOnChannel(channel: Channel): boolean; + abstract channelHasField(channel: Channel): boolean; + getName(text: string, delimiter?: string): string; + renameData(oldName: string, newName: string): void; + /** + * Return the data source name for the given data source type. + * + * For unit spec, this is always simply the spec.name + '-' + dataSourceType. + * We already use the name map so that marks and scales use the correct data. + */ + dataName(dataSourceType: DataSourceType): string; + renameSize(oldName: string, newName: string): void; + channelSizeName(channel: Channel): string; + sizeName(size: string): string; + abstract dataTable(): string; + calculate(): Formula[]; + filterInvalid(): boolean; + filter(): string | OneOfFilter | EqualFilter | RangeFilter | (string | OneOfFilter | EqualFilter | RangeFilter)[]; + /** Get "field" reference for vega */ + field(channel: Channel, opt?: FieldRefOption): string; + abstract fieldDef(channel: Channel): FieldDef; + scale(channel: Channel): Scale; + hasDiscreteScale(channel: Channel): boolean; + renameScale(oldName: string, newName: string): void; + /** + * @return scale name for a given channel after the scale has been parsed and named. + * (DO NOT USE THIS METHOD DURING SCALE PARSING, use model.name() instead) + */ + scaleName(this: Model, originalScaleName: Channel | string, parse?: boolean): string; + sort(channel: Channel): SortField | SortOrder; + axis(channel: Channel): Axis; + legend(channel: Channel): Legend; + /** + * Type checks + */ + isUnit(): boolean; + isFacet(): boolean; + isLayer(): boolean; +} diff --git a/build/src/compile/model.js b/build/src/compile/model.js new file mode 100644 index 0000000000..1766ec894d --- /dev/null +++ b/build/src/compile/model.js @@ -0,0 +1,241 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var channel_1 = require("../channel"); +var data_1 = require("../data"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +var NameMap = (function () { + function NameMap() { + this.nameMap = {}; + } + NameMap.prototype.rename = function (oldName, newName) { + this.nameMap[oldName] = newName; + }; + NameMap.prototype.has = function (name) { + return this.nameMap[name] !== undefined; + }; + NameMap.prototype.get = function (name) { + // If the name appears in the _nameMap, we need to read its new name. + // We have to loop over the dict just in case the new name also gets renamed. + while (this.nameMap[name]) { + name = this.nameMap[name]; + } + return name; + }; + return NameMap; +}()); +exports.NameMap = NameMap; +var Model = (function () { + function Model(spec, parent, parentGivenName) { + this.scales = {}; + this.axes = {}; + this.legends = {}; + this.children = []; + this.parent = parent; + // If name is not provided, always use parent's givenName to avoid name conflicts. + this.name = spec.name || parentGivenName; + // Shared name maps + this.dataNameMap = parent ? parent.dataNameMap : new NameMap(); + this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap(); + this.sizeNameMap = parent ? parent.sizeNameMap : new NameMap(); + this.data = spec.data; + this.description = spec.description; + this.padding = spec.padding; + this.transform = spec.transform; + if (spec.transform) { + if (spec.transform.filterInvalid === undefined && + spec.transform['filterNull'] !== undefined) { + spec.transform.filterInvalid = spec.transform['filterNull']; + log.warn(log.message.DEPRECATED_FILTER_NULL); + } + } + this.component = { data: null, layout: null, mark: null, scales: null, axes: null, axisGroups: null, gridGroups: null, legends: null, selection: null }; + } + Model.prototype.parse = function () { + this.parseData(); + this.parseLayoutData(); + this.parseScale(); // depends on data name + this.parseSelection(); + this.parseAxis(); // depends on scale name + this.parseLegend(); // depends on scale name + this.parseAxisGroup(); // depends on child axis + this.parseGridGroup(); + this.parseMark(); // depends on data name and scale name, axisGroup, gridGroup and children's scale, axis, legend and mark. + }; + Model.prototype.assembleScales = function () { + // FIXME: write assembleScales() in scale.ts that + // help assemble scale domains with scale signature as well + return util_1.flatten(util_1.vals(this.component.scales).map(function (scale) { + var arr = [scale]; + return arr; + })); + }; + Model.prototype.assembleAxes = function () { + return [].concat.apply([], util_1.vals(this.component.axes)); + }; + Model.prototype.assembleLegends = function () { + return util_1.vals(this.component.legends); + }; + Model.prototype.assembleGroup = function () { + var group = {}; + var signals = this.assembleSignals(group.signals || []); + if (signals.length > 0) { + group.signals = signals; + } + // TODO: consider if we want scales to come before marks in the output spec. + group.marks = this.assembleMarks(); + var scales = this.assembleScales(); + if (scales.length > 0) { + group.scales = scales; + } + var axes = this.assembleAxes(); + if (axes.length > 0) { + group.axes = axes; + } + var legends = this.assembleLegends(); + if (legends.length > 0) { + group.legends = legends; + } + return group; + }; + Model.prototype.reduceFieldDef = function (f, init, t) { + return encoding_1.reduce(this.getMapping(), function (acc, cd, c) { + return fielddef_1.isFieldDef(cd) ? f(acc, cd, c) : acc; + }, init, t); + }; + Model.prototype.forEachFieldDef = function (f, t) { + encoding_1.forEach(this.getMapping(), function (cd, c) { + if (fielddef_1.isFieldDef(cd)) { + f(cd, c); + } + }, t); + }; + Model.prototype.hasDescendantWithFieldOnChannel = function (channel) { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (child.isUnit()) { + if (child.channelHasField(channel)) { + return true; + } + } + else { + if (child.hasDescendantWithFieldOnChannel(channel)) { + return true; + } + } + } + return false; + }; + Model.prototype.getName = function (text, delimiter) { + if (delimiter === void 0) { delimiter = '_'; } + if (this.data && text === data_1.SOURCE && data_1.isNamedData(this.data)) { + return this.data.name; + } + return (this.name ? this.name + delimiter : '') + text; + }; + Model.prototype.renameData = function (oldName, newName) { + this.dataNameMap.rename(oldName, newName); + }; + /** + * Return the data source name for the given data source type. + * + * For unit spec, this is always simply the spec.name + '-' + dataSourceType. + * We already use the name map so that marks and scales use the correct data. + */ + Model.prototype.dataName = function (dataSourceType) { + return this.dataNameMap.get(this.getName(String(dataSourceType))); + }; + Model.prototype.renameSize = function (oldName, newName) { + this.sizeNameMap.rename(oldName, newName); + }; + Model.prototype.channelSizeName = function (channel) { + return this.sizeName(channel === channel_1.X || channel === channel_1.COLUMN ? 'width' : 'height'); + }; + Model.prototype.sizeName = function (size) { + return this.sizeNameMap.get(this.getName(size, '_')); + }; + // TRANSFORMS + Model.prototype.calculate = function () { + return this.transform ? this.transform.calculate : undefined; + }; + Model.prototype.filterInvalid = function () { + var transform = this.transform || {}; + if (transform.filterInvalid === undefined) { + return this.parent ? this.parent.filterInvalid() : undefined; + } + return transform.filterInvalid; + }; + Model.prototype.filter = function () { + return this.transform ? this.transform.filter : undefined; + }; + /** Get "field" reference for vega */ + Model.prototype.field = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (fieldDef.bin) { + opt = util_1.extend({ + binSuffix: scale_1.hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start' + }, opt); + } + return fielddef_1.field(fieldDef, opt); + }; + Model.prototype.scale = function (channel) { + return this.scales[channel]; + }; + Model.prototype.hasDiscreteScale = function (channel) { + var scale = this.scale(channel); + return scale && scale_1.hasDiscreteDomain(scale.type); + }; + Model.prototype.renameScale = function (oldName, newName) { + this.scaleNameMap.rename(oldName, newName); + }; + /** + * @return scale name for a given channel after the scale has been parsed and named. + * (DO NOT USE THIS METHOD DURING SCALE PARSING, use model.name() instead) + */ + Model.prototype.scaleName = function (originalScaleName, parse) { + if (parse) { + // During the parse phase always return a value + // No need to refer to rename map because a scale can't be renamed + // before it has the original name. + return this.getName(originalScaleName + ''); + } + // If there is a scale for the channel, it should either + // be in the _scale mapping or exist in the name map + if ( + // in the scale map (the scale is not merged by its parent) + (this.scale && this.scales[originalScaleName]) || + // in the scale name map (the the scale get merged by its parent) + this.scaleNameMap.has(this.getName(originalScaleName + ''))) { + return this.scaleNameMap.get(this.getName(originalScaleName + '')); + } + return undefined; + }; + Model.prototype.sort = function (channel) { + return (this.getMapping()[channel] || {}).sort; + }; + Model.prototype.axis = function (channel) { + return this.axes[channel]; + }; + Model.prototype.legend = function (channel) { + return this.legends[channel]; + }; + /** + * Type checks + */ + Model.prototype.isUnit = function () { + return false; + }; + Model.prototype.isFacet = function () { + return false; + }; + Model.prototype.isLayer = function () { + return false; + }; + return Model; +}()); +exports.Model = Model; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcGlsZS9tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDRCQUE4QjtBQUc5QixzQ0FBOEM7QUFFOUMsZ0NBQWtFO0FBQ2xFLHdDQUE0QztBQUM1Qyx3Q0FBb0Y7QUFFcEYsa0NBQWtEO0FBSWxELGdDQUFvRDtBQXFDcEQ7SUFHRTtRQUNFLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFTSx3QkFBTSxHQUFiLFVBQWMsT0FBZSxFQUFFLE9BQWU7UUFDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxPQUFPLENBQUM7SUFDbEMsQ0FBQztJQUdNLHFCQUFHLEdBQVYsVUFBVyxJQUFZO1FBQ3JCLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLFNBQVMsQ0FBQztJQUMxQyxDQUFDO0lBRU0scUJBQUcsR0FBVixVQUFXLElBQVk7UUFDckIscUVBQXFFO1FBQ3JFLDZFQUE2RTtRQUM3RSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMxQixJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNkLENBQUM7SUFDSCxjQUFDO0FBQUQsQ0FBQyxBQXpCRCxJQXlCQztBQXpCWSwwQkFBTztBQWlDcEI7SUFnQ0UsZUFBWSxJQUFjLEVBQUUsTUFBYSxFQUFFLGVBQXVCO1FBZHRDLFdBQU0sR0FBZ0IsRUFBRSxDQUFDO1FBRXpCLFNBQUksR0FBZSxFQUFFLENBQUM7UUFFdEIsWUFBTyxHQUFpQixFQUFFLENBQUM7UUFNOUIsYUFBUSxHQUFZLEVBQUUsQ0FBQztRQUs5QyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUVyQixrRkFB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 \ No newline at end of file diff --git a/build/src/compile/scale/domain.d.ts b/build/src/compile/scale/domain.d.ts new file mode 100644 index 0000000000..0ed1ab49fa --- /dev/null +++ b/build/src/compile/scale/domain.d.ts @@ -0,0 +1,23 @@ +import { Channel } from '../../channel'; +import { Domain, ScaleConfig, ScaleType } from '../../scale'; +import { VgDomain, VgSortField } from '../../vega.schema'; +import { Model } from '../model'; +import { FieldDef } from '../../fielddef'; +export declare function initDomain(domain: Domain, fieldDef: FieldDef, scale: ScaleType, scaleConfig: ScaleConfig): Domain; +export declare function parseDomain(model: Model, channel: Channel): VgDomain; +export declare function domainSort(model: Model, channel: Channel, scaleType: ScaleType): VgSortField; +/** + * Determine if a scale can use unaggregated domain. + * @return {Boolean} Returns true if all of the following conditons applies: + * 1. `scale.domain` is `unaggregated` + * 2. Aggregation function is not `count` or `sum` + * 3. The scale is quantitative or time scale. + */ +export declare function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): { + valid: boolean; + reason?: string; +}; +/** + * Union two data domains. A unioned domain is always sorted. + */ +export declare function unionDomains(domain1: VgDomain, domain2: VgDomain): VgDomain; diff --git a/build/src/compile/scale/domain.js b/build/src/compile/scale/domain.js new file mode 100644 index 0000000000..94692205c3 --- /dev/null +++ b/build/src/compile/scale/domain.js @@ -0,0 +1,267 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var aggregate_1 = require("../../aggregate"); +var data_1 = require("../../data"); +var datetime_1 = require("../../datetime"); +var scale_1 = require("../../scale"); +var sort_1 = require("../../sort"); +var vega_schema_1 = require("../../vega.schema"); +var util = require("../../util"); +function initDomain(domain, fieldDef, scale, scaleConfig) { + if (domain === 'unaggregated') { + var _a = canUseUnaggregatedDomain(fieldDef, scale), valid = _a.valid, reason = _a.reason; + if (!valid) { + log.warn(reason); + return undefined; + } + } + else if (domain === undefined && scaleConfig.useUnaggregatedDomain) { + // Apply config if domain is not specified. + var valid = canUseUnaggregatedDomain(fieldDef, scale).valid; + if (valid) { + return 'unaggregated'; + } + } + return domain; +} +exports.initDomain = initDomain; +function parseDomain(model, channel) { + var scale = model.scale(channel); + // If channel is either X or Y then union them with X2 & Y2 if they exist + if (channel === 'x' && model.channelHasField('x2')) { + if (model.channelHasField('x')) { + return unionDomains(parseSingleChannelDomain(scale, model, 'x'), parseSingleChannelDomain(scale, model, 'x2')); + } + else { + return parseSingleChannelDomain(scale, model, 'x2'); + } + } + else if (channel === 'y' && model.channelHasField('y2')) { + if (model.channelHasField('y')) { + return unionDomains(parseSingleChannelDomain(scale, model, 'y'), parseSingleChannelDomain(scale, model, 'y2')); + } + else { + return parseSingleChannelDomain(scale, model, 'y2'); + } + } + return parseSingleChannelDomain(scale, model, channel); +} +exports.parseDomain = parseDomain; +function parseSingleChannelDomain(scale, model, channel) { + var fieldDef = model.fieldDef(channel); + if (scale.domain && scale.domain !== 'unaggregated') { + if (datetime_1.isDateTime(scale.domain[0])) { + return scale.domain.map(function (dt) { + return datetime_1.timestamp(dt, true); + }); + } + return scale.domain; + } + // special case for temporal scale + if (fieldDef.type === 'temporal') { + return { + data: model.dataTable(), + field: model.field(channel), + sort: { + field: model.field(channel), + op: 'min' + } + }; + } + // For stack, use STACKED data. + var stack = model.stack; + if (stack && channel === stack.fieldChannel) { + if (stack.offset === 'normalize') { + return [0, 1]; + } + return { + data: model.dataName('stacked'), + fields: [ + model.field(channel, { suffix: 'start' }), + model.field(channel, { suffix: 'end' }) + ] + }; + } + var sort = domainSort(model, channel, scale.type); + if (scale.domain === 'unaggregated') { + return { + data: model.dataTable(), + fields: [ + model.field(channel, { aggregate: 'min' }), + model.field(channel, { aggregate: 'max' }) + ] + }; + } + else if (fieldDef.bin) { + if (scale_1.isBinScale(scale.type)) { + var field = model.getName(fieldDef.field + '_bins'); + return { signal: "sequence(" + field + ".start, " + field + ".stop + " + field + ".step, " + field + ".step)" }; + } + if (scale_1.hasDiscreteDomain(scale.type)) { + // ordinal bin scale takes domain from bin_range, ordered by bin_start + // This is useful for both axis-based scale (x, y, column, and row) and legend-based scale (other channels). + return { + data: model.dataTable(), + field: model.field(channel, { binSuffix: 'range' }), + sort: { + field: model.field(channel, { binSuffix: 'start' }), + op: 'min' // min or max doesn't matter since same _range would have the same _start + } + }; + } + else { + if (channel === 'x' || channel === 'y') { + // X/Y position have to include start and end for non-ordinal scale + return { + data: model.dataTable(), + fields: [ + model.field(channel, { binSuffix: 'start' }), + model.field(channel, { binSuffix: 'end' }) + ] + }; + } + else { + // TODO: use bin_mid + return { + data: model.dataTable(), + field: model.field(channel, { binSuffix: 'start' }) + }; + } + } + } + else if (sort) { + return { + // If sort by aggregation of a specified sort field, we need to use SOURCE table, + // so we can aggregate values for the scale independently from the main aggregation. + data: util.isBoolean(sort) ? model.dataTable() : data_1.SOURCE, + field: model.field(channel), + sort: sort + }; + } + else { + return { + data: model.dataTable(), + field: model.field(channel), + }; + } +} +function domainSort(model, channel, scaleType) { + if (!scale_1.hasDiscreteDomain(scaleType)) { + return undefined; + } + var sort = model.sort(channel); + // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale) + if (sort_1.isSortField(sort)) { + return { + op: sort.op, + field: sort.field + }; + } + if (util.contains(['ascending', 'descending', undefined /* default =ascending*/], sort)) { + return true; + } + // sort === 'none' + return undefined; +} +exports.domainSort = domainSort; +/** + * Determine if a scale can use unaggregated domain. + * @return {Boolean} Returns true if all of the following conditons applies: + * 1. `scale.domain` is `unaggregated` + * 2. Aggregation function is not `count` or `sum` + * 3. The scale is quantitative or time scale. + */ +function canUseUnaggregatedDomain(fieldDef, scaleType) { + if (!fieldDef.aggregate) { + return { + valid: false, + reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef) + }; + } + if (aggregate_1.SHARED_DOMAIN_OPS.indexOf(fieldDef.aggregate) === -1) { + return { + valid: false, + reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate) + }; + } + if (fieldDef.type === 'quantitative') { + if (scaleType === 'log') { + return { + valid: false, + reason: log.message.unaggregatedDomainWithLogScale(fieldDef) + }; + } + } + return { valid: true }; +} +exports.canUseUnaggregatedDomain = canUseUnaggregatedDomain; +/** + * Convert the domain to an array of data refs or an array of values. Also, throw + * away sorting information since we always sort the domain when we union two domains. + */ +function normalizeDomain(domain) { + if (util.isArray(domain)) { + return [domain]; + } + else if (vega_schema_1.isDataRefDomain(domain)) { + delete domain.sort; + return [domain]; + } + else if (vega_schema_1.isFieldRefUnionDomain(domain)) { + return domain.fields.map(function (d) { + return { + data: domain.data, + field: d + }; + }); + } + else if (vega_schema_1.isDataRefUnionedDomain(domain)) { + return domain.fields.map(function (d) { + if (util.isArray(d)) { + return d; + } + return { + field: d.field, + data: d.data + }; + }); + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVAID_DOMAIN); +} +/** + * Union two data domains. A unioned domain is always sorted. + */ +function unionDomains(domain1, domain2) { + if (vega_schema_1.isSignalRefDomain(domain1) || vega_schema_1.isSignalRefDomain(domain2)) { + if (!vega_schema_1.isSignalRefDomain(domain1) || !vega_schema_1.isSignalRefDomain(domain2) || domain1.signal !== domain2.signal) { + throw new Error(log.message.UNABLE_TO_MERGE_DOMAINS); + } + return domain1; + } + var normalizedDomain1 = normalizeDomain(domain1); + var normalizedDomain2 = normalizeDomain(domain2); + var domains = normalizedDomain1.concat(normalizedDomain2); + domains = util.unique(domains, util.hash); + if (domains.length > 1) { + var allData = domains.map(function (d) { + if (vega_schema_1.isDataRefDomain(d)) { + return d.data; + } + return null; + }); + if (util.unique(allData, function (x) { return x; }).length === 1 && allData[0] !== null) { + return { + data: allData[0], + fields: domains.map(function (d) { return d.field; }) + }; + } + return { fields: domains, sort: true }; + } + else { + return domains[0]; + } +} +exports.unionDomains = unionDomains; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2NhbGUvZG9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQWlDO0FBRWpDLDZDQUFrRDtBQUVsRCxtQ0FBa0M7QUFDbEMsMkNBQStEO0FBQy9ELHFDQUFpRztBQUNqRyxtQ0FBdUM7QUFDdkMsaURBVTJCO0FBRTNCLGlDQUFtQztBQUtuQyxvQkFBMkIsTUFBYyxFQUFFLFFBQWtCLEVBQUUsS0FBZ0IsRUFBRSxXQUF3QjtJQUN2RyxFQUFFLENBQUMsQ0FBQyxNQUFNLEtBQUssY0FBYyxDQUFDLENBQUMsQ0FBQztRQUN4QixJQUFBLDhDQUEyRCxFQUExRCxnQkFBSyxFQUFFLGtCQUFNLENBQThDO1FBQ2xFLEVBQUUsQ0FBQSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNWLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakIsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLFdBQVcsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7UUFDckUsMkNBQTJDO1FBQ3BDLElBQUEsdURBQUssQ0FBOEM7UUFDMUQsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNWLE1BQU0sQ0FBQyxjQUFjLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFoQkQsZ0NBZ0JDO0FBR0QscUJBQTRCLEtBQVksRUFBRSxPQUFnQjtJQUN4RCxJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRW5DLHlFQUF5RTtJQUN6RSxFQUFFLENBQUMsQ0FBQyxPQUFPLEtBQUssR0FBRyxJ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 \ No newline at end of file diff --git a/build/src/compile/scale/init.d.ts b/build/src/compile/scale/init.d.ts new file mode 100644 index 0000000000..63d22955bd --- /dev/null +++ b/build/src/compile/scale/init.d.ts @@ -0,0 +1,18 @@ +import { Config } from '../../config'; +import { Channel } from '../../channel'; +import { ScaleFieldDef } from '../../fielddef'; +import { Mark } from '../../mark'; +import { Scale } from '../../scale'; +/** + * All scale properties except type and all range properties. + */ +export declare const NON_TYPE_RANGE_SCALE_PROPERTIES: (keyof Scale)[]; +/** + * Initialize Vega-Lite Scale's properties + * + * Note that we have to apply these rules here because: + * - many other scale and non-scale properties (including layout, mark) depend on scale type + * - layout depends on padding + * - range depends on zero and size (width and height) depends on range + */ +export default function init(channel: Channel, fieldDef: ScaleFieldDef, config: Config, mark: Mark | undefined, topLevelSize: number | undefined, xyRangeSteps: number[]): Scale; diff --git a/build/src/compile/scale/init.js b/build/src/compile/scale/init.js new file mode 100644 index 0000000000..5c500104ee --- /dev/null +++ b/build/src/compile/scale/init.js @@ -0,0 +1,92 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var domain_1 = require("./domain"); +var range_1 = require("./range"); +var rules = require("./rules"); +var type_1 = require("./type"); +var util = require("../../util"); +/** + * All scale properties except type and all range properties. + */ +exports.NON_TYPE_RANGE_SCALE_PROPERTIES = [ + // general properties + 'domain', + 'round', + // quantitative / time + 'clamp', 'nice', + // quantitative + 'exponent', 'zero', + 'interpolate', + // ordinal + 'padding', 'paddingInner', 'paddingOuter' // padding +]; +/** + * Initialize Vega-Lite Scale's properties + * + * Note that we have to apply these rules here because: + * - many other scale and non-scale properties (including layout, mark) depend on scale type + * - layout depends on padding + * - range depends on zero and size (width and height) depends on range + */ +function init(channel, fieldDef, config, mark, topLevelSize, xyRangeSteps) { + var specifiedScale = (fieldDef || {}).scale || {}; + var scale = { + type: type_1.default(specifiedScale.type, channel, fieldDef, mark, topLevelSize !== undefined, specifiedScale.rangeStep, config.scale) + }; + // Use specified value if compatible or determine default values for each property + exports.NON_TYPE_RANGE_SCALE_PROPERTIES.forEach(function (property) { + var specifiedValue = specifiedScale[property]; + var supportedByScaleType = scale_1.scaleTypeSupportProperty(scale.type, property); + var channelIncompatability = scale_1.channelScalePropertyIncompatability(channel, property); + if (specifiedValue !== undefined) { + // If there is a specified value, check if it is compatible with scale type and channel + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scale.type, property, channel)); + } + else if (channelIncompatability) { + log.warn(channelIncompatability); + } + } + if (supportedByScaleType && channelIncompatability === undefined) { + var value = getValue(specifiedValue, property, scale, channel, fieldDef, config.scale); + if (value !== undefined) { + scale[property] = value; + } + } + }); + return util.extend(scale, range_1.default(channel, scale.type, fieldDef.type, specifiedScale, config, scale.zero, mark, topLevelSize, xyRangeSteps)); +} +exports.default = init; +function getValue(specifiedValue, property, scale, channel, fieldDef, scaleConfig) { + // For domain, we might override specified value + if (property === 'domain') { + return domain_1.initDomain(specifiedValue, fieldDef, scale.type, scaleConfig); + } + // Other properties, no overriding default values + if (specifiedValue !== undefined) { + return specifiedValue; + } + return getDefaultValue(property, scale, channel, fieldDef, scaleConfig); +} +function getDefaultValue(property, scale, channel, fieldDef, scaleConfig) { + // If we have default rule-base, determine default value first + switch (property) { + case 'nice': + return rules.nice(scale.type, channel, fieldDef); + case 'padding': + return rules.padding(channel, scale.type, scaleConfig); + case 'paddingInner': + return rules.paddingInner(scale.padding, channel, scaleConfig); + case 'paddingOuter': + return rules.paddingOuter(scale.padding, channel, scale.type, scale.paddingInner, scaleConfig); + case 'round': + return rules.round(channel, scaleConfig); + case 'zero': + return rules.zero(scale, channel, fieldDef); + } + // Otherwise, use scale config + return scaleConfig[property]; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NjYWxlL2luaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBaUM7QUFNakMscUNBQThHO0FBRTlHLG1DQUFvQztBQUNwQyxpQ0FBa0M7QUFDbEMsK0JBQWlDO0FBQ2pDLCtCQUErQjtBQUMvQixpQ0FBbUM7QUFFbkM7O0dBRUc7QUFDVSxRQUFBLCtCQUErQixHQUFvQjtJQUM5RCxxQkFBcUI7SUFDckIsUUFBUTtJQUNSLE9BQU87SUFDUCxzQkFBc0I7SUFDdEIsT0FBTyxFQUFFLE1BQU07SUFDZixlQUFlO0lBQ2YsVUFBVSxFQUFFLE1BQU07SUFDbEIsYUFBYTtJQUNiLFVBQVU7SUFDVixTQUFTLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxVQUFVO0NBQ3JELENBQUM7QUFFRjs7Ozs7OztHQU9HO0FBQ0gsY0FDSSxPQUFnQixFQUFFLFFBQXVCLEVBQUUsTUFBYyxFQUN6RCxJQUFzQixFQUFFLFlBQWdDLEVBQUUsWUFBc0I7SUFDbEYsSUFBTSxjQUFjLEdBQUcsQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztJQUVwRCxJQUFNLEtBQUssR0FBVTtRQUNuQixJQUFJLEVBQUUsY0FBUyxDQUNiLGNBQWMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxLQUFLLFNBQVMsRUFDeEUsY0FBYyxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUN2QztLQUNGLENBQUM7SUFFRixrRkFBa0Y7SUFDbEYsdUNBQStCLENBQUMsT0FBTyxDQUFDLFVBQVMsUUFBUTtRQUN2RCxJQUFNLGNBQWMsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFaEQsSUFBTSxvQkFBb0IsR0FBRyxnQ0FBd0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFFBQVEs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 \ No newline at end of file diff --git a/build/src/compile/scale/parse.d.ts b/build/src/compile/scale/parse.d.ts new file mode 100644 index 0000000000..19409455d0 --- /dev/null +++ b/build/src/compile/scale/parse.d.ts @@ -0,0 +1,14 @@ +import { Channel } from '../../channel'; +import { Scale } from '../../scale'; +import { Dict } from '../../util'; +import { Model } from '../model'; +import { VgScale } from '../../vega.schema'; +/** + * Parse scales for all channels of a model. + */ +export default function parseScaleComponent(model: Model): Dict; +export declare const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES: (keyof Scale)[]; +/** + * Parse scales for a single channel of a model. + */ +export declare function parseScale(model: Model, channel: Channel): VgScale; diff --git a/build/src/compile/scale/parse.js b/build/src/compile/scale/parse.js new file mode 100644 index 0000000000..442f53b338 --- /dev/null +++ b/build/src/compile/scale/parse.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var sort_1 = require("../../sort"); +var domain_1 = require("./domain"); +var range_1 = require("./range"); +/** + * Parse scales for all channels of a model. + */ +function parseScaleComponent(model) { + // TODO: should model.channels() inlcude X2/Y2? + return model.channels().reduce(function (scaleComponentsIndex, channel) { + var scaleComponents = parseScale(model, channel); + if (scaleComponents) { + scaleComponentsIndex[channel] = scaleComponents; + } + return scaleComponentsIndex; + }, {}); +} +exports.default = parseScaleComponent; +exports.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = [ + 'round', + // quantitative / time + 'clamp', 'nice', + // quantitative + 'exponent', 'interpolate', 'zero', + // ordinal + 'padding', 'paddingInner', 'paddingOuter', +]; +/** + * Parse scales for a single channel of a model. + */ +function parseScale(model, channel) { + if (!model.scale(channel)) { + return null; + } + var scale = model.scale(channel); + var sort = model.sort(channel); + var scaleComponent = { + name: model.scaleName(channel + '', true), + type: scale.type, + domain: domain_1.parseDomain(model, channel), + range: range_1.parseRange(scale) + }; + exports.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES.forEach(function (property) { + scaleComponent[property] = scale[property]; + }); + if (sort && (sort_1.isSortField(sort) ? sort.order : sort) === 'descending') { + scaleComponent.reverse = true; + } + return scaleComponent; +} +exports.parseScale = parseScale; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9wYXJzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLG1DQUF1QztBQUt2QyxtQ0FBcUM7QUFDckMsaUNBQW1DO0FBR25DOztHQUVHO0FBQ0gsNkJBQTRDLEtBQVk7SUFDdEQsK0NBQStDO0lBQy9DLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLFVBQVMsb0JBQW1DLEVBQUUsT0FBZ0I7UUFDM0YsSUFBTSxlQUFlLEdBQUcsVUFBVSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNuRCxFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxHQUFHLGVBQWUsQ0FBQztRQUNsRCxDQUFDO1FBQ0QsTUFBTSxDQUFDLG9CQUFvQixDQUFDO0lBQzlCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNULENBQUM7QUFURCxzQ0FTQztBQUVZLFFBQUEsMkNBQTJDLEdBQW9CO0lBQzFFLE9BQU87SUFDUCxzQkFBc0I7SUFDdEIsT0FBTyxFQUFFLE1BQU07SUFDZixlQUFlO0lBQ2YsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNO0lBQ2pDLFVBQVU7SUFDVixTQUFTLEVBQUUsY0FBYyxFQUFFLGNBQWM7Q0FDMUMsQ0FBQztBQUVGOztHQUVHO0FBQ0gsb0JBQTJCLEtBQVksRUFBRSxPQUFnQjtJQUN2RCxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFCLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRWpDLElBQUksY0FBYyxHQUFZO1FBQzVCLElBQUksRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDO1FBQ3pDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtRQUNoQixNQUFNLEVBQUUsb0JBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDO1FBQ25DLEtBQUssRUFBRSxrQkFBVSxDQUFDLEtBQUssQ0FBQztLQUN6QixDQUFDO0lBRUYsbURBQTJDLENBQUMsT0FBTyxDQUFDLFVBQUMsUUFBUTtRQUMzRCxjQUFjLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzdDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsa0JBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDckUsY0FBYyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUNELE1BQU0sQ0FBQyxjQUFjLENBQUM7QUFDeEIsQ0FBQztBQXZCRCxnQ0F1QkMifQ== \ No newline at end of file diff --git a/build/src/compile/scale/range.d.ts b/build/src/compile/scale/range.d.ts new file mode 100644 index 0000000000..13f11f2a8d --- /dev/null +++ b/build/src/compile/scale/range.d.ts @@ -0,0 +1,19 @@ +import { Channel } from '../../channel'; +import { Config } from '../../config'; +import { Mark } from '../../mark'; +import { Scale, ScaleType, Scheme, Range } from '../../scale'; +import { Type } from '../../type'; +import { VgRange } from '../../vega.schema'; +export declare type RangeMixins = { + range: Range; +} | { + rangeStep: number; +} | { + scheme: Scheme; +}; +export declare function parseRange(scale: Scale): VgRange; +export declare const RANGE_PROPERTIES: (keyof Scale)[]; +/** + * Return mixins that includes one of the range properties (range, rangeStep, scheme). + */ +export default function rangeMixins(channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config, zero: boolean, mark: Mark, topLevelSize: number | undefined, xyRangeSteps: number[]): RangeMixins; diff --git a/build/src/compile/scale/range.js b/build/src/compile/scale/range.js new file mode 100644 index 0000000000..1dd509a17b --- /dev/null +++ b/build/src/compile/scale/range.js @@ -0,0 +1,193 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var channel_1 = require("../../channel"); +var scale_1 = require("../../scale"); +var util = require("../../util"); +function parseRange(scale) { + if (scale.rangeStep) { + return { step: scale.rangeStep }; + } + else if (scale.scheme) { + var scheme = scale.scheme; + if (scale_1.isExtendedScheme(scheme)) { + var r = { scheme: scheme.name }; + if (scheme.count) { + r.count = scheme.count; + } + if (scheme.extent) { + r.extent = scheme.extent; + } + return r; + } + else { + return { scheme: scheme }; + } + } + return scale.range; +} +exports.parseRange = parseRange; +exports.RANGE_PROPERTIES = ['range', 'rangeStep', 'scheme']; +/** + * Return mixins that includes one of the range properties (range, rangeStep, scheme). + */ +function rangeMixins(channel, scaleType, type, specifiedScale, config, zero, mark, topLevelSize, xyRangeSteps) { + var specifiedRangeStepIsNull = false; + // Check if any of the range properties is specified. + // If so, check if it is compatible and make sure that we only output one of the properties + for (var _i = 0, RANGE_PROPERTIES_1 = exports.RANGE_PROPERTIES; _i < RANGE_PROPERTIES_1.length; _i++) { + var property = RANGE_PROPERTIES_1[_i]; + if (specifiedScale[property] !== undefined) { + var supportedByScaleType = scale_1.scaleTypeSupportProperty(scaleType, property); + var channelIncompatability = scale_1.channelScalePropertyIncompatability(channel, property); + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel)); + } + else if (channelIncompatability) { + log.warn(channelIncompatability); + } + else { + switch (property) { + case 'range': + return { range: specifiedScale[property] }; + case 'scheme': + return { scheme: specifiedScale[property] }; + case 'rangeStep': + if (topLevelSize === undefined) { + var stepSize = specifiedScale[property]; + if (stepSize !== null) { + return { rangeStep: stepSize }; + } + else { + specifiedRangeStepIsNull = true; + } + } + else { + // If top-level size is specified, we ignore specified rangeStep. + log.warn(log.message.rangeStepDropped(channel)); + } + } + } + } + } + switch (channel) { + // TODO: revise row/column when facetSpec has top-level width/height + case channel_1.ROW: + return { range: 'height' }; + case channel_1.COLUMN: + return { range: 'width' }; + case channel_1.X: + case channel_1.Y: + if (topLevelSize === undefined) { + if (util.contains(['point', 'band'], scaleType) && !specifiedRangeStepIsNull) { + if (channel === channel_1.X && mark === 'text') { + if (config.scale.textXRangeStep) { + return { rangeStep: config.scale.textXRangeStep }; + } + } + else { + if (config.scale.rangeStep) { + return { rangeStep: config.scale.rangeStep }; + } + } + } + // If specified range step is null or the range step config is null. + // Use default topLevelSize rule/config + topLevelSize = channel === channel_1.X ? config.cell.width : config.cell.height; + } + return { range: channel === channel_1.X ? [0, topLevelSize] : [topLevelSize, 0] }; + case channel_1.SIZE: + // TODO: support custom rangeMin, rangeMax + var rangeMin = sizeRangeMin(mark, zero, config); + var rangeMax = sizeRangeMax(mark, xyRangeSteps, config); + return { range: [rangeMin, rangeMax] }; + case channel_1.SHAPE: + case channel_1.COLOR: + return { range: defaultRange(channel, scaleType, type, mark) }; + case channel_1.OPACITY: + // TODO: support custom rangeMin, rangeMax + return { range: [config.scale.minOpacity, config.scale.maxOpacity] }; + } + /* istanbul ignore next: should never reach here */ + throw new Error("Scale range undefined for channel " + channel); +} +exports.default = rangeMixins; +function defaultRange(channel, scaleType, type, mark) { + switch (channel) { + case channel_1.SHAPE: + return 'symbol'; + case channel_1.COLOR: + if (scaleType === 'ordinal') { + // Only nominal data uses ordinal scale by default + return type === 'nominal' ? 'category' : 'ordinal'; + } + return mark === 'rect' ? 'heatmap' : 'ramp'; + } +} +function sizeRangeMin(mark, zero, config) { + if (zero) { + return 0; + } + switch (mark) { + case 'bar': + return config.scale.minBandSize !== undefined ? config.scale.minBandSize : config.bar.continuousBandSize; + case 'tick': + return config.scale.minBandSize; + case 'line': + case 'rule': + return config.scale.minStrokeWidth; + case 'text': + return config.scale.minFontSize; + case 'point': + case 'square': + case 'circle': + if (config.scale.minSize) { + return config.scale.minSize; + } + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMin not implemented for the mark + throw new Error(log.message.incompatibleChannel('size', mark)); +} +function sizeRangeMax(mark, xyRangeSteps, config) { + var scaleConfig = config.scale; + // TODO(#1168): make max size scale based on rangeStep / overall plot size + switch (mark) { + case 'bar': + case 'tick': + if (config.scale.maxBandSize !== undefined) { + return config.scale.maxBandSize; + } + return minXYRangeStep(xyRangeSteps, config.scale) - 1; + case 'line': + case 'rule': + return config.scale.maxStrokeWidth; + case 'text': + return config.scale.maxFontSize; + case 'point': + case 'square': + case 'circle': + if (config.scale.maxSize) { + return config.scale.maxSize; + } + // FIXME this case totally should be refactored + var pointStep = minXYRangeStep(xyRangeSteps, scaleConfig); + return (pointStep - 2) * (pointStep - 2); + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMax not implemented for the mark + throw new Error(log.message.incompatibleChannel('size', mark)); +} +/** + * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale. + */ +function minXYRangeStep(xyRangeSteps, scaleConfig) { + if (xyRangeSteps.length > 0) { + return Math.min.apply(null, xyRangeSteps); + } + if (scaleConfig.rangeStep) { + return scaleConfig.rangeStep; + } + return 21; // FIXME: re-evaluate the default value here. +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9yYW5nZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLCtCQUFpQztBQUVqQyx5Q0FBc0Y7QUFHdEYscUNBQTBKO0FBRzFKLGlDQUFtQztBQUluQyxvQkFBMkIsS0FBWTtJQUNyQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNwQixNQUFNLENBQUMsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLFNBQVMsRUFBQyxDQUFDO0lBQ2pDLENBQUM7SUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDeEIsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUM1QixFQUFFLENBQUMsQ0FBQyx3QkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsSUFBSSxDQUFDLEdBQWtCLEVBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUMsQ0FBQztZQUM3QyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDakIsQ0FBQyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO1lBQ3pCLENBQUM7WUFDRCxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDbEIsQ0FBQyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQzNCLENBQUM7WUFDRCxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sTUFBTSxDQUFDLEVBQUMsTUFBTSxRQUFBLEVBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFD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 \ No newline at end of file diff --git a/build/src/compile/scale/rules.d.ts b/build/src/compile/scale/rules.d.ts new file mode 100644 index 0000000000..594083a796 --- /dev/null +++ b/build/src/compile/scale/rules.d.ts @@ -0,0 +1,9 @@ +import { Channel } from '../../channel'; +import { FieldDef } from '../../fielddef'; +import { Scale, ScaleConfig, ScaleType, NiceTime } from '../../scale'; +export declare function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime; +export declare function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig): number; +export declare function paddingInner(padding: number, channel: Channel, scaleConfig: ScaleConfig): number; +export declare function paddingOuter(padding: number, channel: Channel, scaleType: ScaleType, paddingInner: number, scaleConfig: ScaleConfig): number; +export declare function round(channel: Channel, scaleConfig: ScaleConfig): boolean; +export declare function zero(specifiedScale: Scale, channel: Channel, fieldDef: FieldDef): boolean; diff --git a/build/src/compile/scale/rules.js b/build/src/compile/scale/rules.js new file mode 100644 index 0000000000..e72212e1c9 --- /dev/null +++ b/build/src/compile/scale/rules.js @@ -0,0 +1,83 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var scale_1 = require("../../scale"); +var timeunit_1 = require("../../timeunit"); +var util = require("../../util"); +function nice(scaleType, channel, fieldDef) { + if (util.contains([scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scaleType)) { + return timeunit_1.smallestUnit(fieldDef.timeUnit); + } + return util.contains([channel_1.X, channel_1.Y], channel); // return true for quantitative X/Y +} +exports.nice = nice; +function padding(channel, scaleType, scaleConfig) { + if (util.contains([channel_1.X, channel_1.Y], channel)) { + if (scaleType === scale_1.ScaleType.POINT) { + return scaleConfig.pointPadding; + } + } + return undefined; +} +exports.padding = padding; +function paddingInner(padding, channel, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingInner. + return undefined; + } + if (util.contains([channel_1.X, channel_1.Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + // paddingOuter would only be called if it's a band scale, just return the default for bandScale. + return scaleConfig.bandPaddingInner; + } + return undefined; +} +exports.paddingInner = paddingInner; +function paddingOuter(padding, channel, scaleType, paddingInner, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingOuter. + return undefined; + } + if (util.contains([channel_1.X, channel_1.Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + if (scaleType === scale_1.ScaleType.BAND) { + if (scaleConfig.bandPaddingOuter !== undefined) { + return scaleConfig.bandPaddingOuter; + } + /* By default, paddingOuter is paddingInner / 2. The reason is that + size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter). + and we want the width/height to be integer by default. + Note that step (by default) and cardinality are integers.) */ + return paddingInner / 2; + } + } + return undefined; +} +exports.paddingOuter = paddingOuter; +function round(channel, scaleConfig) { + if (util.contains(['x', 'y', 'row', 'column'], channel)) { + return scaleConfig.round; + } + return undefined; +} +exports.round = round; +function zero(specifiedScale, channel, fieldDef) { + // By default, return true only for the following cases: + // 1) using quantitative field with size + // While this can be either ratio or interval fields, our assumption is that + // ratio are more common. + if (channel === 'size' && fieldDef.type === 'quantitative') { + return true; + } + // 2) non-binned, quantitative x-scale or y-scale if no custom domain is provided. + // (For binning, we should not include zero by default because binning are calculated without zero. + // Similar, if users explicitly provide a domain range, we should not augment zero as that will be unexpected.) + if (!specifiedScale.domain && !fieldDef.bin && util.contains([channel_1.X, channel_1.Y], channel)) { + return true; + } + return false; +} +exports.zero = zero; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zY2FsZS9ydWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLHlDQUE0QztBQUU1QyxxQ0FBb0U7QUFDcEUsMkNBQTRDO0FBQzVDLGlDQUFtQztBQUVuQyxjQUFxQixTQUFvQixFQUFFLE9BQWdCLEVBQUUsUUFBa0I7SUFDN0UsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLGlCQUFTLENBQUMsSUFBSSxFQUFFLGlCQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlELE1BQU0sQ0FBQyx1QkFBWSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQVEsQ0FBQztJQUNoRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxXQUFDLEVBQUUsV0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxtQ0FBbUM7QUFDNUUsQ0FBQztBQUxELG9CQUtDO0FBRUQsaUJBQXdCLE9BQWdCLEVBQUUsU0FBb0IsRUFBRSxXQUF3QjtJQUN0RixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBQyxFQUFFLFdBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxFQUFFLENBQUMsQ0FBQyxTQUFTLEtBQUssaUJBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBUEQsMEJBT0M7QUFFRCxzQkFBNkIsT0FBZSxFQUFFLE9BQWdCLEVBQUcsV0FBd0I7SUFDdkYsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENB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 \ No newline at end of file diff --git a/build/src/compile/scale/type.d.ts b/build/src/compile/scale/type.d.ts new file mode 100644 index 0000000000..000a1ea969 --- /dev/null +++ b/build/src/compile/scale/type.d.ts @@ -0,0 +1,10 @@ +import { Channel } from '../../channel'; +import { Mark } from '../../mark'; +import { ScaleType, ScaleConfig } from '../../scale'; +import { FieldDef } from '../../fielddef'; +export declare type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined; +/** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ +export default function type(specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef, mark: Mark, hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType; diff --git a/build/src/compile/scale/type.js b/build/src/compile/scale/type.js new file mode 100644 index 0000000000..dd5b638e53 --- /dev/null +++ b/build/src/compile/scale/type.js @@ -0,0 +1,128 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var channel_1 = require("../../channel"); +var timeunit_1 = require("../../timeunit"); +var util = require("../../util"); +/** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ +// NOTE: CompassQL uses this method. +function type(specifiedType, channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig) { + var defaultScaleType = defaultType(channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + if (!channel_1.hasScale(channel)) { + // There is no scale for these channels + return null; + } + if (specifiedType !== undefined) { + // for binned fields we don't allow overriding the default scale + if (fieldDef.bin) { + // TODO: generalize this as a method in fieldDef that determines scale type support for a fieldDef (looking at functions and type) + log.warn(log.message.cannotOverrideBinScaleType(channel, defaultScaleType)); + return defaultScaleType; + } + // Check if explicitly specified scale type is supported by the channel + if (channel_1.supportScaleType(channel, specifiedType)) { + return specifiedType; + } + else { + log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType)); + return defaultScaleType; + } + } + return defaultScaleType; +} +exports.default = type; +/** + * Determine appropriate default scale type. + */ +function defaultType(channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig) { + if (util.contains(['row', 'column'], channel)) { + return 'band'; + } + switch (fieldDef.type) { + case 'nominal': + if (channel === 'color' || channel_1.rangeType(channel) === 'discrete') { + return 'ordinal'; + } + return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + case 'ordinal': + if (channel === 'color') { + return 'ordinal'; + } + else if (channel_1.rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal')); + return 'ordinal'; + } + return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + case 'temporal': + if (channel === 'color') { + // Always use `sequential` as the default color scale for continuous data + // since it supports both array range and scheme range. + return 'sequential'; + } + else if (channel_1.rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + if (timeunit_1.isDiscreteByDefault(fieldDef.timeUnit)) { + return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + } + return 'time'; + case 'quantitative': + if (channel === 'color') { + if (fieldDef.bin) { + return 'bin-ordinal'; + } + // Use `sequential` as the default color scale for continuous data + // since it supports both array range and scheme range. + return 'sequential'; + } + else if (channel_1.rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + if (fieldDef.bin) { + return 'bin-linear'; + } + return 'linear'; + } + /* istanbul ignore next: should never reach this */ + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +/** + * Determines default scale type for nominal/ordinal field. + * @returns BAND or POINT scale based on channel, mark, and rangeStep + */ +function discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig) { + if (util.contains(['x', 'y'], channel)) { + if (mark === 'rect') { + // The rect mark should fit into a band. + return 'band'; + } + if (mark === 'bar') { + // For bar, use band only if there is no rangeStep since we need to use band for fit mode. + // However, for non-fit mode, point scale provides better center position. + if (haveRangeStep(hasTopLevelSize, specifiedRangeStep, scaleConfig)) { + return 'point'; + } + return 'band'; + } + } + // Otherwise, use ordinal point scale so we can easily get center positions of the marks. + return 'point'; +} +function haveRangeStep(hasTopLevelSize, specifiedRangeStep, scaleConfig) { + if (hasTopLevelSize) { + // if topLevelSize is provided, rangeStep will be dropped. + return false; + } + if (specifiedRangeStep !== undefined) { + return specifiedRangeStep !== null; + } + return !!scaleConfig.rangeStep; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NjYWxlL3R5cGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBaUM7QUFFakMseUNBQTZFO0FBRzdFLDJDQUFtRDtBQUVuRCxpQ0FBbUM7QUFLbkM7OztHQUdHO0FBQ0gsb0NBQW9DO0FBQ3BDLGNBQ0UsYUFBd0IsRUFBRSxPQUFnQixFQUFFLFFBQWtCLEVBQUUsSUFBVSxFQUMxRSxlQUF3QixFQUFFLGtCQUEwQixFQUFFLFdBQXdCO0lBRTlFLElBQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUVoSCxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLHVDQUF1QztRQUN2QyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELEVBQUUsQ0FBQyxDQUFDLGFBQWEsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLGdFQUFnRTtRQUNoRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNqQixrSUFBa0k7WUFDbEksR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7WUFDNUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1FBQzFCLENBQUM7UUFFRCx1RUFBdUU7UUFDdkUsRUFBRSxDQUFDLENBQUMsMEJBQWdCLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QyxNQUFNLENBQUMsYUFBYSxDQUFDO1FBQ3ZCLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNOLEdBQUcsQ0FB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 \ No newline at end of file diff --git a/build/src/compile/selection/interval.d.ts b/build/src/compile/selection/interval.d.ts new file mode 100644 index 0000000000..70f48a6b15 --- /dev/null +++ b/build/src/compile/selection/interval.d.ts @@ -0,0 +1,8 @@ +import { SelectionComponent, SelectionCompiler } from './selection'; +export declare const BRUSH = "_brush", SIZE = "_size"; +declare const interval: SelectionCompiler; +export { interval as default }; +export declare function projections(selCmpt: SelectionComponent): { + x: number; + y: number; +}; diff --git a/build/src/compile/selection/interval.js b/build/src/compile/selection/interval.js new file mode 100644 index 0000000000..7bae7a8fbb --- /dev/null +++ b/build/src/compile/selection/interval.js @@ -0,0 +1,135 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./selection"); +var channel_1 = require("../../channel"); +var util_1 = require("../../util"); +var log_1 = require("../../log"); +var scales_1 = require("./transforms/scales"); +exports.BRUSH = '_brush', exports.SIZE = '_size'; +var interval = { + predicate: 'vlInterval', + signals: function (model, selCmpt) { + var signals = [], intervals = [], name = selCmpt.name, size = name + exports.SIZE; + if (selCmpt.translate && !(scales_1.default.has(selCmpt))) { + events(selCmpt, function (_, evt) { + var filters = evt.between[0].filter || (evt.between[0].filter = []); + filters.push('!event.item || (event.item && ' + + ("event.item.mark.name !== " + util_1.stringValue(name + exports.BRUSH) + ")")); + }); + } + selCmpt.project.forEach(function (p) { + if (p.encoding !== channel_1.X && p.encoding !== channel_1.Y) { + log_1.warn('Interval selections only support x and y encoding channels.'); + return; + } + var cs = channelSignal(model, selCmpt, p.encoding); + signals.push(cs); + intervals.push("{field: " + util_1.stringValue(p.field) + ", extent: " + cs.name + "}"); + }); + signals.push({ + name: size, + value: [], + on: events(selCmpt, function (on, evt) { + on.push({ + events: evt.between[0], + update: '{x: x(unit), y: y(unit), width: 0, height: 0}' + }); + on.push({ + events: evt, + update: "{x: " + size + ".x, y: " + size + ".y, " + + ("width: abs(x(unit) - " + size + ".x), height: abs(y(unit) - " + size + ".y)}") + }); + return on; + }) + }, { + name: name, + update: "[" + intervals.join(', ') + "]" + }); + return signals; + }, + tupleExpr: function (model, selCmpt) { + return "intervals: " + selCmpt.name; + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + selection_1.TUPLE; + return tpl + ", {unit: " + tpl + ".unit}"; + }, + marks: function (model, selCmpt, marks) { + var name = selCmpt.name, _a = projections(selCmpt), x = _a.x, y = _a.y; + // Do not add a brush if we're binding to scales. + if (scales_1.default.has(selCmpt)) { + return marks; + } + var update = { + x: util_1.extend({}, x !== null ? + { scale: model.scaleName(channel_1.X), signal: name + "[" + x + "].extent[0]" } : + { value: 0 }), + x2: util_1.extend({}, x !== null ? + { scale: model.scaleName(channel_1.X), signal: name + "[" + x + "].extent[1]" } : + { field: { group: 'width' } }), + y: util_1.extend({}, y !== null ? + { scale: model.scaleName(channel_1.Y), signal: name + "[" + y + "].extent[0]" } : + { value: 0 }), + y2: util_1.extend({}, y !== null ? + { scale: model.scaleName(channel_1.Y), signal: name + "[" + y + "].extent[1]" } : + { field: { group: 'height' } }), + }; + return [{ + name: undefined, + type: 'rect', + encode: { + enter: { fill: { value: '#eee' } }, + update: update + } + }].concat(marks, { + name: name + exports.BRUSH, + type: 'rect', + encode: { + enter: { fill: { value: 'transparent' } }, + update: update + } + }); + } +}; +exports.default = interval; +function projections(selCmpt) { + var x = null, y = null; + selCmpt.project.forEach(function (p, i) { + if (p.encoding === channel_1.X) { + x = i; + } + else if (p.encoding === channel_1.Y) { + y = i; + } + }); + return { x: x, y: y }; +} +exports.projections = projections; +function channelSignal(model, selCmpt, channel) { + var name = selection_1.channelSignalName(selCmpt, channel), size = (channel === channel_1.X ? 'width' : 'height'), coord = channel + "(unit)", invert = selection_1.invert.bind(null, model, selCmpt, channel); + return { + name: name, + value: [], + on: scales_1.default.has(selCmpt) ? [] : events(selCmpt, function (on, evt) { + on.push({ + events: evt.between[0], + update: invert("[" + coord + ", " + coord + "]") + }); + on.push({ + events: evt, + update: "[" + name + "[0], " + invert("clamp(" + coord + ", 0, " + size + ")") + ']' + }); + return on; + }) + }; +} +function events(selCmpt, cb) { + return selCmpt.events.reduce(function (on, evt) { + if (!evt.between) { + log_1.warn(evt + " is not an ordered event stream for interval selections"); + return on; + } + return cb(on, evt); + }, []); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJ2YWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vaW50ZXJ2YWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBZ0g7QUFDaEgseUNBQTRDO0FBRTVDLG1DQUErQztBQUMvQyxpQ0FBK0I7QUFDL0IsOENBQXlDO0FBRTVCLFFBQUEsS0FBSyxHQUFHLFFBQVEsRUFDM0IsUUFBQSxJQUFJLEdBQUcsT0FBTyxDQUFDO0FBRWpCLElBQU0sUUFBUSxHQUFxQjtJQUNqQyxTQUFTLEVBQUUsWUFBWTtJQUV2QixPQUFPLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTztRQUM5QixJQUFJLE9BQU8sR0FBVSxFQUFFLEVBQ25CLFNBQVMsR0FBUyxFQUFFLEVBQ3BCLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxFQUNuQixJQUFJLEdBQUcsSUFBSSxHQUFHLFlBQUksQ0FBQztRQUV2QixFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxnQkFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsT0FBTyxFQUFFLFVBQVMsQ0FBUSxFQUFFLEdBQVE7Z0JBQ3pDLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUM7Z0JBQ3BFLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0NBQWdDO3FCQUMzQyw4QkFBNEIsa0JBQVcsQ0FBQyxJQUFJLEdBQUcsYUFBSyxDQUFDLE1BQUcsQ0FBQSxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBUyxD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 \ No newline at end of file diff --git a/build/src/compile/selection/multi.d.ts b/build/src/compile/selection/multi.d.ts new file mode 100644 index 0000000000..47971478a2 --- /dev/null +++ b/build/src/compile/selection/multi.d.ts @@ -0,0 +1,3 @@ +import { SelectionCompiler } from './selection'; +declare const multi: SelectionCompiler; +export { multi as default }; diff --git a/build/src/compile/selection/multi.js b/build/src/compile/selection/multi.js new file mode 100644 index 0000000000..3c008beb7f --- /dev/null +++ b/build/src/compile/selection/multi.js @@ -0,0 +1,27 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./selection"); +var util_1 = require("../../util"); +var multi = { + predicate: 'vlPoint', + signals: function (model, selCmpt) { + var proj = selCmpt.project, datum = '(item().isVoronoi ? datum.datum : datum)', fields = proj.map(function (p) { return util_1.stringValue(p.field); }).join(', '), values = proj.map(function (p) { return datum + "[" + util_1.stringValue(p.field) + "]"; }).join(', '); + return [{ + name: selCmpt.name, + value: {}, + on: [{ + events: selCmpt.events, + update: "{fields: [" + fields + "], values: [" + values + "]}" + }] + }]; + }, + tupleExpr: function (model, selCmpt) { + var name = selCmpt.name; + return "fields: " + name + ".fields, values: " + name + ".values"; + }, + modifyExpr: function (model, selCmpt) { + return selCmpt.name + selection_1.TUPLE; + } +}; +exports.default = multi; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcGlsZS9zZWxlY3Rpb24vbXVsdGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5Q0FBcUQ7QUFDckQsbUNBQXVDO0FBRXZDLElBQU0sS0FBSyxHQUFxQjtJQUM5QixTQUFTLEVBQUUsU0FBUztJQUVwQixPQUFPLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTztRQUM5QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUN0QixLQUFLLEdBQUksMENBQTBDLEVBQ25ELE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsa0JBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQXBCLENBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQ3pELE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUcsS0FBSyxTQUFJLGtCQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFHLEVBQW5DLENBQW1DLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0UsTUFBTSxDQUFDLENBQUM7Z0JBQ04sSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO2dCQUNsQixLQUFLLEVBQUUsRUFBRTtnQkFDVCxFQUFFLEVBQUUsQ0FBQzt3QkFDSCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07d0JBQ3RCLE1BQU0sRUFBRSxlQUFhLE1BQU0sb0JBQWUsTUFBTSxPQUFJO3FCQUNyRCxDQUFDO2FBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFNBQVMsRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPO1FBQ2hDLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDeEIsTUFBTSxDQUFDLGFBQVcsSUFBSSx5QkFBb0IsSUFBSSxZQUFTLENBQUM7SUFDMUQsQ0FBQztJQUVELFVBQVUsRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPO1FBQ2pDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLGlCQUFLLENBQUM7SUFDOUIsQ0FBQztDQUNGLENBQUM7QUFFZSx3QkFBTyJ9 \ No newline at end of file diff --git a/build/src/compile/selection/selection.d.ts b/build/src/compile/selection/selection.d.ts new file mode 100644 index 0000000000..e8ee77a119 --- /dev/null +++ b/build/src/compile/selection/selection.d.ts @@ -0,0 +1,44 @@ +import { SelectionDef, SelectionDomain, SelectionResolutions, SelectionTypes } from '../../selection'; +import { SelectionComponent } from './selection'; +import { Model } from '../model'; +import { UnitModel } from '../unit'; +import { Channel } from '../../channel'; +import { Dict } from '../../util'; +import { VgData, VgBinding } from '../../vega.schema'; +export declare const STORE = "_store", TUPLE = "_tuple", MODIFY = "_modify"; +export interface SelectionComponent { + name: string; + type: SelectionTypes; + domain: SelectionDomain; + events: any; + bind?: 'scales' | VgBinding | { + [key: string]: VgBinding; + }; + resolve: SelectionResolutions; + project?: ProjectComponent[]; + scales?: Channel[]; + toggle?: any; + translate?: any; + zoom?: any; + nearest?: any; +} +export interface ProjectComponent { + field?: string; + encoding?: Channel; +} +export interface SelectionCompiler { + signals: (model: UnitModel, selCmpt: SelectionComponent) => any[]; + topLevelSignals?: (model: Model, selCmpt: SelectionComponent) => any[]; + tupleExpr: (model: UnitModel, selCmpt: SelectionComponent) => string; + modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string; + marks?: (model: UnitModel, selCmpt: SelectionComponent, marks: any[]) => any[]; + predicate: string; +} +export declare function parseUnitSelection(model: UnitModel, selDefs: Dict): Dict; +export declare function assembleUnitSignals(model: UnitModel, signals: any[]): any[]; +export declare function assembleTopLevelSignals(model: Model): any[]; +export declare function assembleUnitData(model: UnitModel, data: VgData[]): VgData[]; +export declare function assembleUnitMarks(model: UnitModel, marks: any[]): any[]; +export declare function predicate(selCmpt: SelectionComponent, datum?: string): string; +export declare function invert(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, expr: string): string; +export declare function channelSignalName(selCmpt: SelectionComponent, channel: Channel): string; diff --git a/build/src/compile/selection/selection.js b/build/src/compile/selection/selection.js new file mode 100644 index 0000000000..ef4d1faa0c --- /dev/null +++ b/build/src/compile/selection/selection.js @@ -0,0 +1,177 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var transforms_1 = require("./transforms/transforms"); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var single_1 = require("./single"); +var multi_1 = require("./multi"); +var interval_1 = require("./interval"); +exports.STORE = '_store', exports.TUPLE = '_tuple', exports.MODIFY = '_modify'; +function parseUnitSelection(model, selDefs) { + var selCmpts = {}, selectionConfig = model.config.selection; + var _loop_1 = function (name_1) { + if (!selDefs.hasOwnProperty(name_1)) { + return "continue"; + } + var selDef = selDefs[name_1], cfg = selectionConfig[selDef.type]; + // Set default values from config if a property hasn't been specified, + // or if it is true. E.g., "translate": true should use the default + // event handlers for translate. However, true may be a valid value for + // a property (e.g., "nearest": true). + for (var key in cfg) { + // A selection should contain either `encodings` or `fields`, only use + // default values for these two values if neither of them is specified. + if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) { + continue; + } + if (selDef[key] === undefined || selDef[key] === true) { + selDef[key] = cfg[key] || selDef[key]; + } + } + var selCmpt = selCmpts[name_1] = util_1.extend({}, selDef, { + name: model.getName(name_1), + events: util_1.isString(selDef.on) ? event_selector_1.default(selDef.on, 'scope') : selDef.on, + domain: 'data', + resolve: 'union' + }); + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.parse) { + txCompiler.parse(model, selDef, selCmpt); + } + }); + }; + for (var name_1 in selDefs) { + _loop_1(name_1); + } + return selCmpts; +} +exports.parseUnitSelection = parseUnitSelection; +function assembleUnitSignals(model, signals) { + forEachSelection(model, function (selCmpt, selCompiler) { + var name = selCmpt.name, tupleExpr = selCompiler.tupleExpr(model, selCmpt), modifyExpr = selCompiler.modifyExpr(model, selCmpt); + signals.push.apply(signals, selCompiler.signals(model, selCmpt)); + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.signals) { + signals = txCompiler.signals(model, selCmpt, signals); + } + if (txCompiler.modifyExpr) { + modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr); + } + }); + signals.push({ + name: name + exports.TUPLE, + on: [{ + events: { signal: name }, + update: "{unit: unit.datum && unit.datum._id, " + tupleExpr + "}" + }] + }, { + name: name + exports.MODIFY, + on: [{ + events: { signal: name }, + update: "modify(" + util_1.stringValue(name + exports.STORE) + ", " + modifyExpr + ")" + }] + }); + }); + return signals; +} +exports.assembleUnitSignals = assembleUnitSignals; +function assembleTopLevelSignals(model) { + var signals = [{ + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'group()._id ? group() : unit' }] + }]; + forEachSelection(model, function (selCmpt, selCompiler) { + if (selCompiler.topLevelSignals) { + signals.push.apply(signals, selCompiler.topLevelSignals(model, selCmpt)); + } + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.topLevelSignals) { + signals = txCompiler.topLevelSignals(model, selCmpt, signals); + } + }); + }); + return signals; +} +exports.assembleTopLevelSignals = assembleTopLevelSignals; +function assembleUnitData(model, data) { + return data + .concat(Object.keys(model.component.selection) + .map(function (k) { + return { name: k + exports.STORE }; + })); +} +exports.assembleUnitData = assembleUnitData; +function assembleUnitMarks(model, marks) { + var clippedGroup = false, selMarks = marks; + forEachSelection(model, function (selCmpt, selCompiler) { + selMarks = selCompiler.marks ? selCompiler.marks(model, selCmpt, selMarks) : selMarks; + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + clippedGroup = clippedGroup || txCompiler.clippedGroup; + if (txCompiler.marks) { + selMarks = txCompiler.marks(model, selCmpt, marks, selMarks); + } + }); + }); + if (clippedGroup) { + selMarks = [{ + type: 'group', + encode: { + enter: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } }, + fill: { value: 'transparent' }, + clip: { value: true } + } + }, + marks: selMarks + }]; + } + return selMarks; +} +exports.assembleUnitMarks = assembleUnitMarks; +var PREDICATES_OPS = { + 'single': '"intersect", "all"', + 'independent': '"intersect", "unit"', + 'union': '"union", "all"', + 'union_others': '"union", "others"', + 'intersect': '"intersect", "all"', + 'intersect_others': '"intersect", "others' +}; +function predicate(selCmpt, datum) { + var store = util_1.stringValue(selCmpt.name + exports.STORE), op = PREDICATES_OPS[selCmpt.resolve]; + datum = datum || 'datum'; + return compiler(selCmpt).predicate + ("(" + store + ", parent._id, " + datum + ", " + op + ")"); +} +exports.predicate = predicate; +// Utility functions +function forEachSelection(model, cb) { + var selections = model.component.selection; + for (var name_2 in selections) { + if (selections.hasOwnProperty(name_2)) { + var sel = selections[name_2]; + cb(sel, compiler(sel)); + } + } +} +function compiler(selCmpt) { + switch (selCmpt.type) { + case 'single': + return single_1.default; + case 'multi': + return multi_1.default; + case 'interval': + return interval_1.default; + } + return null; +} +function invert(model, selCmpt, channel, expr) { + var scale = util_1.stringValue(model.scaleName(channel)); + return selCmpt.domain === 'data' ? "invert(" + scale + ", " + expr + ")" : expr; +} +exports.invert = invert; +function channelSignalName(selCmpt, channel) { + return selCmpt.name + '_' + channel; +} +exports.channelSignalName = channelSignalName; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NlbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUtBLG1DQUErRDtBQUMvRCxzREFBeUQ7QUFDekQseUVBQW1FO0FBRW5FLG1DQUFzQztBQUN0QyxpQ0FBb0M7QUFDcEMsdUNBQTBDO0FBRTdCLFFBQUEsS0FBSyxHQUFHLFFBQVEsRUFDM0IsUUFBQSxLQUFLLEdBQUksUUFBUSxFQUNqQixRQUFBLE1BQU0sR0FBRyxTQUFTLENBQUM7QUFrQ3JCLDRCQUFtQyxLQUFnQixFQUFFLE9BQTJCO0lBQzlFLElBQUksUUFBUSxHQUE2QixFQUFFLEVBQ3ZDLGVBQWUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQzs0QkFFcEMsTUFBSTtRQUNYLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7O1FBRXBDLENBQUM7UUFFRCxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBSSxDQUFDLEVBQ3RCLEdBQUcsR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXZDLHNFQUFzRTtRQUN0RSxtRUFBbUU7UUFDbkUsdUVBQXVFO1FBQ3ZFLHNDQUFzQztRQUN0QyxHQUFHLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLHNFQUFzRTtZQUN0RSx1RUFBdUU7WUFDdkUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssV0FBVyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDckYsUUFBUSxDQUFDO1lBQ1gsQ0FBQztZQUVELEVBQUUsQ0FBQyxDQUFDLE1B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 \ No newline at end of file diff --git a/build/src/compile/selection/single.d.ts b/build/src/compile/selection/single.d.ts new file mode 100644 index 0000000000..8a1db8583c --- /dev/null +++ b/build/src/compile/selection/single.d.ts @@ -0,0 +1,3 @@ +import { SelectionCompiler } from './selection'; +declare const single: SelectionCompiler; +export { single as default }; diff --git a/build/src/compile/selection/single.js b/build/src/compile/selection/single.js new file mode 100644 index 0000000000..fac3a6e067 --- /dev/null +++ b/build/src/compile/selection/single.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./selection"); +var multi_1 = require("./multi"); +var util_1 = require("../../util"); +var single = { + predicate: multi_1.default.predicate, + signals: multi_1.default.signals, + topLevelSignals: function (model, selCmpt) { + var name = selCmpt.name; + return [{ + name: name, + update: "data(" + util_1.stringValue(name + selection_1.STORE) + ")[0]" + }]; + }, + tupleExpr: function (model, selCmpt) { + var name = selCmpt.name, values = name + ".values"; + return "fields: " + name + ".fields, values: " + values + ", " + + selCmpt.project.map(function (p, i) { + return p.field + ": " + values + "[" + i + "]"; + }).join(', '); + }, + modifyExpr: function (model, selCmpt) { + return selCmpt.name + selection_1.TUPLE + ', true'; + } +}; +exports.default = single; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3NpbmdsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlDQUE0RDtBQUM1RCxpQ0FBNEI7QUFDNUIsbUNBQXVDO0FBRXZDLElBQU0sTUFBTSxHQUFxQjtJQUMvQixTQUFTLEVBQUUsZUFBSyxDQUFDLFNBQVM7SUFFMUIsT0FBTyxFQUFFLGVBQUssQ0FBQyxPQUFPO0lBRXRCLGVBQWUsRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPO1FBQ3RDLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDeEIsTUFBTSxDQUFDLENBQUM7Z0JBQ04sSUFBSSxFQUFFLElBQUk7Z0JBQ1YsTUFBTSxFQUFFLFVBQVEsa0JBQVcsQ0FBQyxJQUFJLEdBQUcsaUJBQUssQ0FBQyxTQUFNO2FBQ2hELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTztRQUNoQyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sR0FBTSxJQUFJLFlBQVMsQ0FBQztRQUNuRCxNQUFNLENBQUMsYUFBVyxJQUFJLHlCQUFvQixNQUFNLE9BQUk7WUFDbEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBUyxDQUFDLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxDQUFJLENBQUMsQ0FBQyxLQUFLLFVBQUssTUFBTSxTQUFJLENBQUMsTUFBRyxDQUFDO1lBQ3ZDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQixDQUFDO0lBRUQsVUFBVSxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU87UUFDakMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsaUJBQUssR0FBRyxRQUFRLENBQUM7SUFDekMsQ0FBQztDQUNGLENBQUM7QUFFZ0IseUJBQU8ifQ== \ No newline at end of file diff --git a/build/src/compile/selection/transforms/inputs.d.ts b/build/src/compile/selection/transforms/inputs.d.ts new file mode 100644 index 0000000000..a86baa2131 --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const inputBindings: TransformCompiler; +export { inputBindings as default }; diff --git a/build/src/compile/selection/transforms/inputs.js b/build/src/compile/selection/transforms/inputs.js new file mode 100644 index 0000000000..b29c43a0d2 --- /dev/null +++ b/build/src/compile/selection/transforms/inputs.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../../util"); +var inputBindings = { + has: function (selCmpt) { + return selCmpt.type === 'single' && selCmpt.bind && selCmpt.bind !== 'scales'; + }, + topLevelSignals: function (model, selCmpt, signals) { + var name = selCmpt.name, proj = selCmpt.project, bind = selCmpt.bind, datum = '(item().isVoronoi ? datum.datum : datum)'; + proj.forEach(function (p) { + signals.unshift({ + name: name + id(p.field), + value: '', + on: [{ + events: selCmpt.events, + update: datum + "[" + util_1.stringValue(p.field) + "]" + }], + bind: bind[p.field] || bind[p.encoding] || bind + }); + }); + return signals; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name, proj = selCmpt.project, signal = signals.filter(function (s) { return s.name === name; })[0], fields = proj.map(function (p) { return util_1.stringValue(p.field); }).join(', '), values = proj.map(function (p) { return name + id(p.field); }).join(', '); + signal.update = "{fields: [" + fields + "], values: [" + values + "]}"; + delete signal.value; + delete signal.on; + return signals; + } +}; +exports.default = inputBindings; +function id(str) { + return '_' + str.replace(/\W/g, '_'); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvaW5wdXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esc0NBQTBDO0FBRTFDLElBQU0sYUFBYSxHQUFxQjtJQUN0QyxHQUFHLEVBQUUsVUFBUyxPQUFPO1FBQ25CLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDO0lBQ2hGLENBQUM7SUFFRCxlQUFlLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU87UUFDL0MsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksRUFDbkIsSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQ3RCLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxFQUNuQixLQUFLLEdBQUcsMENBQTBDLENBQUM7UUFFdkQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFTLENBQUM7WUFDckIsT0FBTyxDQUFDLE9BQU8sQ0FBQztnQkFDZCxJQUFJLEVBQUUsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO2dCQUN4QixLQUFLLEVBQUUsRUFBRTtnQkFDVCxFQUFFLEVBQUUsQ0FBQzt3QkFDSCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07d0JBQ3RCLE1BQU0sRUFBSyxLQUFLLFNBQUksa0JBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQUc7cUJBQzVDLENBQUM7Z0JBQ0YsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJO2FBQ2hELENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ3ZDLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQzNDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLEVBQWYsQ0FBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ2xELE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsa0JBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQXBCLENBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQ3pELE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQWxCLENBQWtCLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUQsTUFBTSxDQUFDLE1BQU0sR0FBRyxlQUFhLE1BQU0sb0JBQWUsTUFBTSxPQUFJLENBQUM7UUFDN0QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ3BCLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUVqQixNQUFNLENBQUMsT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FDRixDQUFDO0FBRXVCLGdDQUFPO0FBRWhDLFlBQVksR0FBVztJQUNyQixNQUFNLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZDLENBQUMifQ== \ No newline at end of file diff --git a/build/src/compile/selection/transforms/nearest.d.ts b/build/src/compile/selection/transforms/nearest.d.ts new file mode 100644 index 0000000000..3fc5fb0148 --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const nearest: TransformCompiler; +export { nearest as default }; diff --git a/build/src/compile/selection/transforms/nearest.js b/build/src/compile/selection/transforms/nearest.js new file mode 100644 index 0000000000..f9278fa876 --- /dev/null +++ b/build/src/compile/selection/transforms/nearest.js @@ -0,0 +1,39 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VORONOI = 'voronoi'; +var nearest = { + has: function (selCmpt) { + return selCmpt.nearest !== undefined && selCmpt.nearest !== false; + }, + marks: function (model, selCmpt, marks, selMarks) { + var mark = marks[0], index = selMarks.indexOf(mark), isPathgroup = mark.name === model.getName('pathgroup'), exists = (function (m) { return m.name && m.name.indexOf(VORONOI) >= 0; }), cellDef = { + name: model.getName(VORONOI), + type: 'path', + from: { data: model.getName('marks') }, + encode: { + enter: { + fill: { value: 'transparent' }, + strokeWidth: { value: 0.35 }, + stroke: { value: 'transparent' }, + isVoronoi: { value: true } + } + }, + transform: [{ + type: 'voronoi', + x: 'datum.x', + y: 'datum.y', + size: [{ signal: 'width' }, { signal: 'height' }] + }] + }; + if (isPathgroup && !mark.marks.filter(exists).length) { + mark.marks.push(cellDef); + selMarks.splice(index, 1, mark); + } + else if (!isPathgroup && !selMarks.filter(exists).length) { + selMarks.splice(index + 1, 0, cellDef); + } + return selMarks; + } +}; +exports.default = nearest; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVhcmVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL25lYXJlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxJQUFNLE9BQU8sR0FBRyxTQUFTLENBQUM7QUFFMUIsSUFBTSxPQUFPLEdBQXFCO0lBQ2hDLEdBQUcsRUFBRSxVQUFTLE9BQU87UUFDbkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEtBQUssU0FBUyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDO0lBQ3BFLENBQUM7SUFFRCxLQUFLLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxRQUFRO1FBQzdDLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFDZixLQUFLLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFDOUIsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFDdEQsTUFBTSxHQUFHLENBQUMsVUFBQyxDQUFNLElBQUssT0FBQSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBdEMsQ0FBc0MsQ0FBQyxFQUM3RCxPQUFPLEdBQUc7WUFDUixJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDNUIsSUFBSSxFQUFFLE1BQU07WUFDWixJQUFJLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBQztZQUNwQyxNQUFNLEVBQUU7Z0JBQ04sS0FBSyxFQUFFO29CQUNMLElBQUksRUFBRSxFQUFDLEtBQUssRUFBRSxhQUFhLEVBQUM7b0JBQzVCLFdBQVcsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUM7b0JBQzFCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxhQUFhLEVBQUM7b0JBQzlCLFNBQVMsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUM7aUJBQ3pCO2FBQ0Y7WUFDRCxTQUFTLEVBQUUsQ0FBQztvQkFDVixJQUFJLEVBQUUsU0FBUztvQkFDZixDQUFDLEVBQUUsU0FBUztvQkFDWixDQUFDLEVBQUUsU0FBUztvQkFDWixJQUFJLEVBQUUsQ0FBQyxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUMsRUFBRSxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUMsQ0FBQztpQkFDOUMsQ0FBQztTQUNILENBQUM7UUFFTixFQUFFLENBQUMsQ0FBQyxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3pCLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzNELFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELE1BQU0sQ0FBQyxRQUFRLENBQUM7SUFDbEIsQ0FBQztDQUNGLENBQUM7QUFFaUIsMEJBQU8ifQ== \ No newline at end of file diff --git a/build/src/compile/selection/transforms/project.d.ts b/build/src/compile/selection/transforms/project.d.ts new file mode 100644 index 0000000000..bc267cb167 --- /dev/null +++ b/build/src/compile/selection/transforms/project.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const project: TransformCompiler; +export { project as default }; diff --git a/build/src/compile/selection/transforms/project.js b/build/src/compile/selection/transforms/project.js new file mode 100644 index 0000000000..6446566c83 --- /dev/null +++ b/build/src/compile/selection/transforms/project.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var project = { + has: function (selDef) { + return selDef.fields !== undefined || selDef.encodings !== undefined; + }, + parse: function (model, selDef, selCmpt) { + var fields = {}; + // TODO: find a possible channel mapping for these fields. + (selDef.fields || []).forEach(function (f) { return fields[f] = null; }); + (selDef.encodings || []).forEach(function (e) { return fields[model.field(e)] = e; }); + var projection = selCmpt.project || (selCmpt.project = []); + for (var field in fields) { + if (fields.hasOwnProperty(field)) { + projection.push({ field: field, encoding: fields[field] }); + } + } + } +}; +exports.default = project; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL3Byb2plY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFJQSxJQUFNLE9BQU8sR0FBcUI7SUFDaEMsR0FBRyxFQUFFLFVBQVMsTUFBb0I7UUFDaEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxLQUFLLEVBQUUsVUFBUyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU87UUFDcEMsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLDBEQUEwRDtRQUMxRCxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBaEIsQ0FBZ0IsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQyxDQUFVLElBQUssT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBMUIsQ0FBMEIsQ0FBQyxDQUFDO1FBRTdFLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzNELEdBQUcsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDekIsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGLENBQUM7QUFFaUIsMEJBQU8ifQ== \ No newline at end of file diff --git a/build/src/compile/selection/transforms/scales.d.ts b/build/src/compile/selection/transforms/scales.d.ts new file mode 100644 index 0000000000..c88a3ad069 --- /dev/null +++ b/build/src/compile/selection/transforms/scales.d.ts @@ -0,0 +1,6 @@ +import { TransformCompiler } from './transforms'; +import { Channel } from '../../../channel'; +import { UnitModel } from '../../unit'; +declare const scaleBindings: TransformCompiler; +export { scaleBindings as default }; +export declare function domain(model: UnitModel, channel: Channel): string; diff --git a/build/src/compile/selection/transforms/scales.js b/build/src/compile/selection/transforms/scales.js new file mode 100644 index 0000000000..4c3347bd6e --- /dev/null +++ b/build/src/compile/selection/transforms/scales.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log_1 = require("../../../log"); +var scale_1 = require("../../../scale"); +var selection_1 = require("../selection"); +var interval_1 = require("../interval"); +var util_1 = require("../../../util"); +var scaleBindings = { + clippedGroup: true, + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.bind && selCmpt.bind === 'scales'; + }, + parse: function (model, selDef, selCmpt) { + var scales = model.component.scales; + var bound = selCmpt.scales = []; + selCmpt.project.forEach(function (p) { + var channel = p.encoding; + var scale = scales[channel]; + if (!scale || !scale_1.hasContinuousDomain(scale.type)) { + log_1.warn('Scale bindings are currently only supported for scales with continuous domains.'); + return; + } + scale.domainRaw = { signal: selection_1.channelSignalName(selCmpt, channel) }; + bound.push(channel); + }); + }, + topLevelSignals: function (model, selCmpt, signals) { + return signals.concat(selCmpt.scales.map(function (channel) { + return { name: selection_1.channelSignalName(selCmpt, channel) }; + })); + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + signals = signals.filter(function (s) { + return s.name !== name + interval_1.SIZE && + s.name !== name + selection_1.TUPLE && s.name !== selection_1.MODIFY; + }); + selCmpt.scales.forEach(function (channel) { + var signal = signals.filter(function (s) { return s.name === name + '_' + channel; })[0]; + signal.push = 'outer'; + delete signal.value; + delete signal.update; + }); + return signals; + } +}; +exports.default = scaleBindings; +function domain(model, channel) { + var scale = util_1.stringValue(model.scaleName(channel)); + return "domain(" + scale + ")"; +} +exports.domain = domain; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvc2NhbGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esb0NBQWtDO0FBQ2xDLHdDQUFtRDtBQUVuRCwwQ0FBOEQ7QUFFOUQsd0NBQWtEO0FBQ2xELHNDQUEwQztBQUUxQyxJQUFNLGFBQWEsR0FBcUI7SUFDdEMsWUFBWSxFQUFFLElBQUk7SUFFbEIsR0FBRyxFQUFFLFVBQVMsT0FBTztRQUNuQixNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztJQUNsRixDQUFDO0lBRUQsS0FBSyxFQUFFLFVBQVMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPO1FBQ3BDLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQ3RDLElBQU0sS0FBSyxHQUFhLE9BQU8sQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBRTVDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVMsQ0FBQztZQUNoQyxJQUFNLE9BQU8sR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzNCLElBQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU5QixFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLDJCQUFtQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9DLFVBQUksQ0FBQyxpRkFBaUYsQ0FBQyxDQUFDO2dCQUN4RixNQUFNLENBQUM7WUFDVCxDQUFDO1lBRUQsS0FBSyxDQUFDLFNBQVMsR0FBRyxFQUFDLE1BQU0sRUFBRSw2QkFBaUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUMsQ0FBQztZQUNoRSxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWUsRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTztRQUMvQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFDLE9BQU87WUFDL0MsTUFBTSxDQUFDLEVBQUMsSUFBSSxFQUFFLDZCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsRUFBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ3ZDLElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7UUFDeEIsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBUyxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksR0FBRyxlQUFhO2dCQUNwQyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksR0FBRyxpQkFBSyxJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssa0JBQU0sQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVMsT0FBTztZQUNyQyxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLEdBQUcsR0FBRyxHQUFHLE9BQU8sRUFBL0IsQ0FBK0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDO1lBQ3RCLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQztZQUNwQixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDdkIsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FDRixDQUFDO0FBRXVCLGdDQUFPO0FBRWhDLGdCQUF1QixLQUFnQixFQUFFLE9BQWdCO0lBQ3ZELElBQUksS0FBSyxHQUFHLGtCQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ2xELE1BQU0sQ0FBQyxZQUFVLEtBQUssTUFBRyxDQUFDO0FBQzVCLENBQUM7QUFIRCx3QkFHQyJ9 \ No newline at end of file diff --git a/build/src/compile/selection/transforms/toggle.d.ts b/build/src/compile/selection/transforms/toggle.d.ts new file mode 100644 index 0000000000..22c443e915 --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const toggle: TransformCompiler; +export { toggle as default }; diff --git a/build/src/compile/selection/transforms/toggle.js b/build/src/compile/selection/transforms/toggle.js new file mode 100644 index 0000000000..d3ca2e37e0 --- /dev/null +++ b/build/src/compile/selection/transforms/toggle.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("../selection"); +var TOGGLE = '_toggle'; +var toggle = { + has: function (selCmpt) { + return selCmpt.toggle !== undefined && selCmpt.toggle !== false; + }, + signals: function (model, selCmpt, signals) { + return signals.concat({ + name: selCmpt.name + TOGGLE, + value: false, + on: [{ events: selCmpt.events, update: selCmpt.toggle }] + }); + }, + modifyExpr: function (model, selCmpt, expr) { + var tpl = selCmpt.name + selection_1.TUPLE, signal = selCmpt.name + TOGGLE; + return signal + " ? null : " + tpl + ", " + + (signal + " ? null : true, ") + + (signal + " ? " + tpl + " : null"); + } +}; +exports.default = toggle; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvdG9nZ2xlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsMENBQW1DO0FBRW5DLElBQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQztBQUV6QixJQUFNLE1BQU0sR0FBcUI7SUFDL0IsR0FBRyxFQUFFLFVBQVMsT0FBTztRQUNuQixNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUM7SUFDbEUsQ0FBQztJQUVELE9BQU8sRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTztRQUN2QyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztZQUNwQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksR0FBRyxNQUFNO1lBQzNCLEtBQUssRUFBRSxLQUFLO1lBQ1osRUFBRSxFQUFFLENBQUMsRUFBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sRUFBQyxDQUFDO1NBQ3ZELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxVQUFVLEVBQUUsVUFBUyxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUk7UUFDdkMsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLElBQUksR0FBRyxpQkFBSyxFQUMxQixNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7UUFFbkMsTUFBTSxDQUFJLE1BQU0sa0JBQWEsR0FBRyxPQUFJO2FBQy9CLE1BQU0scUJBQWtCLENBQUE7YUFDeEIsTUFBTSxXQUFNLEdBQUcsWUFBUyxDQUFBLENBQUM7SUFDaEMsQ0FBQztDQUNGLENBQUM7QUFFZ0IseUJBQU8ifQ== \ No newline at end of file diff --git a/build/src/compile/selection/transforms/transforms.d.ts b/build/src/compile/selection/transforms/transforms.d.ts new file mode 100644 index 0000000000..ce2be9ab15 --- /dev/null +++ b/build/src/compile/selection/transforms/transforms.d.ts @@ -0,0 +1,14 @@ +import { Model } from '../../model'; +import { UnitModel } from '../../unit'; +import { SelectionDef } from '../../../selection'; +import { SelectionComponent } from '../selection'; +export interface TransformCompiler { + has: (selCmpt: SelectionComponent | SelectionDef) => boolean; + parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void; + signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: any[]) => any[]; + topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[]; + modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string; + marks?: (model: UnitModel, selCmpt: SelectionComponent, marks: any[], selMarks: any[]) => any[]; + clippedGroup?: boolean; +} +export declare function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void): void; diff --git a/build/src/compile/selection/transforms/transforms.js b/build/src/compile/selection/transforms/transforms.js new file mode 100644 index 0000000000..4cee55c853 --- /dev/null +++ b/build/src/compile/selection/transforms/transforms.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var project_1 = require("./project"); +var toggle_1 = require("./toggle"); +var translate_1 = require("./translate"); +var zoom_1 = require("./zoom"); +var scales_1 = require("./scales"); +var inputs_1 = require("./inputs"); +var nearest_1 = require("./nearest"); +var compilers = { project: project_1.default, toggle: toggle_1.default, scales: scales_1.default, + translate: translate_1.default, zoom: zoom_1.default, inputs: inputs_1.default, nearest: nearest_1.default }; +function forEachTransform(selCmpt, cb) { + for (var t in compilers) { + if (compilers[t].has(selCmpt)) { + cb(compilers[t]); + } + } +} +exports.forEachTransform = forEachTransform; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3Jtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL3RyYW5zZm9ybXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFpQkEscUNBQWdDO0FBQ2hDLG1DQUE4QjtBQUM5Qix5Q0FBb0M7QUFDcEMsK0JBQTBCO0FBQzFCLG1DQUE4QjtBQUM5QixtQ0FBOEI7QUFDOUIscUNBQWdDO0FBQ2hDLElBQU0sU0FBUyxHQUE0QixFQUFDLE9BQU8sbUJBQUEsRUFBRSxNQUFNLGtCQUFBLEVBQUUsTUFBTSxrQkFBQTtJQUNqRSxTQUFTLHFCQUFBLEVBQUUsSUFBSSxnQkFBQSxFQUFFLE1BQU0sa0JBQUEsRUFBRSxPQUFPLG1CQUFBLEVBQUMsQ0FBQztBQUVwQywwQkFBaUMsT0FBMkIsRUFBRSxFQUFtQztJQUMvRixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFORCw0Q0FNQyJ9 \ No newline at end of file diff --git a/build/src/compile/selection/transforms/translate.d.ts b/build/src/compile/selection/transforms/translate.d.ts new file mode 100644 index 0000000000..fffa908ace --- /dev/null +++ b/build/src/compile/selection/transforms/translate.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const translate: TransformCompiler; +export { translate as default }; diff --git a/build/src/compile/selection/transforms/translate.js b/build/src/compile/selection/transforms/translate.js new file mode 100644 index 0000000000..1ed7c94b0d --- /dev/null +++ b/build/src/compile/selection/transforms/translate.js @@ -0,0 +1,64 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var channel_1 = require("../../../channel"); +var util_1 = require("../../../util"); +var scales_1 = require("./scales"); +var interval_1 = require("../interval"); +var ANCHOR = '_translate_anchor', DELTA = '_translate_delta'; +var translate = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.translate !== undefined && selCmpt.translate !== false; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name, scales = scales_1.default.has(selCmpt), size = scales ? 'unit' : name + interval_1.SIZE, anchor = name + ANCHOR, events = event_selector_1.default(selCmpt.translate, 'scope'), _a = interval_1.projections(selCmpt), x = _a.x, y = _a.y; + if (!scales) { + events = events.map(function (e) { return (e.between[0].markname = name + interval_1.BRUSH, e); }); + } + signals.push({ + name: anchor, + value: {}, + on: [{ + events: events.map(function (e) { return e.between[0]; }), + update: '{x: x(unit), y: y(unit), ' + + ("width: " + size + ".width, height: " + size + ".height, ") + + (x !== null ? 'extent_x: ' + (scales ? scales_1.domain(model, channel_1.X) : + "slice(" + name + "_x)") + ', ' : '') + + (y !== null ? 'extent_y: ' + (scales ? scales_1.domain(model, channel_1.Y) : + "slice(" + name + "_y)") + ', ' : '') + '}' + }] + }, { + name: name + DELTA, + value: {}, + on: [{ + events: events, + update: "{x: x(unit) - " + anchor + ".x, y: y(unit) - " + anchor + ".y}" + }] + }); + if (x !== null) { + onDelta(model, selCmpt, channel_1.X, 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, channel_1.Y, 'height', signals); + } + return signals; + } +}; +exports.default = translate; +function getSign(selCmpt, channel) { + var s = channel === channel_1.X ? '+' : '-'; + if (scales_1.default.has(selCmpt)) { + s = s === '+' ? '-' : '+'; + } + return s; +} +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name, signal = signals.filter(function (s) { return s.name === name + '_' + channel; })[0], anchor = name + ANCHOR, delta = name + DELTA, scale = util_1.stringValue(model.scaleName(channel)), extent = ".extent_" + channel, sign = getSign(selCmpt, channel), offset = sign + " abs(span(" + anchor + extent + ")) * " + + (delta + "." + channel + " / " + anchor + "." + size), range = "[" + anchor + extent + "[0] " + offset + ", " + + ("" + anchor + extent + "[1] " + offset + "]"), lo = "invert(" + scale + (channel === channel_1.X ? ', 0' : ", unit." + size) + ')', hi = "invert(" + scale + (channel === channel_1.X ? ", unit." + size : ', 0') + ')'; + signal.on.push({ + events: { signal: delta }, + update: scales_1.default.has(selCmpt) ? range : "clampRange(" + range + ", " + lo + ", " + hi + ")" + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zZm9ybXMvdHJhbnNsYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEseUVBQW1FO0FBR25FLDRDQUErQztBQUMvQyxzQ0FBMEM7QUFFMUMsbUNBQTJEO0FBQzNELHdDQUErRztBQUUvRyxJQUFNLE1BQU0sR0FBRyxtQkFBbUIsRUFDNUIsS0FBSyxHQUFJLGtCQUFrQixDQUFDO0FBRWxDLElBQU0sU0FBUyxHQUFxQjtJQUNsQyxHQUFHLEVBQUUsVUFBUyxPQUFPO1FBQ25CLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFVBQVUsSUFBSSxPQUFPLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxPQUFPLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQztJQUN2RyxDQUFDO0lBRUQsT0FBTyxFQUFFLFVBQVMsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPO1FBQ25DLElBQUEsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQ25CLE1BQU0sR0FBRyxnQkFBYyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFDcEMsSUFBSSxHQUFHLE1BQU0sR0FBRyxNQUFNLEdBQUcsSUFBSSxHQUFHLGVBQWEsRUFDN0MsTUFBTSxHQUFHLElBQUksR0FBRyxNQUFNLEVBQ3RCLE1BQU0sR0FBRyx3QkFBYSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLEVBQ2xELG9DQUFxQyxFQUFwQyxRQUFDLEVBQUUsUUFBQyxDQUFpQztRQUUxQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDWixNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxH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 \ No newline at end of file diff --git a/build/src/compile/selection/transforms/zoom.d.ts b/build/src/compile/selection/transforms/zoom.d.ts new file mode 100644 index 0000000000..a3ff88c3af --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.d.ts @@ -0,0 +1,3 @@ +import { TransformCompiler } from './transforms'; +declare const zoom: TransformCompiler; +export { zoom as default }; diff --git a/build/src/compile/selection/transforms/zoom.js b/build/src/compile/selection/transforms/zoom.js new file mode 100644 index 0000000000..c161b4d2c2 --- /dev/null +++ b/build/src/compile/selection/transforms/zoom.js @@ -0,0 +1,60 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var channel_1 = require("../../../channel"); +var util_1 = require("../../../util"); +var scales_1 = require("./scales"); +var interval_1 = require("../interval"); +var ANCHOR = '_zoom_anchor', DELTA = '_zoom_delta'; +var zoom = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.zoom !== undefined && selCmpt.zoom !== false; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name, delta = name + DELTA, events = event_selector_1.default(selCmpt.zoom, 'scope'), _a = interval_1.projections(selCmpt), x = _a.x, y = _a.y, sx = util_1.stringValue(model.scaleName(channel_1.X)), sy = util_1.stringValue(model.scaleName(channel_1.Y)); + if (!scales_1.default.has(selCmpt)) { + events = events.map(function (e) { return (e.markname = name + interval_1.BRUSH, e); }); + } + signals.push({ + name: name + ANCHOR, + on: [{ + events: events, + update: "{x: invert(" + sx + ", x(unit)), y: invert(" + sy + ", y(unit))}" + }] + }, { + name: delta, + on: [{ + events: events, + force: true, + update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))' + }] + }); + if (x !== null) { + onDelta(model, selCmpt, 'x', 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, 'y', 'height', signals); + } + var size = signals.filter(function (s) { return s.name === name + interval_1.SIZE; }); + if (size.length) { + var sname = size[0].name; + size[0].on.push({ + events: { signal: delta }, + update: "{x: " + sname + ".x, y: " + sname + ".y, " + + ("width: " + sname + ".width * " + delta + " , ") + + ("height: " + sname + ".height * " + delta + "}") + }); + } + return signals; + } +}; +exports.default = zoom; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name, signal = signals.filter(function (s) { return s.name === name + '_' + channel; })[0], scales = scales_1.default.has(selCmpt), base = scales ? scales_1.domain(model, channel) : signal.name, anchor = "" + name + ANCHOR + "." + channel, delta = name + DELTA, scale = util_1.stringValue(model.scaleName(channel)), range = "[" + anchor + " + (" + base + "[0] - " + anchor + ") * " + delta + ", " + + (anchor + " + (" + base + "[1] - " + anchor + ") * " + delta + "]"), lo = "invert(" + scale + (channel === channel_1.X ? ', 0' : ", unit." + size) + ')', hi = "invert(" + scale + (channel === channel_1.X ? ", unit." + size : ', 0') + ')'; + signal.on.push({ + events: { signal: delta }, + update: scales ? range : "clampRange(" + range + ", " + lo + ", " + hi + ")" + }); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21waWxlL3NlbGVjdGlvbi90cmFuc2Zvcm1zL3pvb20udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx5RUFBbUU7QUFHbkUsNENBQStDO0FBQy9DLHNDQUEwQztBQUUxQyxtQ0FBMkQ7QUFDM0Qsd0NBQStHO0FBRS9HLElBQU0sTUFBTSxHQUFHLGNBQWMsRUFDdkIsS0FBSyxHQUFJLGFBQWEsQ0FBQztBQUU3QixJQUFNLElBQUksR0FBcUI7SUFDN0IsR0FBRyxFQUFFLFVBQVMsT0FBTztRQUNuQixNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxVQUFVLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLLENBQUM7SUFDN0YsQ0FBQztJQUVELE9BQU8sRUFBRSxVQUFTLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTztRQUN2QyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxFQUNuQixLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssRUFDcEIsTUFBTSxHQUFHLHdCQUFhLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFDN0Msb0NBQXFDLEVBQXBDLFFBQUMsRUFBRSxRQUFDLEVBQ0wsRUFBRSxHQUFHLGtCQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxXQUFDLENBQUMsQ0FBQyxFQUNwQyxFQUFFLEdBQUcsa0JBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFdBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekMsRUFBRSxDQUFDLENBQUMsQ0FBQyxnQkFBYyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxHQUFHLGdCQUFjLEVBQUUsQ0FBQyxDQUFDLEVBQXZDLENBQXVDLENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBRUQsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNYLElBQUksRUFBRSxJQUFJLEdBQUcsTUFBTTtZQUNuQixFQUFFLEVBQUUsQ0FBQztvQkFDSCxNQUFNLEVBQUUsTUFBTTtvQkFDZCxNQUFNLEVBQUUsZ0JBQWMsRUFBRSw4QkFBeUIsRUFBRSxnQkFBYTtpQkFDakUsQ0FBQztTQUNILEVBQUU7WUFDRCxJQUFJLEVBQUUsS0FBSztZQUNYLEVBQUUsRUFBRSxDQUFDO29CQUNILE1BQU0sRUFBRSxNQUFNO29CQUNkLEtBQUssRUFBRSxJQUFJO29CQUNYLE1BQU0sRUFBRSxxREFBcUQ7aUJBQzlELENBQUM7U0FDSCxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUssSUFBSyxPQUFBLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHLGVBQWEsRUFBL0IsQ0FBK0IsQ0FBQyxDQUFDO1FBQ3RFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2hCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7Z0JBQ2QsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQztnQkFDdkIsTUFBTSxFQUFFLFNBQU8sS0FBSyxlQUFVLEtBQUssU0FBTTtxQkFDdkMsWUFBVSxLQUFLLGlCQUFZLEtBQUssUUFBSyxDQUFBO3FCQUNyQyxhQUFXLEtBQUssa0JBQWEsS0FBSyxNQUFHLENBQUE7YUFDeEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE1BQU0sQ0FBQyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUNGLENBQUM7QUFFYyx1QkFBTztBQUV2QixpQkFBaUIsS0FBZ0IsRUFBRSxPQUEyQixFQUFFLE9BQWdCLEVBQUUsSUFBWSxFQUFFLE9BQWM7SUFDNUcsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksRUFDbkIsTUFBTSxHQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFLLElBQUssT0FBQSxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksR0FBRyxHQUFHLEdBQUcsT0FBTyxFQUEvQixDQUErQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQzFFLE1BQU0sR0FBRyxnQkFBYyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFDcEMsSUFBSSxHQUFHLE1BQU0sR0FBRyxlQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLEVBQ3BELE1BQU0sR0FBRyxLQUFHLElBQUksR0FBRyxNQUFNLFNBQUksT0FBUyxFQUN0QyxLQUFLLEdBQUksSUFBSSxHQUFHLEtBQUssRUFDckIsS0FBSyxHQUFJLGtCQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUM5QyxLQUFLLEdBQUksTUFBSSxNQUFNLFlBQU8sSUFBSSxjQUFTLE1BQU0sWUFBTyxLQUFLLE9BQUk7U0FDeEQsTUFBTSxZQUFPLElBQUksY0FBUyxNQUFNLFlBQU8sS0FBSyxNQUFHLENBQUEsRUFDcEQsRUFBRSxHQUFHLFlBQVUsS0FBTyxHQUFHLENBQUMsT0FBTyxLQUFLLFdBQUMsR0FBRyxLQUFLLEdBQUcsWUFBVSxJQUFNLENBQUMsR0FBRyxHQUFHLEVBQ3pFLEVBQUUsR0FBRyxZQUFVLEtBQU8sR0FBRyxDQUFDLE9BQU8sS0FBSyxXQUFDLEdBQUcsWUFBVSxJQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBRTlFLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQ2IsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQztRQUN2QixNQUFNLEVBQUUsTUFBTSxHQUFHLEtBQUssR0FBRyxnQkFBYyxLQUFLLFVBQUssRUFBRSxVQUFLLEVBQUUsTUFBRztLQUM5RCxDQUFDLENBQUM7QUFDTCxDQUFDIn0= \ No newline at end of file diff --git a/build/src/compile/unit.d.ts b/build/src/compile/unit.d.ts new file mode 100644 index 0000000000..e9f7a31a8e --- /dev/null +++ b/build/src/compile/unit.d.ts @@ -0,0 +1,76 @@ +import { Axis } from '../axis'; +import { Channel } from '../channel'; +import { Config, CellConfig } from '../config'; +import { Encoding } from '../encoding'; +import { FieldDef, FieldRefOption } from '../fielddef'; +import { Legend } from '../legend'; +import { Mark, MarkDef } from '../mark'; +import { Scale } from '../scale'; +import { UnitSpec } from '../spec'; +import { Dict } from '../util'; +import { VgData } from '../vega.schema'; +import { Model } from './model'; +import { StackProperties } from '../stack'; +import { SelectionDef } from '../selection'; +/** + * Internal model of Vega-Lite specification for the compiler. + */ +export declare class UnitModel extends Model { + /** + * Fixed width for the unit visualization. + * If undefined (e.g., for ordinal scale), the width of the + * visualization will be calculated dynamically. + */ + readonly width: number; + /** + * Fixed height for the unit visualization. + * If undefined (e.g., for ordinal scale), the height of the + * visualization will be calculated dynamically. + */ + readonly height: number; + readonly markDef: MarkDef & { + filled: boolean; + }; + readonly encoding: Encoding; + protected readonly selection: Dict; + protected readonly scales: Dict; + protected readonly axes: Dict; + protected readonly legends: Dict; + readonly config: Config; + readonly stack: StackProperties; + children: Model[]; + constructor(spec: UnitSpec, parent: Model, parentGivenName: string); + /** + * Init config by merging config from parent and, if applicable, from facet config + */ + private initConfig(specConfig, parent); + private initScales(mark, encoding, config, topLevelWidth, topLevelHeight); + private initSize(mark, scale, width, height, cellConfig, scaleConfig); + private initAxes(encoding, config); + private initLegend(encoding, config); + parseData(): void; + parseSelection(): void; + parseLayoutData(): void; + parseScale(): void; + parseMark(): void; + parseAxis(): void; + parseAxisGroup(): void; + parseGridGroup(): void; + parseLegend(): void; + assembleSignals(signals: any[]): any[]; + assembleSelectionData(data: VgData[]): VgData[]; + assembleData(data: VgData[]): VgData[]; + assembleLayout(layoutData: VgData[]): VgData[]; + assembleMarks(): any[]; + assembleParentGroupProperties(cellConfig: CellConfig): any; + channels(): ("text" | "x" | "y" | "x2" | "y2" | "color" | "opacity" | "size" | "shape" | "detail" | "order")[]; + protected getMapping(): Encoding; + toSpec(excludeConfig?: any, excludeData?: any): any; + mark(): Mark; + channelHasField(channel: Channel): boolean; + fieldDef(channel: Channel): FieldDef; + /** Get "field" reference for vega */ + field(channel: Channel, opt?: FieldRefOption): string; + dataTable(): string; + isUnit(): boolean; +} diff --git a/build/src/compile/unit.js b/build/src/compile/unit.js new file mode 100644 index 0000000000..35f6ac5aae --- /dev/null +++ b/build/src/compile/unit.js @@ -0,0 +1,268 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var axis_1 = require("../axis"); +var channel_1 = require("../channel"); +var config_1 = require("../config"); +var data_1 = require("../data"); +var encoding_1 = require("../encoding"); +var vlEncoding = require("../encoding"); // TODO: remove +var fielddef_1 = require("../fielddef"); +var mark_1 = require("../mark"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var common_1 = require("./common"); +var data_2 = require("./data/data"); +var parse_2 = require("./legend/parse"); +var layout_1 = require("./layout"); +var model_1 = require("./model"); +var mark_2 = require("./mark/mark"); +var init_1 = require("./scale/init"); +var parse_3 = require("./scale/parse"); +var stack_1 = require("../stack"); +var selection_1 = require("./selection/selection"); +var init_2 = require("./mark/init"); +/** + * Internal model of Vega-Lite specification for the compiler. + */ +var UnitModel = (function (_super) { + tslib_1.__extends(UnitModel, _super); + function UnitModel(spec, parent, parentGivenName) { + var _this = _super.call(this, spec, parent, parentGivenName) || this; + _this.selection = {}; + _this.scales = {}; + _this.axes = {}; + _this.legends = {}; + _this.children = []; + // use top-level width / height or parent's top-level width / height + // FIXME: once facet supports width/height, this is no longer correct! + var providedWidth = spec.width !== undefined ? spec.width : + parent ? parent['width'] : undefined; // only exists if parent is layer + var providedHeight = spec.height !== undefined ? spec.height : + parent ? parent['height'] : undefined; // only exists if parent is layer + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = _this.encoding = encoding_1.dropInvalidFieldDefs(mark, spec.encoding || {}); + // TODO?: ideally we should use config only inside this constructor + var config = _this.config = _this.initConfig(spec.config, parent); + // calculate stack properties + _this.stack = stack_1.stack(mark, encoding, config.stack); + _this.scales = _this.initScales(mark, encoding, config, providedWidth, providedHeight); + _this.markDef = init_2.initMarkDef(spec.mark, encoding, _this.scales, config); + _this.encoding = init_2.initEncoding(mark, encoding, _this.stack, config); + _this.axes = _this.initAxes(encoding, config); + _this.legends = _this.initLegend(encoding, config); + // Selections will be initialized upon parse. + _this.selection = spec.selection; + // width / height + var _a = _this.initSize(mark, _this.scales, providedWidth, providedHeight, config.cell, config.scale), _b = _a.width, width = _b === void 0 ? _this.width : _b, _c = _a.height, height = _c === void 0 ? _this.height : _c; + _this.width = width; + _this.height = height; + return _this; + } + /** + * Init config by merging config from parent and, if applicable, from facet config + */ + UnitModel.prototype.initConfig = function (specConfig, parent) { + var config = util_1.mergeDeep(util_1.duplicate(config_1.defaultConfig), parent ? parent.config : {}, specConfig); + var hasFacetParent = false; + while (parent !== null) { + if (parent.isFacet()) { + hasFacetParent = true; + break; + } + parent = parent.parent; + } + if (hasFacetParent) { + config.cell = util_1.extend({}, config.cell, config.facet.cell); + } + return config; + }; + UnitModel.prototype.initScales = function (mark, encoding, config, topLevelWidth, topLevelHeight) { + var xyRangeSteps = []; + return channel_1.UNIT_SCALE_CHANNELS.reduce(function (scales, channel) { + if (vlEncoding.channelHasField(encoding, channel) || + (channel === channel_1.X && vlEncoding.channelHasField(encoding, channel_1.X2)) || + (channel === channel_1.Y && vlEncoding.channelHasField(encoding, channel_1.Y2))) { + var scale = scales[channel] = init_1.default(channel, encoding[channel], config, mark, channel === channel_1.X ? topLevelWidth : channel === channel_1.Y ? topLevelHeight : undefined, xyRangeSteps // for determine point / bar size + ); + if (channel === channel_1.X || channel === channel_1.Y) { + if (scale.rangeStep) { + xyRangeSteps.push(scale.rangeStep); + } + } + } + return scales; + }, {}); + }; + // TODO: consolidate this with scale? Current scale range is in parseScale (later), + // but not in initScale because scale range depends on size, + // but size depends on scale type and rangeStep + UnitModel.prototype.initSize = function (mark, scale, width, height, cellConfig, scaleConfig) { + if (width === undefined) { + if (scale[channel_1.X]) { + if (!scale_1.hasDiscreteDomain(scale[channel_1.X].type) || !scale[channel_1.X].rangeStep) { + width = cellConfig.width; + } // else: Do nothing, use dynamic width. + } + else { + if (mark === mark_1.TEXT) { + // for text table without x/y scale we need wider rangeStep + width = scaleConfig.textXRangeStep; + } + else { + if (typeof scaleConfig.rangeStep === 'string') { + throw new Error('_initSize does not handle string rangeSteps'); + } + width = scaleConfig.rangeStep; + } + } + } + if (height === undefined) { + if (scale[channel_1.Y]) { + if (!scale_1.hasDiscreteDomain(scale[channel_1.Y].type) || !scale[channel_1.Y].rangeStep) { + height = cellConfig.height; + } // else: Do nothing, use dynamic height . + } + else { + if (typeof scaleConfig.rangeStep === 'string') { + throw new Error('_initSize does not handle string rangeSteps'); + } + height = scaleConfig.rangeStep; + } + } + return { width: width, height: height }; + }; + UnitModel.prototype.initAxes = function (encoding, config) { + return [channel_1.X, channel_1.Y].reduce(function (_axis, channel) { + // Position Axis + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef) || + (channel === channel_1.X && fielddef_1.isFieldDef(encoding.x2)) || + (channel === channel_1.Y && fielddef_1.isFieldDef(encoding.y2))) { + var axisSpec = fielddef_1.isFieldDef(channelDef) ? channelDef.axis : null; + // We no longer support false in the schema, but we keep false here for backward compatability. + if (axisSpec !== null && axisSpec !== false) { + var vlOnlyAxisProperties_1 = {}; + axis_1.VL_ONLY_AXIS_PROPERTIES.forEach(function (property) { + if (config.axis[property] !== undefined) { + vlOnlyAxisProperties_1[property] = config.axis[property]; + } + }); + _axis[channel] = tslib_1.__assign({}, vlOnlyAxisProperties_1, axisSpec); + } + } + return _axis; + }, {}); + }; + UnitModel.prototype.initLegend = function (encoding, config) { + return channel_1.NONSPATIAL_SCALE_CHANNELS.reduce(function (_legend, channel) { + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef)) { + var legendSpec = channelDef.legend; + if (legendSpec !== null && legendSpec !== false) { + _legend[channel] = tslib_1.__assign({}, legendSpec); + } + } + return _legend; + }, {}); + }; + UnitModel.prototype.parseData = function () { + this.component.data = data_2.parseUnitData(this); + }; + UnitModel.prototype.parseSelection = function () { + this.component.selection = selection_1.parseUnitSelection(this, this.selection); + }; + UnitModel.prototype.parseLayoutData = function () { + this.component.layout = layout_1.parseUnitLayout(this); + }; + UnitModel.prototype.parseScale = function () { + this.component.scales = parse_3.default(this); + }; + UnitModel.prototype.parseMark = function () { + this.component.mark = mark_2.parseMark(this); + }; + UnitModel.prototype.parseAxis = function () { + this.component.axes = parse_1.parseAxisComponent(this, [channel_1.X, channel_1.Y]); + }; + UnitModel.prototype.parseAxisGroup = function () { + return null; + }; + UnitModel.prototype.parseGridGroup = function () { + return null; + }; + UnitModel.prototype.parseLegend = function () { + this.component.legends = parse_2.parseLegendComponent(this); + }; + UnitModel.prototype.assembleSignals = function (signals) { + return selection_1.assembleUnitSignals(this, signals); + }; + UnitModel.prototype.assembleSelectionData = function (data) { + return selection_1.assembleUnitData(this, data); + }; + UnitModel.prototype.assembleData = function (data) { + return data_2.assembleData(this, data); + }; + UnitModel.prototype.assembleLayout = function (layoutData) { + return layout_1.assembleLayout(this, layoutData); + }; + UnitModel.prototype.assembleMarks = function () { + return selection_1.assembleUnitMarks(this, this.component.mark); + }; + UnitModel.prototype.assembleParentGroupProperties = function (cellConfig) { + return common_1.applyConfig({}, cellConfig, mark_1.FILL_STROKE_CONFIG.concat(['clip'])); + }; + UnitModel.prototype.channels = function () { + return channel_1.UNIT_CHANNELS; + }; + UnitModel.prototype.getMapping = function () { + return this.encoding; + }; + UnitModel.prototype.toSpec = function (excludeConfig, excludeData) { + var encoding = util_1.duplicate(this.encoding); + var spec; + spec = { + mark: this.markDef, + encoding: encoding + }; + if (!excludeConfig) { + spec.config = util_1.duplicate(this.config); + } + if (!excludeData) { + spec.data = util_1.duplicate(this.data); + } + // remove defaults + return spec; + }; + UnitModel.prototype.mark = function () { + return this.markDef.type; + }; + UnitModel.prototype.channelHasField = function (channel) { + return vlEncoding.channelHasField(this.encoding, channel); + }; + UnitModel.prototype.fieldDef = function (channel) { + // TODO: remove this || {} + // Currently we have it to prevent null pointer exception. + return this.encoding[channel] || {}; + }; + /** Get "field" reference for vega */ + UnitModel.prototype.field = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (fieldDef.bin) { + opt = util_1.extend({ + binSuffix: scale_1.hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start' + }, opt); + } + return fielddef_1.field(fieldDef, opt); + }; + UnitModel.prototype.dataTable = function () { + return this.dataName(vlEncoding.isAggregate(this.encoding) ? data_1.SUMMARY : data_1.SOURCE); + }; + UnitModel.prototype.isUnit = function () { + return true; + }; + return UnitModel; +}(model_1.Model)); +exports.UnitModel = UnitModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21waWxlL3VuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsZ0NBQXNFO0FBQ3RFLHNDQUFpSDtBQUNqSCxvQ0FBNEQ7QUFDNUQsZ0NBQXdDO0FBQ3hDLHdDQUEyRDtBQUMzRCx3Q0FBMEMsQ0FBQyxlQUFlO0FBQzFELHdDQUF3RTtBQUV4RSxnQ0FBd0Y7QUFDeEYsa0NBQStEO0FBRS9ELGdDQUEyRDtBQUczRCxzQ0FBZ0Q7QUFDaEQsbUNBQXFDO0FBQ3JDLG9DQUF3RDtBQUN4RCx3Q0FBb0Q7QUFDcEQsbUNBQXlEO0FBQ3pELGlDQUE4QjtBQUM5QixvQ0FBc0M7QUFDdEMscUNBQXFDO0FBQ3JDLHVDQUFnRDtBQUNoRCxrQ0FBZ0Q7QUFFaEQsbURBQXNLO0FBQ3RLLG9DQUFzRDtBQUV0RDs7R0FFRztBQUNIO0lBQStCLHFDQUFLO0lBMEJsQyxtQkFBWSxJQUFjLEVBQUUsTUFBYSxFQUFFLGVBQXVCO1FBQWxFLFlBQ0Usa0JBQU0sSUFBSSxFQUFFLE1BQU0sRUFBRSxlQUFlLENBQUMsU0FxQ3JDO1FBOUNrQixlQUFTLEdBQXVCLEVBQUUsQ0FBQztRQUNuQyxZQUFNLEdBQWdCLEVBQUUsQ0FBQztRQUN6QixVQUFJLEdBQWUsRUFBRSxDQUFDO1FBQ3RCLGFBQU8sR0FBaUIsRUFBRSxDQUFDO1FBR3ZDLGNBQVEsR0FBWSxFQUFFLENBQUM7UUFLNUIsb0VBQW9FO1FBRXBFLHNFQUFzRTtRQUN0RSxJQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSztZQUN6RCxNQUFNLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDLGlDQUFpQztRQUN6RSxJQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTTtZQUM1RCxNQUFNLEdB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 \ No newline at end of file diff --git a/build/src/compositemark.d.ts b/build/src/compositemark.d.ts new file mode 100644 index 0000000000..98b13bb354 --- /dev/null +++ b/build/src/compositemark.d.ts @@ -0,0 +1,11 @@ +import { MarkDef } from './mark'; +import { GenericUnitSpec, LayerSpec } from './spec'; +export declare const ERRORBAR: 'error-bar'; +export declare type ERRORBAR = typeof ERRORBAR; +export declare type UnitNormalizer = (spec: GenericUnitSpec) => LayerSpec; +export declare function add(mark: string, normalizer: UnitNormalizer): void; +export declare function remove(mark: string): void; +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +export declare function normalize(spec: GenericUnitSpec): LayerSpec; diff --git a/build/src/compositemark.js b/build/src/compositemark.js new file mode 100644 index 0000000000..430dad6d9a --- /dev/null +++ b/build/src/compositemark.js @@ -0,0 +1,49 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mark_1 = require("./mark"); +exports.ERRORBAR = 'error-bar'; +/** + * Registry index for all composite mark's normalizer + */ +var normalizerRegistry = {}; +function add(mark, normalizer) { + normalizerRegistry[mark] = normalizer; +} +exports.add = add; +function remove(mark) { + delete normalizerRegistry[mark]; +} +exports.remove = remove; +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +function normalize( + // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels. + spec) { + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var normalizer = normalizerRegistry[mark]; + if (normalizer) { + return normalizer(spec); + } + throw new Error("Unregistered composite mark " + mark); +} +exports.normalize = normalize; +add(exports.ERRORBAR, function (spec) { + var _m = spec.mark, encoding = spec.encoding, outerSpec = tslib_1.__rest(spec, ["mark", "encoding"]); + var _s = encoding.size, encodingWithoutSize = tslib_1.__rest(encoding, ["size"]); + var _x2 = encoding.x2, _y2 = encoding.y2, encodingWithoutX2Y2 = tslib_1.__rest(encoding, ["x2", "y2"]); + return tslib_1.__assign({}, outerSpec, { layer: [ + { + mark: 'rule', + encoding: encodingWithoutSize + }, { + mark: 'tick', + encoding: encodingWithoutX2Y2 + }, { + mark: 'tick', + encoding: tslib_1.__assign({}, encodingWithoutX2Y2, (encoding.x2 ? { x: encoding.x2 } : {}), (encoding.y2 ? { y: encoding.y2 } : {})) + } + ] }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9zaXRlbWFyay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb3NpdGVtYXJrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLCtCQUEwQztBQUc3QixRQUFBLFFBQVEsR0FBZ0IsV0FBVyxDQUFDO0FBS2pEOztHQUVHO0FBQ0gsSUFBTSxrQkFBa0IsR0FBcUMsRUFBRSxDQUFDO0FBRWhFLGFBQW9CLElBQVksRUFBRSxVQUEwQjtJQUMxRCxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxVQUFVLENBQUM7QUFDeEMsQ0FBQztBQUZELGtCQUVDO0FBRUQsZ0JBQXVCLElBQVk7SUFDakMsT0FBTyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBRkQsd0JBRUM7QUFFRDs7R0FFRztBQUNIO0lBQ0kseUhBQXlIO0lBQ3pILElBQTRDO0lBRzlDLElBQU0sSUFBSSxHQUFHLGdCQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDL0QsSUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNmLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsaUNBQStCLElBQU0sQ0FBQyxDQUFDO0FBQ3pELENBQUM7QUFaRCw4QkFZQztBQUdELEdBQUcsQ0FBQyxnQkFBUSxFQUFFLFVBQUMsSUFBeUM7SUFDL0MsSUFBQSxjQUFRLEVBQUUsd0JBQWtCLEVBQUUsc0RBQVksQ0FBUztJQUNuRCxJQUFBLGtCQUFRLEVBQUUsd0RBQXNCLENBQWE7SUFDN0MsSUFBQSxpQkFBTyxFQUFFLGlCQUFPLEVBQUUsNERBQXNCLENBQWE7SUFFNUQsTUFBTSxzQkFDRCxTQUFTLElBQ1osS0FBSyxFQUFFO1lBQ0w7Z0JBQ0UsSUFBSSxFQUFFLE1BQU07Z0JBQ1osUUFBUSxFQUFFLG1CQUFtQjthQUM5QixFQUFDO2dCQUNBLElBQUksRUFBRSxNQUFNO2dCQUNaLFFBQVEsRUFBRSxtQkFBbUI7YUFDOUIsRUFBRTtnQkFDRCxJQUFJLEVBQUUsTUFBTTtnQkFDWixRQUFRLHVCQUNILG1CQUFtQixFQUNuQixDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsRUFBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBQyxHQUFHLEVBQUUsQ0FBQyxFQUNyQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsRUFBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBQyxHQUFHLEVBQUUsQ0FBQyxDQUN6QzthQUNGO1NBQ0YsSUFDRDtBQUNKLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/src/config.d.ts b/build/src/config.d.ts new file mode 100644 index 0000000000..5ee4142b2f --- /dev/null +++ b/build/src/config.d.ts @@ -0,0 +1,147 @@ +import { AxisConfig } from './axis'; +import { LegendConfig } from './legend'; +import { MarkConfig, BarConfig, TextConfig, TickConfig } from './mark'; +import { ScaleConfig } from './scale'; +import { StackOffset } from './stack'; +import { Padding } from './spec'; +import { VgRangeScheme } from './vega.schema'; +import { SelectionConfig } from './selection'; +export interface CellConfig { + width?: number; + height?: number; + clip?: boolean; + /** + * The fill color. + */ + fill?: string; + /** The fill opacity (value between [0,1]). */ + fillOpacity?: number; + /** The stroke color. */ + stroke?: string; + /** The stroke opacity (value between [0,1]). */ + strokeOpacity?: number; + /** The stroke width, in pixels. */ + strokeWidth?: number; + /** An array of alternating stroke, space lengths for creating dashed or dotted lines. */ + strokeDash?: number[]; + /** The offset (in pixels) into which to begin drawing with the stroke dash array. */ + strokeDashOffset?: number; +} +export declare const defaultCellConfig: CellConfig; +export declare const defaultFacetCellConfig: CellConfig; +export interface FacetConfig { + /** Facet Axis Config */ + axis?: AxisConfig; + /** Facet Grid Config */ + grid?: FacetGridConfig; + /** Facet Cell Config */ + cell?: CellConfig; +} +export interface FacetGridConfig { + color?: string; + opacity?: number; + offset?: number; +} +export declare const defaultFacetConfig: FacetConfig; +export declare type AreaOverlay = 'line' | 'linepoint' | 'none'; +export interface OverlayConfig { + /** + * Whether to overlay line with point. + */ + line?: boolean; + /** + * Type of overlay for area mark (line or linepoint) + */ + area?: AreaOverlay; + /** + * Default style for the overlayed point. + */ + pointStyle?: MarkConfig; + /** + * Default style for the overlayed point. + */ + lineStyle?: MarkConfig; +} +export declare const defaultOverlayConfig: OverlayConfig; +export declare type RangeConfig = (number | string)[] | VgRangeScheme | { + step: number; +}; +export interface Config { + /** + * The width and height of the on-screen viewport, in pixels. If necessary, clipping and scrolling will be applied. + */ + viewport?: number; + /** + * CSS color property to use as background of visualization. Default is `"transparent"`. + */ + background?: string; + /** + * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. This can be a single number or an object with `"top"`, `"left"`, `"right"`, `"bottom"` properties. + * + * __Default value__: `5` + * + * * @minimum 0 + */ + padding?: Padding; + /** + * D3 Number format for axis labels and text tables. For example "s" for SI units. + */ + numberFormat?: string; + /** + * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend. + */ + timeFormat?: string; + /** + * Default axis and legend title for count fields. + * @type {string} + */ + countTitle?: string; + /** Cell Config */ + cell?: CellConfig; + /** Default stack offset for stackable mark. */ + stack?: StackOffset; + /** Mark Config */ + mark?: MarkConfig; + /** Area-Specific Config */ + area?: MarkConfig; + /** Bar-Specific Config */ + bar?: BarConfig; + /** Circle-Specific Config */ + circle?: MarkConfig; + /** Line-Specific Config */ + line?: MarkConfig; + /** Point-Specific Config */ + point?: MarkConfig; + /** Rect-Specific Config */ + rect?: MarkConfig; + /** Rule-Specific Config */ + rule?: MarkConfig; + /** Square-Specific Config */ + square?: MarkConfig; + /** Text-Specific Config */ + text?: TextConfig; + /** Tick-Specific Config */ + tick?: TickConfig; + /** Mark Overlay Config */ + overlay?: OverlayConfig; + /** Scale Config */ + scale?: ScaleConfig; + /** + * Scale range config, or properties defining named range arrays + * that can be used within scale range definitions + * (such as `{"type": "ordinal", "range": "category"}`). + * For default range that Vega-Lite adopts from Vega, see https://github.com/vega/vega-parser#scale-range-properties. + */ + range?: { + [name: string]: RangeConfig; + }; + /** Axis Config */ + axis?: AxisConfig; + /** Legend Config */ + legend?: LegendConfig; + /** Facet Config */ + facet?: FacetConfig; + /** Selection Config */ + selection?: SelectionConfig; +} +export declare const defaultConfig: Config; diff --git a/build/src/config.js b/build/src/config.js new file mode 100644 index 0000000000..e8f8be202b --- /dev/null +++ b/build/src/config.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var axis_1 = require("./axis"); +var legend_1 = require("./legend"); +var mark = require("./mark"); +var scale_1 = require("./scale"); +var selection_1 = require("./selection"); +exports.defaultCellConfig = { + width: 200, + height: 200, + fill: 'transparent' +}; +exports.defaultFacetCellConfig = { + stroke: '#ccc', + strokeWidth: 1 +}; +var defaultFacetGridConfig = { + color: '#000000', + opacity: 0.4, + offset: 0 +}; +exports.defaultFacetConfig = { + axis: {}, + grid: defaultFacetGridConfig, + cell: exports.defaultFacetCellConfig +}; +exports.defaultOverlayConfig = { + line: false, + pointStyle: { filled: true }, + lineStyle: {} +}; +exports.defaultConfig = { + padding: 5, + numberFormat: 's', + timeFormat: '%b %d, %Y', + countTitle: 'Number of Records', + cell: exports.defaultCellConfig, + mark: mark.defaultMarkConfig, + area: {}, + bar: mark.defaultBarConfig, + circle: {}, + line: {}, + point: {}, + rect: {}, + rule: {}, + square: {}, + text: mark.defaultTextConfig, + tick: mark.defaultTickConfig, + overlay: exports.defaultOverlayConfig, + scale: scale_1.defaultScaleConfig, + axis: axis_1.defaultAxisConfig, + legend: legend_1.defaultLegendConfig, + facet: exports.defaultFacetConfig, + selection: selection_1.defaultConfig +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLCtCQUFxRDtBQUNyRCxtQ0FBMkQ7QUFFM0QsNkJBQStCO0FBQy9CLGlDQUF3RDtBQUl4RCx5Q0FBcUY7QUFpQ3hFLFFBQUEsaUJBQWlCLEdBQWU7SUFDM0MsS0FBSyxFQUFFLEdBQUc7SUFDVixNQUFNLEVBQUUsR0FBRztJQUNYLElBQUksRUFBRSxhQUFhO0NBQ3BCLENBQUM7QUFFVyxRQUFBLHNCQUFzQixHQUFlO0lBQ2hELE1BQU0sRUFBRSxNQUFNO0lBQ2QsV0FBVyxFQUFFLENBQUM7Q0FDZixDQUFDO0FBbUJGLElBQU0sc0JBQXNCLEdBQW9CO0lBQzlDLEtBQUssRUFBRSxTQUFTO0lBQ2hCLE9BQU8sRUFBRSxHQUFHO0lBQ1osTUFBTSxFQUFFLENBQUM7Q0FDVixDQUFDO0FBRVcsUUFBQSxrQkFBa0IsR0FBZ0I7SUFDN0MsSUFBSSxFQUFFLEVBQUU7SUFDUixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLElBQUksRUFBRSw4QkFBc0I7Q0FDN0IsQ0FBQztBQTBCVyxRQUFBLG9CQUFvQixHQUFrQjtJQUNqRCxJQUFJLEVBQUUsS0FBSztJQUNYLFVBQVUsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUM7SUFDMUIsU0FBUyxFQUFFLEVBQUU7Q0FDZCxDQUFDO0FBaUhXLFFBQUEsYUFBYSxHQUFXO0lBQ25DLE9BQU8sRUFBRSxDQUFDO0lBQ1YsWUFBWSxFQUFFLEdBQUc7SUFDakIsVUFBVSxFQUFFLFdBQVc7SUFDdkIsVUFBVSxFQUFFLG1CQUFtQjtJQUUvQixJQUFJLEVBQUUseUJBQWlCO0lBRXZCLElBQUksRUFBRSxJQUFJLENBQUMsaUJBQWlCO0lBQzVCLElBQUksRUFBRSxFQUFFO0lBQ1IsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7SUFDMUIsTUFBTSxFQUFFLEVBQUU7SUFDVixJQUFJLEVBQUUsRUFBRTtJQUNSLEtBQUssRUFBRSxFQUFFO0lBQ1QsSUFBSSxFQUFFLEVBQUU7SUFDUixJQUFJLEVBQUUsRUFBRTtJQUNSLE1BQU0sRUFBRSxFQUFFO0lBQ1YsSUFBSSxFQUFFLElBQUksQ0FBQyxpQkFBaUI7SUFDNUIsSUFBSSxFQUFFLElBQUksQ0FBQyxpQkFBaUI7SUFFNUIsT0FBTyxFQUFFLDRCQUFvQjtJQUM3QixLQUFLLEVBQUUsMEJBQWtCO0lBQ3pCLElBQUksRUFBRSx3QkFBaUI7SUFDdkIsTUFBTSxFQUFFLDRCQUFtQjtJQUUzQixLQUFLLEVBQUUsMEJBQWtCO0lBRXpCLFNBQVMsRUFBRSx5QkFBc0I7Q0FDbEMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/data.d.ts b/build/src/data.d.ts new file mode 100644 index 0000000000..fc713396de --- /dev/null +++ b/build/src/data.d.ts @@ -0,0 +1,65 @@ +export interface DataFormat { + /** + * Type of input data: `"json"`, `"csv"`, `"tsv"`. + * The default format type is determined by the extension of the file url. + * If no extension is detected, `"json"` will be used by default. + */ + type?: DataFormatType; + /** + * A collection of parsing instructions can be used to define the data types of string-valued attributes in the JSON file. Each instruction is a name-value pair, where the name is the name of the attribute, and the value is the desired data type (one of `"number"`, `"boolean"` or `"date"`). For example, `"parse": {"modified_on":"date"}` ensures that the `modified_on` value in each row of the input data is parsed as a Date value. (See Datalib's [`dl.read.types` method](https://github.com/vega/datalib/wiki/Import#dl_read_types) for more information.) + */ + parse?: any; + /** + * JSON only) The JSON property containing the desired data. + * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data. + * For example `"property": "values.features"` is equivalent to retrieving `json.values.features` + * from the loaded JSON object. + */ + property?: string; + /** + * The name of the TopoJSON object set to convert to a GeoJSON feature collection. + * For example, in a map of the world, there may be an object set named `"countries"`. + * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country. + */ + feature?: string; + /** + * The name of the TopoJSON object set to convert to a mesh. + * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set. + * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features. + * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties. + */ + mesh?: string; +} +export declare type DataFormatType = 'json' | 'csv' | 'tsv' | 'topojson'; +export declare type Data = UrlData | InlineData | NamedData; +export interface UrlData { + /** + * An object that specifies the format for the data file or values. + */ + format?: DataFormat; + /** + * A URL from which to load the data set. Use the format.type property + * to ensure the loaded data is correctly parsed. + */ + url: string; +} +export interface InlineData { + /** + * Pass array of objects instead of a url to a file. + */ + values: any[]; +} +export interface NamedData { + /** + * Provide a placeholder name and bind data at runtime. + */ + name: string; +} +export declare function isUrlData(data: Data): data is UrlData; +export declare function isInlineData(data: Data): data is InlineData; +export declare function isNamedData(data: Data): data is NamedData; +export declare type DataSourceType = 'source' | 'summary' | 'stacked' | 'layout'; +export declare const SUMMARY: 'summary'; +export declare const SOURCE: 'source'; +export declare const STACKED: 'stacked'; +export declare const LAYOUT: 'layout'; diff --git a/build/src/data.js b/build/src/data.js new file mode 100644 index 0000000000..32e7a95c91 --- /dev/null +++ b/build/src/data.js @@ -0,0 +1,22 @@ +/* + * Constants and utilities for data. + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isUrlData(data) { + return !!data['url']; +} +exports.isUrlData = isUrlData; +function isInlineData(data) { + return !!data['values']; +} +exports.isInlineData = isInlineData; +function isNamedData(data) { + return !!data['name']; +} +exports.isNamedData = isNamedData; +exports.SUMMARY = 'summary'; +exports.SOURCE = 'source'; +exports.STACKED = 'stacked'; +exports.LAYOUT = 'layout'; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHOzs7QUFxRUgsbUJBQTBCLElBQVU7SUFDbEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDdkIsQ0FBQztBQUZELDhCQUVDO0FBRUQsc0JBQTZCLElBQVU7SUFDckMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDMUIsQ0FBQztBQUZELG9DQUVDO0FBRUQscUJBQTRCLElBQVU7SUFDcEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDeEIsQ0FBQztBQUZELGtDQUVDO0FBSVksUUFBQSxPQUFPLEdBQWMsU0FBUyxDQUFDO0FBQy9CLFFBQUEsTUFBTSxHQUFhLFFBQVEsQ0FBQztBQUM1QixRQUFBLE9BQU8sR0FBYyxTQUFTLENBQUM7QUFDL0IsUUFBQSxNQUFNLEdBQWEsUUFBUSxDQUFDIn0= \ No newline at end of file diff --git a/build/src/datetime.d.ts b/build/src/datetime.d.ts new file mode 100644 index 0000000000..7c1c6e62a5 --- /dev/null +++ b/build/src/datetime.d.ts @@ -0,0 +1,101 @@ +/** + * @minimum 1 + * @maximum 12 + * @TJS-type integer + */ +export declare type Month = number; +/** + * @minimum 1 + * @maximum 7 + */ +export declare type Day = number; +/** + * Object for defining datetime in Vega-Lite Filter. + * If both month and quarter are provided, month has higher precedence. + * `day` cannot be combined with other date. + * We accept string for month and day names. + */ +export interface DateTime { + /** + * Integer value representing the year. + * @TJS-type integer + */ + year?: number; + /** + * Integer value representing the quarter of the year (from 1-4). + * @minimum 1 + * @maximum 4 + * @TJS-type integer + */ + quarter?: number; + /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `"January"`); (3) case-insensitive, 3-character short month name (e.g., `"Jan"`). */ + month?: Month | string; + /** + * Integer value representing the date from 1-31. + * @minimum 1 + * @maximum 31 + * @TJS-type integer + */ + date?: number; + /** + * Value representing the day of week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `"Monday"`); (3) case-insensitive, 3-character short day name (e.g., `"Mon"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`. + */ + day?: Day | string; + /** + * Integer value representing the hour of day from 0-23. + * @minimum 0 + * @maximum 23 + * @TJS-type integer + */ + hours?: number; + /** + * Integer value representing minute segment of a time from 0-59. + * @minimum 0 + * @maximum 59 + * @TJS-type integer + */ + minutes?: number; + /** + * Integer value representing second segment of a time from 0-59. + * @minimum 0 + * @maximum 59 + * @TJS-type integer + */ + seconds?: number; + /** + * Integer value representing millisecond segment of a time. + * @minimum 0 + * @maximum 999 + * @TJS-type integer + */ + milliseconds?: number; +} +/** + * Internal Object for defining datetime expressions. + * This is an expression version of DateTime. + * If both month and quarter are provided, month has higher precedence. + * `day` cannot be combined with other date. + */ +export interface DateTimeExpr { + year?: string; + quarter?: string; + month?: string; + date?: string; + day?: string; + hours?: string; + minutes?: string; + seconds?: string; + milliseconds?: string; +} +export declare function isDateTime(o: any): o is DateTime; +export declare const MONTHS: string[]; +export declare const SHORT_MONTHS: string[]; +export declare const DAYS: string[]; +export declare const SHORT_DAYS: string[]; +export declare function timestamp(d: DateTime, normalize: boolean): number; +/** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ +export declare function dateTimeExpr(d: DateTime | DateTimeExpr, normalize?: boolean): string; diff --git a/build/src/datetime.js b/build/src/datetime.js new file mode 100644 index 0000000000..0095a3e6a8 --- /dev/null +++ b/build/src/datetime.js @@ -0,0 +1,180 @@ +// DateTime definition object +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var log = require("./log"); +/* + * A designated year that starts on Sunday. + */ +var SUNDAY_YEAR = 2006; +function isDateTime(o) { + return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day || + !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds); +} +exports.isDateTime = isDateTime; +exports.MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; +exports.SHORT_MONTHS = exports.MONTHS.map(function (m) { return m.substr(0, 3); }); +exports.DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; +exports.SHORT_DAYS = exports.DAYS.map(function (d) { return d.substr(0, 3); }); +function normalizeQuarter(q) { + if (util_1.isNumber(q)) { + if (q > 4) { + log.warn(log.message.invalidTimeUnit('quarter', q)); + } + // We accept 1-based quarter, so need to readjust to 0-based quarter + return (q - 1) + ''; + } + else { + // Invalid quarter + throw new Error(log.message.invalidTimeUnit('quarter', q)); + } +} +function normalizeMonth(m) { + if (util_1.isNumber(m)) { + // We accept 1-based month, so need to readjust to 0-based month + return (m - 1) + ''; + } + else { + var lowerM = m.toLowerCase(); + var monthIndex = exports.MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + var shortM = lowerM.substr(0, 3); + var shortMonthIndex = exports.SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(log.message.invalidTimeUnit('month', m)); + } +} +function normalizeDay(d) { + if (util_1.isNumber(d)) { + // mod so that this can be both 0-based where 0 = sunday + // and 1-based where 7=sunday + return (d % 7) + ''; + } + else { + var lowerD = d.toLowerCase(); + var dayIndex = exports.DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + var shortD = lowerD.substr(0, 3); + var shortDayIndex = exports.SHORT_DAYS.indexOf(shortD); + if (shortDayIndex !== -1) { + return shortDayIndex + ''; + } + // Invalid day + throw new Error(log.message.invalidTimeUnit('day', d)); + } +} +function timestamp(d, normalize) { + var date = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date + // FIXME support UTC + if (d.day !== undefined) { + if (util_1.keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = util_1.duplicate(d); + delete d.day; + } + else { + // Use a year that has 1/1 as Sunday so we can setDate below + date.setFullYear(SUNDAY_YEAR); + var day = normalize ? normalizeDay(d.day) : d.day; + date.setDate(+day + 1); // +1 since date start at 1 in JS + } + } + if (d.year !== undefined) { + date.setFullYear(d.year); + } + if (d.quarter !== undefined) { + var quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + date.setMonth(+quarter * 3); + } + if (d.month !== undefined) { + var month = normalize ? normalizeMonth(d.month) : d.month; + date.setMonth(+month); + } + if (d.date !== undefined) { + date.setDate(d.date); + } + if (d.hours !== undefined) { + date.setHours(d.hours); + } + if (d.minutes !== undefined) { + date.setMinutes(d.minutes); + } + if (d.seconds !== undefined) { + date.setSeconds(d.seconds); + } + if (d.milliseconds !== undefined) { + date.setMilliseconds(d.milliseconds); + } + return date.getTime(); +} +exports.timestamp = timestamp; +/** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ +function dateTimeExpr(d, normalize) { + if (normalize === void 0) { normalize = false; } + var units = []; + if (normalize && d.day !== undefined) { + if (util_1.keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = util_1.duplicate(d); + delete d.day; + } + } + if (d.year !== undefined) { + units.push(d.year); + } + else if (d.day !== undefined) { + // Set year to 2006 for working with day since January 1 2006 is a Sunday + units.push(SUNDAY_YEAR); + } + else { + units.push(0); + } + if (d.month !== undefined) { + var month = normalize ? normalizeMonth(d.month) : d.month; + units.push(month); + } + else if (d.quarter !== undefined) { + var quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + units.push(quarter + '*3'); + } + else { + units.push(0); // months start at zero in JS + } + if (d.date !== undefined) { + units.push(d.date); + } + else if (d.day !== undefined) { + // HACK: Day only works as a standalone unit + // This is only correct because we always set year to 2006 for day + var day = normalize ? normalizeDay(d.day) : d.day; + units.push(day + '+1'); + } + else { + units.push(1); // Date starts at 1 in JS + } + // Note: can't use TimeUnit enum here as importing it will create + // circular dependency problem! + for (var _i = 0, _a = ['hours', 'minutes', 'seconds', 'milliseconds']; _i < _a.length; _i++) { + var timeUnit = _a[_i]; + if (d[timeUnit] !== undefined) { + units.push(d[timeUnit]); + } + else { + units.push(0); + } + } + return 'datetime(' + units.join(', ') + ')'; +} +exports.dateTimeExpr = dateTimeExpr; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0ZXRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkJBQTZCOzs7QUFFN0IsK0JBQWlEO0FBQ2pELDJCQUE2QjtBQUU3Qjs7R0FFRztBQUNILElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQztBQXdHekIsb0JBQTJCLENBQU07SUFDL0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUc7UUFDeEUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBSEQsZ0NBR0M7QUFFWSxRQUFBLE1BQU0sR0FBRyxDQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDcEksUUFBQSxZQUFZLEdBQUcsY0FBTSxDQUFDLEdBQUcsQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFkLENBQWMsQ0FBQyxDQUFDO0FBRWpELFFBQUEsSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxRQUFR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 \ No newline at end of file diff --git a/build/src/encoding.d.ts b/build/src/encoding.d.ts new file mode 100644 index 0000000000..e0a75df15e --- /dev/null +++ b/build/src/encoding.d.ts @@ -0,0 +1,73 @@ +import { FieldDef, PositionFieldDef, LegendFieldDef, OrderFieldDef, ValueDef, TextFieldDef, ConditionalValueDef } from './fielddef'; +import { Channel } from './channel'; +import { Facet } from './facet'; +import { Mark } from './mark'; +export interface Encoding { + /** + * X coordinates for `point`, `circle`, `square`, + * `line`, `rule`, `text`, and `tick` + * (or to width and height for `bar` and `area` marks). + */ + x?: PositionFieldDef | ValueDef; + /** + * Y coordinates for `point`, `circle`, `square`, + * `line`, `rule`, `text`, and `tick` + * (or to width and height for `bar` and `area` marks). + */ + y?: PositionFieldDef | ValueDef; + /** + * X2 coordinates for ranged `bar`, `rule`, `area` + */ + x2?: FieldDef | ValueDef; + /** + * Y2 coordinates for ranged `bar`, `rule`, `area` + */ + y2?: FieldDef | ValueDef; + /** + * Color of the marks – either fill or stroke color based on mark type. + * (By default, fill color for `area`, `bar`, `tick`, `text`, `circle`, and `square` / + * stroke color for `line` and `point`.) + */ + color?: LegendFieldDef | ConditionalValueDef; + /** + * Opacity of the marks – either can be a value or in a range. + */ + opacity?: LegendFieldDef | ConditionalValueDef; + /** + * Size of the mark. + * - For `point`, `square` and `circle` + * – the symbol size, or pixel area of the mark. + * - For `bar` and `tick` – the bar and tick's size. + * - For `text` – the text's font size. + * - Size is currently unsupported for `line` and `area`. + */ + size?: LegendFieldDef | ConditionalValueDef; + /** + * The symbol's shape (only for `point` marks). The supported values are + * `"circle"` (default), `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, + * or `"triangle-down"`, or else a custom SVG path string. + */ + shape?: LegendFieldDef | ConditionalValueDef; + /** + * Additional levels of detail for grouping data in aggregate views and + * in line and area marks without mapping data to a specific visual channel. + */ + detail?: FieldDef | FieldDef[]; + /** + * Text of the `text` mark. + */ + text?: TextFieldDef | ConditionalValueDef; + /** + * stack order for stacked marks or order of data points in line marks. + */ + order?: OrderFieldDef | OrderFieldDef[]; +} +export interface EncodingWithFacet extends Encoding, Facet { +} +export declare function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean; +export declare function isAggregate(encoding: EncodingWithFacet): boolean; +export declare function dropInvalidFieldDefs(mark: Mark, encoding: Encoding): Encoding; +export declare function isRanged(encoding: EncodingWithFacet): boolean; +export declare function fieldDefs(encoding: EncodingWithFacet): FieldDef[]; +export declare function forEach(mapping: any, f: (fd: FieldDef, c: Channel) => void, thisArg?: any): void; +export declare function reduce(mapping: U, f: (acc: any, fd: FieldDef, c: Channel) => U, init: T, thisArg?: any): any; diff --git a/build/src/encoding.js b/build/src/encoding.js new file mode 100644 index 0000000000..57b55544b3 --- /dev/null +++ b/build/src/encoding.js @@ -0,0 +1,132 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// utility for encoding mapping +var fielddef_1 = require("./fielddef"); +var channel_1 = require("./channel"); +var util_1 = require("./util"); +var log = require("./log"); +function channelHasField(encoding, channel) { + var channelDef = encoding && encoding[channel]; + if (channelDef) { + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.field; }); + } + else { + return fielddef_1.isFieldDef(channelDef); + } + } + return false; +} +exports.channelHasField = channelHasField; +function isAggregate(encoding) { + return util_1.some(channel_1.CHANNELS, function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.aggregate; }); + } + else { + return fielddef_1.isFieldDef(channelDef) && !!channelDef.aggregate; + } + } + return false; + }); +} +exports.isAggregate = isAggregate; +function dropInvalidFieldDefs(mark, encoding) { + // clone to prevent side effect to the original spec + encoding = util_1.duplicate(encoding); + Object.keys(encoding).forEach(function (channel) { + if (!channel_1.supportMark(channel, mark)) { + // Drop unsupported channel + log.warn(log.message.incompatibleChannel(channel, mark)); + delete encoding[channel]; + return; + } + // Drop line's size if the field is aggregated. + if (channel === 'size' && mark === 'line') { + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef) && channelDef.aggregate) { + log.warn(log.message.incompatibleChannel(channel, mark, 'when the field is aggregated.')); + delete encoding[channel]; + } + return; + } + if (util_1.isArray(encoding[channel])) { + // Array of fieldDefs for detail channel (or production rule) + encoding[channel] = encoding[channel].reduce(function (channelDefs, channelDef) { + if (!fielddef_1.isFieldDef(channelDef) && !fielddef_1.isValueDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + } + else { + channelDefs.push(fielddef_1.normalize(channelDef, channel)); + } + return channelDefs; + }, []); + } + else { + var channelDef = encoding[channel]; + if (!fielddef_1.isFieldDef(channelDef) && !fielddef_1.isValueDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + delete encoding[channel]; + return; + } + fielddef_1.normalize(channelDef, channel); + } + }); + return encoding; +} +exports.dropInvalidFieldDefs = dropInvalidFieldDefs; +function isRanged(encoding) { + return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2)); +} +exports.isRanged = isRanged; +function fieldDefs(encoding) { + var arr = []; + channel_1.CHANNELS.forEach(function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + arr.push(fieldDef); + }); + } + }); + return arr; +} +exports.fieldDefs = fieldDefs; +; +function forEach(mapping, f, thisArg) { + if (!mapping) { + return; + } + Object.keys(mapping).forEach(function (c) { + var channel = c; + if (util_1.isArray(mapping[channel])) { + mapping[channel].forEach(function (channelDef) { + f.call(thisArg, channelDef, channel); + }); + } + else { + f.call(thisArg, mapping[channel], channel); + } + }); +} +exports.forEach = forEach; +function reduce(mapping, f, init, thisArg) { + if (!mapping) { + return init; + } + return Object.keys(mapping).reduce(function (r, c) { + var channel = c; + if (util_1.isArray(mapping[channel])) { + return mapping[channel].reduce(function (r1, channelDef) { + return f.call(thisArg, r1, channelDef, channel); + }, r); + } + else { + return f.call(thisArg, r, mapping[channel], channel); + } + }, init); +} +exports.reduce = reduce; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZW5jb2RpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBK0I7QUFDL0IsdUNBQWlMO0FBQ2pMLHFDQUF5RDtBQUV6RCwrQkFBZ0Q7QUFFaEQsMkJBQTZCO0FBMkU3Qix5QkFBZ0MsUUFBMkIsRUFBRSxPQUFnQjtJQUMzRSxJQUFNLFVBQVUsR0FBRyxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pELEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDZixFQUFFLENBQUMsQ0FBQyxjQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxXQUFJLENBQUMsVUFBVSxFQUFFLFVBQUMsUUFBUSxJQUFLLE9BQUEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQWhCLENBQWdCLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFNLENBQUMscUJBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDO0FBVkQsMENBVUM7QUFFRCxxQkFBNEIsUUFBMkI7SUFDckQsTUFBTSxDQUFDLFdBQUksQ0FBQyxrQkFBUSxFQUFFLFVBQUMsT0FBTztRQUM1QixFQUFFLENBQUMsQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QyxJQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsRUFBRSxDQUFDLENBQUMsY0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsTUFBTSxDQUFDLFdBQUksQ0FBQyxVQUFVLEVBQUUsVUFBQyxRQUFRLElBQUssT0FBQSxDQUFDLENBQUMs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 \ No newline at end of file diff --git a/build/src/facet.d.ts b/build/src/facet.d.ts new file mode 100644 index 0000000000..2bcf2e8b49 --- /dev/null +++ b/build/src/facet.d.ts @@ -0,0 +1,11 @@ +import { FacetFieldDef } from './fielddef'; +export interface Facet { + /** + * Vertical facets for trellis plots. + */ + row?: FacetFieldDef; + /** + * Horizontal facets for trellis plots. + */ + column?: FacetFieldDef; +} diff --git a/build/src/facet.js b/build/src/facet.js new file mode 100644 index 0000000000..3e0258672f --- /dev/null +++ b/build/src/facet.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmFjZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9 \ No newline at end of file diff --git a/build/src/fielddef.d.ts b/build/src/fielddef.d.ts new file mode 100644 index 0000000000..9268fb8ccc --- /dev/null +++ b/build/src/fielddef.d.ts @@ -0,0 +1,125 @@ +import { AggregateOp } from './aggregate'; +import { Axis } from './axis'; +import { Bin } from './bin'; +import { Channel } from './channel'; +import { Config } from './config'; +import { Legend } from './legend'; +import { Scale } from './scale'; +import { StackOffset } from './stack'; +import { SortField, SortOrder } from './sort'; +import { TimeUnit } from './timeunit'; +import { Type } from './type'; +/** + * Definition object for a constant value of an encoding channel. + */ +export interface ValueDef { + /** + * A constant value in visual domain. + */ + value?: T; +} +export interface ConditionalValueDef extends ValueDef { + condition?: Condition; +} +/** + * Definition object for a data field, its type and transformation of an encoding channel. + */ +export interface FieldDef { + /** + * Name of the field from which to pull a data value. + */ + field?: string; + /** + * The encoded field's type of measurement. This can be either a full type + * name (`"quantitative"`, `"temporal"`, `"ordinal"`, and `"nominal"`) + * or an initial character of the type name (`"Q"`, `"T"`, `"O"`, `"N"`). + * This property is case insensitive. + */ + type?: Type; + /** + * Time unit for a `temporal` field (e.g., `year`, `yearmonth`, `month`, `hour`). + */ + timeUnit?: TimeUnit; + /** + * Flag for binning a `quantitative` field, or a bin property object + * for binning parameters. + */ + bin?: boolean | Bin; + /** + * Aggregation function for the field + * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`). + */ + aggregate?: AggregateOp; + /** + * Title for axis or legend. + */ + title?: string; +} +export interface Condition { + selection: string; + value: T; +} +export interface ScaleFieldDef extends FieldDef { + scale?: Scale; + sort?: SortField | SortOrder; +} +export interface PositionFieldDef extends ScaleFieldDef { + /** + * @nullable + */ + axis?: Axis; + /** + * Type of stacking offset if the field should be stacked. + * "none" or null, if the field should not be stacked. + */ + stack?: StackOffset; +} +export interface LegendFieldDef extends ScaleFieldDef { + /** + * @nullable + */ + legend?: Legend; + condition?: Condition; +} +export interface OrderFieldDef extends FieldDef { + sort?: SortOrder; +} +export interface TextFieldDef extends FieldDef { + /** + * The formatting pattern for text value. If not defined, this will be determined automatically. + */ + format?: string; + condition?: Condition; +} +export declare type ChannelDef = FieldDef | ValueDef; +export declare function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | LegendFieldDef | OrderFieldDef | TextFieldDef; +export declare function isValueDef(channelDef: ChannelDef): channelDef is ValueDef; +export declare type FacetFieldDef = PositionFieldDef; +export interface FieldRefOption { + /** exclude bin, aggregate, timeUnit */ + nofn?: boolean; + /** Wrap the field inside datum[...] per Vega convention */ + datum?: boolean; + /** prepend fn with custom function prefix */ + prefix?: string; + /** append suffix to the field ref for bin (default='start') */ + binSuffix?: 'start' | 'end' | 'range'; + /** append suffix to the field ref (general) */ + suffix?: string; + /** Overrride which aggregate to use. Needed for unaggregated domain. */ + aggregate?: AggregateOp; +} +export declare function field(fieldDef: FieldDef, opt?: FieldRefOption): string; +export declare function isDiscrete(fieldDef: FieldDef): boolean; +export declare function isContinuous(fieldDef: FieldDef): boolean; +export declare function isCount(fieldDef: FieldDef): boolean; +export declare function title(fieldDef: FieldDef, config: Config): string; +export declare function defaultType(fieldDef: FieldDef, channel: Channel): Type; +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +export declare function normalize(fieldDef: ChannelDef, channel: Channel): ChannelDef; +export declare function channelCompatibility(fieldDef: FieldDef, channel: Channel): { + compatible: boolean; + warning?: string; +}; diff --git a/build/src/fielddef.js b/build/src/fielddef.js new file mode 100644 index 0000000000..f99041d00f --- /dev/null +++ b/build/src/fielddef.js @@ -0,0 +1,190 @@ +// utility for a field definition object +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var log = require("./log"); +var timeunit_1 = require("./timeunit"); +var type_1 = require("./type"); +; +function isFieldDef(channelDef) { + return channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); +} +exports.isFieldDef = isFieldDef; +function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; +} +exports.isValueDef = isValueDef; +function field(fieldDef, opt) { + if (opt === void 0) { opt = {}; } + var field = fieldDef.field; + var prefix = opt.prefix; + var suffix = opt.suffix; + if (isCount(fieldDef)) { + field = 'count_*'; + } + else { + var fn = undefined; + if (!opt.nofn) { + if (fieldDef.bin) { + fn = 'bin'; + suffix = opt.binSuffix; + } + else if (fieldDef.aggregate) { + fn = String(opt.aggregate || fieldDef.aggregate); + } + else if (fieldDef.timeUnit) { + fn = String(fieldDef.timeUnit); + } + } + if (!!fn) { + field = fn + "_" + field; + } + } + if (!!suffix) { + field = field + "_" + suffix; + } + if (!!prefix) { + field = prefix + "_" + field; + } + if (opt.datum) { + field = "datum[\"" + field + "\"]"; + } + return field; +} +exports.field = field; +function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'temporal': + // TODO: deal with custom scale type case. + return timeunit_1.isDiscreteByDefault(fieldDef.timeUnit); + } + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +exports.isDiscrete = isDiscrete; +function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); +} +exports.isContinuous = isContinuous; +function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; +} +exports.isCount = isCount; +function title(fieldDef, config) { + if (fieldDef.title != null) { + return fieldDef.title; + } + if (isCount(fieldDef)) { + return config.countTitle; + } + var fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin'); + if (fn) { + return fn.toString().toUpperCase() + '(' + fieldDef.field + ')'; + } + else { + return fieldDef.field; + } +} +exports.title = title; +function defaultType(fieldDef, channel) { + if (!!fieldDef.timeUnit) { + return 'temporal'; + } + if (!!fieldDef.bin) { + return 'quantitative'; + } + switch (channel_1.rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible': + return 'nominal'; + default: + return 'quantitative'; + } +} +exports.defaultType = defaultType; +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +function normalize(fieldDef, channel) { + // If a fieldDef contains a field, we need type. + if (isFieldDef(fieldDef)) { + // convert short type to full type + var fullType = type_1.getFullName(fieldDef.type); + if (fullType) { + fieldDef.type = fullType; + } + else { + // If type is empty / invalid, then augment with default type + var newType = defaultType(fieldDef, channel); + log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType)); + fieldDef.type = newType; + } + var _a = channelCompatibility(fieldDef, channel), compatible = _a.compatible, warning = _a.warning; + if (!compatible) { + log.warn(warning); + } + } + return fieldDef; +} +exports.normalize = normalize; +var COMPATIBLE = { compatible: true }; +function channelCompatibility(fieldDef, channel) { + switch (channel) { + case 'row': + case 'column': + if (isContinuous(fieldDef) && !fieldDef.timeUnit) { + // TODO:(https://github.com/vega/vega-lite/issues/2011): + // with timeUnit it's not always strictly continuous + return { + compatible: false, + warning: log.message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'text': + case 'detail': + return COMPATIBLE; + case 'opacity': + case 'size': + case 'x2': + case 'y2': + if (isDiscrete(fieldDef) && !fieldDef.bin) { + return { + compatible: false, + warning: "Channel " + channel + " should not be used with discrete field." + }; + } + return COMPATIBLE; + case 'shape': + if (fieldDef.type !== 'nominal') { + return { + compatible: false, + warning: 'Shape channel should be used with nominal data only' + }; + } + else { + return COMPATIBLE; + } + case 'order': + if (fieldDef.type === 'nominal') { + return { + compatible: false, + warning: "Channel order is inappropriate for nominal field, which has no inherent order." + }; + } + return COMPATIBLE; + } + throw new Error('channelCompatability not implemented for channel ' + channel); +} +exports.channelCompatibility = channelCompatibility; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRkZWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmllbGRkZWYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0NBQXdDOzs7QUFLeEMscUNBQTZDO0FBRzdDLDJCQUE2QjtBQUk3Qix1Q0FBeUQ7QUFDekQsK0JBQXlDO0FBMEd4QyxDQUFDO0FBSUYsb0JBQTJCLFVBQXNCO0lBQy9DLE1BQU0sQ0FBQyxVQUFVLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLFVBQVUsQ0FBQyxXQUFXLENBQUMsS0FBSyxPQUFPLENBQUMsQ0FBQztBQUN0RixDQUFDO0FBRkQsZ0NBRUM7QUFFRCxvQkFBMkIsVUFBc0I7SUFDL0MsTUFBTSxDQUFDLFVBQVUsSUFBSSxPQUFPLElBQUksVUFBVSxJQUFJLFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDbEYsQ0FBQztBQUZELGdDQUVDO0FBb0JELGVBQXNCLFFBQWtCLEVBQUUsR0FBd0I7SUFBeEIsb0JBQUEsRUFBQSxRQUF3QjtJQUNoRSxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO0lBQzNCLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7SUFDeEIsSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUV4QixFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLEtBQUssR0FBRyxTQUFTLENBQUM7SUFDcEIsQ0FBQztJQUFDLElBQUksQ0FBQyxDQUFDO1FBQ04sSUFBSSxFQUFFLEdBQVcsU0FBUyxDQUFDO1FBRTNCLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDZCxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDakIsRUFBRSxHQUFHLEtBQUss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 \ No newline at end of file diff --git a/build/src/filter.d.ts b/build/src/filter.d.ts new file mode 100644 index 0000000000..dda3ae44ea --- /dev/null +++ b/build/src/filter.d.ts @@ -0,0 +1,53 @@ +import { DateTime } from './datetime'; +import { TimeUnit } from './timeunit'; +export declare type Filter = EqualFilter | RangeFilter | OneOfFilter; +export interface EqualFilter { + /** + * Time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered. + */ + field: string; + /** + * Value that the field should be equal to. + */ + equal: string | number | boolean | DateTime; +} +export declare function isEqualFilter(filter: any): filter is EqualFilter; +export interface RangeFilter { + /** + * time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered + */ + field: string; + /** + * Array of inclusive minimum and maximum values + * for a field value of a data item to be included in the filtered data. + * @maxItems 2 + * @minItems 2 + */ + range: (number | DateTime)[]; +} +export declare function isRangeFilter(filter: any): filter is RangeFilter; +export interface OneOfFilter { + /** + * time unit for the field to be filtered. + */ + timeUnit?: TimeUnit; + /** + * Field to be filtered + */ + field: string; + /** + * A set of values that the `field`'s value should be a member of, + * for a data item included in the filtered data. + */ + oneOf: (string | number | boolean | DateTime)[]; +} +export declare function isOneOfFilter(filter: any): filter is OneOfFilter; +export declare function expression(filter: Filter | string): string; diff --git a/build/src/filter.js b/build/src/filter.js new file mode 100644 index 0000000000..047ce34d59 --- /dev/null +++ b/build/src/filter.js @@ -0,0 +1,79 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("./datetime"); +var fielddef_1 = require("./fielddef"); +var timeunit_1 = require("./timeunit"); +var util_1 = require("./util"); +function isEqualFilter(filter) { + return filter && !!filter.field && filter.equal !== undefined; +} +exports.isEqualFilter = isEqualFilter; +function isRangeFilter(filter) { + if (filter && !!filter.field) { + if (util_1.isArray(filter.range) && filter.range.length === 2) { + return true; + } + } + return false; +} +exports.isRangeFilter = isRangeFilter; +function isOneOfFilter(filter) { + return filter && !!filter.field && (util_1.isArray(filter.oneOf) || + util_1.isArray(filter.in) // backward compatibility + ); +} +exports.isOneOfFilter = isOneOfFilter; +function expression(filter) { + if (util_1.isString(filter)) { + return filter; + } + else { + var fieldExpr = filter.timeUnit ? + // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly. + // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline + // TODO: support utc + ('time(' + timeunit_1.fieldExpr(filter.timeUnit, filter.field) + ')') : + fielddef_1.field(filter, { datum: true }); + if (isEqualFilter(filter)) { + return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit); + } + else if (isOneOfFilter(filter)) { + // "oneOf" was formerly "in" -- so we need to add backward compatibility + var oneOf = filter.oneOf || filter['in']; + return 'indexof([' + + oneOf.map(function (v) { return valueExpr(v, filter.timeUnit); }).join(',') + + '], ' + fieldExpr + ') !== -1'; + } + else if (isRangeFilter(filter)) { + var lower = filter.range[0]; + var upper = filter.range[1]; + if (lower !== null && upper !== null) { + return 'inrange(' + fieldExpr + ', ' + + valueExpr(lower, filter.timeUnit) + ', ' + + valueExpr(upper, filter.timeUnit) + ')'; + } + else if (lower !== null) { + return fieldExpr + ' >= ' + lower; + } + else if (upper !== null) { + return fieldExpr + ' <= ' + upper; + } + } + } + return undefined; +} +exports.expression = expression; +function valueExpr(v, timeUnit) { + if (datetime_1.isDateTime(v)) { + var expr = datetime_1.dateTimeExpr(v, true); + return 'time(' + expr + ')'; + } + if (timeunit_1.isSingleTimeUnit(timeUnit)) { + var datetime = {}; + datetime[timeUnit] = v; + var expr = datetime_1.dateTimeExpr(datetime, true); + return 'time(' + expr + ')'; + } + return JSON.stringify(v); +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ZpbHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHVDQUE4RDtBQUM5RCx1Q0FBaUM7QUFDakMsdUNBQXNGO0FBQ3RGLCtCQUF5QztBQXlCekMsdUJBQThCLE1BQVc7SUFDdkMsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsS0FBSyxLQUFHLFNBQVMsQ0FBQztBQUM5RCxDQUFDO0FBRkQsc0NBRUM7QUF5QkQsdUJBQThCLE1BQVc7SUFDdkMsRUFBRSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM3QixFQUFFLENBQUMsQ0FBQyxjQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkQsTUFBTSxDQUFDLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFQRCxzQ0FPQztBQXVCRCx1QkFBOEIsTUFBVztJQUN2QyxNQUFNLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLENBQ2pDLGNBQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ3JCLGNBQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMseUJBQXlCO0tBQzdDLENBQUM7QUFDSixDQUFDO0FBTEQsc0NBS0M7QUFFRCxvQkFBMkIsTUFBdUI7SUFDaEQsRUFBRSxDQUFDLENBQUMsZUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsTUFBZ0IsQ0FBQztJQUMxQixDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDTixJ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 \ No newline at end of file diff --git a/build/src/legend.d.ts b/build/src/legend.d.ts new file mode 100644 index 0000000000..35ab6fce3e --- /dev/null +++ b/build/src/legend.d.ts @@ -0,0 +1,51 @@ +import { DateTime } from './datetime'; +import { VgLegendEncode, VgLegendBase, VgLegendConfig } from './vega.schema'; +export interface LegendConfig extends VgLegendConfig { + /** + * Whether month names and weekday names should be abbreviated. + */ + shortTimeLabels?: boolean; +} +/** + * Properties of a legend or boolean flag for determining whether to show it. + */ +export interface Legend extends VgLegendBase { + /** + * Optional mark definitions for custom legend encoding. + */ + encode?: VgLegendEncode; + /** + * An optional formatting pattern for legend labels. Vega uses D3\'s format pattern. + */ + format?: string; + /** + * The desired number of tick values for quantitative legends. + */ + tickCount?: number; + /** + * A title for the legend. (Shows field name and its function by default.) + */ + title?: string; + /** + * Explicitly set the visible legend values. + */ + values?: number[] | string[] | DateTime[]; + /** + * The name of a scale that maps to a shape value. + */ + shape?: string; + /** + * The type of the legend. Use `symbol` to create a discrete legend and `gradient` for a continuous color gradient. + */ + type?: 'symbol' | 'gradient'; + /** + * A non-positive integer indicating z-index of the legend. + * If zindex is 0, legend should be drawn behind all chart elements. + * To put them in front, use zindex = 1. + * @TJS-type integer + * @minimum 0 + */ + zindex?: number; +} +export declare const defaultLegendConfig: LegendConfig; +export declare const LEGEND_PROPERTIES: (keyof Legend)[]; diff --git a/build/src/legend.js b/build/src/legend.js new file mode 100644 index 0000000000..7f60b681b3 --- /dev/null +++ b/build/src/legend.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultLegendConfig = { + orient: undefined, +}; +exports.LEGEND_PROPERTIES = ['entryPadding', 'format', 'offset', 'orient', 'tickCount', 'title', 'type', 'values', 'zindex']; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGVnZW5kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xlZ2VuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTBEYSxRQUFBLG1CQUFtQixHQUFpQjtJQUMvQyxNQUFNLEVBQUUsU0FBUztDQUNsQixDQUFDO0FBRVcsUUFBQSxpQkFBaUIsR0FBb0IsQ0FBQyxjQUFjLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/src/log.d.ts b/build/src/log.d.ts new file mode 100644 index 0000000000..475502e91b --- /dev/null +++ b/build/src/log.d.ts @@ -0,0 +1,78 @@ +/// +/** + * Vega-Lite's singleton logger utility. + */ +import { LoggerInterface } from 'vega-util'; +import { AggregateOp } from './aggregate'; +import { Channel } from './channel'; +import { DateTime, DateTimeExpr } from './datetime'; +import { FieldDef } from './fielddef'; +import { Mark } from './mark'; +import { TimeUnit } from './timeunit'; +import { Type } from './type'; +import { ScaleType } from './scale'; +export { LoggerInterface } from 'vega-util'; +/** + * Logger tool for checking if the code throws correct warning + */ +export declare class LocalLogger implements LoggerInterface { + warns: any[]; + infos: any[]; + debugs: any[]; + level(): this; + warn(...args: any[]): this; + info(...args: any[]): this; + debug(...args: any[]): this; +} +export declare function runLocalLogger(f: (localLogger: LocalLogger) => void): void; +export declare function wrap(f: (logger: LocalLogger) => void): () => void; +/** + * Set the singleton logger to be a custom logger + */ +export declare function set(logger: LoggerInterface): LoggerInterface; +/** + * Reset the main logger to use the default Vega Logger + */ +export declare function reset(): LoggerInterface; +export declare function warn(..._: any[]): void; +export declare function info(..._: any[]): void; +export declare function debug(..._: any[]): void; +/** + * Collection of all Vega-Lite Error Messages + */ +export declare namespace message { + const INVALID_SPEC = "Invalid spec"; + const DEPRECATED_FILTER_NULL = "filterNull is deprecated. Please use filterInvalid instead."; + function invalidFieldType(type: Type): string; + function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type): string; + function emptyFieldDef(fieldDef: FieldDef, channel: Channel): string; + function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet', when?: string): string; + function facetChannelShouldBeDiscrete(channel: string): string; + function discreteChannelCannotEncode(channel: Channel, type: Type): string; + const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = "Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead."; + function unclearOrientContinuous(mark: Mark): string; + function unclearOrientDiscreteOrEmpty(mark: Mark): string; + function orientOverridden(original: string, actual: string): string; + const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = "custom domain scale cannot be unioned with default field-based domain"; + function cannotUseScalePropertyWithNonColor(prop: string): string; + function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef): string; + function unaggregateDomainWithNonSharedDomainOp(aggregate: AggregateOp): string; + function unaggregatedDomainWithLogScale(fieldDef: FieldDef): string; + const CANNOT_USE_RANGE_WITH_POSITION = "Cannot use custom range with x or y channel. Please customize width, height, padding, or rangeStep instead."; + const CANNOT_USE_PADDING_WITH_FACET = "Cannot use padding with facet's scale. Please use spacing instead."; + function cannotUseRangePropertyWithFacet(propName: string): string; + function rangeStepDropped(channel: Channel): string; + function cannotOverrideBinScaleType(channel: Channel, defaultScaleType: ScaleType): string; + function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType): string; + function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel): string; + function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType): string; + const INVAID_DOMAIN = "Invalid scale domain"; + const UNABLE_TO_MERGE_DOMAINS = "Unable to merge domains"; + const INVALID_CHANNEL_FOR_AXIS = "Invalid channel for axis."; + function cannotStackRangedMark(channel: Channel): string; + function cannotStackNonLinearScale(scaleType: ScaleType): string; + function cannotStackNonSummativeAggregate(aggregate: AggregateOp): string; + function invalidTimeUnit(unitName: string, value: string | number): string; + function dayReplacedWithDate(fullTimeUnit: TimeUnit): string; + function droppedDay(d: DateTime | DateTimeExpr): string; +} diff --git a/build/src/log.js b/build/src/log.js new file mode 100644 index 0000000000..4eacc08bf6 --- /dev/null +++ b/build/src/log.js @@ -0,0 +1,234 @@ +/// +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Vega-Lite's singleton logger utility. + */ +var vega_util_1 = require("vega-util"); +/** + * Main (default) Vega Logger instance for Vega-Lite + */ +var main = vega_util_1.logger(vega_util_1.Warn); +var current = main; +/** + * Logger tool for checking if the code throws correct warning + */ +var LocalLogger = (function () { + function LocalLogger() { + this.warns = []; + this.infos = []; + this.debugs = []; + } + LocalLogger.prototype.level = function () { + return this; + }; + LocalLogger.prototype.warn = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.warns).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.infos).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.debug = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.debugs).push.apply(_a, args); + return this; + var _a; + }; + return LocalLogger; +}()); +exports.LocalLogger = LocalLogger; +function runLocalLogger(f) { + var localLogger = current = new LocalLogger(); + f(localLogger); + reset(); +} +exports.runLocalLogger = runLocalLogger; +function wrap(f) { + return function () { + var logger = current = new LocalLogger(); + f(logger); + reset(); + }; +} +exports.wrap = wrap; +/** + * Set the singleton logger to be a custom logger + */ +function set(logger) { + current = logger; + return current; +} +exports.set = set; +/** + * Reset the main logger to use the default Vega Logger + */ +function reset() { + current = main; + return current; +} +exports.reset = reset; +function warn() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.warn.apply(current, arguments); +} +exports.warn = warn; +function info() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.info.apply(current, arguments); +} +exports.info = info; +function debug() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.debug.apply(current, arguments); +} +exports.debug = debug; +/** + * Collection of all Vega-Lite Error Messages + */ +var message; +(function (message) { + message.INVALID_SPEC = 'Invalid spec'; + // DATA + message.DEPRECATED_FILTER_NULL = 'filterNull is deprecated. Please use filterInvalid instead.'; + // ENCODING & FACET + function invalidFieldType(type) { + return "Invalid field type \"" + type + "\""; + } + message.invalidFieldType = invalidFieldType; + function emptyOrInvalidFieldType(type, channel, newType) { + return "Invalid field type (" + type + ") for channel " + channel + ", using " + newType + " instead."; + } + message.emptyOrInvalidFieldType = emptyOrInvalidFieldType; + function emptyFieldDef(fieldDef, channel) { + return "Dropping " + JSON.stringify(fieldDef) + " from channel " + channel + " since it does not contain data field or value."; + } + message.emptyFieldDef = emptyFieldDef; + function incompatibleChannel(channel, markOrFacet, when) { + return channel + " dropped as it is incompatible with " + markOrFacet + + when ? "when " + when : ''; + } + message.incompatibleChannel = incompatibleChannel; + function facetChannelShouldBeDiscrete(channel) { + return channel + " encoding should be discrete (ordinal / nominal / binned)."; + } + message.facetChannelShouldBeDiscrete = facetChannelShouldBeDiscrete; + function discreteChannelCannotEncode(channel, type) { + return "Using discrete channel " + channel + " to encode " + type + " field can be misleading as it does not encode " + (type === 'ordinal' ? 'order' : 'magnitude') + "."; + } + message.discreteChannelCannotEncode = discreteChannelCannotEncode; + // Mark + message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.'; + function unclearOrientContinuous(mark) { + return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode continous fields. In this case, we use vertical by default'; + } + message.unclearOrientContinuous = unclearOrientContinuous; + function unclearOrientDiscreteOrEmpty(mark) { + return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode discrete or empty fields.'; + } + message.unclearOrientDiscreteOrEmpty = unclearOrientDiscreteOrEmpty; + function orientOverridden(original, actual) { + return "Specified orient " + original + " overridden with " + actual; + } + message.orientOverridden = orientOverridden; + // SCALE + message.CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain'; + function cannotUseScalePropertyWithNonColor(prop) { + return "Cannot use " + prop + " with non-color channel."; + } + message.cannotUseScalePropertyWithNonColor = cannotUseScalePropertyWithNonColor; + function unaggregateDomainHasNoEffectForRawField(fieldDef) { + return "Using unaggregated domain with raw field has no effect (" + JSON.stringify(fieldDef) + ")."; + } + message.unaggregateDomainHasNoEffectForRawField = unaggregateDomainHasNoEffectForRawField; + function unaggregateDomainWithNonSharedDomainOp(aggregate) { + return "Unaggregated domain not applicable for " + aggregate + " since it produces values outside the origin domain of the source data."; + } + message.unaggregateDomainWithNonSharedDomainOp = unaggregateDomainWithNonSharedDomainOp; + function unaggregatedDomainWithLogScale(fieldDef) { + return "Unaggregated domain is currently unsupported for log scale (" + JSON.stringify(fieldDef) + ")."; + } + message.unaggregatedDomainWithLogScale = unaggregatedDomainWithLogScale; + message.CANNOT_USE_RANGE_WITH_POSITION = 'Cannot use custom range with x or y channel. Please customize width, height, padding, or rangeStep instead.'; + message.CANNOT_USE_PADDING_WITH_FACET = 'Cannot use padding with facet\'s scale. Please use spacing instead.'; + function cannotUseRangePropertyWithFacet(propName) { + return "Cannot use custom " + propName + " with row or column channel. Please use width, height, or spacing instead."; + } + message.cannotUseRangePropertyWithFacet = cannotUseRangePropertyWithFacet; + function rangeStepDropped(channel) { + return "rangeStep for " + channel + " is dropped as top-level " + (channel === 'x' ? 'width' : 'height') + " is provided."; + } + message.rangeStepDropped = rangeStepDropped; + function cannotOverrideBinScaleType(channel, defaultScaleType) { + return "Cannot override scale type for binned channel " + channel + ". We are using " + defaultScaleType + " scale instead."; + } + message.cannotOverrideBinScaleType = cannotOverrideBinScaleType; + function scaleTypeNotWorkWithChannel(channel, scaleType, defaultScaleType) { + return "Channel " + channel + " does not work with " + scaleType + " scale. We are using " + defaultScaleType + " scale instead."; + } + message.scaleTypeNotWorkWithChannel = scaleTypeNotWorkWithChannel; + function scalePropertyNotWorkWithScaleType(scaleType, propName, channel) { + return channel + "-scale's \"" + propName + "\" is dropped as it does not work with " + scaleType + " scale."; + } + message.scalePropertyNotWorkWithScaleType = scalePropertyNotWorkWithScaleType; + function scaleTypeNotWorkWithMark(mark, scaleType) { + return "Scale type \"" + scaleType + "\" does not work with mark " + mark + "."; + } + message.scaleTypeNotWorkWithMark = scaleTypeNotWorkWithMark; + message.INVAID_DOMAIN = 'Invalid scale domain'; + message.UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains'; + // AXIS + message.INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.'; + // STACK + function cannotStackRangedMark(channel) { + return "Cannot stack " + channel + " if there is already " + channel + "2"; + } + message.cannotStackRangedMark = cannotStackRangedMark; + function cannotStackNonLinearScale(scaleType) { + return "Cannot stack non-linear scale (" + scaleType + ")"; + } + message.cannotStackNonLinearScale = cannotStackNonLinearScale; + function cannotStackNonSummativeAggregate(aggregate) { + return "Cannot stack when the aggregate function is non-summative (" + aggregate + ")"; + } + message.cannotStackNonSummativeAggregate = cannotStackNonSummativeAggregate; + // TIMEUNIT + function invalidTimeUnit(unitName, value) { + return "Invalid " + unitName + ": " + value; + } + message.invalidTimeUnit = invalidTimeUnit; + function dayReplacedWithDate(fullTimeUnit) { + return "Time unit \"" + fullTimeUnit + "\" is not supported. We are replacing it with " + + (fullTimeUnit + '').replace('day', 'date') + '.'; + } + message.dayReplacedWithDate = dayReplacedWithDate; + function droppedDay(d) { + return 'Dropping day from datetime ' + JSON.stringify(d) + + ' as day cannot be combined with other units.'; + } + message.droppedDay = droppedDay; +})(message = exports.message || (exports.message = {})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxpREFBaUQ7OztBQUVqRDs7R0FFRztBQUVILHVDQUF3RDtBQWF4RDs7R0FFRztBQUNILElBQU0sSUFBSSxHQUFHLGtCQUFNLENBQUMsZ0JBQUksQ0FBQyxDQUFDO0FBQzFCLElBQUksT0FBTyxHQUFvQixJQUFJLENBQUM7QUFFcEM7O0dBRUc7QUFDSDtJQUFBO1FBQ1MsVUFBSyxHQUFVLEVBQUUsQ0FBQztRQUNsQixVQUFLLEdBQVUsRUFBRSxDQUFDO1FBQ2xCLFdBQU0sR0FBVSxFQUFFLENBQUM7SUFvQjVCLENBQUM7SUFsQlEsMkJBQUssR0FBWjtRQUNFLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sMEJBQUksR0FBWDtRQUFZLGNBQWM7YUFBZCxVQUFjLEVBQWQscUJBQWMsRUFBZCxJQUFjO1lBQWQseUJBQWM7O1FBQ3hCLENBQUEsS0FBQSxJQUFJLENBQUMsS0FBSyxDQUFBLENBQUMsSUFBSSxXQUFJLElBQUksRUFBRTtRQUN6QixNQUFNLENBQUMsSUFBSSxDQUFDOztJQUNkLENBQUM7SUFFTSwwQkFBSSxHQUFYO1FBQVksY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDeEIsQ0FBQSxLQUFBLElBQUksQ0FBQyxLQUFLLENBQUEsQ0FBQyxJQUFJLFdBQUksSUFBSSxFQUFFO1FBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUM7O0lBQ2QsQ0FBQztJQUVNLDJCQUFLLEdBQVo7UUFBYSxjQUFjO2FBQWQsVUFBYyxFQUFkLHFCQUFjLEVBQWQsSUFBYztZQUFkLHlCQUFjOztRQUN6QixDQUFBLEtBQUEsSUFBSSxDQUFDLE1BQU0sQ0FBQSxDQUFDLElBQUksV0FBSSxJQUFJLEVBQUU7UUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQzs7SUFDZCxDQUFDO0lBQ0gsa0JBQUM7QUFBRCxDQUFDLEFBdkJELElBdUJDO0FBdkJZLGtDQUFXO0FBeUJ4Qix3QkFBK0IsQ0FBcUM7SUFDbEUsSUFBTSxXQUFXLEdBQUcsT0FBTyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7SUFDaEQsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2YsS0FBSyxFQUFFLENBQUM7QUFDVixDQUFDO0FBSkQsd0NBSUM7QUFFRCxjQUFxQixDQUFnQztJQUNuRCxNQUFNLENBQUM7UUFDTCxJQUFNLE1BQU0sR0FBRyxPQUFPLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUMzQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDVixLQUFLLEVBQUUsQ0FBQztJQUNWLENBQUMsQ0FBQztBQUNKLENBQUM7QUFORCxvQkFNQztBQUVEOztHQUVHO0FBQ0gsYUFBb0IsTUFBdUI7SUFDekMsT0FBTyxHQUFHLE1BQU0sQ0FBQztJQUNqQixNQUFNLENBQUMsT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFIRCxrQkFHQztBQUVEOztHQUVHO0FBQ0g7SUFDRSxPQUFPLEdBQUcsSUFBSSxDQUFDO0lBQ2YsTUFBTSxDQUFDLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBSEQsc0JBR0M7QUFFRDtJQUFxQixXQUFXO1NBQVgsVUFBVyxFQUFYLHFCQUFXLEVBQVgsSUFBVztRQUFYLHNCQUFXOztJQUM5QixPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUZELG9CQUVDO0FBRUQ7SUFBcUIsV0FBVztTQUFYLFVBQVcsRUFBWCxxQkFBVyxFQUFYLElBQVc7UUFBWCxzQkFBVzs7SUFDOUIsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFGRCxvQkFFQztBQUVEO0lBQXNCLFdBQVc7U0FBWCxVQUFXLEVBQVgscUJBQVcsRUFBWCxJQUFXO1FBQVgsc0JBQVc7O0lBQy9CLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBRkQsc0JBRUM7QUFFRDs7R0FFRztBQUNILElBQWlCLE9BQU8sQ0FrSXZCO0FBbElELFdBQWlCLE9BQU87SUFDVCxvQkFBWSxHQUFHLGNBQWMsQ0FBQztJQUUzQyxPQUFPO0lBQ00sOEJBQXNCLEdBQUcsNkRBQTZELENBQUM7SUFFcEcsbUJBQW1CO0lBQ25CLDBCQUFpQyxJQUFVO1FBQ3pDLE1BQU0sQ0FBQywwQkFBdUIsSUFBSSxPQUFHLENBQUM7SUFDeEMsQ0FBQztJQUZlLHdCQUFnQixtQkFFL0IsQ0FBQTtJQUVELGlDQUF3QyxJQUFtQixFQUFFLE9BQWdCLEVBQUUsT0FBYTtRQUMxRixNQUFNLENBQUMseUJBQXVCLElBQUksc0JBQWlCLE9BQU8sZ0JBQVcsT0FBTyxjQUFXLENBQUM7SUFDMUYsQ0FBQztJQUZlLCtCQUF1QiwwQkFFdEMsQ0FBQTtJQUVELHVCQUE4QixRQUFrQixFQUFFLE9BQWdCO1FBQ2hFLE1BQU0sQ0FBQyxjQUFZLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLHNCQUFpQixPQUFPLG9EQUFpRCxDQUFDO0lBQ3ZILENBQUM7SUFGZSxxQkFBYSxnQkFFNUIsQ0FBQTtJQUVELDZCQUFvQyxPQUFnQixFQUFFLFdBQTJCLEVBQUUsSUFBYTtRQUM5RixNQUFNLENBQUksT0FBTyw0Q0FBdUMsV0FBYTtZQUNuRSxJQUFJLEdBQUcsVUFBUSxJQUFNLEdBQUcsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFIZSwyQkFBbUIsc0JBR2xDLENBQUE7SUFFRCxzQ0FBNkMsT0FBZTtRQUMxRCxNQUFNLENBQUksT0FBTywrREFBNEQsQ0FBQztJQUNoRixDQUFDO0lBRmUsb0NBQTRCLCtCQUUzQyxDQUFBO0lBRUQscUNBQTRDLE9BQWdCLEVBQUUsSUFBVTtRQUN0RSxNQUFNLENBQUMsNEJBQTBCLE9BQU8sbUJBQWMsSUFBSSx3REFBa0QsSUFBSSxLQUFLLFNBQVMsR0FBRyxPQUFPLEdBQUcsV0FBVyxPQUFHLENBQUM7SUFDNUosQ0FBQztJQUZlLG1DQUEyQiw4QkFFMUMsQ0FBQTtJQUVELE9BQU87SUFDTSwrQ0FBdUMsR0FBRyxxR0FBcUcsQ0FBQztJQUU3SixpQ0FBd0MsSUFBVTtRQUNoRCxNQUFNLENBQUMsMkNBQTJDLEdBQUcsSUFBSSxHQUFHLCtGQUErRixDQUFDO0lBQzlKLENBQUM7SUFGZSwrQkFBdUIsMEJBRXRDLENBQUE7SUFFRCxzQ0FBNkMsSUFBVTtRQUNyRCxNQUFNLENBQUMsMkNBQTJDLEdBQUcsSUFBSSxHQUFHLDhEQUE4RCxDQUFDO0lBQzdILENBQUM7SUFGZSxvQ0FBNEIsK0JBRTNDLENBQUE7SUFFRCwwQkFBaUMsUUFBZ0IsRUFBRSxNQUFjO1FBQy9ELE1BQU0sQ0FBQyxzQkFBb0IsUUFBUSx5QkFBb0IsTUFBUSxDQUFDO0lBQ2xFLENBQUM7SUFGZSx3QkFBZ0IsbUJBRS9CLENBQUE7SUFFRCxRQUFRO0lBQ0ssb0RBQTRDLEdBQUcsdUVBQXVFLENBQUM7SUFFcEksNENBQW1ELElBQVk7UUFDN0QsTUFBTSxDQUFDLGdCQUFjLElBQUksNkJBQTBCLENBQUM7SUFDdEQsQ0FBQztJQUZlLDBDQUFrQyxxQ0FFakQsQ0FBQTtJQUVELGlEQUF3RCxRQUFrQjtRQUN4RSxNQUFNLENBQUMsNkRBQTJELElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE9BQUksQ0FBQztJQUNqRyxDQUFDO0lBRmUsK0NBQXVDLDBDQUV0RCxDQUFBO0lBRUQsZ0RBQXVELFNBQXNCO1FBQzNFLE1BQU0sQ0FBQyw0Q0FBMEMsU0FBUyw0RUFBeUUsQ0FBQztJQUN0SSxDQUFDO0lBRmUsOENBQXNDLHlDQUVyRCxDQUFBO0lBRUQsd0NBQStDLFFBQWtCO1FBQy9ELE1BQU0sQ0FBQyxpRUFBK0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBSSxDQUFDO0lBQ3JHLENBQUM7SUFGZSxzQ0FBOEIsaUNBRTdDLENBQUE7SUFFWSxzQ0FBOEIsR0FDekMsOEdBQThHLENBQUM7SUFFbEcscUNBQTZCLEdBQUcsc0VBQXNFLENBQUM7SUFFdEgseUNBQWdELFFBQWdCO1FBQzlELE1BQU0sQ0FBQyx1QkFBcUIsUUFBUSwrRUFBNEUsQ0FBQztJQUNuSCxDQUFDO0lBRmUsdUNBQStCLGtDQUU5QyxDQUFBO0lBRUQsMEJBQWlDLE9BQWdCO1FBQy9DLE1BQU0sQ0FBQyxtQkFBaUIsT0FBTyxrQ0FDN0IsT0FBTyxLQUFLLEdBQUcsR0FBRyxPQUFPLEdBQUcsUUFBUSxtQkFBZSxDQUFDO0lBQ3hELENBQUM7SUFIZSx3QkFBZ0IsbUJBRy9CLENBQUE7SUFFRCxvQ0FBMkMsT0FBZ0IsRUFBRSxnQkFBMkI7UUFDdEYsTUFBTSxDQUFDLG1EQUFpRCxPQUFPLHVCQUFrQixnQkFBZ0Isb0JBQWlCLENBQUM7SUFDckgsQ0FBQztJQUZlLGtDQUEwQiw2QkFFekMsQ0FBQTtJQUVELHFDQUE0QyxPQUFnQixFQUFFLFNBQW9CLEVBQUUsZ0JBQTJCO1FBQzdHLE1BQU0sQ0FBQyxhQUFXLE9BQU8sNEJBQXVCLFNBQVMsNkJBQXdCLGdCQUFnQixvQkFBaUIsQ0FBQztJQUNySCxDQUFDO0lBRmUsbUNBQTJCLDhCQUUxQyxDQUFBO0lBRUQsMkNBQWtELFNBQW9CLEVBQUUsUUFBZ0IsRUFBRSxPQUFnQjtRQUN4RyxNQUFNLENBQUksT0FBTyxtQkFBYSxRQUFRLCtDQUF5QyxTQUFTLFlBQVMsQ0FBQztJQUNwRyxDQUFDO0lBRmUseUNBQWlDLG9DQUVoRCxDQUFBO0lBRUQsa0NBQXlDLElBQVUsRUFBRSxTQUFvQjtRQUN2RSxNQUFNLENBQUMsa0JBQWUsU0FBUyxtQ0FBNkIsSUFBSSxNQUFHLENBQUM7SUFDdEUsQ0FBQztJQUZlLGdDQUF3QiwyQkFFdkMsQ0FBQTtJQUVZLHFCQUFhLEdBQUcsc0JBQXNCLENBQUM7SUFFdkMsK0JBQXVCLEdBQUcseUJBQXlCLENBQUM7SUFFakUsT0FBTztJQUNNLGdDQUF3QixHQUFHLDJCQUEyQixDQUFDO0lBRXBFLFFBQVE7SUFDUiwrQkFBc0MsT0FBZ0I7UUFDcEQsTUFBTSxDQUFDLGtCQUFnQixPQUFPLDZCQUF3QixPQUFPLE1BQUcsQ0FBQztJQUNuRSxDQUFDO0lBRmUsNkJBQXFCLHdCQUVwQyxDQUFBO0lBRUQsbUNBQTBDLFNBQW9CO1FBQzVELE1BQU0sQ0FBQyxvQ0FBa0MsU0FBUyxNQUFHLENBQUM7SUFDeEQsQ0FBQztJQUZlLGlDQUF5Qiw0QkFFeEMsQ0FBQTtJQUVELDBDQUFpRCxTQUFzQjtRQUNyRSxNQUFNLENBQUMsZ0VBQThELFNBQVMsTUFBRyxDQUFDO0lBQ3BGLENBQUM7SUFGZSx3Q0FBZ0MsbUNBRS9DLENBQUE7SUFFRCxXQUFXO0lBQ1gseUJBQWdDLFFBQWdCLEVBQUUsS0FBc0I7UUFDdEUsTUFBTSxDQUFDLGFBQVcsUUFBUSxVQUFLLEtBQU8sQ0FBQztJQUN6QyxDQUFDO0lBRmUsdUJBQWUsa0JBRTlCLENBQUE7SUFFRCw2QkFBb0MsWUFBc0I7UUFDeEQsTUFBTSxDQUFDLGlCQUFjLFlBQVksbURBQStDO1lBQzlFLENBQUMsWUFBWSxHQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQ25ELENBQUM7SUFIZSwyQkFBbUIsc0JBR2xDLENBQUE7SUFFRCxvQkFBMkIsQ0FBMEI7UUFDbkQsTUFBTSxDQUFDLDZCQUE2QixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ2xELDhDQUE4QyxDQUFDO0lBQ3ZELENBQUM7SUFIZSxrQkFBVSxhQUd6QixDQUFBO0FBQ0gsQ0FBQyxFQWxJZ0IsT0FBTyxHQUFQLGVBQU8sS0FBUCxlQUFPLFFBa0l2QiJ9 \ No newline at end of file diff --git a/build/src/mark.d.ts b/build/src/mark.d.ts new file mode 100644 index 0000000000..96ee29a948 --- /dev/null +++ b/build/src/mark.d.ts @@ -0,0 +1,130 @@ +import { Orient, Interpolate, VgMarkConfig } from './vega.schema'; +export { Orient } from './vega.schema'; +export declare namespace Mark { + const AREA: 'area'; + const BAR: 'bar'; + const LINE: 'line'; + const POINT: 'point'; + const RECT: 'rect'; + const RULE: 'rule'; + const TEXT: 'text'; + const TICK: 'tick'; + const CIRCLE: 'circle'; + const SQUARE: 'square'; +} +/** + * All types of primitive marks. + */ +export declare type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE; +export declare const AREA: "area"; +export declare const BAR: "bar"; +export declare const LINE: "line"; +export declare const POINT: "point"; +export declare const TEXT: "text"; +export declare const TICK: "tick"; +export declare const RECT: "rect"; +export declare const RULE: "rule"; +export declare const CIRCLE: "circle"; +export declare const SQUARE: "square"; +export declare const PRIMITIVE_MARKS: ("area" | "circle" | "line" | "rect" | "text" | "bar" | "point" | "rule" | "tick" | "square")[]; +export interface MarkDef { + /** + * The mark type. + * One of `"bar"`, `"circle"`, `"square"`, `"tick"`, `"line"`, + * `"area"`, `"point"`, `"rule"`, and `"text"`. + */ + type: Mark; + /** + * The orientation of a non-stacked bar, tick, area, and line charts. + * The value is either horizontal (default) or vertical. + * - For bar, rule and tick, this determines whether the size of the bar and tick + * should be applied to x or y dimension. + * - For area, this property determines the orient property of the Vega output. + * - For line, this property determines the sort order of the points in the line + * if `config.sortLineBy` is not specified. + * For stacked charts, this is always determined by the orientation of the stack; + * therefore explicitly specified value will be ignored. + */ + orient?: Orient; + /** + * The line interpolation method to use for line and area marks. One of the following: + * - `"linear"`: piecewise linear segments, as in a polyline. + * - `"linear-closed"`: close the linear segments to form a polygon. + * - `"step"`: alternate between horizontal and vertical segments, as in a step function. + * - `"step-before"`: alternate between vertical and horizontal segments, as in a step function. + * - `"step-after"`: alternate between horizontal and vertical segments, as in a step function. + * - `"basis"`: a B-spline, with control point duplication on the ends. + * - `"basis-open"`: an open B-spline; may not intersect the start or end. + * - `"basis-closed"`: a closed B-spline, as in a loop. + * - `"cardinal"`: a Cardinal spline, with control point duplication on the ends. + * - `"cardinal-open"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points. + * - `"cardinal-closed"`: a closed Cardinal spline, as in a loop. + * - `"bundle"`: equivalent to basis, except the tension parameter is used to straighten the spline. + * - `"monotone"`: cubic interpolation that preserves monotonicity in y. + */ + interpolate?: Interpolate; + /** + * Depending on the interpolation type, sets the tension parameter (for line and area marks). + * @minimum 0 + * @maximum 1 + */ + tension?: number; +} +export declare function isMarkDef(mark: string | MarkDef): mark is MarkDef; +export declare function isPrimitiveMark(mark: string | MarkDef): mark is Mark; +export declare const STROKE_CONFIG: string[]; +export declare const FILL_CONFIG: string[]; +export declare const FILL_STROKE_CONFIG: any[]; +export interface MarkConfig extends VgMarkConfig { + /** + * Whether the shape\'s color should be used as fill color instead of stroke color. + * This is only applicable for "bar", "point", and "area". + * All marks except "point", "line", and "rule" are filled by default. + */ + filled?: boolean; + /** + * Default color. + */ + color?: string; +} +export declare const defaultMarkConfig: MarkConfig; +export interface BarConfig extends MarkConfig { + /** + * Offset between bar for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style). + * @minimum 0 + */ + binSpacing?: number; + /** + * Default size of the bars on continuous scales. + * @minimum 0 + */ + continuousBandSize?: number; + /** + * The size of the bars. If unspecified, the default size is `bandSize-1`, + * which provides 1 pixel offset between bars. + * @minimum 0 + */ + discreteBandSize?: number; +} +export declare const defaultBarConfig: BarConfig; +export interface TextConfig extends MarkConfig { + /** + * Whether month names and weekday names should be abbreviated. + */ + shortTimeLabels?: boolean; +} +export declare const defaultTextConfig: TextConfig; +export interface TickConfig extends MarkConfig { + /** + * The width of the ticks. + * If this value is undefined (by default,), we use 2/3 of rangeStep by default. + * @minimum 0 + */ + bandSize?: number; + /** + * Thickness of the tick mark. + * @minimum 0 + */ + thickness?: number; +} +export declare const defaultTickConfig: TickConfig; diff --git a/build/src/mark.js b/build/src/mark.js new file mode 100644 index 0000000000..01d0d9fe5e --- /dev/null +++ b/build/src/mark.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var Mark; +(function (Mark) { + Mark.AREA = 'area'; + Mark.BAR = 'bar'; + Mark.LINE = 'line'; + Mark.POINT = 'point'; + Mark.RECT = 'rect'; + Mark.RULE = 'rule'; + Mark.TEXT = 'text'; + Mark.TICK = 'tick'; + Mark.CIRCLE = 'circle'; + Mark.SQUARE = 'square'; +})(Mark = exports.Mark || (exports.Mark = {})); +exports.AREA = Mark.AREA; +exports.BAR = Mark.BAR; +exports.LINE = Mark.LINE; +exports.POINT = Mark.POINT; +exports.TEXT = Mark.TEXT; +exports.TICK = Mark.TICK; +exports.RECT = Mark.RECT; +exports.RULE = Mark.RULE; +exports.CIRCLE = Mark.CIRCLE; +exports.SQUARE = Mark.SQUARE; +exports.PRIMITIVE_MARKS = [exports.AREA, exports.BAR, exports.LINE, exports.POINT, exports.TEXT, exports.TICK, exports.RECT, exports.RULE, exports.CIRCLE, exports.SQUARE]; +function isMarkDef(mark) { + return mark['type']; +} +exports.isMarkDef = isMarkDef; +var PRIMITIVE_MARK_INDEX = util_1.toSet(exports.PRIMITIVE_MARKS); +function isPrimitiveMark(mark) { + var markType = isMarkDef(mark) ? mark.type : mark; + return markType in PRIMITIVE_MARK_INDEX; +} +exports.isPrimitiveMark = isPrimitiveMark; +exports.STROKE_CONFIG = ['stroke', 'strokeWidth', + 'strokeDash', 'strokeDashOffset', 'strokeOpacity']; +exports.FILL_CONFIG = ['fill', 'fillOpacity']; +exports.FILL_STROKE_CONFIG = [].concat(exports.STROKE_CONFIG, exports.FILL_CONFIG); +exports.defaultMarkConfig = { + color: '#4c78a8', +}; +exports.defaultBarConfig = { + binSpacing: 1, + continuousBandSize: 2 +}; +exports.defaultTextConfig = { + baseline: 'middle', +}; +exports.defaultTickConfig = { + thickness: 1 +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYXJrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQTZCO0FBSTdCLElBQWlCLElBQUksQ0FXcEI7QUFYRCxXQUFpQixJQUFJO0lBQ04sU0FBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixRQUFHLEdBQVUsS0FBSyxDQUFDO0lBQ25CLFNBQUksR0FBVyxNQUFNLENBQUM7SUFDdEIsVUFBSyxHQUFZLE9BQU8sQ0FBQztJQUN6QixTQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLFNBQUksR0FBVyxNQUFNLENBQUM7SUFDdEIsU0FBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixTQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ3RCLFdBQU0sR0FBYSxRQUFRLENBQUM7SUFDNUIsV0FBTSxHQUFhLFFBQVEsQ0FBQztBQUMzQyxDQUFDLEVBWGdCLElBQUksR0FBSixZQUFJLEtBQUosWUFBSSxRQVdwQjtBQVFZLFFBQUEsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDakIsUUFBQSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNmLFFBQUEsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDakIsUUFBQSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztBQUNuQixRQUFBLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ2pCLFFBQUEsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7QUFDakIsUUFBQSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUNqQixRQUFBLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBRWpCLFFBQUEsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDckIsUUFBQSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUVyQixRQUFBLGVBQWUsR0FBRyxDQUFDLFlBQUksRUFBRSxXQUFHLEVBQUUsWUFBSSxFQUFFLGFBQUssRUFBRSxZQUFJLEVBQUUsWUFBSSxFQUFFLFlBQUksRUFBRSxZQUFJLEVBQUUsY0FBTSxFQUFFLGNBQU0sQ0FBQyxDQUFDO0FBaURoRyxtQkFBMEIsSUFBc0I7SUFDOUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN0QixDQUFDO0FBRkQsOEJBRUM7QUFFRCxJQUFNLG9CQUFvQixHQUFHLFlBQUssQ0FBQyx1QkFBZSxDQUFDLENBQUM7QUFFcEQseUJBQWdDLElBQXNCO0lBQ3BELElBQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNwRCxNQUFNLENBQUMsUUFBUSxJQUFJLG9CQUFvQixDQUFDO0FBQzFDLENBQUM7QUFIRCwwQ0FHQztBQUVZLFFBQUEsYUFBYSxHQUFHLENBQUMsUUFBUSxFQUFFLGFBQWE7SUFDbkQsWUFBWSxFQUFFLGtCQUFrQixFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBRXhDLFFBQUEsV0FBVyxHQUFHLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0FBRXRDLFFBQUEsa0JBQWtCLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxxQkFBYSxFQUFFLG1CQUFXLENBQUMsQ0FBQztBQW1CM0QsUUFBQSxpQkFBaUIsR0FBZTtJQUMzQyxLQUFLLEVBQUUsU0FBUztDQUNqQixDQUFDO0FBc0JXLFFBQUEsZ0JBQWdCLEdBQWM7SUFDekMsVUFBVSxFQUFFLENBQUM7SUFDYixrQkFBa0IsRUFBRSxDQUFDO0NBQ3RCLENBQUM7QUFTVyxRQUFBLGlCQUFpQixHQUFlO0lBQzNDLFFBQVEsRUFBRSxRQUFRO0NBQ25CLENBQUM7QUFpQlcsUUFBQSxpQkFBaUIsR0FBZTtJQUMzQyxTQUFTLEVBQUUsQ0FBQztDQUNiLENBQUMifQ== \ No newline at end of file diff --git a/build/src/scale.d.ts b/build/src/scale.d.ts new file mode 100644 index 0000000000..44ec1b4bc6 --- /dev/null +++ b/build/src/scale.d.ts @@ -0,0 +1,257 @@ +import { Channel } from './channel'; +import { DateTime } from './datetime'; +export declare namespace ScaleType { + const LINEAR: 'linear'; + const BIN_LINEAR: 'bin-linear'; + const LOG: 'log'; + const POW: 'pow'; + const SQRT: 'sqrt'; + const TIME: 'time'; + const UTC: 'utc'; + const SEQUENTIAL: 'sequential'; + const QUANTILE: 'quantile'; + const QUANTIZE: 'quantize'; + const THRESHOLD: 'threshold'; + const ORDINAL: 'ordinal'; + const BIN_ORDINAL: 'bin-ordinal'; + const POINT: 'point'; + const BAND: 'band'; +} +export declare type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR | typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT | typeof ScaleType.TIME | typeof ScaleType.UTC | typeof ScaleType.SEQUENTIAL | typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND; +export declare const SCALE_TYPES: ScaleType[]; +export declare const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[]; +export declare const CONTINUOUS_DOMAIN_SCALES: ScaleType[]; +export declare const DISCRETE_DOMAIN_SCALES: ScaleType[]; +export declare const TIME_SCALE_TYPES: ScaleType[]; +export declare function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band'; +export declare function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal'; +export declare function hasContinuousDomain(type: ScaleType): type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' | 'sequential'; +export declare function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'; +export declare type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'; +export interface ScaleConfig { + /** + * If true, rounds numeric output values to integers. + * This can be helpful for snapping to the pixel grid. + * (Only available for `x`, `y`, `size`, `row`, and `column` scales.) + */ + round?: boolean; + /** + * If true, values that exceed the data domain are clamped to either the minimum or maximum range value + */ + clamp?: boolean; + /** + * Default range step for `x` ordinal scale when is mark is `text`. + * @minimum 0 + */ + textXRangeStep?: number; + /** + * Default range step for (1) `y` ordinal scale, + * and (2) `x` ordinal scale when the mark is not `text`. + * + * @minimum 0 + * @nullable + */ + rangeStep?: number | null; + /** + * Default inner padding for `x` and `y` band-ordinal scales. + * @minimum 0 + * @maximum 1 + */ + bandPaddingInner?: number; + /** + * Default outer padding for `x` and `y` band-ordinal scales. + * If not specified, by default, band scale's paddingOuter is paddingInner/2. + * @minimum 0 + * @maximum 1 + */ + bandPaddingOuter?: number; + /** + * Default outer padding for `x` and `y` point-ordinal scales. + * @minimum 0 + * @maximum 1 + */ + pointPadding?: number; + /** + * Default spacing between faceted plots. + * @TJS-type integer + * @minimum 0 + */ + facetSpacing?: number; + /** + * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis. + * This property only works with aggregate functions that produce values within the raw data domain (`"mean"`, `"average"`, `"median"`, `"q1"`, `"q3"`, `"min"`, `"max"`). For other aggregations that produce values outside of the raw data domain (e.g. `"count"`, `"sum"`), this property is ignored. + */ + useUnaggregatedDomain?: boolean; + /** + * The default max value for mapping quantitative fields to bar's size/bandSize. + * If undefined (default), we will use bandSize - 1. + * @minimum 0 + */ + maxBandSize?: number; + /** + * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false + * If undefined (default), we will use the `continuousBandSize` value for bar and 3 for ticks. + * @minimum 0 + */ + minBandSize?: number; + /** + * The default max value for mapping quantitative fields to text's size/fontSize. + * If undefined (default), we will use bandSize - 1. + * @minimum 0 + */ + maxFontSize?: number; + /** + * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false + * @minimum 0 + */ + minFontSize?: number; + /** + * Default minimum opacity for mapping a field to opacity. + * @minimum 0 + * @maximum 1 + */ + minOpacity?: number; + /** + * Default max opacity for mapping a field to opacity. + * @minimum 0 + * @maximum 1 + */ + maxOpacity?: number; + /** + * Default minimum value for point size scale with zero=false. + * @minimum 0 + */ + minSize?: number; + /** + * Default max value for point size scale. + * @minimum 0 + */ + maxSize?: number; + /** + * Default minimum strokeWidth for strokeWidth (or rule/line's size) scale with zero=false. + * @minimum 0 + */ + minStrokeWidth?: number; + /** + * Default max strokeWidth for strokeWidth (or rule/line's size) scale. + * @minimum 0 + */ + maxStrokeWidth?: number; + /** + * The default collection of symbol shapes for mapping nominal fields to shapes of point marks (i.e., range of a `shape` scale). + * Each value should be one of: `"circle"`, `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, or `"triangle-down"`, or a custom SVG path. + */ + shapes?: string[]; +} +export declare const defaultScaleConfig: { + round: boolean; + textXRangeStep: number; + rangeStep: number; + pointPadding: number; + bandPaddingInner: number; + facetSpacing: number; + minFontSize: number; + maxFontSize: number; + minOpacity: number; + maxOpacity: number; + minSize: number; + minStrokeWidth: number; + maxStrokeWidth: number; + shapes: string[]; +}; +export interface ExtendedScheme { + /** + * Color scheme that determines output color of an ordinal/sequential color scale. + */ + name: string; + extent?: number[]; + count?: number; +} +export declare type Domain = number[] | string[] | DateTime[] | 'unaggregated'; +export declare type Scheme = string | ExtendedScheme; +export declare type Range = number[] | string[] | string; +export declare function isExtendedScheme(scheme: string | ExtendedScheme): scheme is ExtendedScheme; +export interface Scale { + type?: ScaleType; + /** + * The domain of the scale, representing the set of data values. For quantitative data, this can take the form of a two-element array with minimum and maximum values. For ordinal/categorical data, this may be an array of valid input values. + * + * If the domain is 'unaggregated', we use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis. + * This property only works with aggregate functions that produce values within the raw data domain (`"mean"`, `"average"`, `"median"`, `"q1"`, `"q3"`, `"min"`, `"max"`). For other aggregations that produce values outside of the raw data domain (e.g. `"count"`, `"sum"`), this property is ignored. + */ + domain?: Domain; + /** + * The range of the scale, representing the set of visual values. For numeric values, the range can take the form of a two-element array with minimum and maximum values. For ordinal or quantized data, the range may by an array of desired output values, which are mapped to elements in the specified domain. + */ + range?: Range; + /** + * If true, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid. + * + * __Default Rule:__ `true` for `"x"`, `"y"`, `"row"`, `"column"` channels if scale config's `round` is `true`; `false` otherwise. + */ + round?: boolean; + /** + * The distance between the starts of adjacent bands or points in band or point scales. + * If this value is `null`, this will be determined to fit width (for x) or height (for y) of the plot. + * If both width and x-scale's rangeStep is provided, rangeStep will be dropped. (The same rule is applied for height and y-scale's rangeStep.) + * + * __Default Rule:__ for `x` ordinal scale of a `text` mark, derived from [scale config](config.html#scale-config)'s `textXRangeStep`. Otherwise, derived from [scale config](config.html#scale-config)'s `rangeStep`. + * __Warning:__ If the cardinality of the scale domain is too high, the rangeStep might become less than one pixel and the mark might not appear correctly. + * @minimum 0 + * @nullable + */ + rangeStep?: number | null; + /** + * Range scheme (e.g., color schemes such as "category10" or "viridis"). + */ + scheme?: Scheme; + /** + * (For `row` and `column` only) A pixel value for padding between cells in the trellis plots. + * @TJS-type integer + */ + spacing?: number; + /** + * Applies spacing among ordinal elements in the scale range. The actual effect depends on how the scale is configured. If the __points__ parameter is `true`, the padding value is interpreted as a multiple of the spacing between points. A reasonable value is 1.0, such that the first and last point will be offset from the minimum and maximum value by half the distance between points. Otherwise, padding is typically in the range [0, 1] and corresponds to the fraction of space in the range interval to allocate to padding. A value of 0.5 means that the band size will be equal to the padding width. For more, see the [D3 ordinal scale documentation](https://github.com/mbostock/d3/wiki/Ordinal-Scales). + * A convenience property for setting the inner and outer padding to the same value. + * @minimum 0 + * @maximum 1 + */ + padding?: number; + /** + * The inner padding of a band scale determines the ratio of the range that is reserved for blank space between bands. (For point scale, this property is ignored.) + * @minimum 0 + * @maximum 1 + */ + paddingInner?: number; + /** + * The outer padding determines the ratio of the range that is reserved for blank space before the first and after the last bands/points. + * @minimum 0 + * @maximum 1 + */ + paddingOuter?: number; + /** + * If true, values that exceed the data domain are clamped to either the minimum or maximum range value + */ + clamp?: boolean; + /** + * If specified, modifies the scale domain to use a more human-friendly value range. If specified as a true boolean, modifies the scale domain to use a more human-friendly number range (e.g., 7 instead of 6.96). If specified as a string, modifies the scale domain to use a more human-friendly value range. For time and utc scale types only, the nice value should be a string indicating the desired time interval. + */ + nice?: boolean | NiceTime; + /** + * Sets the exponent of the scale transformation. For pow scale types only, otherwise ignored. + */ + exponent?: number; + /** + * If `true`, ensures that a zero baseline value is included in the scale domain. + * Default value: `true` for `x` and `y` channel if the quantitative field is not binned + * and no custom `domain` is provided; `false` otherwise. + */ + zero?: boolean; + interpolate?: 'rgb' | 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long'; +} +export declare const SCALE_PROPERTIES: (keyof Scale)[]; +export declare function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale): boolean; +/** + * Returns undefined if the input channel supports the input scale property name + */ +export declare function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string; diff --git a/build/src/scale.js b/build/src/scale.js new file mode 100644 index 0000000000..079bdf57d9 --- /dev/null +++ b/build/src/scale.js @@ -0,0 +1,169 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("./log"); +var util_1 = require("./util"); +var ScaleType; +(function (ScaleType) { + // Continuous - Quantitative + ScaleType.LINEAR = 'linear'; + ScaleType.BIN_LINEAR = 'bin-linear'; + ScaleType.LOG = 'log'; + ScaleType.POW = 'pow'; + ScaleType.SQRT = 'sqrt'; + // Continuous - Time + ScaleType.TIME = 'time'; + ScaleType.UTC = 'utc'; + // sequential + ScaleType.SEQUENTIAL = 'sequential'; + // Quantile, Quantize, threshold + ScaleType.QUANTILE = 'quantile'; + ScaleType.QUANTIZE = 'quantize'; + ScaleType.THRESHOLD = 'threshold'; + ScaleType.ORDINAL = 'ordinal'; + ScaleType.BIN_ORDINAL = 'bin-ordinal'; + ScaleType.POINT = 'point'; + ScaleType.BAND = 'band'; +})(ScaleType = exports.ScaleType || (exports.ScaleType = {})); +exports.SCALE_TYPES = [ + // Continuous - Quantitative + 'linear', 'bin-linear', 'log', 'pow', 'sqrt', + // Continuous - Time + 'time', 'utc', + // Sequential + 'sequential', + // Discrete + 'ordinal', 'bin-ordinal', 'point', 'band', +]; +exports.CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc']; +var CONTINUOUS_TO_CONTINUOUS_INDEX = util_1.toSet(exports.CONTINUOUS_TO_CONTINUOUS_SCALES); +exports.CONTINUOUS_DOMAIN_SCALES = exports.CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]); +var CONTINUOUS_DOMAIN_INDEX = util_1.toSet(exports.CONTINUOUS_DOMAIN_SCALES); +exports.DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; +var DISCRETE_DOMAIN_INDEX = util_1.toSet(exports.DISCRETE_DOMAIN_SCALES); +var BIN_SCALES_INDEX = util_1.toSet(['bin-linear', 'bin-ordinal']); +exports.TIME_SCALE_TYPES = ['time', 'utc']; +function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; +} +exports.hasDiscreteDomain = hasDiscreteDomain; +function isBinScale(type) { + return type in BIN_SCALES_INDEX; +} +exports.isBinScale = isBinScale; +function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; +} +exports.hasContinuousDomain = hasContinuousDomain; +function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; +} +exports.isContinuousToContinuous = isContinuousToContinuous; +exports.defaultScaleConfig = { + round: true, + textXRangeStep: 90, + rangeStep: 21, + pointPadding: 0.5, + bandPaddingInner: 0.1, + facetSpacing: 16, + minFontSize: 8, + maxFontSize: 40, + minOpacity: 0.3, + maxOpacity: 0.8, + // FIXME: revise if these *can* become ratios of rangeStep + minSize: 9, + minStrokeWidth: 1, + maxStrokeWidth: 4, + shapes: ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down'] +}; +function isExtendedScheme(scheme) { + return scheme && !!scheme['name']; +} +exports.isExtendedScheme = isExtendedScheme; +exports.SCALE_PROPERTIES = [ + 'type', 'domain', 'range', 'round', 'rangeStep', 'scheme', 'padding', 'paddingInner', 'paddingOuter', 'clamp', 'nice', + 'exponent', 'zero', 'interpolate' +]; +function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'range': + case 'scheme': + return true; + case 'interpolate': + return scaleType === 'linear' || scaleType === 'bin-linear'; + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'rangeStep': + case 'padding': + case 'paddingOuter': + return util_1.contains(['point', 'band'], scaleType); + case 'paddingInner': + return scaleType === 'band'; + case 'clamp': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential'; + case 'nice': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType === 'quantize'; + case 'exponent': + return scaleType === 'pow' || scaleType === 'log'; + case 'zero': + // TODO: what about quantize, threshold? + return scaleType === 'bin-ordinal' || (!hasDiscreteDomain(scaleType) && !util_1.contains(['log', 'time', 'utc'], scaleType)); + } + /* istanbul ignore next: should never reach here*/ + throw new Error("Invalid scale property " + propName + "."); +} +exports.scaleTypeSupportProperty = scaleTypeSupportProperty; +/** + * Returns undefined if the input channel supports the input scale property name + */ +function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'range': + // User should not customize range for position and facet channel directly. + if (channel === 'x' || channel === 'y') { + return log.message.CANNOT_USE_RANGE_WITH_POSITION; + } + if (channel === 'row' || channel === 'column') { + return log.message.cannotUseRangePropertyWithFacet('range'); + } + return undefined; // GOOD! + // band / point + case 'rangeStep': + if (channel === 'row' || channel === 'column') { + return log.message.cannotUseRangePropertyWithFacet('rangeStep'); + } + return undefined; // GOOD! + case 'padding': + case 'paddingInner': + case 'paddingOuter': + if (channel === 'row' || channel === 'column') { + /* + * We do not use d3 scale's padding for row/column because padding there + * is a ratio ([0, 1]) and it causes the padding to be decimals. + * Therefore, we manually calculate "spacing" in the layout by ourselves. + */ + return log.message.CANNOT_USE_PADDING_WITH_FACET; + } + return undefined; // GOOD! + case 'interpolate': + case 'scheme': + if (channel !== 'color') { + return log.message.cannotUseScalePropertyWithNonColor(channel); + } + return undefined; + case 'type': + case 'domain': + case 'round': + case 'clamp': + case 'exponent': + case 'nice': + case 'zero': + // These channel do not have strict requirement + return undefined; // GOOD! + } + /* istanbul ignore next: it should never reach here */ + throw new Error('Invalid scale property "${propName}".'); +} +exports.channelScalePropertyIncompatability = channelScalePropertyIncompatability; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NhbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyQkFBNkI7QUFHN0IsK0JBQXVDO0FBRXZDLElBQWlCLFNBQVMsQ0FzQnpCO0FBdEJELFdBQWlCLFNBQVM7SUFDeEIsNEJBQTRCO0lBQ2YsZ0JBQU0sR0FBYSxRQUFRLENBQUM7SUFDNUIsb0JBQVUsR0FBaUIsWUFBWSxDQUFDO0lBQ3hDLGFBQUcsR0FBVSxLQUFLLENBQUM7SUFDbkIsYUFBRyxHQUFVLEtBQUssQ0FBQztJQUNuQixjQUFJLEdBQVcsTUFBTSxDQUFDO0lBQ25DLG9CQUFvQjtJQUNQLGNBQUksR0FBVyxNQUFNLENBQUM7SUFDdEIsYUFBRyxHQUFXLEtBQUssQ0FBQztJQUNqQyxhQUFhO0lBQ0Esb0JBQVUsR0FBaUIsWUFBWSxDQUFDO0lBRXJELGdDQUFnQztJQUNuQixrQkFBUSxHQUFlLFVBQVUsQ0FBQztJQUNsQyxrQkFBUSxHQUFlLFVBQVUsQ0FBQztJQUNsQyxtQkFBUyxHQUFnQixXQUFXLENBQUM7SUFFckMsaUJBQU8sR0FBYyxTQUFTLENBQUM7SUFDL0IscUJBQVcsR0FBa0IsYUFBYSxDQUFDO0lBQzNDLGVBQUssR0FBWSxPQUFPLENBQUM7SUFDekIsY0FBSSxHQUFXLE1BQU0sQ0FBQztBQUNyQyxDQUFDLEVBdEJnQixTQUFTLEdBQVQsaUJBQVMsS0FBVCxpQkFBUyxRQXNCekI7QUFTWSxRQUFBLFdBQVcsR0FBZ0I7SUFDdEMsNEJBQTRCO0lBQzVCLFFBQVEsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNO0lBQzVDLG9CQUFvQjtJQUNwQixNQUFNLEVBQUUsS0FBSztJQUNiLGFBQWE7SUFDYixZQUFZO0lBQ1osV0FBVztJQUNYLFNBQVMsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU07Q0FDMUMsQ0FBQztBQUVXLFFBQUEsK0JBQStCLEdBQWdCLENBQUMs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 \ No newline at end of file diff --git a/build/src/selection.d.ts b/build/src/selection.d.ts new file mode 100644 index 0000000000..dcc4d3dc02 --- /dev/null +++ b/build/src/selection.d.ts @@ -0,0 +1,25 @@ +import { VgBinding } from './vega.schema'; +export declare type SelectionTypes = 'single' | 'multi' | 'interval'; +export declare type SelectionDomain = 'data' | 'visual'; +export declare type SelectionResolutions = 'single' | 'independent' | 'union' | 'union_others' | 'intersect' | 'intersect_others'; +export interface BaseSelectionDef { + on?: any; + bind?: 'scales' | VgBinding | { + [key: string]: VgBinding; + }; + fields?: string[]; + encodings?: string[]; + toggle?: string | boolean; + translate?: string | boolean; + zoom?: string | boolean; + nearest?: boolean; +} +export interface SelectionDef extends BaseSelectionDef { + type: SelectionTypes; +} +export interface SelectionConfig { + single: BaseSelectionDef; + multi: BaseSelectionDef; + interval: BaseSelectionDef; +} +export declare const defaultConfig: SelectionConfig; diff --git a/build/src/selection.js b/build/src/selection.js new file mode 100644 index 0000000000..5a61539206 --- /dev/null +++ b/build/src/selection.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultConfig = { + single: { on: 'click', fields: ['_id'] }, + multi: { on: 'click', fields: ['_id'], toggle: 'event.shiftKey' }, + interval: { + on: '[mousedown, window:mouseup] > window:mousemove!', + encodings: ['x', 'y'], + translate: '[mousedown, window:mouseup] > window:mousemove!', + zoom: 'wheel' + } +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbGVjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdDYSxRQUFBLGFBQWEsR0FBbUI7SUFDM0MsTUFBTSxFQUFFLEVBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBQztJQUN0QyxLQUFLLEVBQUUsRUFBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsRUFBQztJQUMvRCxRQUFRLEVBQUU7UUFDUixFQUFFLEVBQUUsaURBQWlEO1FBQ3JELFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUM7UUFDckIsU0FBUyxFQUFFLGlEQUFpRDtRQUM1RCxJQUFJLEVBQUUsT0FBTztLQUNkO0NBQ0YsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/sort.d.ts b/build/src/sort.d.ts new file mode 100644 index 0000000000..3935258ad0 --- /dev/null +++ b/build/src/sort.d.ts @@ -0,0 +1,14 @@ +import { AggregateOp } from './aggregate'; +export declare type SortOrder = 'ascending' | 'descending' | null; +export interface SortField { + /** + * The field name to aggregate over. + */ + field: string; + /** + * The sort aggregation operator + */ + op: AggregateOp; + order?: SortOrder; +} +export declare function isSortField(sort: SortOrder | SortField): sort is SortField; diff --git a/build/src/sort.js b/build/src/sort.js new file mode 100644 index 0000000000..6fb14cb7de --- /dev/null +++ b/build/src/sort.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isSortField(sort) { + return !!sort && !!sort['field'] && !!sort['op']; +} +exports.isSortField = isSortField; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zb3J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBaUJBLHFCQUE0QixJQUEyQjtJQUNyRCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUZELGtDQUVDIn0= \ No newline at end of file diff --git a/build/src/spec.d.ts b/build/src/spec.d.ts new file mode 100644 index 0000000000..2785738784 --- /dev/null +++ b/build/src/spec.d.ts @@ -0,0 +1,101 @@ +import { Config } from './config'; +import { Data } from './data'; +import { EncodingWithFacet, Encoding } from './encoding'; +import { Facet } from './facet'; +import { FieldDef } from './fielddef'; +import { Mark, MarkDef } from './mark'; +import { Transform } from './transform'; +import { SelectionDef } from './selection'; +export declare type Padding = number | { + top?: number; + bottom?: number; + left?: number; + right?: number; +}; +export interface BaseSpec { + /** + * URL to JSON schema for this Vega-Lite specification. + * @format uri + */ + $schema?: string; + /** + * Name of the visualization for later reference. + */ + name?: string; + /** + * An optional description of this mark for commenting purpose. + * This property has no effect on the output visualization. + */ + description?: string; + /** + * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. This can be a single number or an object with `"top"`, `"left"`, `"right"`, `"bottom"` properties. + * + * __Default value__: `5` + * + * @minimum 0 + */ + padding?: Padding; + /** + * An object describing the data source + */ + data?: Data; + /** + * An object describing filter and new field calculation. + */ + transform?: Transform; + /** + * Configuration object + */ + config?: Config; +} +export interface GenericUnitSpec extends BaseSpec { + width?: number; + height?: number; + /** + * The mark type. + * One of `"bar"`, `"circle"`, `"square"`, `"tick"`, `"line"`, + * `"area"`, `"point"`, `"rule"`, and `"text"`. + */ + mark: M; + /** + * A key-value mapping between encoding channels and definition of fields. + */ + encoding: E; + /** + * A key-value mapping between selection names and definitions. + */ + selection?: { + [name: string]: SelectionDef; + }; +} +export declare type UnitSpec = GenericUnitSpec; +export declare type LayeredUnitSpec = GenericUnitSpec; +export declare type FacetedUnitSpec = GenericUnitSpec; +export interface GenericLayerSpec> extends BaseSpec { + width?: number; + height?: number; + /** + * Unit specs that will be layered. + */ + layer: (GenericLayerSpec | U)[]; +} +export declare type LayerSpec = GenericLayerSpec; +export interface GenericFacetSpec> extends BaseSpec { + facet: Facet; + spec: GenericLayerSpec | U; +} +export declare type FacetSpec = GenericFacetSpec; +export declare type ExtendedFacetSpec = GenericFacetSpec; +export declare type GenericSpec> = U | GenericLayerSpec | GenericFacetSpec; +export declare type ExtendedSpec = GenericSpec; +export declare type Spec = GenericSpec; +export declare function isFacetSpec(spec: GenericSpec>): spec is GenericFacetSpec>; +export declare function isFacetedUnitSpec(spec: ExtendedSpec): spec is FacetedUnitSpec; +export declare function isUnitSpec(spec: ExtendedSpec | Spec): spec is FacetedUnitSpec | UnitSpec; +export declare function isLayerSpec(spec: ExtendedSpec | Spec): spec is GenericLayerSpec>; +/** + * Decompose extended unit specs into composition of pure unit specs. + */ +export declare function normalize(spec: ExtendedSpec): Spec; +export declare function fieldDefs(spec: ExtendedSpec | ExtendedFacetSpec): FieldDef[]; +export declare function isStacked(spec: FacetedUnitSpec): boolean; diff --git a/build/src/spec.js b/build/src/spec.js new file mode 100644 index 0000000000..d9096ebd30 --- /dev/null +++ b/build/src/spec.js @@ -0,0 +1,210 @@ +/* Package of defining Vega-lite Specification's json schema at its utility functions */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var config_1 = require("./config"); +var compositeMark = require("./compositemark"); +var encoding_1 = require("./encoding"); +var log = require("./log"); +var mark_1 = require("./mark"); +var stack_1 = require("./stack"); +var channel_1 = require("./channel"); +var vlEncoding = require("./encoding"); +var util_1 = require("./util"); +/* Custom type guards */ +function isFacetSpec(spec) { + return spec['facet'] !== undefined; +} +exports.isFacetSpec = isFacetSpec; +function isFacetedUnitSpec(spec) { + if (isUnitSpec(spec)) { + var hasRow = encoding_1.channelHasField(spec.encoding, channel_1.ROW); + var hasColumn = encoding_1.channelHasField(spec.encoding, channel_1.COLUMN); + return hasRow || hasColumn; + } + return false; +} +exports.isFacetedUnitSpec = isFacetedUnitSpec; +function isUnitSpec(spec) { + return !!spec['mark']; +} +exports.isUnitSpec = isUnitSpec; +function isLayerSpec(spec) { + return spec['layer'] !== undefined; +} +exports.isLayerSpec = isLayerSpec; +/** + * Decompose extended unit specs into composition of pure unit specs. + */ +// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize +function normalize(spec) { + if (isFacetSpec(spec)) { + return normalizeFacet(spec); + } + if (isLayerSpec(spec)) { + return normalizeLayer(spec); + } + if (isFacetedUnitSpec(spec)) { + return normalizeFacetedUnit(spec); + } + if (isUnitSpec(spec)) { + return normalizeNonFacetUnit(spec); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.normalize = normalize; +function normalizeNonFacet(spec) { + if (isLayerSpec(spec)) { + return normalizeLayer(spec); + } + return normalizeNonFacetUnit(spec); +} +function normalizeFacet(spec) { + var subspec = spec.spec, rest = tslib_1.__rest(spec, ["spec"]); + return tslib_1.__assign({}, rest, { spec: normalizeNonFacet(subspec) }); +} +function normalizeLayer(spec) { + var layer = spec.layer, rest = tslib_1.__rest(spec, ["layer"]); + return tslib_1.__assign({}, rest, { layer: layer.map(normalizeNonFacet) }); +} +function normalizeFacetedUnit(spec) { + // New encoding in the inside spec should not contain row / column + // as row/column should be moved to facet + var _a = spec.encoding, row = _a.row, column = _a.column, encoding = tslib_1.__rest(_a, ["row", "column"]); + // Mark and encoding should be moved into the inner spec + var mark = spec.mark, _ = spec.encoding, outerSpec = tslib_1.__rest(spec, ["mark", "encoding"]); + return tslib_1.__assign({}, outerSpec, { facet: tslib_1.__assign({}, (row ? { row: row } : {}), (column ? { column: column } : {})), spec: normalizeNonFacetUnit({ + mark: mark, + encoding: encoding + }) }); +} +function isNonFacetUnitSpecWithPrimitiveMark(spec) { + return mark_1.isPrimitiveMark(spec.mark); +} +function normalizeNonFacetUnit(spec) { + var config = spec.config; + var overlayConfig = config && config.overlay; + var overlayWithLine = overlayConfig && spec.mark === mark_1.AREA && + util_1.contains(['linepoint', 'line'], overlayConfig.area); + var overlayWithPoint = overlayConfig && ((overlayConfig.line && spec.mark === mark_1.LINE) || + (overlayConfig.area === 'linepoint' && spec.mark === mark_1.AREA)); + if (isNonFacetUnitSpecWithPrimitiveMark(spec)) { + // TODO: thoroughly test + if (encoding_1.isRanged(spec.encoding)) { + return normalizeRangedUnit(spec); + } + // TODO: consider moving this to become another case of compositeMark + if (overlayWithPoint || overlayWithLine) { + return normalizeOverlay(spec, overlayWithPoint, overlayWithLine); + } + return spec; // Nothing to normalize + } + else { + return compositeMark.normalize(spec); + } +} +function normalizeRangedUnit(spec) { + var hasX = encoding_1.channelHasField(spec.encoding, channel_1.X); + var hasY = encoding_1.channelHasField(spec.encoding, channel_1.Y); + var hasX2 = encoding_1.channelHasField(spec.encoding, channel_1.X2); + var hasY2 = encoding_1.channelHasField(spec.encoding, channel_1.Y2); + if ((hasX2 && !hasX) || (hasY2 && !hasY)) { + var normalizedSpec = util_1.duplicate(spec); + if (hasX2 && !hasX) { + normalizedSpec.encoding.x = normalizedSpec.encoding.x2; + delete normalizedSpec.encoding.x2; + } + if (hasY2 && !hasY) { + normalizedSpec.encoding.y = normalizedSpec.encoding.y2; + delete normalizedSpec.encoding.y2; + } + return normalizedSpec; + } + return spec; +} +// FIXME(#1804): rewrite this +function normalizeOverlay(spec, overlayWithPoint, overlayWithLine) { + var outerProps = ['name', 'description', 'data', 'transform']; + var baseSpec = util_1.omit(spec, outerProps.concat('config')); + var baseConfig = util_1.duplicate(spec.config); + delete baseConfig.overlay; + // TODO: remove shape, size + // Need to copy stack config to overlayed layer + var stacked = stack_1.stack(spec.mark, spec.encoding, spec.config ? spec.config.stack : undefined); + var layerSpec = tslib_1.__assign({}, util_1.pick(spec, outerProps), { layer: [baseSpec] }, (util_1.keys(baseConfig).length > 0 ? { config: baseConfig } : {})); + if (overlayWithLine) { + // TODO: add name with suffix + var lineSpec = util_1.duplicate(baseSpec); + lineSpec.mark = mark_1.LINE; + // TODO: remove shape, size + var markConfig = util_1.extend({}, config_1.defaultOverlayConfig.lineStyle, spec.config.overlay.lineStyle, stacked ? { stacked: stacked.offset } : null); + if (util_1.keys(markConfig).length > 0) { + lineSpec.config = { mark: markConfig }; + } + layerSpec.layer.push(lineSpec); + } + if (overlayWithPoint) { + // TODO: add name with suffix + var pointSpec = util_1.duplicate(baseSpec); + pointSpec.mark = mark_1.POINT; + var markConfig = util_1.extend({}, config_1.defaultOverlayConfig.pointStyle, spec.config.overlay.pointStyle, stacked ? { stacked: stacked.offset } : null); + if (util_1.keys(markConfig).length > 0) { + pointSpec.config = { mark: markConfig }; + } + layerSpec.layer.push(pointSpec); + } + return layerSpec; +} +// TODO: add vl.spec.validate & move stuff from vl.validate to here +/* Accumulate non-duplicate fieldDefs in a dictionary */ +function accumulate(dict, fieldDefs) { + fieldDefs.forEach(function (fieldDef) { + // Consider only pure fieldDef properties (ignoring scale, axis, legend) + var pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce(function (f, key) { + if (fieldDef[key] !== undefined) { + f[key] = fieldDef[key]; + } + return f; + }, {}); + var key = util_1.hash(pureFieldDef); + dict[key] = dict[key] || fieldDef; + }); + return dict; +} +/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */ +function fieldDefIndex(spec, dict) { + if (dict === void 0) { dict = {}; } + // TODO: Support repeat and concat + if (isLayerSpec(spec)) { + spec.layer.forEach(function (layer) { + if (isUnitSpec(layer)) { + accumulate(dict, vlEncoding.fieldDefs(layer.encoding)); + } + else { + fieldDefIndex(layer, dict); + } + }); + } + else if (isFacetSpec(spec)) { + accumulate(dict, vlEncoding.fieldDefs(spec.facet)); + fieldDefIndex(spec.spec, dict); + } + else { + accumulate(dict, vlEncoding.fieldDefs(spec.encoding)); + } + return dict; +} +/* Returns all non-duplicate fieldDefs in a spec in a flat array */ +function fieldDefs(spec) { + return util_1.vals(fieldDefIndex(spec)); +} +exports.fieldDefs = fieldDefs; +; +function isStacked(spec) { + if (mark_1.isPrimitiveMark(spec.mark)) { + return stack_1.stack(spec.mark, spec.encoding, spec.config ? spec.config.stack : undefined) !== null; + } + return false; +} +exports.isStacked = isStacked; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHdGQUF3Rjs7OztBQUV4RixtQ0FBc0Q7QUFDdEQsK0NBQWlEO0FBRWpELHVDQUFrRjtBQUlsRiwyQkFBNkI7QUFDN0IsK0JBQXlFO0FBQ3pFLGlDQUE4QjtBQUU5QixxQ0FBb0Q7QUFDcEQsdUNBQXlDO0FBQ3pDLCtCQUFpRjtBQStHakYsd0JBQXdCO0FBR3hCLHFCQUE0QixJQUE0QztJQUN0RSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFNBQVMsQ0FBQztBQUNyQyxDQUFDO0FBRkQsa0NBRUM7QUFFRCwyQkFBa0MsSUFBa0I7SUFDbEQsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQixJQUFNLE1BQU0sR0FBRywwQkFBZSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsYUFBRyxDQUFDLENBQUM7UUFDbkQsSUFBTSxTQUFTLEdBQUcsMEJBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLGdCQUFNLENBQUMsQ0FBQztRQUV6RCxNQUFNLENBQUMsTUFBTSxJQUFJLFNBQVMsQ0FBQztJQUM3QixDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFURCw4Q0FTQztBQUVELG9CQUEyQixJQUF5QjtJQUNsRCxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN4QixDQUFDO0FBRkQsZ0NBRUM7QUFFRCxxQkFBNEIsSUFBeUI7SUFDbkQsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxTQUFTLENBQUM7QUFDckMsQ0FBQztBQUZELGtDQUVDO0FBRUQ7O0dBRUc7QUFDSCx1RkFBdUY7QUFDdkYsbUJBQTBCLElBQWtCO0lBQzFDLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJ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 \ No newline at end of file diff --git a/build/src/stack.d.ts b/build/src/stack.d.ts new file mode 100644 index 0000000000..e06e6a3a39 --- /dev/null +++ b/build/src/stack.d.ts @@ -0,0 +1,29 @@ +import { Channel } from './channel'; +import { Encoding } from './encoding'; +import { FieldDef } from './fielddef'; +import { Mark, MarkDef } from './mark'; +export declare type StackOffset = 'zero' | 'center' | 'normalize' | 'none'; +export interface StackProperties { + /** Dimension axis of the stack ('x' or 'y'). */ + groupbyChannel: Channel; + /** Measure axis of the stack ('x' or 'y'). */ + fieldChannel: Channel; + /** Stack-by fields e.g., color, detail */ + stackBy: { + fieldDef: FieldDef; + channel: Channel; + }[]; + /** + * Modes for stacking marks: + * - `zero`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](mark.html#stacked-bar-chart) and [area](mark.html#stacked-area-chart) chart). + * - `normalize` - stacking with normalized domain (for creating normalized stacked [bar](mark.html#normalized-stacked-bar-chart) and [area](mark.html#normalized-stacked-area-chart) chart).
+ * -`center` - stacking with center baseline (for [streamgraph](mark.html#streamgraph)). + * - `none` - No-stacking. This will produce layered [bar](mark.html#layered-bar-chart) and area chart. + * + * __Default value:__ `zero` for plots with all of the following conditions: (1) `bar` or `area` marks (2) `color`, `opacity`, `size`, or `detail` channel mapped to a group-by field (3) One ordinal or nominal axis, and (4) one quantitative axis with linear scale and summative aggregation function (e.g., `sum`, `count`). + */ + offset: StackOffset; +} +export declare const STACKABLE_MARKS: ("area" | "circle" | "line" | "text" | "bar" | "point" | "rule" | "tick" | "square")[]; +export declare const STACK_BY_DEFAULT_MARKS: ("area" | "bar")[]; +export declare function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties; diff --git a/build/src/stack.js b/build/src/stack.js new file mode 100644 index 0000000000..bbf648d1a8 --- /dev/null +++ b/build/src/stack.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("./log"); +var aggregate_1 = require("./aggregate"); +var channel_1 = require("./channel"); +var encoding_1 = require("./encoding"); +var fielddef_1 = require("./fielddef"); +var mark_1 = require("./mark"); +var scale_1 = require("./scale"); +var util_1 = require("./util"); +exports.STACKABLE_MARKS = [mark_1.BAR, mark_1.AREA, mark_1.RULE, mark_1.POINT, mark_1.CIRCLE, mark_1.SQUARE, mark_1.LINE, mark_1.TEXT, mark_1.TICK]; +exports.STACK_BY_DEFAULT_MARKS = [mark_1.BAR, mark_1.AREA]; +// Note: CompassQL uses this method and only pass in required properties of each argument object. +// If required properties change, make sure to update CompassQL. +function stack(m, encoding, stackConfig) { + var mark = mark_1.isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!util_1.contains(exports.STACKABLE_MARKS, mark)) { + return null; + } + // Should be aggregate plot + if (!encoding_1.isAggregate(encoding)) { + return null; + } + // Should have grouping level of detail + var stackBy = channel_1.STACK_GROUP_CHANNELS.reduce(function (sc, channel) { + if (encoding_1.channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + if (fielddef_1.isFieldDef(fieldDef) && !fieldDef.aggregate) { + sc.push({ + channel: channel, + fieldDef: fieldDef + }); + } + }); + } + return sc; + }, []); + if (stackBy.length === 0) { + return null; + } + // Has only one aggregate axis + var hasXField = fielddef_1.isFieldDef(encoding.x); + var hasYField = fielddef_1.isFieldDef(encoding.y); + var xIsAggregate = fielddef_1.isFieldDef(encoding.x) && !!encoding.x.aggregate; + var yIsAggregate = fielddef_1.isFieldDef(encoding.y) && !!encoding.y.aggregate; + if (xIsAggregate !== yIsAggregate) { + var fieldChannel = xIsAggregate ? channel_1.X : channel_1.Y; + var fieldDef = encoding[fieldChannel]; + var fieldChannelAggregate = fieldDef.aggregate; + var fieldChannelScale = fieldDef.scale; + var stackOffset = null; + if (fieldDef.stack !== undefined) { + stackOffset = fieldDef.stack; + } + else if (util_1.contains(exports.STACK_BY_DEFAULT_MARKS, mark)) { + // Bar and Area with sum ops are automatically stacked by default + stackOffset = stackConfig === undefined ? 'zero' : stackConfig; + } + else { + stackOffset = stackConfig; + } + if (!stackOffset || stackOffset === 'none') { + return null; + } + // If stacked, check if it qualifies for stacking (and log warning if not qualified.) + if (fieldChannelScale && fieldChannelScale.type && fieldChannelScale.type !== scale_1.ScaleType.LINEAR) { + log.warn(log.message.cannotStackNonLinearScale(fieldChannelScale.type)); + return null; + } + if (encoding_1.channelHasField(encoding, fieldChannel === channel_1.X ? channel_1.X2 : channel_1.Y2)) { + log.warn(log.message.cannotStackRangedMark(fieldChannel)); + return null; + } + if (!util_1.contains(aggregate_1.SUM_OPS, fieldChannelAggregate)) { + log.warn(log.message.cannotStackNonSummativeAggregate(fieldChannelAggregate)); + return null; + } + return { + groupbyChannel: xIsAggregate ? (hasYField ? channel_1.Y : null) : (hasXField ? channel_1.X : null), + fieldChannel: fieldChannel, + stackBy: stackBy, + offset: stackOffset + }; + } + return null; +} +exports.stack = stack; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyQkFBNkI7QUFFN0IseUNBQW9DO0FBQ3BDLHFDQUFzRTtBQUN0RSx1Q0FBa0U7QUFDbEUsdUNBQWtFO0FBQ2xFLCtCQUEwRztBQUMxRyxpQ0FBa0M7QUFDbEMsK0JBQXlDO0FBK0I1QixRQUFBLGVBQWUsR0FBRyxDQUFDLFVBQUcsRUFBRSxXQUFJLEVBQUUsV0FBSSxFQUFFLFlBQUssRUFBRSxhQUFNLEVBQUUsYUFBTSxFQUFFLFdBQUksRUFBRSxXQUFJLEVBQUUsV0FBSSxDQUFDLENBQUM7QUFDN0UsUUFBQSxzQkFBc0IsR0FBRyxDQUFDLFVBQUcsRUFBRSxXQUFJLENBQUMsQ0FBQztBQUVsRCxpR0FBaUc7QUFDakcsZ0VBQWdFO0FBRWhFLGVBQXNCLENBQWlCLEVBQUUsUUFBa0IsRUFBRSxXQUF3QjtJQUNuRixJQUFNLElBQUksR0FBRyxnQkFBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZDLDZCQUE2QjtJQUM3QixFQUFFLENBQUMsQ0FBQyxDQUFDLGVBQVEsQ0FBQyx1QkFBZSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELDJCQUEyQjtJQUMzQixFQUFFLENBQUMsQ0FBQyxDQUFDLHNCQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLElBQU0sT0FBTyxHQUFHLDhCQUFvQixDQUFDLE1BQU0sQ0FBQyxVQUFDLEVBQUUsRUFBRSxPQUFPO1FBQ3RELEVBQUUsQ0FBQyxDQUFDLDBCQUFlLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztZ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 \ No newline at end of file diff --git a/build/src/timeunit.d.ts b/build/src/timeunit.d.ts new file mode 100644 index 0000000000..22a06075b5 --- /dev/null +++ b/build/src/timeunit.d.ts @@ -0,0 +1,48 @@ +export declare namespace TimeUnit { + const YEAR: 'year'; + const MONTH: 'month'; + const DAY: 'day'; + const DATE: 'date'; + const HOURS: 'hours'; + const MINUTES: 'minutes'; + const SECONDS: 'seconds'; + const MILLISECONDS: 'milliseconds'; + const YEARMONTH: 'yearmonth'; + const YEARMONTHDATE: 'yearmonthdate'; + const YEARMONTHDATEHOURS: 'yearmonthdatehours'; + const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes'; + const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds'; + const MONTHDATE: 'monthdate'; + const HOURSMINUTES: 'hoursminutes'; + const HOURSMINUTESSECONDS: 'hoursminutesseconds'; + const MINUTESSECONDS: 'minutesseconds'; + const SECONDSMILLISECONDS: 'secondsmilliseconds'; + const QUARTER: 'quarter'; + const YEARQUARTER: 'yearquarter'; + const QUARTERMONTH: 'quartermonth'; + const YEARQUARTERMONTH: 'yearquartermonth'; +} +export declare type TimeUnit = typeof TimeUnit.YEAR | typeof TimeUnit.MONTH | typeof TimeUnit.DAY | typeof TimeUnit.DATE | typeof TimeUnit.HOURS | typeof TimeUnit.MINUTES | typeof TimeUnit.SECONDS | typeof TimeUnit.MILLISECONDS | typeof TimeUnit.YEARMONTH | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES | typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS | typeof TimeUnit.MONTHDATE | typeof TimeUnit.HOURSMINUTES | typeof TimeUnit.HOURSMINUTESSECONDS | typeof TimeUnit.MINUTESSECONDS | typeof TimeUnit.SECONDSMILLISECONDS | typeof TimeUnit.QUARTER | typeof TimeUnit.YEARQUARTER | typeof TimeUnit.QUARTERMONTH | typeof TimeUnit.YEARQUARTERMONTH; +/** Time Unit that only corresponds to only one part of Date objects. */ +export declare const SINGLE_TIMEUNITS: ("day" | "month" | "year" | "date" | "hours" | "minutes" | "seconds" | "milliseconds" | "quarter")[]; +export declare function isSingleTimeUnit(timeUnit: TimeUnit): boolean; +/** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ +export declare function convert(unit: TimeUnit, date: Date): Date; +export declare const MULTI_TIMEUNITS: ("yearmonth" | "yearmonthdate" | "yearmonthdatehours" | "yearmonthdatehoursminutes" | "yearmonthdatehoursminutesseconds" | "hoursminutes" | "hoursminutesseconds" | "minutesseconds" | "secondsmilliseconds" | "yearquarter" | "quartermonth" | "yearquartermonth")[]; +export declare function isMultiTimeUnit(timeUnit: TimeUnit): boolean; +export declare const TIMEUNITS: ("day" | "month" | "year" | "date" | "hours" | "minutes" | "seconds" | "milliseconds" | "yearmonth" | "yearmonthdate" | "yearmonthdatehours" | "yearmonthdatehoursminutes" | "yearmonthdatehoursminutesseconds" | "hoursminutes" | "hoursminutesseconds" | "minutesseconds" | "secondsmilliseconds" | "quarter" | "yearquarter" | "quartermonth" | "yearquartermonth")[]; +/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ +export declare function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit): boolean; +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +export declare function fieldExpr(fullTimeUnit: TimeUnit, field: string): string; +/** returns the smallest nice unit for scale.nice */ +export declare function smallestUnit(timeUnit: TimeUnit): string; +/** returns the signal expression used for axis labels for a time unit */ +export declare function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean): string; +export declare function isDiscreteByDefault(timeUnit: TimeUnit): boolean; diff --git a/build/src/timeunit.js b/build/src/timeunit.js new file mode 100644 index 0000000000..4f1113507c --- /dev/null +++ b/build/src/timeunit.js @@ -0,0 +1,275 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("./datetime"); +var util_1 = require("./util"); +var log = require("./log"); +var TimeUnit; +(function (TimeUnit) { + TimeUnit.YEAR = 'year'; + TimeUnit.MONTH = 'month'; + TimeUnit.DAY = 'day'; + TimeUnit.DATE = 'date'; + TimeUnit.HOURS = 'hours'; + TimeUnit.MINUTES = 'minutes'; + TimeUnit.SECONDS = 'seconds'; + TimeUnit.MILLISECONDS = 'milliseconds'; + TimeUnit.YEARMONTH = 'yearmonth'; + TimeUnit.YEARMONTHDATE = 'yearmonthdate'; + TimeUnit.YEARMONTHDATEHOURS = 'yearmonthdatehours'; + TimeUnit.YEARMONTHDATEHOURSMINUTES = 'yearmonthdatehoursminutes'; + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS = 'yearmonthdatehoursminutesseconds'; + // MONTHDATE always include 29 February since we use year 0th (which is a leap year); + TimeUnit.MONTHDATE = 'monthdate'; + TimeUnit.HOURSMINUTES = 'hoursminutes'; + TimeUnit.HOURSMINUTESSECONDS = 'hoursminutesseconds'; + TimeUnit.MINUTESSECONDS = 'minutesseconds'; + TimeUnit.SECONDSMILLISECONDS = 'secondsmilliseconds'; + TimeUnit.QUARTER = 'quarter'; + TimeUnit.YEARQUARTER = 'yearquarter'; + TimeUnit.QUARTERMONTH = 'quartermonth'; + TimeUnit.YEARQUARTERMONTH = 'yearquartermonth'; +})(TimeUnit = exports.TimeUnit || (exports.TimeUnit = {})); +/** Time Unit that only corresponds to only one part of Date objects. */ +exports.SINGLE_TIMEUNITS = [ + TimeUnit.YEAR, + TimeUnit.QUARTER, + TimeUnit.MONTH, + TimeUnit.DAY, + TimeUnit.DATE, + TimeUnit.HOURS, + TimeUnit.MINUTES, + TimeUnit.SECONDS, + TimeUnit.MILLISECONDS, +]; +var SINGLE_TIMEUNIT_INDEX = exports.SINGLE_TIMEUNITS.reduce(function (d, timeUnit) { + d[timeUnit] = true; + return d; +}, {}); +function isSingleTimeUnit(timeUnit) { + return !!SINGLE_TIMEUNIT_INDEX[timeUnit]; +} +exports.isSingleTimeUnit = isSingleTimeUnit; +/** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ +function convert(unit, date) { + var result = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date + exports.SINGLE_TIMEUNITS.forEach(function (singleUnit) { + if (containsTimeUnit(unit, singleUnit)) { + switch (singleUnit) { + case TimeUnit.DAY: + throw new Error('Cannot convert to TimeUnits containing \'day\''); + case TimeUnit.YEAR: + result.setFullYear(date.getFullYear()); + break; + case TimeUnit.QUARTER: + // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3) + result.setMonth((Math.floor(date.getMonth() / 3)) * 3); + break; + case TimeUnit.MONTH: + result.setMonth(date.getMonth()); + break; + case TimeUnit.DATE: + result.setDate(date.getDate()); + break; + case TimeUnit.HOURS: + result.setHours(date.getHours()); + break; + case TimeUnit.MINUTES: + result.setMinutes(date.getMinutes()); + break; + case TimeUnit.SECONDS: + result.setSeconds(date.getSeconds()); + break; + case TimeUnit.MILLISECONDS: + result.setMilliseconds(date.getMilliseconds()); + break; + } + } + }); + return result; +} +exports.convert = convert; +exports.MULTI_TIMEUNITS = [ + TimeUnit.YEARQUARTER, + TimeUnit.YEARQUARTERMONTH, + TimeUnit.YEARMONTH, + TimeUnit.YEARMONTHDATE, + TimeUnit.YEARMONTHDATEHOURS, + TimeUnit.YEARMONTHDATEHOURSMINUTES, + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, + TimeUnit.QUARTERMONTH, + TimeUnit.HOURSMINUTES, + TimeUnit.HOURSMINUTESSECONDS, + TimeUnit.MINUTESSECONDS, + TimeUnit.SECONDSMILLISECONDS, +]; +var MULTI_TIMEUNIT_INDEX = exports.MULTI_TIMEUNITS.reduce(function (d, timeUnit) { + d[timeUnit] = true; + return d; +}, {}); +function isMultiTimeUnit(timeUnit) { + return !!MULTI_TIMEUNIT_INDEX[timeUnit]; +} +exports.isMultiTimeUnit = isMultiTimeUnit; +exports.TIMEUNITS = [ + TimeUnit.YEAR, + TimeUnit.QUARTER, + TimeUnit.MONTH, + TimeUnit.DAY, + TimeUnit.DATE, + TimeUnit.HOURS, + TimeUnit.MINUTES, + TimeUnit.SECONDS, + TimeUnit.MILLISECONDS, + TimeUnit.YEARQUARTER, + TimeUnit.YEARQUARTERMONTH, + TimeUnit.YEARMONTH, + TimeUnit.YEARMONTHDATE, + TimeUnit.YEARMONTHDATEHOURS, + TimeUnit.YEARMONTHDATEHOURSMINUTES, + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, + TimeUnit.QUARTERMONTH, + TimeUnit.HOURSMINUTES, + TimeUnit.HOURSMINUTESSECONDS, + TimeUnit.MINUTESSECONDS, + TimeUnit.SECONDSMILLISECONDS +]; +/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ +function containsTimeUnit(fullTimeUnit, timeUnit) { + var fullTimeUnitStr = fullTimeUnit.toString(); + var timeUnitStr = timeUnit.toString(); + var index = fullTimeUnitStr.indexOf(timeUnitStr); + return index > -1 && + (timeUnit !== TimeUnit.SECONDS || + index === 0 || + fullTimeUnitStr.charAt(index - 1) !== 'i' // exclude milliseconds + ); +} +exports.containsTimeUnit = containsTimeUnit; +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +function fieldExpr(fullTimeUnit, field) { + var fieldRef = "datum[\"" + field + "\"]"; + function func(timeUnit) { + if (timeUnit === TimeUnit.QUARTER) { + // quarter starting at 0 (0,3,6,9). + return "(quarter(" + fieldRef + ")-1)"; + } + else { + return timeUnit + "(" + fieldRef + ")"; + } + } + var d = exports.SINGLE_TIMEUNITS.reduce(function (_d, tu) { + if (containsTimeUnit(fullTimeUnit, tu)) { + _d[tu] = func(tu); + } + return _d; + }, {}); + if (d.day && util_1.keys(d).length > 1) { + log.warn(log.message.dayReplacedWithDate(fullTimeUnit)); + delete d.day; + d.date = func(TimeUnit.DATE); + } + return datetime_1.dateTimeExpr(d); +} +exports.fieldExpr = fieldExpr; +/** returns the smallest nice unit for scale.nice */ +function smallestUnit(timeUnit) { + if (!timeUnit) { + return undefined; + } + if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) { + return 'second'; + } + if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) { + return 'minute'; + } + if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) { + return 'hour'; + } + if (containsTimeUnit(timeUnit, TimeUnit.DAY) || + containsTimeUnit(timeUnit, TimeUnit.DATE)) { + return 'day'; + } + if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) { + return 'month'; + } + if (containsTimeUnit(timeUnit, TimeUnit.YEAR)) { + return 'year'; + } + return undefined; +} +exports.smallestUnit = smallestUnit; +/** returns the signal expression used for axis labels for a time unit */ +function formatExpression(timeUnit, field, shortTimeLabels) { + if (!timeUnit) { + return undefined; + } + var dateComponents = []; + var expression = ''; + var hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR); + if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) { + // special expression for quarter as prefix + expression = "'Q' + quarter(" + field + ")"; + } + if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) { + // By default use short month name + dateComponents.push(shortTimeLabels !== false ? '%b' : '%B'); + } + if (containsTimeUnit(timeUnit, TimeUnit.DAY)) { + dateComponents.push(shortTimeLabels ? '%a' : '%A'); + } + else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) { + dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year + } + if (hasYear) { + dateComponents.push(shortTimeLabels ? '%y' : '%Y'); + } + var timeComponents = []; + if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) { + timeComponents.push('%H'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) { + timeComponents.push('%M'); + } + if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) { + timeComponents.push('%S'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) { + timeComponents.push('%L'); + } + var dateTimeComponents = []; + if (dateComponents.length > 0) { + dateTimeComponents.push(dateComponents.join(' ')); + } + if (timeComponents.length > 0) { + dateTimeComponents.push(timeComponents.join(':')); + } + if (dateTimeComponents.length > 0) { + if (expression) { + // Add space between quarter and main time format + expression += " + ' ' + "; + } + expression += "timeFormat(" + field + ", '" + dateTimeComponents.join(' ') + "')"; + } + // If expression is still an empty string, return undefined instead. + return expression || undefined; +} +exports.formatExpression = formatExpression; +function isDiscreteByDefault(timeUnit) { + switch (timeUnit) { + // These time unit use discrete scale by default + case 'hours': + case 'day': + case 'month': + case 'quarter': + return true; + } + return false; +} +exports.isDiscreteByDefault = isDiscreteByDefault; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGltZXVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx1Q0FBc0Q7QUFDdEQsK0JBQWtDO0FBQ2xDLDJCQUE2QjtBQUU3QixJQUFpQixRQUFRLENBeUJ4QjtBQXpCRCxXQUFpQixRQUFRO0lBQ1YsYUFBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixjQUFLLEdBQVksT0FBTyxDQUFDO0lBQ3pCLFlBQUcsR0FBVSxLQUFLLENBQUM7SUFDbkIsYUFBSSxHQUFXLE1BQU0sQ0FBQztJQUN0QixjQUFLLEdBQVksT0FBTyxDQUFDO0lBQ3pCLGdCQUFPLEdBQWMsU0FBUyxDQUFDO0lBQy9CLGdCQUFPLEdBQWMsU0FBUyxDQUFDO0lBQy9CLHFCQUFZLEdBQW1CLGNBQWMsQ0FBQztJQUM5QyxrQkFBUyxHQUFnQixXQUFXLENBQUM7SUFDckMsc0JBQWEsR0FBb0IsZUFBZSxDQUFDO0lBQ2pELDJCQUFrQixHQUF5QixvQkFBb0IsQ0FBQztJQUNoRSxrQ0FBeUIsR0FBZ0MsMkJBQTJCLENBQUM7SUFDckYseUNBQWdDLEdBQXVDLGtDQUFrQyxDQUFDO0lBRXZILHFGQUFxRjtJQUN4RSxrQkFBUyxHQUFnQixXQUFXLENBQUM7SUFDckMscUJBQVksR0FBbUIsY0FBYyxDQUFDO0lBQzlDLDRCQUFtQixHQUEwQixxQkFBcUIsQ0FBQztJQUNuRSx1QkFBYyxHQUFxQixnQkFBZ0IsQ0FBQztJQUNwRCw0QkFBbUIsR0FBMEIscUJBQXFCLENBQUM7SUFDbkUsZ0JBQU8sR0FBYyxTQUFTLENBQUM7SUFDL0Isb0JBQVcsR0FBa0IsYUFBYSxDQUFDO0lBQzNDLHFCQUFZLEdBQW1CLGNBQWMsQ0FBQztJQUM5Qyx5QkFBZ0IsR0FBdUIsa0JBQWtCLENBQUM7QUFDekUsQ0FBQyxFQXpCZ0IsUUFBUSxHQUFSLGdCQUFRLEtBQVIsZ0JBQVEsUUF5QnhCO0FBU0Qsd0VBQXdFO0FBQzNELFFBQUEs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 \ No newline at end of file diff --git a/build/src/transform.d.ts b/build/src/transform.d.ts new file mode 100644 index 0000000000..54a7f1da9c --- /dev/null +++ b/build/src/transform.d.ts @@ -0,0 +1,31 @@ +import { Filter } from './filter'; +/** + * Top-level transform object. + */ +export interface Transform { + /** + * A string containing the filter Vega expression. Use `datum` to refer to the current data object. + */ + filter?: string | Filter | (string | Filter)[]; + /** + * Whether to filter invalid values (`null` and `NaN`) from the data. By default (`undefined`), only quantitative and temporal fields are filtered. If set to `true`, all data items with null values are filtered. If `false`, all data items are included. + */ + filterInvalid?: boolean; + /** + * Calculate new field(s) using the provided expresssion(s). Calculation are applied before filter. + */ + calculate?: Formula[]; +} +/** + * Formula object for calculate. + */ +export interface Formula { + /** + * The field in which to store the computed formula value. + */ + as: string; + /** + * A string containing an expression for the formula. Use the variable `datum` to to refer to the current data object. + */ + expr: string; +} diff --git a/build/src/transform.js b/build/src/transform.js new file mode 100644 index 0000000000..9285243a87 --- /dev/null +++ b/build/src/transform.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyYW5zZm9ybS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0= \ No newline at end of file diff --git a/build/src/type.d.ts b/build/src/type.d.ts new file mode 100644 index 0000000000..e93dbc04d3 --- /dev/null +++ b/build/src/type.d.ts @@ -0,0 +1,19 @@ +/** Constants and utilities for data type */ +/** Data type based on level of measurement */ +export declare namespace Type { + const QUANTITATIVE: 'quantitative'; + const ORDINAL: 'ordinal'; + const TEMPORAL: 'temporal'; + const NOMINAL: 'nominal'; +} +export declare type Type = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL; +export declare const QUANTITATIVE: "quantitative"; +export declare const ORDINAL: "ordinal"; +export declare const TEMPORAL: "temporal"; +export declare const NOMINAL: "nominal"; +/** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ +export declare function getFullName(type: Type | string): Type; diff --git a/build/src/type.js b/build/src/type.js new file mode 100644 index 0000000000..b006ce0f68 --- /dev/null +++ b/build/src/type.js @@ -0,0 +1,43 @@ +/** Constants and utilities for data type */ +/** Data type based on level of measurement */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Type; +(function (Type) { + Type.QUANTITATIVE = 'quantitative'; + Type.ORDINAL = 'ordinal'; + Type.TEMPORAL = 'temporal'; + Type.NOMINAL = 'nominal'; +})(Type = exports.Type || (exports.Type = {})); +exports.QUANTITATIVE = Type.QUANTITATIVE; +exports.ORDINAL = Type.ORDINAL; +exports.TEMPORAL = Type.TEMPORAL; +exports.NOMINAL = Type.NOMINAL; +/** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ +function getFullName(type) { + if (type) { + type = type.toLowerCase(); + switch (type) { + case 'q': + case exports.QUANTITATIVE: + return 'quantitative'; + case 't': + case exports.TEMPORAL: + return 'temporal'; + case 'o': + case exports.ORDINAL: + return 'ordinal'; + case 'n': + case exports.NOMINAL: + return 'nominal'; + } + } + // If we get invalid input, return undefined type. + return undefined; +} +exports.getFullName = getFullName; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDRDQUE0QztBQUM1Qyw4Q0FBOEM7OztBQUU5QyxJQUFpQixJQUFJLENBS3BCO0FBTEQsV0FBaUIsSUFBSTtJQUNOLGlCQUFZLEdBQW1CLGNBQWMsQ0FBQztJQUM5QyxZQUFPLEdBQWMsU0FBUyxDQUFDO0lBQy9CLGFBQVEsR0FBZSxVQUFVLENBQUM7SUFDbEMsWUFBTyxHQUFjLFNBQVMsQ0FBQztBQUM5QyxDQUFDLEVBTGdCLElBQUksR0FBSixZQUFJLEtBQUosWUFBSSxRQUtwQjtBQUdZLFFBQUEsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7QUFDakMsUUFBQSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN2QixRQUFBLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3pCLFFBQUEsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7QUFFcEM7Ozs7R0FJRztBQUNILHFCQUE0QixJQUFpQjtJQUMzQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ1QsSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMxQixNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2IsS0FBSyxHQUFHLENBQUM7WUFDVCxLQUFLLG9CQUFZO2dCQUNmLE1BQU0sQ0FBQyxjQUFjLENBQUM7WUFDeEIsS0FBSyxHQUFHLENBQUM7WUFDVCxLQUFLLGdCQUFRO2dCQUNYLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDcEIsS0FBSyxHQUFHLENBQUM7WUFDVCxLQUFLLGVBQU87Z0JBQ1YsTUFBTSxDQUFDLFNBQVMsQ0FBQztZQUNuQixLQUFLLEdBQUcsQ0FBQztZQUNULEtBQUssZUFBTztnQkFDVixNQUFNLENBQUMsU0FBUyxDQUFDO1FBQ3JCLENBQUM7SUFDSCxDQUFDO0lBQ0Qsa0RBQWtEO0lBQ2xELE1BQU0sQ0FBQyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQXBCRCxrQ0FvQkMifQ== \ No newline at end of file diff --git a/build/src/util.d.ts b/build/src/util.d.ts new file mode 100644 index 0000000000..909b3f6472 --- /dev/null +++ b/build/src/util.d.ts @@ -0,0 +1,49 @@ +export { extend, isArray, isObject, isNumber, isString, truncate, toSet, stringValue } from 'vega-util'; +/** + * Creates an object composed of the picked object properties. + * + * Example: (from lodash) + * + * var object = {'a': 1, 'b': '2', 'c': 3}; + * pick(object, ['a', 'c']); + * // → {'a': 1, 'c': 3} + * + */ +export declare function pick(obj: any, props: string[]): {}; +/** + * The opposite of _.pick; this method creates an object composed of the own + * and inherited enumerable string keyed properties of object that are not omitted. + */ +export declare function omit(obj: any, props: string[]): any; +export declare function hash(a: any): string; +export declare function contains(array: Array, item: T): boolean; +/** Returns the array without the elements in item */ +export declare function without(array: Array, excludedItems: Array): T[]; +export declare function union(array: Array, other: Array): T[]; +export declare function reduce(obj: any, f: (a: any, i: any, d: any, k: any, o: any) => any, init: any, thisArg?: any): any; +/** + * Returns true if any item returns true. + */ +export declare function some(arr: Array, f: (d: T, k?: any, i?: any) => boolean): boolean; +/** + * Returns true if all items return true. + */ +export declare function every(arr: Array, f: (d: T, k?: any, i?: any) => boolean): boolean; +export declare function flatten(arrays: any[]): any; +/** + * recursively merges src into dest + */ +export declare function mergeDeep(dest: any, ...src: any[]): any; +export declare function unique(values: T[], f: (item: T) => string): T[]; +export interface Dict { + [key: string]: T; +} +export declare type StringSet = Dict; +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +export declare function differ(dict: Dict, other: Dict): boolean; +export declare const keys: (o: any) => string[]; +export declare function vals(x: any): any[]; +export declare function duplicate(obj: T): T; +export declare function isBoolean(b: any): b is boolean; diff --git a/build/src/util.js b/build/src/util.js new file mode 100644 index 0000000000..3550485cc7 --- /dev/null +++ b/build/src/util.js @@ -0,0 +1,202 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var vega_util_1 = require("vega-util"); +exports.extend = vega_util_1.extend; +exports.isArray = vega_util_1.isArray; +exports.isObject = vega_util_1.isObject; +exports.isNumber = vega_util_1.isNumber; +exports.isString = vega_util_1.isString; +exports.truncate = vega_util_1.truncate; +exports.toSet = vega_util_1.toSet; +exports.stringValue = vega_util_1.stringValue; +var vega_util_2 = require("vega-util"); +/** + * Creates an object composed of the picked object properties. + * + * Example: (from lodash) + * + * var object = {'a': 1, 'b': '2', 'c': 3}; + * pick(object, ['a', 'c']); + * // → {'a': 1, 'c': 3} + * + */ +function pick(obj, props) { + var copy = {}; + props.forEach(function (prop) { + if (obj.hasOwnProperty(prop)) { + copy[prop] = obj[prop]; + } + }); + return copy; +} +exports.pick = pick; +/** + * The opposite of _.pick; this method creates an object composed of the own + * and inherited enumerable string keyed properties of object that are not omitted. + */ +function omit(obj, props) { + var copy = duplicate(obj); + props.forEach(function (prop) { + delete copy[prop]; + }); + return copy; +} +exports.omit = omit; +function hash(a) { + if (vega_util_2.isString(a) || vega_util_2.isNumber(a) || isBoolean(a)) { + return String(a); + } + return stringify(a); +} +exports.hash = hash; +function contains(array, item) { + return array.indexOf(item) > -1; +} +exports.contains = contains; +/** Returns the array without the elements in item */ +function without(array, excludedItems) { + return array.filter(function (item) { return !contains(excludedItems, item); }); +} +exports.without = without; +function union(array, other) { + return array.concat(without(other, array)); +} +exports.union = union; +function reduce(obj, f, init, thisArg) { + if (obj.reduce) { + return obj.reduce.call(thisArg, f, init); + } + else { + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + init = f.call(thisArg, init, obj[k], k, obj); + } + } + return init; + } +} +exports.reduce = reduce; +/** + * Returns true if any item returns true. + */ +function some(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (f(arr[k], k, i++)) { + return true; + } + } + return false; +} +exports.some = some; +/** + * Returns true if all items return true. + */ +function every(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (!f(arr[k], k, i++)) { + return false; + } + } + return true; +} +exports.every = every; +function flatten(arrays) { + return [].concat.apply([], arrays); +} +exports.flatten = flatten; +/** + * recursively merges src into dest + */ +function mergeDeep(dest) { + var src = []; + for (var _i = 1; _i < arguments.length; _i++) { + src[_i - 1] = arguments[_i]; + } + for (var _a = 0, src_1 = src; _a < src_1.length; _a++) { + var s = src_1[_a]; + dest = deepMerge_(dest, s); + } + return dest; +} +exports.mergeDeep = mergeDeep; +; +// recursively merges src into dest +function deepMerge_(dest, src) { + if (typeof src !== 'object' || src === null) { + return dest; + } + for (var p in src) { + if (!src.hasOwnProperty(p)) { + continue; + } + if (src[p] === undefined) { + continue; + } + if (typeof src[p] !== 'object' || vega_util_2.isArray(src[p]) || src[p] === null) { + dest[p] = src[p]; + } + else if (typeof dest[p] !== 'object' || dest[p] === null) { + dest[p] = mergeDeep(src[p].constructor === Array ? [] : {}, src[p]); + } + else { + mergeDeep(dest[p], src[p]); + } + } + return dest; +} +function unique(values, f) { + var results = []; + var u = {}; + var v; + for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { + var val = values_1[_i]; + v = f(val); + if (v in u) { + continue; + } + u[v] = 1; + results.push(val); + } + return results; +} +exports.unique = unique; +; +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +function differ(dict, other) { + for (var key in dict) { + if (dict.hasOwnProperty(key)) { + if (other[key] && dict[key] && other[key] !== dict[key]) { + return true; + } + } + } + return false; +} +exports.differ = differ; +exports.keys = Object.keys; +function vals(x) { + var _vals = []; + for (var k in x) { + if (x.hasOwnProperty(k)) { + _vals.push(x[k]); + } + } + return _vals; +} +exports.vals = vals; +; +function duplicate(obj) { + return JSON.parse(JSON.stringify(obj)); +} +exports.duplicate = duplicate; +; +function isBoolean(b) { + return b === true || b === false; +} +exports.isBoolean = isBoolean; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaURBQW1EO0FBQ25ELHVDQUFzRztBQUE5Riw2QkFBQSxNQUFNLENBQUE7QUFBRSw4QkFBQSxPQUFPLENBQUE7QUFBRSwrQkFBQSxRQUFRLENBQUE7QUFBRSwrQkFBQSxRQUFRLENBQUE7QUFBRSwrQkFBQSxRQUFRLENBQUE7QUFBRSwrQkFBQSxRQUFRLENBQUE7QUFBRSw0QkFBQSxLQUFLLENBQUE7QUFBRSxrQ0FBQSxXQUFXLENBQUE7QUFDbkYsdUNBQXNEO0FBRXREOzs7Ozs7Ozs7R0FTRztBQUNILGNBQXFCLEdBQVEsRUFBRSxLQUFlO0lBQzVDLElBQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNoQixLQUFLLENBQUMsT0FBTyxDQUFDLFVBQUMsSUFBSTtRQUNqQixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBUkQsb0JBUUM7QUFFRDs7O0dBR0c7QUFDSCxjQUFxQixHQUFRLEVBQUUsS0FBZTtJQUM1QyxJQUFNLElBQUksR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQUk7UUFDakIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQU5ELG9CQU1DO0FBRUQsY0FBcUIsQ0FBTTtJQUN6QixFQUFFLENBQUMsQ0FBQyxvQkFBUSxDQUFDLENBQUMsQ0FB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 \ No newline at end of file diff --git a/build/src/validate.d.ts b/build/src/validate.d.ts new file mode 100644 index 0000000000..57820ab94e --- /dev/null +++ b/build/src/validate.d.ts @@ -0,0 +1,32 @@ +import { FacetedUnitSpec } from './spec'; +export interface RequiredChannelMap { + [mark: string]: Array; +} +/** + * Required Encoding Channels for each mark type + * @type {Object} + */ +export declare const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap; +export interface SupportedChannelMap { + [mark: string]: { + [channel: string]: number; + }; +} +/** + * Supported Encoding Channel for each mark type + */ +export declare const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap; +/** + * Further check if encoding mapping of a spec is invalid and + * return error if it is invalid. + * + * This checks if + * (1) all the required encoding channels for the mark type are specified + * (2) all the specified encoding channels are supported by the mark type + * @param {[type]} spec [description] + * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap + * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap + * @return {String} Return one reason why the encoding is invalid, + * or null if the encoding is valid. + */ +export declare function getEncodingMappingError(spec: FacetedUnitSpec, requiredChannelMap?: RequiredChannelMap, supportedChannelMap?: SupportedChannelMap): string; diff --git a/build/src/validate.js b/build/src/validate.js new file mode 100644 index 0000000000..b456ff46a7 --- /dev/null +++ b/build/src/validate.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var mark_1 = require("./mark"); +// TODO: move to vl.spec.validator? +var util_1 = require("./util"); +var mark_2 = require("./mark"); +/** + * Required Encoding Channels for each mark type + * @type {Object} + */ +exports.DEFAULT_REQUIRED_CHANNEL_MAP = { + text: ['text'], + line: ['x', 'y'], + area: ['x', 'y'] +}; +/** + * Supported Encoding Channel for each mark type + */ +exports.DEFAULT_SUPPORTED_CHANNEL_TYPE = { + bar: util_1.toSet(['row', 'column', 'x', 'y', 'size', 'color', 'detail']), + line: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + area: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + tick: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + circle: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + square: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + point: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']), + text: util_1.toSet(['row', 'column', 'size', 'color', 'text']) // TODO(#724) revise +}; +// TODO: consider if we should add validate method and +// requires ZSchema in the main vega-lite repo +/** + * Further check if encoding mapping of a spec is invalid and + * return error if it is invalid. + * + * This checks if + * (1) all the required encoding channels for the mark type are specified + * (2) all the specified encoding channels are supported by the mark type + * @param {[type]} spec [description] + * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap + * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap + * @return {String} Return one reason why the encoding is invalid, + * or null if the encoding is valid. + */ +function getEncodingMappingError(spec, requiredChannelMap, supportedChannelMap) { + if (requiredChannelMap === void 0) { requiredChannelMap = exports.DEFAULT_REQUIRED_CHANNEL_MAP; } + if (supportedChannelMap === void 0) { supportedChannelMap = exports.DEFAULT_SUPPORTED_CHANNEL_TYPE; } + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = spec.encoding; + var requiredChannels = requiredChannelMap[mark]; + var supportedChannels = supportedChannelMap[mark]; + for (var i in requiredChannels) { + if (!(requiredChannels[i] in encoding)) { + return 'Missing encoding channel \"' + requiredChannels[i] + + '\" for mark \"' + mark + '\"'; + } + } + for (var channel in encoding) { + if (!supportedChannels[channel]) { + return 'Encoding channel \"' + channel + + '\" is not supported by mark type \"' + mark + '\"'; + } + } + if (mark === mark_2.BAR && !encoding.x && !encoding.y) { + return 'Missing both x and y for bar'; + } + return null; +} +exports.getEncodingMappingError = getEncodingMappingError; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmFsaWRhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFDQSwrQkFBaUM7QUFFakMsbUNBQW1DO0FBRW5DLCtCQUE2QjtBQUM3QiwrQkFBMkI7QUFNM0I7OztHQUdHO0FBQ1UsUUFBQSw0QkFBNEIsR0FBdUI7SUFDOUQsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ2QsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQztJQUNoQixJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDO0NBQ2pCLENBQUM7QUFRRjs7R0FFRztBQUNVLFFBQUEsOEJBQThCLEdBQXdCO0lBQ2pFLEdBQUcsRUFBRSxZQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNsRSxJQUFJLEVBQUUsWUFBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMzRCxJQUFJLEVBQUUsWUFBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMzRCxJQUFJLEVBQUUsWUFBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMzRCxNQUFNLEVBQUUsWUFBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDckUsTUFBTSxFQUFFLFlBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3JFLEtBQUssRUFBRSxZQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDN0UsSUFBSSxFQUFFLFlBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtDQUM3RSxDQUFDO0FBRUYsc0RBQXNEO0FBQ3RELDhDQUE4QztBQUU5Qzs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxpQ0FBd0MsSUFBcUIsRUFDM0Qsa0JBQXFFLEVBQ3JFLG1CQUF5RTtJQUR6RSxtQ0FBQSxFQUFBLHlEQUFxRTtJQUNyRSxvQ0FBQSxFQUFBLDREQUF5RTtJQUV6RSxJQUFJLElBQUksR0FBRyxnQkFBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQzdELElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDN0IsSUFBSSxnQkFBZ0IsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoRCxJQUFJLGlCQUFpQixHQUFHLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWxELEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLGdCQUFnQixDQUFDLENBQUMsQ0FBQztRQUMvQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sQ0FBQyw2QkFBNkIsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hELGdCQUFnQixHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7UUFDbkMsQ0FBQztJQUNILENBQUM7SUFFRCxHQUFHLENBQUMsQ0FBQyxJQUFJLE9BQU8sSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQzdCLEVBQUUsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxxQkFBcUIsR0FBRyxPQUFPO2dCQUNwQyxxQ0FBcUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ3hELENBQUM7SUFDSCxDQUFDO0lBRUQsRUFBRSxDQUFDLENBQUMsSUFBSSxLQUFLLFVBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQyxNQUFNLENBQUMsOEJBQThCLENBQUM7SUFDeEMsQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBNUJELDBEQTRCQyJ9 \ No newline at end of file diff --git a/build/src/vega.schema.d.ts b/build/src/vega.schema.d.ts new file mode 100644 index 0000000000..f8f27b173d --- /dev/null +++ b/build/src/vega.schema.d.ts @@ -0,0 +1,540 @@ +import { StackOffset } from './stack'; +import { ScaleType, NiceTime } from './scale'; +export interface VgData { + name: string; + source?: string; + values?: any; + format?: any; + url?: any; + transform?: any; +} +export declare type VgParentRef = { + parent: string; +}; +export declare type VgFieldRef = string | VgParentRef | VgParentRef[]; +export declare type VgSortField = boolean | { + field: VgFieldRef; + op: string; +}; +export declare type VgDataRef = { + data: string; + field: VgFieldRef; + sort?: VgSortField; +}; +export declare type VgSignalRef = { + signal: string; +}; +export declare type VgValueRef = { + value?: number | string | boolean; + field?: string | { + datum?: string; + group?: string; + parent?: string; + }; + signal?: string; + scale?: string; + mult?: number; + offset?: number | VgValueRef; + band?: boolean | number; +}; +export declare type DataRefUnionDomain = { + fields: (any[] | VgDataRef)[]; + sort?: boolean | { + op: 'count'; + }; +}; +export declare type FieldRefUnionDomain = { + data: string; + fields: VgFieldRef[]; + sort?: boolean | { + op: 'count'; + }; +}; +export declare type VgRangeScheme = { + scheme: string; + extent?: number[]; + count?: number; +}; +export declare type VgRange = string | VgDataRef | (number | string | VgDataRef)[] | VgRangeScheme | { + step: number; +}; +export declare type VgDomain = any[] | VgDataRef | DataRefUnionDomain | FieldRefUnionDomain | VgSignalRef; +export declare type VgScale = { + name: string; + type: ScaleType; + domain: VgDomain; + domainRaw?: VgSignalRef; + range: VgRange; + clamp?: boolean; + exponent?: number; + nice?: boolean | NiceTime; + padding?: number; + paddingInner?: number; + paddingOuter?: number; + reverse?: boolean; + round?: boolean; + zero?: boolean; +}; +export declare function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain; +export declare function isFieldRefUnionDomain(domain: VgDomain): domain is FieldRefUnionDomain; +export declare function isDataRefDomain(domain: VgDomain): domain is VgDataRef; +export declare function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef; +export declare type VgEncodeEntry = any; +export declare type VgAxis = any; +export declare type VgLegend = any; +export interface VgBinTransform { + type: 'bin'; + field: string; + as: string; + extent?: { + signal: string; + }; +} +export interface VgExtentTransform { + type: 'extent'; + field: string; + signal: string; +} +export interface VgFormulaTransform { + type: 'formula'; + as: string; + expr: string; +} +export interface VgAxisEncode { + ticks?: VgGuideEncode; + labels?: VgGuideEncode; + title?: VgGuideEncode; + grid?: VgGuideEncode; + domain?: VgGuideEncode; +} +export interface VgLegendEncode { + title?: VgGuideEncode; + labels?: VgGuideEncode; + legend?: VgGuideEncode; + symbols?: VgGuideEncode; + gradient?: VgGuideEncode; +} +export declare type VgGuideEncode = any; +export declare type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | any; +export interface VgStackTransform { + type: 'stack'; + offset?: StackOffset; + groupby: string[]; + field: string; + sort: VgSort; + as: string[]; +} +export declare type VgSort = { + field: string; + order: 'ascending' | 'descending'; +} | { + field: string[]; + order: ('ascending' | 'descending')[]; +}; +export interface VgImputeTransform { + type: 'impute'; + groupby?: string[]; + field: string; + orderby?: string[]; + method?: 'value' | 'median' | 'max' | 'min' | 'mean'; + value?: any; +} +export declare type VgCheckboxBinding = { + input: 'checkbox'; + element?: string; +}; +export declare type VgRadioBinding = { + input: 'radio'; + options: string[]; + element?: string; +}; +export declare type VgSelectBinding = { + input: 'select'; + options: string[]; + element?: string; +}; +export declare type VgRangeBinding = { + input: 'range'; + min?: number; + max?: number; + step?: number; + element?: string; +}; +export declare type VgGenericBinding = { + input: string; + element?: string; +}; +export declare type VgBinding = VgCheckboxBinding | VgRadioBinding | VgSelectBinding | VgRangeBinding | VgGenericBinding; +/** + * Base object for Vega's Axis and Axis Config. + * All of these properties are both properties of Vega's Axis and Axis Config. + */ +export interface VgAxisBase { + /** + * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis (default true). + */ + domain?: boolean; + /** + * A flag indicate if gridlines should be created in addition to ticks. If `grid` is unspecified, the default value is `true` for ROW and COL. For X and Y, the default value is `true` for quantitative and time fields and `false` otherwise. + */ + grid?: boolean; + /** + * A boolean flag indicating if labels should be included as part of the axis (default true). + */ + labels?: boolean; + /** + * The rotation angle of the axis labels. + * @minimum 0 + * @maximum 360 + */ + labelAngle?: number; + /** + * Whether the axis should include ticks. + */ + ticks?: boolean; + /** + * The size, in pixels, of major, minor and end ticks. + * @minimum 0 + */ + tickSize?: number; + /** + * Max length for axis title if the title is automatically generated from the field's description. By default, this is automatically based on cell size and characterWidth property. + * @minimum 0 + * @TJS-type integer + */ + titleMaxLength?: number; + /** + * The padding, in pixels, between title and axis. + */ + titlePadding?: number; + /** + * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles. + */ + minExtent?: number; + /** + * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles. + */ + maxExtent?: number; +} +export interface VgAxisConfig extends VgAxisBase { + /** + * Stroke width of axis domain line + */ + domainWidth?: number; + /** + * Color of axis domain line. + */ + domainColor?: string; + /** + * Color of gridlines. + */ + gridColor?: string; + /** + * The offset (in pixels) into which to begin drawing with the grid dash array. + * @minimum 0 + */ + gridDash?: number[]; + /** + * The stroke opacity of grid (value between [0,1]) + * @minimum 0 + * @maximum 1 + */ + gridOpacity?: number; + /** + * The grid width, in pixels. + * @minimum 0 + */ + gridWidth?: number; + /** + * The color of the axis's tick. + */ + tickColor?: string; + /** + * The color of the tick label, can be in hex color code or regular color name. + */ + labelColor?: string; + /** + * The font of the tick label. + */ + labelFont?: string; + /** + * The font size of label, in pixels. + * @minimum 0 + */ + labelFontSize?: number; + /** + * The width, in pixels, of ticks. + * @minimum 0 + */ + tickWidth?: number; + /** + * Color of the title, can be in hex color code or regular color name. + */ + titleColor?: string; + /** + * Font of the title. + */ + titleFont?: string; + /** + * Font size of the title. + * @minimum 0 + */ + titleFontSize?: number; + /** + * Font weight of the title. + */ + titleFontWeight?: string | number; +} +export interface VgLegendBase { + /** + * Padding (in pixels) between legend entries in a symbol legend. + */ + entryPadding?: number; + /** + * The orientation of the legend. One of "left" or "right". This determines how the legend is positioned within the scene. The default is "right". + */ + orient?: string; + /** + * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle. + */ + offset?: number; + /** + * The padding, in pixels, between the legend and axis. + */ + padding?: number; +} +export interface VgLegendConfig extends VgLegendBase { + /** + * The color of the gradient stroke, can be in hex color code or regular color name. + */ + gradientStrokeColor?: string; + /** + * The width of the gradient stroke, in pixels. + * @minimum 0 + */ + gradientStrokeWidth?: number; + /** + * The height of the gradient, in pixels. + * @minimum 0 + */ + gradientHeight?: number; + /** + * The width of the gradient, in pixels. + * @minimum 0 + */ + gradientWidth?: number; + /** + * The alignment of the legend label, can be left, middle or right. + */ + labelAlign?: string; + /** + * The position of the baseline of legend label, can be top, middle or bottom. + */ + labelBaseline?: string; + /** + * The color of the legend label, can be in hex color code or regular color name. + */ + labelColor?: string; + /** + * The font of the legend label. + */ + labelFont?: string; + /** + * The font size of legend label. + * @minimum 0 + */ + labelFontSize?: number; + /** + * The offset of the legend label. + * @minimum 0 + */ + labelOffset?: number; + /** + * The color of the legend symbol, + */ + symbolColor?: string; + /** + * Default shape type (such as "circle") for legend symbols. + */ + symbolType?: string; + /** + * The size of the legend symbol, in pixels. + * @minimum 0 + */ + symbolSize?: number; + /** + * The width of the symbol's stroke. + * @minimum 0 + */ + symbolStrokeWidth?: number; + /** + * Optional mark property definitions for custom legend styling. + */ + /** + * The color of the legend title, can be in hex color code or regular color name. + */ + titleColor?: string; + /** + * The font of the legend title. + */ + titleFont?: string; + /** + * The font size of the legend title. + */ + titleFontSize?: number; + /** + * The font weight of the legend title. + */ + titleFontWeight?: string | number; + /** + * The padding, in pixels, between title and legend. + */ + titlePadding?: number; +} +export declare type FontStyle = 'normal' | 'italic'; +export declare type FontWeight = 'normal' | 'bold'; +/** + * @TJS-type integer + * @minimum 100 + * @maximum 900 + */ +export declare type FontWeightNumber = number; +export declare type HorizontalAlign = 'left' | 'right' | 'center'; +export declare type Interpolate = 'linear' | 'linear-closed' | 'step' | 'step-before' | 'step-after' | 'basis' | 'basis-open' | 'basis-closed' | 'cardinal' | 'cardinal-open' | 'cardinal-closed' | 'bundle' | 'monotone'; +export declare type Orient = 'horizontal' | 'vertical'; +export declare type VerticalAlign = 'top' | 'middle' | 'bottom'; +export interface VgMarkConfig { + /** + * Default Fill Color. This has higher precedence than config.color + */ + fill?: string; + /** + * Default Stroke Color. This has higher precedence than config.color + */ + stroke?: string; + /** + * @minimum 0 + * @maximum 1 + */ + opacity?: number; + /** + * @minimum 0 + * @maximum 1 + */ + fillOpacity?: number; + /** + * @minimum 0 + * @maximum 1 + */ + strokeOpacity?: number; + /** + * @minimum 0 + */ + strokeWidth?: number; + /** + * An array of alternating stroke, space lengths for creating dashed or dotted lines. + */ + strokeDash?: number[]; + /** + * The offset (in pixels) into which to begin drawing with the stroke dash array. + */ + strokeDashOffset?: number; + /** + * The orientation of a non-stacked bar, tick, area, and line charts. + * The value is either horizontal (default) or vertical. + * - For bar, rule and tick, this determines whether the size of the bar and tick + * should be applied to x or y dimension. + * - For area, this property determines the orient property of the Vega output. + * - For line, this property determines the sort order of the points in the line + * if `config.sortLineBy` is not specified. + * For stacked charts, this is always determined by the orientation of the stack; + * therefore explicitly specified value will be ignored. + */ + orient?: Orient; + /** + * The line interpolation method to use for line and area marks. One of the following: + * - `"linear"`: piecewise linear segments, as in a polyline. + * - `"linear-closed"`: close the linear segments to form a polygon. + * - `"step"`: alternate between horizontal and vertical segments, as in a step function. + * - `"step-before"`: alternate between vertical and horizontal segments, as in a step function. + * - `"step-after"`: alternate between horizontal and vertical segments, as in a step function. + * - `"basis"`: a B-spline, with control point duplication on the ends. + * - `"basis-open"`: an open B-spline; may not intersect the start or end. + * - `"basis-closed"`: a closed B-spline, as in a loop. + * - `"cardinal"`: a Cardinal spline, with control point duplication on the ends. + * - `"cardinal-open"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points. + * - `"cardinal-closed"`: a closed Cardinal spline, as in a loop. + * - `"bundle"`: equivalent to basis, except the tension parameter is used to straighten the spline. + * - `"monotone"`: cubic interpolation that preserves monotonicity in y. + */ + interpolate?: Interpolate; + /** + * Depending on the interpolation type, sets the tension parameter (for line and area marks). + * @minimum 0 + * @maximum 1 + */ + tension?: number; + /** + * The default symbol shape to use. One of: `"circle"` (default), `"square"`, `"cross"`, `"diamond"`, `"triangle-up"`, or `"triangle-down"`, or a custom SVG path. + */ + shape?: string; + /** + * The pixel area each the point/circle/square. + * For example: in the case of circles, the radius is determined in part by the square root of the size value. + * @minimum 0 + */ + size?: number; + /** + * The horizontal alignment of the text. One of left, right, center. + */ + align?: HorizontalAlign; + /** + * The rotation angle of the text, in degrees. + * @minimum 0 + * @maximum 360 + */ + angle?: number; + /** + * The vertical alignment of the text. One of top, middle, bottom. + */ + baseline?: VerticalAlign; + /** + * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property. + */ + dx?: number; + /** + * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property. + */ + dy?: number; + /** + * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the x and y properties. + * @minimum 0 + */ + radius?: number; + /** + * Polar coordinate angle, in radians, of the text label from the origin determined by the x and y properties. Values for theta follow the same convention of arc mark startAngle and endAngle properties: angles are measured in radians, with 0 indicating "north". + */ + theta?: number; + /** + * The typeface to set the text in (e.g., Helvetica Neue). + * @minimum 0 + */ + font?: string; + /** + * The font size, in pixels. + * @minimum 0 + */ + fontSize?: number; + /** + * The font style (e.g., italic). + */ + fontStyle?: FontStyle; + /** + * The font weight (e.g., `"normal"`, `"bold"`, `900`). + */ + fontWeight?: FontWeight | FontWeightNumber; + /** + * Placeholder Text + */ + text?: string; +} diff --git a/build/src/vega.schema.js b/build/src/vega.schema.js new file mode 100644 index 0000000000..afc040d8a0 --- /dev/null +++ b/build/src/vega.schema.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +function isDataRefUnionedDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && !('data' in domain); + } + return false; +} +exports.isDataRefUnionedDomain = isDataRefUnionedDomain; +function isFieldRefUnionDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && 'data' in domain; + } + return false; +} +exports.isFieldRefUnionDomain = isFieldRefUnionDomain; +function isDataRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'field' in domain && 'data' in domain; + } + return false; +} +exports.isDataRefDomain = isDataRefDomain; +function isSignalRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'signal' in domain; + } + return false; +} +exports.isSignalRefDomain = isSignalRefDomain; +; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVnYS5zY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmVnYS5zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSwrQkFBK0I7QUF3Ri9CLGdDQUF1QyxNQUFnQjtJQUNyRCxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFMRCx3REFLQztBQUVELCtCQUFzQyxNQUFnQjtJQUNwRCxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQztJQUNoRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFMRCxzREFLQztBQUVELHlCQUFnQyxNQUFnQjtJQUM5QyxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQztJQUNoRCxDQUFDO0lBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFMRCwwQ0FLQztBQUVELDJCQUFrQyxNQUFnQjtJQUNoRCxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUM7SUFDNUIsQ0FBQztJQUNELE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDO0FBTEQsOENBS0M7QUE4RUEsQ0FBQyJ9 \ No newline at end of file diff --git a/build/src/vl.d.ts b/build/src/vl.d.ts new file mode 100644 index 0000000000..ef15285ba8 --- /dev/null +++ b/build/src/vl.d.ts @@ -0,0 +1,24 @@ +export import axis = require('./axis'); +export import aggregate = require('./aggregate'); +export import bin = require('./bin'); +export import channel = require('./channel'); +export import compositeMark = require('./compositemark'); +export { compile } from './compile/compile'; +export import config = require('./config'); +export import data = require('./data'); +export import datetime = require('./datetime'); +export import encoding = require('./encoding'); +export import facet = require('./facet'); +export import fieldDef = require('./fielddef'); +export import legend = require('./legend'); +export import mark = require('./mark'); +export import scale = require('./scale'); +export import sort = require('./sort'); +export import spec = require('./spec'); +export import stack = require('./stack'); +export import timeUnit = require('./timeunit'); +export import transform = require('./transform'); +export import type = require('./type'); +export import util = require('./util'); +export import validate = require('./validate'); +export declare const version: string; diff --git a/build/src/vl.js b/build/src/vl.js new file mode 100644 index 0000000000..a2d2ce6ccb --- /dev/null +++ b/build/src/vl.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.axis = require("./axis"); +exports.aggregate = require("./aggregate"); +exports.bin = require("./bin"); +exports.channel = require("./channel"); +exports.compositeMark = require("./compositemark"); +var compile_1 = require("./compile/compile"); +exports.compile = compile_1.compile; +exports.config = require("./config"); +exports.data = require("./data"); +exports.datetime = require("./datetime"); +exports.encoding = require("./encoding"); +exports.facet = require("./facet"); +exports.fieldDef = require("./fielddef"); +exports.legend = require("./legend"); +exports.mark = require("./mark"); +exports.scale = require("./scale"); +exports.sort = require("./sort"); +exports.spec = require("./spec"); +exports.stack = require("./stack"); +exports.timeUnit = require("./timeunit"); +exports.transform = require("./transform"); +exports.type = require("./type"); +exports.util = require("./util"); +exports.validate = require("./validate"); +exports.version = require('../package.json').version; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBdUM7QUFDdkMsMkNBQWlEO0FBQ2pELCtCQUFxQztBQUNyQyx1Q0FBNkM7QUFDN0MsbURBQXlEO0FBQ3pELDZDQUEyQztBQUFuQyw0QkFBQSxPQUFPLENBQUE7QUFDZixxQ0FBMkM7QUFDM0MsaUNBQXVDO0FBQ3ZDLHlDQUErQztBQUMvQyx5Q0FBK0M7QUFDL0MsbUNBQXlDO0FBQ3pDLHlDQUErQztBQUMvQyxxQ0FBMkM7QUFDM0MsaUNBQXVDO0FBQ3ZDLG1DQUF5QztBQUN6QyxpQ0FBdUM7QUFDdkMsaUNBQXVDO0FBQ3ZDLG1DQUF5QztBQUN6Qyx5Q0FBK0M7QUFDL0MsMkNBQWlEO0FBQ2pELGlDQUF1QztBQUN2QyxpQ0FBdUM7QUFDdkMseUNBQStDO0FBRWxDLFFBQUEsT0FBTyxHQUFXLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/babel.d.ts b/build/test/babel.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/babel.js b/build/test/babel.js new file mode 100644 index 0000000000..24189b6d4e --- /dev/null +++ b/build/test/babel.js @@ -0,0 +1,6 @@ +// Helper required by Mocha to force Babel to run on vega-parser files +// (which aren't parsed by default as they reside in node_modules). +require('babel-core/register')({ + ignore: /node_modules\/(?!vega-parser)/ +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFiZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2JhYmVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHNFQUFzRTtBQUN0RSxtRUFBbUU7QUFDbkUsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDN0IsTUFBTSxFQUFFLCtCQUErQjtDQUN4QyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/channel.test.d.ts b/build/test/channel.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/channel.test.js b/build/test/channel.test.js new file mode 100644 index 0000000000..e6ac920c6a --- /dev/null +++ b/build/test/channel.test.js @@ -0,0 +1,120 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../src/channel"); +var channel_2 = require("../src/channel"); +var scale_1 = require("../src/scale"); +var chai_1 = require("chai"); +var util_1 = require("../src/util"); +describe('channel', function () { + describe('UNIT_CHANNELS', function () { + it('should be CHANNELS without row and column', function () { + chai_1.assert.deepEqual(channel_2.UNIT_CHANNELS, util_1.without(channel_2.CHANNELS, ['row', 'column'])); + }); + }); + describe('UNIT_SCALE_CHANNELS', function () { + it('should be UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT, LABEL', function () { + chai_1.assert.deepEqual(channel_2.UNIT_SCALE_CHANNELS, util_1.without(channel_2.UNIT_CHANNELS, ['x2', 'y2', 'order', 'detail', 'text', 'label'])); + }); + }); + describe('SCALE_CHANNELS', function () { + it('should be UNIT_SCALE_CHANNELS and ROW and COLUMN', function () { + chai_1.assert.deepEqual(channel_2.SCALE_CHANNELS, [].concat(channel_2.UNIT_SCALE_CHANNELS, ['row', 'column'])); + }); + }); + describe('NONSPATIAL_CHANNELS', function () { + it('should be UNIT_CHANNELS without x, y, x2, y2', function () { + chai_1.assert.deepEqual(channel_2.NONSPATIAL_CHANNELS, util_1.without(channel_2.UNIT_CHANNELS, ['x', 'y', 'x2', 'y2'])); + }); + }); + describe('NONSPATIAL_SCALE_CHANNELS', function () { + it('should be UNIT_SCALE_CHANNELS without x, y, x2, y2', function () { + chai_1.assert.deepEqual(channel_2.NONSPATIAL_SCALE_CHANNELS, util_1.without(channel_2.UNIT_SCALE_CHANNELS, ['x', 'y'])); + }); + }); + describe('hasScale', function () { + it('should return true for all scale channel', function () { + for (var _i = 0, SCALE_CHANNELS_1 = channel_2.SCALE_CHANNELS; _i < SCALE_CHANNELS_1.length; _i++) { + var channel = SCALE_CHANNELS_1[_i]; + chai_1.assert(channel_1.hasScale(channel)); + } + }); + }); + describe('supportScaleType', function () { + // Make sure we always edit this when we add new channel + it('should have at least one supported scale types for all channels with scale', function () { + var _loop_1 = function (channel) { + chai_1.assert(util_1.some(scale_1.SCALE_TYPES, function (scaleType) { + return channel_1.supportScaleType(channel, scaleType); + })); + }; + for (var _i = 0, SCALE_CHANNELS_2 = channel_2.SCALE_CHANNELS; _i < SCALE_CHANNELS_2.length; _i++) { + var channel = SCALE_CHANNELS_2[_i]; + _loop_1(channel); + } + }); + // Make sure we always edit this when we add new scale type + it('should have at least one supported channel for all scale types', function () { + var _loop_2 = function (scaleType) { + chai_1.assert(util_1.some(channel_2.SCALE_CHANNELS, function (channel) { + return channel_1.supportScaleType(channel, scaleType); + })); + }; + for (var _i = 0, SCALE_TYPES_1 = scale_1.SCALE_TYPES; _i < SCALE_TYPES_1.length; _i++) { + var scaleType = SCALE_TYPES_1[_i]; + _loop_2(scaleType); + } + }); + it('row,column should support only band', function () { + for (var _i = 0, _a = ['row', 'column']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(channel_1.supportScaleType(channel, 'band')); + var nonBands = util_1.without(scale_1.SCALE_TYPES, ['band']); + for (var _b = 0, nonBands_1 = nonBands; _b < nonBands_1.length; _b++) { + var scaleType = nonBands_1[_b]; + chai_1.assert(!channel_1.supportScaleType(channel, scaleType)); + } + } + }); + it('shape should support only ordinal', function () { + chai_1.assert(channel_1.supportScaleType('shape', 'ordinal')); + var nonOrdinal = util_1.without(scale_1.SCALE_TYPES, ['ordinal']); + for (var _i = 0, nonOrdinal_1 = nonOrdinal; _i < nonOrdinal_1.length; _i++) { + var scaleType = nonOrdinal_1[_i]; + chai_1.assert(!channel_1.supportScaleType('shape', scaleType)); + } + }); + it('color should support all scale types except band', function () { + for (var _i = 0, SCALE_TYPES_2 = scale_1.SCALE_TYPES; _i < SCALE_TYPES_2.length; _i++) { + var scaleType = SCALE_TYPES_2[_i]; + chai_1.assert.equal(channel_1.supportScaleType('color', scaleType), scaleType !== 'band'); + } + }); + it('x, y, size, opacity should support all scale type except ordinal and sequential', function () { + // x,y should use either band or point for ordinal input + var nonOrdinal = util_1.without(scale_1.SCALE_TYPES, ['ordinal', 'sequential']); + for (var _i = 0, _a = ['x', 'y', 'size', 'opacity']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(!channel_1.supportScaleType(channel, 'ordinal')); + chai_1.assert(!channel_1.supportScaleType(channel, 'sequential')); + for (var _b = 0, nonOrdinal_2 = nonOrdinal; _b < nonOrdinal_2.length; _b++) { + var scaleType = nonOrdinal_2[_b]; + chai_1.assert(channel_1.supportScaleType(channel, scaleType), "Error: " + channel + ", " + scaleType); + } + } + }); + }); + describe('rangeType', function () { + it('should be defined for all channels (no error).', function () { + var _loop_3 = function (c) { + chai_1.assert.doesNotThrow(function () { + channel_1.rangeType(c); + }); + }; + for (var _i = 0, CHANNELS_1 = channel_2.CHANNELS; _i < CHANNELS_1.length; _i++) { + var c = CHANNELS_1[_i]; + _loop_3(c); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC9jaGFubmVsLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwQ0FBOEU7QUFDOUUsMENBQTRJO0FBQzVJLHNDQUFvRDtBQUNwRCw2QkFBNEI7QUFDNUIsb0NBQTBDO0FBRzFDLFFBQVEsQ0FBQyxTQUFTLEVBQUU7SUFDbEIsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixFQUFFLENBQUMsMkNBQTJDLEVBQUU7WUFDOUMsYUFBTSxDQUFDLFNBQVMsQ0FBQyx1QkFBYSxFQUFFLGNBQU8sQ0FBQyxrQkFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHFCQUFxQixFQUFFO1FBQzlCLEVBQUUsQ0FBQyxvRUFBb0UsRUFBRTtZQUN2RSxhQUFNLENBQUMsU0FBUyxDQUFDLDZCQUFtQixFQUFFLGNBQU8sQ0FBQyx1QkFBYSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEgsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixFQUFFLENBQUMsa0RBQWtELEVBQUU7WUFDckQsYUFBTSxDQUFDLFNBQVMsQ0FBQyx3QkFBYyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsNkJBQW1CLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RGLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMscUJBQXFCLEVBQUU7UUFDOUIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lB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 \ No newline at end of file diff --git a/build/test/compile/axis/encode.test.d.ts b/build/test/compile/axis/encode.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/axis/encode.test.js b/build/test/compile/axis/encode.test.js new file mode 100644 index 0000000000..ddb25fa1c2 --- /dev/null +++ b/build/test/compile/axis/encode.test.js @@ -0,0 +1,62 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var encode = require("../../../src/compile/axis/encode"); +describe('compile/axis', function () { + describe('encode.labels()', function () { + it('should show truncated labels by default', function () { + var labels = encode.labels(util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: 'a', type: "ordinal" } + } + }), 'x', {}, { orient: 'top' }); + chai_1.assert.deepEqual(labels.text.signal, 'truncate(datum.value, 25)'); + }); + it('should rotate label', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "month" } + } + }); + var labels = encode.labels(model, 'x', {}, {}); + chai_1.assert.equal(labels.angle.value, 270); + }); + it('should also rotate labels if the channel is column', function () { + var model = util_1.parseModel({ + mark: "point", + encoding: { + column: { field: "a", type: "temporal", timeUnit: "month", axis: { labelAngle: 270 } } + } + }); + var labels = encode.labels(model, 'column', {}, {}); + chai_1.assert.equal(labels.angle.value, 270); + }); + it('should have correct text.signal for quarter timeUnits', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "quarter" } + } + }); + var labels = encode.labels(model, 'x', {}, {}); + var expected = "'Q' + quarter(datum.value)"; + chai_1.assert.equal(labels.text.signal, expected); + }); + it('should have correct text.signal for yearquartermonth timeUnits', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal", timeUnit: "yearquartermonth" } + } + }); + var labels = encode.labels(model, 'x', {}, {}); + var expected = "'Q' + quarter(datum.value) + ' ' + timeFormat(datum.value, '%b %Y')"; + chai_1.assert.equal(labels.text.signal, expected); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvYXhpcy9lbmNvZGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFFNUIsbUNBQXNEO0FBQ3RELHlEQUEyRDtBQUczRCxRQUFRLENBQUMsY0FBYyxFQUFFO0lBQ3ZCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtRQUMxQixFQUFFLENBQUMseUNBQXlDLEVBQUU7WUFDNUMsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxxQkFBYyxDQUFDO2dCQUN4QyxJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO2lCQUNqQzthQUNGLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7WUFDaEMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO1FBQ3BFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFCQUFxQixFQUFFO1lBQ3hCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBQztpQkFDckQ7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELGFBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsSUFBTSxLQUFLLEdBQUcsaUJBQVUsQ0FBQztnQkFDdkIsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFDLFVBQVUsRUFBRSxHQUFHLEVBQUMsRUFBQztpQkFDbkY7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELGFBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFDO2lCQUN2RDthQUNGLENBQUMsQ0FBQztZQUNILElBQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDakQsSUFBSSxRQUFRLEdBQUcsNEJBQTRCLENBQUM7WUFDNUMsYUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnRUFBZ0UsRUFBRTtZQUNuRSxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsRUFBQztpQkFDaEU7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELElBQUksUUFBUSxHQUFHLHFFQUFxRSxDQUFDO1lBQ3JGLGFBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/test/compile/axis/parse.test.d.ts b/build/test/compile/axis/parse.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/axis/parse.test.js b/build/test/compile/axis/parse.test.js new file mode 100644 index 0000000000..c0175c3978 --- /dev/null +++ b/build/test/compile/axis/parse.test.js @@ -0,0 +1,95 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var axisParse = require("../../../src/compile/axis/parse"); +var channel_1 = require("../../../src/channel"); +describe('Axis', function () { + // TODO: move this to model.test.ts + describe('= true', function () { + it('should produce default properties for axis', function () { + var model1 = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum", "axis": true } + }, + "data": { "url": "data/movies.json" } + }); + var model2 = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "data": { "url": "data/movies.json" } + }); + chai_1.assert.deepEqual(model1.axis(channel_1.Y), model2.axis(channel_1.Y)); + }); + }); + describe('parseAxisComponent', function () { + it('should produce Vega grid axis objects for both main axis and for grid axis)', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: true, gridColor: "blue", gridWidth: 20 } + } + } + }); + var axisComponent = axisParse.parseAxisComponent(model, ['x', 'y']); + chai_1.assert.equal(axisComponent['x'].length, 2); + chai_1.assert.equal(axisComponent['x'][0].grid, undefined); + chai_1.assert.equal(axisComponent['x'][1].grid, true); + }); + it('should produce Vega grid axis objects for only main axis if grid is disabled)', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: false, gridColor: "blue", gridWidth: 20 } + } + } + }); + var axisComponent = axisParse.parseAxisComponent(model, ['x', 'y']); + chai_1.assert.equal(axisComponent['x'].length, 1); + chai_1.assert.equal(axisComponent['x'][0].grid, undefined); + }); + }); + describe('parseGridAxis', function () { + it('should produce a Vega grid axis object with correct type, scale and grid properties', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { + field: "a", + type: "quantitative", + axis: { grid: true } + } + } + }); + var def = axisParse.parseGridAxis(channel_1.X, model); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.orient, 'bottom'); + chai_1.assert.equal(def.scale, 'x'); + }); + }); + describe('parseMainAxis', function () { + it('should produce a Vega axis object with correct type and scale', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "quantitative" } + } + }); + var def = axisParse.parseMainAxis(channel_1.X, model); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.orient, 'bottom'); + chai_1.assert.equal(def.scale, 'x'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9heGlzL3BhcnNlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBRTVCLG1DQUEwQztBQUMxQywyREFBNkQ7QUFDN0QsZ0RBQTBDO0FBRTFDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixtQ0FBbUM7SUFDbkMsUUFBUSxDQUFDLFFBQVEsRUFBRTtRQUNqQixFQUFFLENBQUMsNENBQTRDLEVBQUU7WUFDL0MsSUFBTSxNQUFNLEdBQUcscUJBQWMsQ0FBQztnQkFDNUIsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUM7aUJBQ3JGO2dCQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQzthQUNwQyxDQUFDLENBQUM7WUFFSCxJQUFNLE1BQU0sR0FBRyxxQkFBYyxDQUFDO2dCQUM1QixNQUFNLEVBQUUsS0FBSztnQkFDYixVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUM7aUJBQ3ZFO2dCQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQzthQUNwQyxDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDSCxRQUFRLENBQUMs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 \ No newline at end of file diff --git a/build/test/compile/axis/rules.test.d.ts b/build/test/compile/axis/rules.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/axis/rules.test.js b/build/test/compile/axis/rules.test.js new file mode 100644 index 0000000000..4ed712e277 --- /dev/null +++ b/build/test/compile/axis/rules.test.js @@ -0,0 +1,142 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var channel_1 = require("../../../src/channel"); +var rules = require("../../../src/compile/axis/rules"); +describe('compile/axis', function () { + describe('grid()', function () { + it('should return specified orient', function () { + var grid = rules.grid(util_1.parseModel({ + mark: "point", + encoding: { + x: { field: 'a', type: 'quantitative', axis: { grid: false } } + } + }), channel_1.X, true); + chai_1.assert.deepEqual(grid, false); + }); + it('should return true by default', function () { + var grid = rules.grid(util_1.parseModel({ + mark: "point", + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }), channel_1.X, true); + chai_1.assert.deepEqual(grid, true); + }); + it('should return undefined for COLUMN', function () { + var grid = rules.grid(util_1.parseModel({ + mark: "point", + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }), channel_1.COLUMN, true); + chai_1.assert.deepEqual(grid, false); + }); + it('should return undefined for ROW', function () { + var grid = rules.grid(util_1.parseModel({ + mark: "point", + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }), channel_1.ROW, true); + chai_1.assert.deepEqual(grid, false); + }); + it('should return undefined for non-gridAxis', function () { + var grid = rules.grid(util_1.parseModel({ + mark: "point", + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }), channel_1.X, false); + chai_1.assert.deepEqual(grid, undefined); + }); + }); + describe('orient()', function () { + it('should return specified orient', function () { + var orient = rules.orient({ orient: 'bottom' }, 'x'); + chai_1.assert.deepEqual(orient, 'bottom'); + }); + it('should return bottom for x by default', function () { + var orient = rules.orient({}, 'x'); + chai_1.assert.deepEqual(orient, 'bottom'); + }); + it('should return top for column by default', function () { + var orient = rules.orient({}, 'column'); + chai_1.assert.deepEqual(orient, 'top'); + }); + it('should return left for row by default', function () { + var orient = rules.orient({}, 'row'); + chai_1.assert.deepEqual(orient, 'left'); + }); + it('should return left for y by default', function () { + var orient = rules.orient({}, 'y'); + chai_1.assert.deepEqual(orient, 'left'); + }); + }); + describe('tickCount', function () { + it('should return undefined by default for non-x', function () { + var tickCount = rules.tickCount({}, 'y', { field: 'a', type: 'quantitative' }); + chai_1.assert.deepEqual(tickCount, undefined); + }); + it('should return 5 by default for x', function () { + var tickCount = rules.tickCount({}, 'x', { field: 'a', type: 'quantitative' }); + chai_1.assert.deepEqual(tickCount, 5); + }); + it('should return specified tickCount', function () { + var tickCount = rules.tickCount({ tickCount: 10 }, 'x', { field: 'a', type: 'quantitative' }); + chai_1.assert.deepEqual(tickCount, 10); + }); + }); + describe('title()', function () { + it('should add explicitly specified title', function () { + var title = rules.title({ title: 'Custom' }, { field: 'a', type: "quantitative" }, {}, false); + chai_1.assert.deepEqual(title, 'Custom'); + }); + it('should add return fieldTitle by default', function () { + var title = rules.title({ titleMaxLength: 3 }, { field: 'a', type: "quantitative" }, {}, false); + chai_1.assert.deepEqual(title, 'a'); + }); + it('should add return fieldTitle by default', function () { + var title = rules.title({ titleMaxLength: 10 }, { aggregate: 'sum', field: 'a', type: "quantitative" }, {}, false); + chai_1.assert.deepEqual(title, 'SUM(a)'); + }); + it('should add return fieldTitle by default and truncate', function () { + var title = rules.title({ titleMaxLength: 3 }, { aggregate: 'sum', field: 'a', type: "quantitative" }, {}, false); + chai_1.assert.deepEqual(title, 'SU…'); + }); + it('should add return undefined for gridAxis', function () { + var title = rules.title({ titleMaxLength: 3 }, { field: 'a', type: "quantitative" }, {}, true); + chai_1.assert.deepEqual(title, undefined); + }); + }); + describe('values', function () { + it('should return correct timestamp values for DateTimes', function () { + var values = rules.values({ values: [{ year: 1970 }, { year: 1980 }] }); + chai_1.assert.deepEqual(values, [ + new Date(1970, 0, 1).getTime(), + new Date(1980, 0, 1).getTime() + ]); + }); + it('should simply return values for non-DateTime', function () { + var values = rules.values({ values: [1, 2, 3, 4] }); + chai_1.assert.deepEqual(values, [1, 2, 3, 4]); + }); + }); + describe('zindex()', function () { + it('should return undefined by default without grid defined', function () { + var zindex = rules.zindex({}, false); + chai_1.assert.deepEqual(zindex, 1); + }); + it('should return back by default with grid defined', function () { + var zindex = rules.zindex({}, true); + chai_1.assert.deepEqual(zindex, 0); + }); + it('should return specified zindex', function () { + var zindex = rules.zindex({ zindex: 2 }, false); + chai_1.assert.deepEqual(zindex, 2); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9heGlzL3J1bGVzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLG1DQUFzQztBQUN0QyxnREFBb0Q7QUFDcEQsdURBQXlEO0FBRXpELFFBQVEsQ0FBQyxjQUFjLEVBQUU7SUFDdkIsUUFBUSxDQUFDLFFBQVEsRUFBRTtRQUNqQixFQUFFLENBQUMsZ0NBQWdDLEVBQUU7WUFDbkMsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBVSxDQUFDO2dCQUMvQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBQyxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUMsRUFBQztpQkFDMUQ7YUFDRixDQUFDLEVBQUUsV0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2YsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0JBQStCLEVBQUU7WUFDbEMsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBVSxDQUFDO2dCQUMvQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsRUFBRSxXQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDZixhQUFNLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtZQUN2QyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGlCQUFVLENBQUM7Z0JBQy9CLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7aUJBQ3RDO2FBQ0YsQ0FBQyxFQUFFLGdCQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDcEIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUU7WUFDcEMsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBVSxDQUFDO2dCQUMvQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsRUFBRSxhQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDakIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxFQUFFLENBQUMsMENBQTBDLEVBQUU7WUFDN0MsSUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBVSxDQUFDO2dCQUMvQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2lCQUN0QzthQUNGLENBQUMsRUFBRSxXQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDaEIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsRUFBRSxDQUFDLGdDQUFnQyxFQUFFO1lBQ25DLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsUUFBUSxFQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDckQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDckMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUU7WUFDNUMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDMUMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDdkMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscUNBQXFDLEVBQUU7WUFDeEMsSUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDckMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxXQUFXLEVBQUU7UUFDcEIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELElBQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLENBQUM7WUFDL0UsYUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUU7WUFDckMsSUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDLENBQUMsQ0FBQztZQUMvRSxhQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRTtZQUN0QyxJQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUMsU0FBUyxFQUFFLEVBQUUsRUFBQyxFQUFFLEdBQUcsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxDQUFDLENBQUM7WUFDNUYsYUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxTQUFTLEVBQUU7UUFDbEIsRUFBRSxDQUFDLHVDQUF1QyxFQUFFO1lBQzFDLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDNUYsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUU7WUFDNUMsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFDLGNBQWMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM5RixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRTtZQUM1QyxJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUMsY0FBYyxFQUFFLEVBQUUsRUFBQyxFQUFFLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDakgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0RBQXNELEVBQUU7WUFDekQsSUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFDLGNBQWMsRUFBRSxDQUFDLEVBQUMsRUFBRSxFQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2hILGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBR0gsRUFBRSxDQUFDLDBDQUEwQyxFQUFFO1lBQzdDLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBQyxjQUFjLEVBQUUsQ0FBQyxFQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0YsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxRQUFRLEVBQUU7UUFDakIsRUFBRSxDQUFDLHNEQUFzRCxFQUFFO1lBQ3pELElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUVwRSxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtnQkFDdkIsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUU7Z0JBQzlCLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFO2FBQy9CLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7WUFFakQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsVUFBVSxFQUFFO1FBQ25CLEVBQUUsQ0FBQyx5REFBeUQsRUFBRTtZQUM1RCxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2QyxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRTtZQUNwRCxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN0QyxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRTtZQUNuQyxJQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUMsTUFBTSxFQUFFLENBQUMsRUFBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2hELGFBQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/compile/common.test.d.ts b/build/test/compile/common.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/common.test.js b/build/test/compile/common.test.js new file mode 100644 index 0000000000..bbc87df013 --- /dev/null +++ b/build/test/compile/common.test.js @@ -0,0 +1,59 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../src/channel"); +var config_1 = require("../../src/config"); +var timeunit_1 = require("../../src/timeunit"); +var fielddef_1 = require("../../src/fielddef"); +var type_1 = require("../../src/type"); +var common_1 = require("../../src/compile/common"); +describe('Common', function () { + describe('timeFormat()', function () { + it('should get the right time expression for month with shortTimeLabels=true', function () { + var fieldDef = { timeUnit: timeunit_1.TimeUnit.MONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { datum: true }), timeunit_1.TimeUnit.MONTH, undefined, true, config_1.defaultConfig.timeFormat); + chai_1.assert.equal(expression, "timeFormat(datum[\"month_a\"], '%b')"); + }); + it('should get the right time expression for month with shortTimeLabels=false', function () { + var fieldDef = { timeUnit: timeunit_1.TimeUnit.MONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { datum: true }), timeunit_1.TimeUnit.MONTH, undefined, false, config_1.defaultConfig.timeFormat); + chai_1.assert.equal(expression, "timeFormat(datum[\"month_a\"], '%B')"); + }); + it('should get the right time expression for yearmonth with custom format', function () { + var fieldDef = { timeUnit: timeunit_1.TimeUnit.YEARMONTH, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { datum: true }), timeunit_1.TimeUnit.MONTH, '%Y', true, config_1.defaultConfig.timeFormat); + chai_1.assert.equal(expression, "timeFormat(datum[\"yearmonth_a\"], '%Y')"); + }); + it('should get the right time expression for quarter', function () { + var fieldDef = { timeUnit: timeunit_1.TimeUnit.QUARTER, field: 'a', type: type_1.TEMPORAL }; + var expression = common_1.timeFormatExpression(fielddef_1.field(fieldDef, { datum: true }), timeunit_1.TimeUnit.QUARTER, undefined, true, config_1.defaultConfig.timeFormat); + chai_1.assert.equal(expression, "'Q' + quarter(datum[\"quarter_a\"])"); + }); + it('should get the right time expression for yearquarter', function () { + var expression = common_1.timeFormatExpression('datum["data"]', timeunit_1.TimeUnit.YEARQUARTER, undefined, true, config_1.defaultConfig.timeFormat); + chai_1.assert.equal(expression, "'Q' + quarter(datum[\"data\"]) + ' ' + timeFormat(datum[\"data\"], '%y')"); + }); + }); + describe('numberFormat()', function () { + it('should use number format for quantitative scale', function () { + chai_1.assert.equal(common_1.numberFormat({ field: 'a', type: type_1.QUANTITATIVE }, undefined, { numberFormat: 'd' }, channel_1.X), 'd'); + }); + it('should support empty number format', function () { + chai_1.assert.equal(common_1.numberFormat({ field: 'a', type: type_1.QUANTITATIVE }, undefined, { numberFormat: '' }, channel_1.X), ''); + }); + it('should use format if provided', function () { + chai_1.assert.equal(common_1.numberFormat({ field: 'a', type: type_1.QUANTITATIVE }, 'a', 'd', channel_1.X), 'a'); + }); + it('should not use number format for binned quantitative scale', function () { + chai_1.assert.equal(common_1.numberFormat({ bin: true, field: 'a', type: type_1.QUANTITATIVE }, undefined, 'd', channel_1.X), undefined); + }); + it('should not use number format for non-quantitative scale', function () { + for (var _i = 0, _a = [type_1.TEMPORAL, type_1.NOMINAL, type_1.ORDINAL]; _i < _a.length; _i++) { + var type = _a[_i]; + chai_1.assert.equal(common_1.numberFormat({ bin: true, field: 'a', type: type }, undefined, 'd', channel_1.X), undefined); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2NvbXBpbGUvY29tbW9uLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLDZDQUFvQztBQUNwQywyQ0FBK0M7QUFDL0MsK0NBQTRDO0FBQzVDLCtDQUFtRDtBQUNuRCx1Q0FBd0U7QUFDeEUsbURBQTRFO0FBRTVFLFFBQVEsQ0FBQyxRQUFRLEVBQUU7SUFDakIsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMsMEVBQTBFLEVBQUU7WUFDN0UsSUFBTSxRQUFRLEdBQWEsRUFBQyxRQUFRLEVBQUUsbUJBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsZUFBUSxFQUFDLENBQUM7WUFDbEYsSUFBTSxVQUFVLEdBQUcsNkJBQW9CLENBQUMsZ0JBQUssQ0FBQyxRQUFRLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUMsRUFBRSxtQkFBUSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLHNCQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDbkksYUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsc0NBQW9DLENBQUMsQ0FBQztRQUNqRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyRUFBMkUsRUFBRTtZQUM5RSxJQUFNLFFBQVEsR0FBYSxFQUFDLFFBQVEsRUFBRSxtQkFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxlQUFRLEVBQUMsQ0FBQztZQUNsRixJQUFNLFVBQVUsR0FBRyw2QkFBb0IsQ0FBQyxnQkFBSyxDQUFDLFFBQVEsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUMsQ0FBQyxFQUFFLG1CQUFRLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsc0JBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwSSxhQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxzQ0FBb0MsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVFQUF1RSxFQUFFO1lBQzFFLElBQU0sUUFBUSxHQUFhLEVBQUMsUUFBUSxFQUFFLG1CQUFRLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGVBQVEsRUFBQyxDQUFDO1lBQ3RGLElBQU0sVUFBVSxHQUFHLDZCQUFvQixDQUFDLGdCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBQyxDQUFDLEVBQUUsbUJBQVEsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxzQkFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzlILGFBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLDBDQUF3QyxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUU7WUFDckQsSUFBTSxRQUFRLEdBQWEsRUFBQyxRQUFRLEVBQUUsbUJBQVEsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsZUFBUSxFQUFDLENBQUM7WUFDcEYsSUFBTSxVQUFVLEdBQUcsNkJBQW9CLENBQUMsZ0JBQUssQ0FBQyxRQUFRLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUMsRUFBRSxtQkFBUSxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLHNCQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDckksYUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUscUNBQW1DLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRTtZQUN6RCxJQUFNLFVBQVUsR0FBRyw2QkFBb0IsQ0FBQyxlQUFlLEVBQUUsbUJBQVEsQ0FBQyxXQUFXLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxzQkFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzFILGFBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLDBFQUFzRSxDQUFDLENBQUM7UUFDbkcsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixFQUFFLENBQUMsaURBQWlELEVBQUU7WUFDcEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBWSxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsbUJBQVksRUFBQyxFQUFFLFNBQVMsRUFBRSxFQUFDLFlBQVksRUFBRSxHQUFHLEVBQUMsRUFBRSxXQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN2RyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtZQUN2QyxhQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFZLENBQUMsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxtQkFBWSxFQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUMsWUFBWSxFQUFFLEVBQUUsRUFBQyxFQUFFLFdBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3JHLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtCQUErQixFQUFFO1lBQ2xDLGFBQU0sQ0FBQyxLQUFLLENBQUMscUJBQVksQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLG1CQUFZLEVBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLFdBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2pGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDREQUE0RCxFQUFFO1lBQy9ELGFBQU0sQ0FBQyxLQUFLLENBQUMscUJBQVksQ0FBQyxFQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsbUJBQVksRUFBQyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsV0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDeEcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseURBQXlELEVBQUU7WUFDNUQsR0FBRyxDQUFDLENBQWEsVUFBNEIsRUFBNUIsTUFBQyxlQUFRLEVBQUUsY0FBTyxFQUFFLGNBQU8sQ0FBQyxFQUE1QixjQUE0QixFQUE1QixJQUE0QjtnQkFBeEMsSUFBSSxJQUFJLFNBQUE7Z0JBQ1gsYUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBWSxDQUFDLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFdBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQy9GO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/test/compile/compile.test.d.ts b/build/test/compile/compile.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/compile.test.js b/build/test/compile/compile.test.js new file mode 100644 index 0000000000..c9b4c66ba9 --- /dev/null +++ b/build/test/compile/compile.test.js @@ -0,0 +1,90 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../util"); +var log = require("../../src/log"); +var compile_1 = require("../../src/compile/compile"); +describe('Compile', function () { + it('should throw error for invalid spec', function () { + chai_1.assert.throws(function () { + compile_1.compile({}); + }, Error, log.message.INVALID_SPEC); + }); + describe('compile', function () { + it('should return a spec with basic top-level properties, size signals, data and marks', function () { + var spec = compile_1.compile({ + "data": { + "values": [{ "a": "A", "b": 28 }] + }, + "mark": "point", + "encoding": {} + }).spec; + chai_1.assert.equal(spec.padding, 5); + chai_1.assert.equal(spec.autosize, 'pad'); + chai_1.assert.deepEqual(spec.signals, [ + { + name: 'width', + update: "data('layout')[0].width" + }, + { + name: 'height', + update: "data('layout')[0].height" + }, + { + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'group()._id ? group() : unit' }] + } + ]); + chai_1.assert.equal(spec.data.length, 2); // just source and layout + chai_1.assert.equal(spec.marks.length, 1); // just the root group + }); + }); + describe('assembleRootGroup()', function () { + it('produce correct from and size.', function () { + var model = util_1.parseUnitModel({ + "description": "A simple bar chart with embedded data.", + "data": { + "values": [ + { "a": "A", "b": 28 }, { "a": "B", "b": 55 }, { "a": "C", "b": 43 }, + { "a": "D", "b": 91 }, { "a": "E", "b": 81 }, { "a": "F", "b": 53 }, + { "a": "G", "b": 19 }, { "a": "H", "b": 87 }, { "a": "I", "b": 52 } + ] + }, + "mark": "bar", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var rootGroup = compile_1.assembleRootGroup(model); + chai_1.assert.deepEqual(rootGroup.from, { "data": "layout" }); + chai_1.assert.deepEqual(rootGroup.encode.update.width, { field: "width" }); + chai_1.assert.deepEqual(rootGroup.encode.update.height, { field: "height" }); + }); + it('produce correct from and size when a chart name is provided.', function () { + var model = util_1.parseUnitModel({ + "name": "chart", + "description": "A simple bar chart with embedded data.", + "data": { + "values": [ + { "a": "A", "b": 28 }, { "a": "B", "b": 55 }, { "a": "C", "b": 43 }, + { "a": "D", "b": 91 }, { "a": "E", "b": 81 }, { "a": "F", "b": 53 }, + { "a": "G", "b": 19 }, { "a": "H", "b": 87 }, { "a": "I", "b": 52 } + ] + }, + "mark": "bar", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var rootGroup = compile_1.assembleRootGroup(model); + chai_1.assert.deepEqual(rootGroup.from, { "data": "chart_layout" }); + chai_1.assert.deepEqual(rootGroup.encode.update.width, { field: "chart_width" }); + chai_1.assert.deepEqual(rootGroup.encode.update.height, { field: "chart_height" }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC9jb21waWxlL2NvbXBpbGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsZ0NBQXVDO0FBRXZDLG1DQUFxQztBQUVyQyxxREFBcUU7QUFHckUsUUFBUSxDQUFDLFNBQVMsRUFBRTtJQUNsQixFQUFFLENBQUMscUNBQXFDLEVBQUU7UUFDeEMsYUFBTSxDQUFDLE1BQU0sQ0FBQztZQUNaLGlCQUFPLENBQUMsRUFBUyxDQUFDLENBQUM7UUFDckIsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUMsb0ZBQW9GLEVBQUU7WUFDdkYsSUFBTSxJQUFJLEdBQUcsaUJBQU8sQ0FBQztnQkFDbkIsTUFBTSxFQUFFO29CQUNOLFFBQVEsRUFBRSxDQUFDLEVBQUMsR0FBRyxFQUFFLEdBQUcsRUFBQyxHQUFHLEVBQUUsRUFBRSxFQUFDLENBQUM7aUJBQy9CO2dCQUNELE1BQU0sRUFBRSxPQUFPO2dCQUNmLFVBQVUsRUFBRSxFQUFFO2FBQ2YsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUVSLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5QixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUM3QjtvQkFDRSxJQUFJLEVBQUUsT0FBTztvQkFDYixNQUFNLEVBQUUseUJBQXlCO2lCQUNsQztnQkFDRDtvQkFDRSxJQUFJLEVBQUUsUUFBUTtvQkFDZCxNQUFNLEVB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 \ No newline at end of file diff --git a/build/test/compile/data/bin.test.d.ts b/build/test/compile/data/bin.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/bin.test.js b/build/test/compile/data/bin.test.js new file mode 100644 index 0000000000..00c36c07f2 --- /dev/null +++ b/build/test/compile/data/bin.test.js @@ -0,0 +1,72 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var bin_1 = require("../../../src/compile/data/bin"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../util"); +describe('compile/data/bin', function () { + describe('parseUnit', function () { + describe('binned field with custom extent', function () { + it('should add bin transform and correctly apply bin', function () { + var model = util_2.parseUnitModel({ + mark: "point", + encoding: { + y: { + bin: { extent: [0, 100] }, + 'field': 'Acceleration', + 'type': "quantitative" + } + } + }); + var transform = util_1.vals(bin_1.bin.parseUnit(model))[0]; + chai_1.assert.deepEqual(transform[0], { + type: 'bin', + field: 'Acceleration', + as: ['bin_Acceleration_start', 'bin_Acceleration_end'], + maxbins: 10, + extent: [0, 100], + signal: "Acceleration_bins", + }); + }); + }); + describe('binned field without custom extent', function () { + var model = util_2.parseUnitModel({ + mark: "point", + encoding: { + y: { + bin: true, + 'field': 'Acceleration', + 'type': "quantitative" + } + } + }); + var transform = util_1.vals(bin_1.bin.parseUnit(model))[0]; + it('should add bin transform and correctly apply bin', function () { + chai_1.assert.deepEqual(transform[0], { + type: 'extent', + field: 'Acceleration', + signal: 'Acceleration_extent' + }); + chai_1.assert.deepEqual(transform[1], { + type: 'bin', + field: 'Acceleration', + as: ['bin_Acceleration_start', 'bin_Acceleration_end'], + maxbins: 10, + signal: "Acceleration_bins", + extent: { signal: 'Acceleration_extent' } + }); + }); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + // TODO: write test + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9iaW4udGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFFNUIscURBQWtEO0FBQ2xELDBDQUF1QztBQUV2QyxtQ0FBMEM7QUFFMUMsUUFBUSxDQUFDLGtCQUFrQixFQUFFO0lBQzNCLFFBQVEsQ0FBQyxXQUFXLEVBQUU7UUFDcEIsUUFBUSxDQUFDLGlDQUFpQyxFQUFFO1lBQzFDLEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtnQkFDckQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztvQkFDM0IsSUFBSSxFQUFFLE9BQU87b0JBQ2IsUUFBUSxFQUFFO3dCQUNSLENBQUMsRUFBRTs0QkFDRCxHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUM7NEJBQ3ZCLE9BQU8sRUFBRSxjQUFjOzRCQUN2QixNQUFNLEVBQUUsY0FBYzt5QkFDdkI7cUJBQ0Y7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILElBQU0sU0FBUyxHQUFHLFdBQUksQ0FBQyxTQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hELGFBQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUM3QixJQUFJLEVBQUUsS0FBSztvQkFDWCxLQUFLLEVBQUUsY0FBYztvQkFDckIsRUFBRSxFQUFFLENBQUMsd0JBQXdCLEVBQUUsc0JBQXNCLENBQUM7b0JBQ3RELE9BQU8sRUFBRSxFQUFFO29CQUNYLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7b0JBQ2hCLE1BQU0sRUFBRSxtQkFBbUI7aUJBQzVCLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxRQUFRLENBQUMsb0NBQW9DLEVBQUU7WUFDN0MsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRTt3QkFDRCxHQUFHLEVBQUUsSUFBSTt3QkFDVCxPQUFPLEVBQUUsY0FBYzt3QkFDdkIsTUFBTSxFQUFFLGNBQWM7cUJBQ3ZCO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsSUFBTSxTQUFTLEdBQUcsV0FBSSxDQUFDLFNBQUcsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVoRCxFQUFFLENBQUMsa0RBQWtELEVBQUU7Z0JBQ3JELGFBQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUM3QixJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsY0FBYztvQkFDckIsTUFBTSxFQUFFLHFCQUFxQjtpQkFDOUIsQ0FBQyxDQUFDO2dCQUNILGFBQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO29CQUM3QixJQUFJLEVBQUUsS0FBSztvQkFDWCxLQUFLLEVBQUUsY0FBYztvQkFDckIsRUFBRSxFQUFFLENBQUMsd0JBQXdCLEVBQUUsc0JBQXNCLENBQUM7b0JBQ3RELE9BQU8sRUFBRSxFQUFFO29CQUNYLE1BQU0sRUFBRSxtQkFBbUI7b0JBQzNCLE1BQU0sRUFBRSxFQUFDLE1BQU0sRUFBRSxxQkFBcUIsRUFBQztpQkFDeEMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixtQkFBbUI7SUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFO1FBQ3JCLG1CQUFtQjtJQUNyQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsbUJBQW1CO0lBQ3JCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/data/data.test.d.ts b/build/test/compile/data/data.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/data.test.js b/build/test/compile/data/data.test.js new file mode 100644 index 0000000000..cf0ac6a5db --- /dev/null +++ b/build/test/compile/data/data.test.js @@ -0,0 +1,113 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var data_1 = require("../../../src/compile/data/data"); +var util_1 = require("../../util"); +function compileAssembleData(model) { + model.parseData(); + return data_1.assembleData(model, []); +} +describe('data', function () { + describe('compileData & assembleData', function () { + describe('for aggregate encoding', function () { + it('should contain 2 tables', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: 'a', type: "temporal" }, + y: { field: 'b', type: "quantitative", scale: { type: 'log' }, aggregate: 'sum' } + } + }); + var data = compileAssembleData(model); + chai_1.assert.equal(data.length, 2); + }); + }); + describe('when contains log in non-aggregate', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: 'a', type: "temporal" }, + y: { field: 'b', type: "quantitative", scale: { type: 'log' } } + } + }); + var data = compileAssembleData(model); + it('should contains 1 table', function () { + chai_1.assert.equal(data.length, 1); + }); + it('should have filter non-positive in source', function () { + var sourceTransform = data[0].transform; + chai_1.assert.deepEqual(sourceTransform[sourceTransform.length - 1], { + type: 'filter', + expr: 'datum["b"] > 0' + }); + }); + }); + describe('stacked bar chart with binned dimension', function () { + var model = util_1.parseUnitModel({ + "mark": "area", + "encoding": { + "x": { + "bin": { "maxbins": 10 }, + "field": "IMDB_Rating", + "type": "quantitative" + }, + "color": { + "field": "Source", + "type": "nominal" + }, + "y": { + "aggregate": "count", + "type": "quantitative" + } + } + }); + var data = compileAssembleData(model); + it('should contains 3 tables', function () { + chai_1.assert.equal(data.length, 3); + }); + it('should have collect transform as the last transform in stacked', function () { + var stackedTransform = data[2].transform; + chai_1.assert.deepEqual(stackedTransform[stackedTransform.length - 1], { + type: 'collect', + sort: { + "field": "bin_IMDB_Rating_start", + "order": "descending" + } + }); + }); + }); + }); + describe('assemble', function () { + it('should have correct order of transforms (null filter, timeUnit, bin then filter)', function () { + var model = util_1.parseUnitModel({ + transform: { + calculate: [{ + as: 'b2', + expr: '2 * datum["b"]' + }], + filter: 'datum["a"] > datum["b"] && datum["c"] === datum["d"]' + }, + mark: "point", + encoding: { + x: { field: 'a', type: "temporal", timeUnit: 'year' }, + y: { + bin: { + extent: [0, 100] + }, + 'field': 'Acceleration', + 'type': "quantitative" + }, + size: { field: 'b2', type: 'quantitative' } + } + }); + var transform = compileAssembleData(model)[0].transform; + chai_1.assert.deepEqual(transform[0].type, 'formula'); + chai_1.assert.deepEqual(transform[1].type, 'filter'); + chai_1.assert.deepEqual(transform[2].type, 'filter'); + chai_1.assert.deepEqual(transform[3].type, 'bin'); + chai_1.assert.deepEqual(transform[4].type, 'formula'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2RhdGEvZGF0YS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1Qix1REFBNEQ7QUFFNUQsbUNBQTBDO0FBRTFDLDZCQUE2QixLQUFZO0lBQ3ZDLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNsQixNQUFNLENBQUMsbUJBQVksQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVELFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixRQUFRLENBQUMsNEJBQTRCLEVBQUU7UUFDckMsUUFBUSxDQUFDLHdCQUF3QixFQUFFO1lBQ2pDLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtnQkFDNUIsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztvQkFDekIsSUFBSSxFQUFFLE9BQU87b0JBQ2IsUUFBUSxFQUFFO3dCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBQzt3QkFDakMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFDO3FCQUM5RTtpQkFDRixDQUFDLENBQUM7Z0JBRUwsSUFBTSxJQUFJLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3hDLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLG9DQUFvQyxFQUFFO1lBQzdDLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLElB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 \ No newline at end of file diff --git a/build/test/compile/data/datatestutil.d.ts b/build/test/compile/data/datatestutil.d.ts new file mode 100644 index 0000000000..a65a71fb15 --- /dev/null +++ b/build/test/compile/data/datatestutil.d.ts @@ -0,0 +1,2 @@ +import { DataComponent } from '../../../src/compile/data/data'; +export declare function mockDataComponent(): DataComponent; diff --git a/build/test/compile/data/datatestutil.js b/build/test/compile/data/datatestutil.js new file mode 100644 index 0000000000..368b2db548 --- /dev/null +++ b/build/test/compile/data/datatestutil.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// FIXME refactor signature of assemble methods() +function mockDataComponent() { + return { + formatParse: null, + nullFilter: null, + filter: null, + nonPositiveFilter: null, + pathOrder: null, + source: null, + bin: null, + calculate: null, + timeUnit: null, + summary: null, + stack: null + }; +} +exports.mockDataComponent = mockDataComponent; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXRlc3R1dGlsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2RhdGEvZGF0YXRlc3R1dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsaURBQWlEO0FBRWpEO0lBQ0UsTUFBTSxDQUFDO1FBQ0wsV0FBVyxFQUFFLElBQUk7UUFDakIsVUFBVSxFQUFFLElBQUk7UUFDaEIsTUFBTSxFQUFFLElBQUk7UUFDWixpQkFBaUIsRUFBRSxJQUFJO1FBQ3ZCLFNBQVMsRUFBRSxJQUFJO1FBRWYsTUFBTSxFQUFFLElBQUk7UUFDWixHQUFHLEVBQUUsSUFBSTtRQUNULFNBQVMsRUFBRSxJQUFJO1FBQ2YsUUFBUSxFQUFFLElBQUk7UUFDZCxPQUFPLEVBQUUsSUFBSTtRQUNiLEtBQUssRUFBRSxJQUFJO0tBQ1osQ0FBQztBQUNKLENBQUM7QUFmRCw4Q0FlQyJ9 \ No newline at end of file diff --git a/build/test/compile/data/filter.test.d.ts b/build/test/compile/data/filter.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/filter.test.js b/build/test/compile/data/filter.test.js new file mode 100644 index 0000000000..7298fd2caf --- /dev/null +++ b/build/test/compile/data/filter.test.js @@ -0,0 +1,53 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* tslint:disable:quotemark */ +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var filter_1 = require("../../../src/compile/data/filter"); +describe('compile/data/filter', function () { + describe('parseUnit', function () { + it('should return a correct expression for an array of filter', function () { + var model = util_1.parseUnitModel({ + "data": { "values": [] }, + "transform": { + "filter": [ + { field: 'color', equal: 'red' }, + { field: 'color', oneOf: ['red', 'yellow'] }, + { field: 'x', range: [0, 5] }, + 'datum["x"]===5', + { field: 'x', range: [null, null] }, + ] + }, + mark: 'point', + encoding: {} + }); + var expr = filter_1.filter.parseUnit(model); + chai_1.assert.equal(expr, '(datum["color"]==="red") && ' + + '(indexof(["red","yellow"], datum["color"]) !== -1) && ' + + '(inrange(datum["x"], 0, 5)) && ' + + '(datum["x"]===5)'); + }); + it('should return a correct expression for a single filter', function () { + var model = util_1.parseUnitModel({ + "data": { "values": [] }, + "transform": { + "filter": 'datum["x"]===5' + }, + mark: 'point', + encoding: {} + }); + var expr = filter_1.filter.parseUnit(model); + chai_1.assert.equal(expr, 'datum["x"]===5'); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + // TODO: write test + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9maWx0ZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDhCQUE4QjtBQUM5Qiw2QkFBNEI7QUFFNUIsbUNBQTBDO0FBQzFDLDJEQUF3RDtBQUV4RCxRQUFRLENBQUMscUJBQXFCLEVBQUU7SUFDOUIsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsMkRBQTJELEVBQUU7WUFDOUQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsTUFBTSxFQUFFLEVBQUMsUUFBUSxFQUFFLEVBQUUsRUFBQztnQkFDdEIsV0FBVyxFQUFFO29CQUNYLFFBQVEsRUFBRTt3QkFDUixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQzt3QkFDOUIsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsRUFBQzt3QkFDMUMsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQzt3QkFDM0IsZ0JBQWdCO3dCQUNoQixFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFDO3FCQUNsQztpQkFDRjtnQkFDRCxJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUUsRUFBRTthQUNiLENBQUMsQ0FBQztZQUNILElBQU0sSUFBSSxHQUFHLGVBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsOEJBQThCO2dCQUMvQyx3REFBd0Q7Z0JBQ3hELGlDQUFpQztnQkFDakMsa0JBQWtCLENBQUMsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztRQUdILEVBQUUsQ0FBQyx3REFBd0QsRUFBRTtZQUMzRCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixNQUFNLEVBQUUsRUFBQyxRQUFRLEVBQUUsRUFBRSxFQUFDO2dCQUN0QixXQUFXLEVBQUU7b0JBQ1gsUUFBUSxFQUFFLGdCQUFnQjtpQkFDM0I7Z0JBQ0QsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFLEVBQUU7YUFDYixDQUFDLENBQUM7WUFDSCxJQUFNLElBQUksR0FBRyxlQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDckIsbUJBQW1CO0lBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixtQkFBbUI7SUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsVUFBVSxFQUFFO1FBQ25CLG1CQUFtQjtJQUNyQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/test/compile/data/formatparse.test.d.ts b/build/test/compile/data/formatparse.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/formatparse.test.js b/build/test/compile/data/formatparse.test.js new file mode 100644 index 0000000000..5eb2b50a63 --- /dev/null +++ b/build/test/compile/data/formatparse.test.js @@ -0,0 +1,99 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* tslint:disable:quotemark */ +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var formatparse_1 = require("../../../src/compile/data/formatparse"); +describe('compile/data/formatparse', function () { + describe('parseUnit', function () { + it('should return a correct parse for encoding mapping', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "a.json" }, + "mark": "point", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "temporal" }, + "color": { "field": "c", "type": "ordinal" }, + "shape": { "field": "d", "type": "nominal" } + } + }); + var parseComponent = formatparse_1.formatParse.parseUnit(model); + chai_1.assert.deepEqual(parseComponent, { + a: 'number', + b: 'date' + }); + }); + it('should return a correct parse for filtered fields', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "a.json" }, + "transform": { + "filter": [ + { "field": "a", "equal": { year: 2000 } }, + { "field": "b", "oneOf": ["a", "b"] }, + { "field": "c", "range": [{ year: 2000 }, { year: 2001 }] }, + { "field": "d", "range": [1, 2] } + ] + }, + "mark": "point", + encoding: {} + }); + var parseComponent = formatparse_1.formatParse.parseUnit(model); + chai_1.assert.deepEqual(parseComponent, { + a: 'date', + b: 'string', + c: 'date', + d: 'number' + }); + }); + it('should return a correct customized parse.', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "a.json", "format": { "parse": { "c": "number", "d": "date" } } }, + "mark": "point", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "temporal" }, + "color": { "field": "c", "type": "ordinal" }, + "shape": { "field": "c", "type": "nominal" } + } + }); + var parseComponent = formatparse_1.formatParse.parseUnit(model); + chai_1.assert.deepEqual(parseComponent, { + a: 'number', + b: 'date', + c: 'number', + d: 'date' + }); + }); + it('should include parse for all applicable fields, and exclude calculated fields', function () { + var model = util_1.parseUnitModel({ + transform: { + calculate: [ + { as: 'b2', expr: 'datum["b"] * 2' } + ] + }, + mark: "point", + encoding: { + x: { field: 'a', type: "temporal" }, + y: { field: 'b', type: "quantitative" }, + color: { field: '*', type: "quantitative", aggregate: 'count' }, + size: { field: 'b2', type: "quantitative" }, + } + }); + var formatParseComponent = formatparse_1.formatParse.parseUnit(model); + chai_1.assert.deepEqual(formatParseComponent, { + 'a': 'date', + 'b': 'number' + }); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + // TODO: write test + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybWF0cGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL2Zvcm1hdHBhcnNlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw4QkFBOEI7QUFDOUIsNkJBQTRCO0FBRTVCLG1DQUEwQztBQUMxQyxxRUFBa0U7QUFFbEUsUUFBUSxDQUFDLDBCQUEwQixFQUFFO0lBQ25DLFFBQVEsQ0FBQyxXQUFXLEVBQUU7UUFDcEIsRUFBRSxDQUFDLG9EQUFvRCxFQUFFO1lBQ3ZELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUM7Z0JBQ3pCLE1BQU0sRUFBRSxPQUFPO2dCQUNmLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7b0JBQzNDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBQztvQkFDdkMsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFDO29CQUMxQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7aUJBQzNDO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsSUFBTSxjQUFjLEdBQUcseUJBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUM7Z0JBQzlCLENBQUMsRUFBRSxRQUFRO2dCQUNYLENBQUMsRUFBRSxNQUFNO2FBQ1YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbURBQW1ELEVBQUU7WUFDdEQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsTUFB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 \ No newline at end of file diff --git a/build/test/compile/data/formula.test.d.ts b/build/test/compile/data/formula.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/formula.test.js b/build/test/compile/data/formula.test.js new file mode 100644 index 0000000000..1fe2a2a63b --- /dev/null +++ b/build/test/compile/data/formula.test.js @@ -0,0 +1,48 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* tslint:disable:quotemark */ +var chai_1 = require("chai"); +var formula_1 = require("../../../src/compile/data/formula"); +var unit_1 = require("../../../src/compile/unit"); +var util_1 = require("../../../src/util"); +describe('compile/data/formula', function () { + describe('parseUnit', function () { + it('should return a dictionary of formula', function () { + var f = { + "as": "a", + "expr": "5" + }; + var model = new unit_1.UnitModel({ + "data": { "url": "a.json" }, + "transform": { + "calculate": [f] + }, + "mark": "point", + "encoding": {} + }, null, ''); + var formulaComponent = formula_1.formula.parseUnit(model); + var hashed = util_1.hash(f); + var expected = {}; + expected[hashed] = f; + chai_1.assert.deepEqual(formulaComponent, expected); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + // TODO: write test + }); + describe('assemble', function () { + it('should return correct vega formula transform', function () { + chai_1.assert.deepEqual(formula_1.formula.assemble({ + aaa: { as: 'a', expr: '5' } + }), [{ + type: 'formula', + as: 'a', + expr: '5' + }]); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybXVsYS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2RhdGEvZm9ybXVsYS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOEJBQThCO0FBQzlCLDZCQUE0QjtBQUM1Qiw2REFBMEQ7QUFDMUQsa0RBQW9EO0FBQ3BELDBDQUE2QztBQUc3QyxRQUFRLENBQUMsc0JBQXNCLEVBQUU7SUFDL0IsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsSUFBTSxDQUFDLEdBQVk7Z0JBQ2pCLElBQUksRUFBRSxHQUFHO2dCQUNULE1BQU0sRUFBRSxHQUFHO2FBQ1osQ0FBQztZQUNGLElBQU0sS0FBSyxHQUFHLElBQUksZ0JBQVMsQ0FBQztnQkFDMUIsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQztnQkFDekIsV0FBVyxFQUFFO29CQUNYLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztpQkFDakI7Z0JBQ0QsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsVUFBVSxFQUFFLEVBQUU7YUFDZixFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUViLElBQU0sZ0JBQWdCLEdBQUcsaUJBQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEQsSUFBTSxNQUFNLEdBQUcsV0FBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLElBQUksUUFBUSxHQUFHLEVBQUUsQ0FBQztZQUNsQixRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLGFBQU0sQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDckIsbUJBQW1CO0lBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixtQkFBbUI7SUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsVUFBVSxFQUFFO1FBQ25CLEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxhQUFNLENBQUMsU0FBUyxDQUFDLGlCQUFPLENBQUMsUUFBUSxDQUFDO2dCQUNoQyxHQUFHLEVBQUUsRUFBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUM7YUFDVCxDQUFDLEVBQUUsQ0FBQztvQkFDcEIsSUFBSSxFQUFFLFNBQVM7b0JBQ2YsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsSUFBSSxFQUFFLEdBQUc7aUJBQ1YsQ0FBQyxDQUFDLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/data/nonpositivefilter.test.d.ts b/build/test/compile/data/nonpositivefilter.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/nonpositivefilter.test.js b/build/test/compile/data/nonpositivefilter.test.js new file mode 100644 index 0000000000..5de5542312 --- /dev/null +++ b/build/test/compile/data/nonpositivefilter.test.js @@ -0,0 +1,45 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var nonpositivefilter_1 = require("../../../src/compile/data/nonpositivefilter"); +var util_1 = require("../../util"); +describe('compile/data/nonpositivefilter', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: 'a', type: "temporal" }, + y: { field: 'b', type: "quantitative", scale: { type: 'log' } } + } + }); + describe('parseUnit & assemble', function () { + it('should produce the correct nonPositiveFilter component', function () { + model.component.data = {}; + model.component.data.nonPositiveFilter = nonpositivefilter_1.nonPositiveFilter.parseUnit(model); + chai_1.assert.deepEqual(model.component.data.nonPositiveFilter, { + b: true, + a: false + }); + }); + it('should assemble the correct filter transform', function () { + var filterTransform = nonpositivefilter_1.nonPositiveFilter.assemble(model.component.data.nonPositiveFilter)[0]; + chai_1.assert.deepEqual(filterTransform, { + type: 'filter', + expr: 'datum["b"] > 0' + }); + }); + // it('unit (with aggregated log scale)', function() { + // // TODO: write + // }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + // TODO: write test + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9ucG9zaXRpdmVmaWx0ZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL25vbnBvc2l0aXZlZmlsdGVyLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBRTVCLGlGQUE4RTtBQUU5RSxtQ0FBMEM7QUFFMUMsUUFBUSxDQUFDLGdDQUFnQyxFQUFFO0lBQ3pDLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7UUFDM0IsSUFBSSxFQUFFLE9BQU87UUFDYixRQUFRLEVBQUU7WUFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUM7WUFDakMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUMsRUFBQztTQUM1RDtLQUNGLENBQUMsQ0FBQztJQUNILFFBQVEsQ0FBQyxzQkFBc0IsRUFBRTtRQUMvQixFQUFFLENBQUMsd0RBQXdELEVBQUU7WUFDM0QsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztZQUMzQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxxQ0FBaUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUUsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDdkQsQ0FBQyxFQUFFLElBQUk7Z0JBQ1AsQ0FBQyxFQUFFLEtBQUs7YUFDVCxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxJQUFNLGVBQWUsR0FBRyxxQ0FBaUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5RixhQUFNLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRTtnQkFDaEMsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsSUFBSSxFQUFFLGdCQUFnQjthQUN2QixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILHNEQUFzRDtRQUN0RCxtQkFBbUI7UUFDbkIsTUFBTTtJQUNSLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixtQkFBbUI7SUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFO1FBQ3JCLG1CQUFtQjtJQUNyQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsbUJBQW1CO0lBQ3JCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/data/nullfilter.test.d.ts b/build/test/compile/data/nullfilter.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/nullfilter.test.js b/build/test/compile/data/nullfilter.test.js new file mode 100644 index 0000000000..b9a9b0e9ff --- /dev/null +++ b/build/test/compile/data/nullfilter.test.js @@ -0,0 +1,85 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var nullfilter_1 = require("../../../src/compile/data/nullfilter"); +var log = require("../../../src/log"); +var util_1 = require("../../../src/util"); +var util_2 = require("../../util"); +describe('compile/data/nullfilter', function () { + describe('compileUnit', function () { + var spec = { + mark: "point", + encoding: { + y: { field: 'qq', type: "quantitative" }, + x: { field: 'tt', type: "temporal" }, + color: { field: 'oo', type: "ordinal" } + } + }; + it('should add filterNull for Q and T by default', function () { + var model = util_2.parseUnitModel(spec); + chai_1.assert.deepEqual(nullfilter_1.nullFilter.parseUnit(model), { + qq: { field: 'qq', type: "quantitative" }, + tt: { field: 'tt', type: "temporal" }, + oo: null + }); + }); + it('should add filterNull for O when specified', function () { + log.runLocalLogger(function (localLogger) { + var model = util_2.parseUnitModel(util_1.mergeDeep(spec, { + transform: { + filterNull: true + } + })); + chai_1.assert.deepEqual(nullfilter_1.nullFilter.parseUnit(model), { + qq: { field: 'qq', type: "quantitative" }, + tt: { field: 'tt', type: "temporal" }, + oo: { field: 'oo', type: "ordinal" } + }); + chai_1.assert.equal(localLogger.warns[0], log.message.DEPRECATED_FILTER_NULL); + }); + }); + it('should add no null filter if filterInvalid is false', function () { + var model = util_2.parseUnitModel(util_1.mergeDeep(spec, { + transform: { + filterInvalid: false + } + })); + chai_1.assert.deepEqual(nullfilter_1.nullFilter.parseUnit(model), { + qq: null, + tt: null, + oo: null + }); + }); + it('should add no null filter for count field', function () { + log.runLocalLogger(function (localLogger) { + var model = util_2.parseUnitModel({ + transform: { + filterNull: true + }, + mark: "point", + encoding: { + y: { aggregate: 'count', field: '*', type: "quantitative" } + } + }); // as any so we can set deprecated property transform.filterNull + chai_1.assert.deepEqual(nullfilter_1.nullFilter.parseUnit(model), {}); + chai_1.assert.equal(localLogger.warns[0], log.message.DEPRECATED_FILTER_NULL); + }); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + it('should produce child\'s filter if child has no source and the facet has no filter', function () { + // TODO: write + }); + it('should produce child\'s filter and its own filter if child has no source and the facet has filter', function () { + // TODO: write + }); + }); + describe('assemble', function () { + // TODO: write + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVsbGZpbHRlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2RhdGEvbnVsbGZpbHRlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUU1QixtRUFBZ0U7QUFDaEUsc0NBQXdDO0FBRXhDLDBDQUE0QztBQUU1QyxtQ0FBMEM7QUFFMUMsUUFBUSxDQUFDLHlCQUF5QixFQUFFO0lBQ2xDLFFBQVEsQ0FBQyxhQUFhLEVBQUU7UUFDdEIsSUFBTSxJQUFJLEdBQWE7WUFDckIsSUFBSSxFQUFFLE9BQU87WUFDYixRQUFRLEVBQUU7Z0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO2dCQUN0QyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUM7Z0JBQ2xDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzthQUN0QztTQUNGLENBQUM7UUFFRixFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQyxhQUFNLENBQUMsU0FBUyxDQUFDLHVCQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUM1QyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7Z0JBQ3ZDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBQztnQkFDbkMsRUFBRSxFQUFFLElBQUk7YUFDVCxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRTtZQUMvQyxHQUFHLENBQUMsY0FBYyxD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 \ No newline at end of file diff --git a/build/test/compile/data/pathorder.test.d.ts b/build/test/compile/data/pathorder.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/pathorder.test.js b/build/test/compile/data/pathorder.test.js new file mode 100644 index 0000000000..c6515a85f7 --- /dev/null +++ b/build/test/compile/data/pathorder.test.js @@ -0,0 +1,164 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var pathorder_1 = require("../../../src/compile/data/pathorder"); +var util_1 = require("../../util"); +describe('compile/data/pathorder', function () { + describe('compileUnit', function () { + it('should order by order field for line with order (connected scatterplot)', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/driving.json" }, + "mark": "line", + "encoding": { + "x": { "field": "miles", "type": "quantitative", "scale": { "zero": false } }, + "y": { "field": "gas", "type": "quantitative", "scale": { "zero": false } }, + "order": { "field": "year", "type": "temporal" } + } + }); + chai_1.assert.deepEqual(pathorder_1.pathOrder.parseUnit(model), { + field: ['year'], + order: ['ascending'] + }); + }); + it('should order by x by default if x is the dimension', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/movies.json" }, + "mark": "line", + "encoding": { + "x": { + "bin": { "maxbins": 10 }, + "field": "IMDB_Rating", + "type": "quantitative" + }, + "color": { + "field": "Source", + "type": "nominal" + }, + "y": { + "aggregate": "count", + "type": "quantitative" + } + } + }); + chai_1.assert.deepEqual(pathorder_1.pathOrder.parseUnit(model), { + field: 'bin_IMDB_Rating_start', + order: 'descending' + }); + }); + it('should order by x by default if y is the dimension', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/movies.json" }, + "mark": "line", + "encoding": { + "y": { + "bin": { "maxbins": 10 }, + "field": "IMDB_Rating", + "type": "quantitative" + }, + "color": { + "field": "Source", + "type": "nominal" + }, + "x": { + "aggregate": "count", + "type": "quantitative" + } + } + }); + chai_1.assert.deepEqual(pathorder_1.pathOrder.parseUnit(model), { + field: 'bin_IMDB_Rating_start', + order: 'descending' + }); + }); + }); + describe('parseLayer', function () { + it('should return line order for line when merging line and point', function () { + var model = util_1.parseFacetModel({ + "data": { "url": "data/movies.json" }, + "facet": { + "column": { + "field": "Source", + "type": "nominal" + } + }, + "spec": { + "mark": "line", + "encoding": { + "y": { + "bin": { "maxbins": 10 }, + "field": "IMDB_Rating", + "type": "quantitative" + }, + "x": { + "aggregate": "count", + "type": "quantitative" + } + } + } + }); + var child = model.child; + child.component.data = { + pathOrder: pathorder_1.pathOrder.parseUnit(child) + }; + chai_1.assert.deepEqual(pathorder_1.pathOrder.parseFacet(model), { + field: 'bin_IMDB_Rating_start', + order: 'descending' + }); + }); + }); + describe('parseFacet', function () { + it('should return line order for line for faceted line', function () { + var model = util_1.parseModel({ + "data": { "url": "data/movies.json" }, + "mark": "line", + "encoding": { + "y": { + "bin": { "maxbins": 10 }, + "field": "IMDB_Rating", + "type": "quantitative" + }, + "color": { + "field": "Source", + "type": "nominal" + }, + "x": { + "aggregate": "count", + "type": "quantitative" + } + }, + "config": { + "overlay": { + "line": true + } + } + }); + var children = model.children; + children[0].component.data = { + pathOrder: pathorder_1.pathOrder.parseUnit(children[0]) + }; + children[1].component.data = { + pathOrder: pathorder_1.pathOrder.parseUnit(children[1]) + }; + chai_1.assert.deepEqual(pathorder_1.pathOrder.parseLayer(model), { + field: 'bin_IMDB_Rating_start', + order: 'descending' + }); + }); + }); + describe('assemble', function () { + it('should correctly assemble a collect transform', function () { + chai_1.assert.deepEqual(pathorder_1.pathOrder.assemble({ + field: 'a', + order: 'ascending' + }), { + type: 'collect', + sort: { + field: 'a', + order: 'ascending' + } + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aG9yZGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9wYXRob3JkZXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFFNUIsaUVBQThEO0FBRTlELG1DQUF1RTtBQUV2RSxRQUFRLENBQUMsd0JBQXdCLEVBQUU7SUFDakMsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixFQUFFLENBQUMseUVBQXlFLEVBQUU7WUFDNUUsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLG1CQUFtQixFQUFDO2dCQUNwQyxNQUFNLEVBQUUsTUFBTTtnQkFDZCxVQUFVLEVBQUU7b0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsRUFBQztvQkFDeEUsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsRUFBQztvQkFDdEUsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFDO2lCQUM5QzthQUNGLENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxTQUFTLENBQUMscUJBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzNDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQztnQkFDZixLQUFLLEVBQUUsQ0FBQyxXQUFXLENBQUM7YUFDckIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFD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 \ No newline at end of file diff --git a/build/test/compile/data/source.test.d.ts b/build/test/compile/data/source.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/source.test.js b/build/test/compile/data/source.test.js new file mode 100644 index 0000000000..010c171305 --- /dev/null +++ b/build/test/compile/data/source.test.js @@ -0,0 +1,129 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var source_1 = require("../../../src/compile/data/source"); +var util_1 = require("../../util"); +describe('compile/data/source', function () { + describe('compileUnit', function () { + describe('with explicit values', function () { + var model = util_1.parseUnitModel({ + data: { + values: [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }] + }, + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + it('should have values', function () { + chai_1.assert.equal(sourceComponent.name, 'source'); + chai_1.assert.deepEqual(sourceComponent.values, [{ a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }]); + }); + it('should have source.format.type', function () { + chai_1.assert.deepEqual(sourceComponent.format.type, 'json'); + }); + }); + describe('with link to url', function () { + var model = util_1.parseUnitModel({ + data: { + url: 'http://foo.bar', + }, + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + it('should have format.type json', function () { + chai_1.assert.equal(sourceComponent.name, 'source'); + chai_1.assert.equal(sourceComponent.format.type, 'json'); + }); + it('should have correct url', function () { + chai_1.assert.equal(sourceComponent.url, 'http://foo.bar'); + }); + }); + describe('with no data specified', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + it('should provide placeholder source data', function () { + chai_1.assert.deepEqual(sourceComponent, { name: 'source' }); + }); + }); + describe('with named data source provided', function () { + var model = util_1.parseUnitModel({ + data: { name: 'foo' }, + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + it('should provide named source data', function () { + chai_1.assert.deepEqual(sourceComponent, { name: 'foo' }); + }); + }); + describe('data format', function () { + describe('json', function () { + it('should include property if specified', function () { + var model = util_1.parseUnitModel({ + data: { + url: 'http://foo.bar', + format: { type: 'json', property: 'baz' } + }, + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + chai_1.assert.equal(sourceComponent.format.property, 'baz'); + }); + }); + describe('topojson', function () { + describe('feature property is specified', function () { + var model = util_1.parseUnitModel({ + data: { + url: 'http://foo.bar', + format: { type: 'topojson', feature: 'baz' } + }, + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + it('should have format.type topojson', function () { + chai_1.assert.equal(sourceComponent.name, 'source'); + chai_1.assert.equal(sourceComponent.format.type, 'topojson'); + }); + it('should have format.feature baz', function () { + chai_1.assert.equal(sourceComponent.format.feature, 'baz'); + }); + }); + describe('mesh property is specified', function () { + var model = util_1.parseUnitModel({ + data: { + url: 'http://foo.bar', + format: { type: 'topojson', mesh: 'baz' } + }, + mark: 'point', + encoding: {} + }); + var sourceComponent = source_1.source.parseUnit(model); + it('should have format.type topojson', function () { + chai_1.assert.equal(sourceComponent.name, 'source'); + chai_1.assert.equal(sourceComponent.format.type, 'topojson'); + }); + it('should have format.mesh baz', function () { + chai_1.assert.equal(sourceComponent.format.mesh, 'baz'); + }); + }); + }); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + // TODO: write test + }); + describe('assemble', function () { + // TODO: write test + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvZGF0YS9zb3VyY2UudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFFNUIsMkRBQXdEO0FBRXhELG1DQUEwQztBQUUxQyxRQUFRLENBQUMscUJBQXFCLEVBQUU7SUFDOUIsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixRQUFRLENBQUMsc0JBQXNCLEVBQUU7WUFDL0IsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFO29CQUNKLE1BQU0sRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUMsRUFBRSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUM7aUJBQzdDO2dCQUNELElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRSxFQUFFO2FBQ2IsQ0FBQyxDQUFDO1lBRUgsSUFBTSxlQUFlLEdBQUcsZUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVoRCxFQUFFLENBQUMsb0JBQW9CLEVBQUU7Z0JBQ3ZCLGFBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDN0MsYUFBTSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDLENBQUMsRUFBQyxFQUFFLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakYsQ0FB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 \ No newline at end of file diff --git a/build/test/compile/data/stack.test.d.ts b/build/test/compile/data/stack.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/stack.test.js b/build/test/compile/data/stack.test.js new file mode 100644 index 0000000000..9af8b83b56 --- /dev/null +++ b/build/test/compile/data/stack.test.js @@ -0,0 +1,304 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var stack_1 = require("../../../src/compile/data/stack"); +var datatestutil_1 = require("./datatestutil"); +var util_1 = require("../../util"); +describe('compile/data/stack', function () { + describe('parseUnit', function () { + it('should not produce stack component for unit without stack', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": {} + }); + var stackComponent = stack_1.stack.parseUnit(model); + chai_1.assert.equal(stackComponent, undefined); + }); + }); + it('should produce correct stack component for bar with color', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + var stackComponent = stack_1.stack.parseUnit(model); + chai_1.assert.deepEqual(stackComponent, { + name: 'stacked', + source: 'summary', + groupby: ['b'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false + }); + }); + it('should produce correct stack component with both start and end of the binned field for bar with color and binned y', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "bin": true, "field": "b", "type": "quantitative" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + var stackComponent = stack_1.stack.parseUnit(model); + chai_1.assert.deepEqual(stackComponent, { + name: 'stacked', + source: 'summary', + groupby: ['bin_b_start', 'bin_b_end'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false + }); + }); + it('should produce correct stack component for 1D bar with color', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "c", "type": "ordinal", } + } + }); + model.component.data = {}; + model.component.data.stack = stack_1.stack.parseUnit(model); + var stackComponent = model.component.data.stack; + chai_1.assert.deepEqual(stackComponent, { + name: 'stacked', + source: 'summary', + groupby: [], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: false + }); + }); + it('should produce correct stack component for area with color and order', function () { + var model = util_1.parseUnitModel({ + "mark": "area", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "nominal" }, + "order": { "aggregate": "mean", "field": "d", "type": "quantitative" } + } + }); + var stackComponent = stack_1.stack.parseUnit(model); + chai_1.assert.deepEqual(stackComponent, { + name: 'stacked', + source: 'summary', + groupby: ['b'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + offset: 'zero', + impute: true + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + it('should produce correct stack component for trellis colored bar', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { "field": "d", "type": "nominal" } + }, + spec: { + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "nominal" } + } + } + }); + var child = model.child; + child.component.data = datatestutil_1.mockDataComponent(); + child.component.data.stack = { + name: 'stacked', + source: 'summary', + groupby: ['b'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: true + }; + var stackComponent = stack_1.stack.parseFacet(model); + chai_1.assert.deepEqual(stackComponent, { + name: 'stacked', + source: 'summary', + groupby: ['b', 'd'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: true + }); + }); + it('should produce correct stack component for trellis colored bar with faceted y', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { "field": "b", "type": "nominal" } + }, + spec: { + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" }, + "color": { "field": "c", "type": "nominal" } + } + } + }); + var child = model.child; + child.component.data = datatestutil_1.mockDataComponent(); + child.component.data.stack = { + name: 'stacked', + source: 'summary', + groupby: ['b'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: true + }; + var stackComponent = stack_1.stack.parseFacet(model); + chai_1.assert.deepEqual(stackComponent, { + name: 'stacked', + source: 'summary', + groupby: ['b'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['c'], + order: ['descending'] + }, + offset: 'zero', + impute: true + }); + }); + it('should produce correct stack component for trellis non-stacked bar', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { "field": "d", "type": "nominal" } + }, + spec: { + "mark": "bar", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "y": { "field": "b", "type": "nominal" } + } + } + }); + var child = model.child; + child.component.data = datatestutil_1.mockDataComponent(); + child.component.data.stack = undefined; + var stackComponent = stack_1.stack.parseFacet(model); + chai_1.assert.equal(stackComponent, undefined); + }); + }); + describe('assemble', function () { + it('should assemble correct imputed stack data source', function () { + var stackData = stack_1.stack.assemble({ + name: 'stacked', + source: 'summary', + groupby: ['bin_b_start'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + offset: 'zero', + impute: true + }); + chai_1.assert.deepEqual(stackData, { + name: 'stacked', + source: 'summary', + transform: [ + { + type: 'impute', + field: 'sum_a', + groupby: ['c'], + orderby: ['bin_b_start'], + method: "value", + value: 0 + }, + { + type: 'stack', + groupby: ['bin_b_start'], + field: 'sum_a', + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + as: ['sum_a_start', 'sum_a_end'], + offset: 'zero' + } + ] + }); + }); + it('should assemble correct unimputed stack data source', function () { + var stackData = stack_1.stack.assemble({ + name: 'stacked', + source: 'summary', + groupby: ['bin_b_start'], + field: 'sum_a', + stackby: ['c'], + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + offset: 'zero', + impute: false + }); + chai_1.assert.deepEqual(stackData, { + name: 'stacked', + source: 'summary', + transform: [ + { + type: 'stack', + groupby: ['bin_b_start'], + field: 'sum_a', + sort: { + field: ['mean_d'], + order: ['ascending'] + }, + as: ['sum_a_start', 'sum_a_end'], + offset: 'zero' + } + ] + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2sudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL3N0YWNrLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBRTVCLHlEQUFzRDtBQUd0RCwrQ0FBaUQ7QUFDakQsbUNBQTJEO0FBRTNELFFBQVEsQ0FBQyxvQkFBb0IsRUFBRTtJQUM3QixRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLEVBQUUsQ0FBQywyREFBMkQsRUFBRTtZQUM5RCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixNQUFNLEVBQUUsT0FBTztnQkFDZixVQUFVLEVBQUUsRUFBRTthQUNmLENBQUMsQ0FBQztZQUNILElBQU0sY0FBYyxHQUFHLGFBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDOUMsYUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywyREFBMkQsRUFBRTtRQUM5RCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1lBQzNCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMvRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7Z0JBQ3RDLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsR0FBRTthQUM1QztTQUNGLENBQUMsQ0FBQztRQUVILElBQU0sY0FBYyxHQUFHLGFBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUMs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 \ No newline at end of file diff --git a/build/test/compile/data/summary.test.d.ts b/build/test/compile/data/summary.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/summary.test.js b/build/test/compile/data/summary.test.js new file mode 100644 index 0000000000..0c7ed026a9 --- /dev/null +++ b/build/test/compile/data/summary.test.js @@ -0,0 +1,123 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var summary_1 = require("../../../src/compile/data/summary"); +var util_1 = require("../../util"); +describe('compile/data/summary', function () { + describe('parseUnit', function () { + it('should produce the correct summary component for sum(Acceleration) and count(*)', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'y': { + 'aggregate': 'sum', + 'field': 'Acceleration', + 'type': "quantitative" + }, + 'x': { + 'field': 'Origin', + 'type': "ordinal" + }, + color: { field: '*', type: "quantitative", aggregate: 'count' } + } + }); + model.component.data = {}; + model.component.data.summary = summary_1.summary.parseUnit(model); + chai_1.assert.deepEqual(model.component.data.summary, [{ + name: 'summary', + // source will be added in assemble step + dimensions: { Origin: true }, + measures: { '*': { count: true }, Acceleration: { sum: true } } + }]); + }); + it('should produce the correct summary component for aggregated plot with detail arrays', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative" }, + 'detail': [ + { 'field': 'Origin', 'type': "ordinal" }, + { 'field': 'Cylinders', 'type': "quantitative" } + ] + } + }); + model.component.data = {}; + model.component.data.summary = summary_1.summary.parseUnit(model); + chai_1.assert.deepEqual(model.component.data.summary, [{ + name: 'summary', + // source will be added in assemble step + dimensions: { Origin: true, Cylinders: true }, + measures: { Displacement: { mean: true } } + }]); + }); + it('should add min and max if needed for unaggregated scale domain', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + 'x': { 'aggregate': 'mean', 'field': 'Displacement', 'type': "quantitative", scale: { domain: 'unaggregated' } }, + } + }); + model.component.data = {}; + model.component.data.summary = summary_1.summary.parseUnit(model); + chai_1.assert.deepEqual(model.component.data.summary, [{ + name: 'summary', + // source will be added in assemble step + dimensions: {}, + measures: { Displacement: { mean: true, min: true, max: true } } + }]); + }); + }); + describe('parseLayer', function () { + // TODO: write test + }); + describe('parseFacet', function () { + it('should produce child\'s filter if child has no source and the facet has no filter', function () { + // TODO: write + }); + it('should produce child\'s filter and its own filter if child has no source and the facet has filter', function () { + // TODO: write + }); + }); + describe('assemble', function () { + it('should assemble the correct summary data', function () { + var summaryComponent = [{ + name: 'summary', + // source will be added in assemble step + dimensions: { Origin: true }, + measures: { '*': { count: true }, Acceleration: { sum: true } } + }]; + var summaryData = summary_1.summary.assemble(summaryComponent, 'source')[0]; + chai_1.assert.deepEqual(summaryData, { + 'name': "summary", + 'source': 'source', + 'transform': [{ + 'type': 'aggregate', + 'groupby': ['Origin'], + 'fields': ['*', 'Acceleration',], + 'ops': ['count', 'sum',] + }] + }); + }); + it('should assemble the correct summary data', function () { + var summaryComponent = [{ + name: 'summary', + // source will be added in assemble step + dimensions: { Origin: true, Cylinders: true }, + measures: { Displacement: { mean: true } } + }]; + var summaryData = summary_1.summary.assemble(summaryComponent, 'source')[0]; + chai_1.assert.deepEqual(summaryData, { + 'name': "summary", + 'source': 'source', + 'transform': [{ + 'type': 'aggregate', + 'groupby': ['Origin', 'Cylinders'], + 'fields': ['Displacement'], + 'ops': ['mean'] + }] + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VtbWFyeS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL2RhdGEvc3VtbWFyeS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUc1Qiw2REFBMEQ7QUFDMUQsbUNBQTBDO0FBRTFDLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRTtJQUMvQixRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLEVBQUUsQ0FBQyxpRkFBaUYsRUFBRztZQUNyRixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsR0FBRyxFQUFFO3dCQUNILFdBQVcsRUFBRSxLQUFLO3dCQUNsQixPQUFPLEVBQUUsY0FBYzt3QkFDdkIsTUFBTSxFQUFFLGNBQWM7cUJBQ3ZCO29CQUNELEdBQUcsRUFBRTt3QkFDSCxPQUFPLEVBQUUsUUFBUTt3QkFDakIsTUFBTSxFQUFFLFNBQVM7cUJBQ2xCO29CQUNELEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFDO2lCQUM5RDthQUNGLENBQUMsQ0FBQztZQUVILEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLEVBQW1CLENBQUM7WUFDM0MsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLGlCQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQzlDLElBQUksRUFBRSxTQUFTO29CQUNmLHdDQUF3QztvQkFDeEMsVUFBVSxFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztvQkFDMUIsUUFBUSxFQUFFLEVBQUMsR0FB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 \ No newline at end of file diff --git a/build/test/compile/data/timeunit.test.d.ts b/build/test/compile/data/timeunit.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/data/timeunit.test.js b/build/test/compile/data/timeunit.test.js new file mode 100644 index 0000000000..905b80fb65 --- /dev/null +++ b/build/test/compile/data/timeunit.test.js @@ -0,0 +1,37 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var timeunit_1 = require("../../../src/compile/data/timeunit"); +describe('compile/data/timeunit', function () { + describe('parseUnit', function () { + it('should return a dictionary of formula transform', function () { + var model = util_1.parseUnitModel({ + "data": { "values": [] }, + "mark": "point", + "encoding": { + "x": { field: 'a', type: 'temporal', timeUnit: 'month' } + } + }); + var timeUnitComponent = timeunit_1.timeUnit.parseUnit(model); + chai_1.assert.deepEqual(timeUnitComponent, { + month_a: { + type: 'formula', + as: 'month_a', + expr: 'datetime(0, month(datum["a"]), 1, 0, 0, 0, 0)' + } + }); + }); + }); + describe('parseFacet', function () { + // TODO: + }); + describe('parseLayer', function () { + // TODO: + }); + describe('assemble', function () { + // TODO: + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9kYXRhL3RpbWV1bml0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLG1DQUEwQztBQUMxQywrREFBNEQ7QUFFNUQsUUFBUSxDQUFDLHVCQUF1QixFQUFFO0lBQ2hDLFFBQVEsQ0FBQyxXQUFXLEVBQUU7UUFFcEIsRUFBRSxDQUFDLGlEQUFpRCxFQUFFO1lBRXBELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLE1BQU0sRUFBRSxFQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUM7Z0JBQ3RCLE1BQU0sRUFBRSxPQUFPO2dCQUNmLFVBQVUsRUFBRTtvQkFDVixHQUFHLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBQztpQkFDdkQ7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFNLGlCQUFpQixHQUFHLG1CQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BELGFBQU0sQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQ2hDO2dCQUNFLE9BQU8sRUFBRTtvQkFDUCxJQUFJLEVBQUUsU0FBUztvQkFDZixFQUFFLEVBQUUsU0FBUztvQkFDYixJQUFJLEVBQUUsK0NBQStDO2lCQUN0RDthQUNGLENBQ0YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFO1FBQ3JCLFFBQVE7SUFDVixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDckIsUUFBUTtJQUNWLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFVBQVUsRUFBRTtRQUNuQixRQUFRO0lBQ1YsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/compile/facet.test.d.ts b/build/test/compile/facet.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/facet.test.js b/build/test/compile/facet.test.js new file mode 100644 index 0000000000..aecb67a617 --- /dev/null +++ b/build/test/compile/facet.test.js @@ -0,0 +1,367 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../../src/log"); +var facet_1 = require("../../src/compile/facet"); +var facet = require("../../src/compile/facet"); +var channel_1 = require("../../src/channel"); +var config_1 = require("../../src/config"); +var mark_1 = require("../../src/mark"); +var type_1 = require("../../src/type"); +var util_1 = require("../util"); +describe('FacetModel', function () { + it('should say it is facet', function () { + var model = new facet_1.FacetModel({ facet: {}, spec: { + mark: mark_1.POINT, + encoding: {} + } }, null, null); + chai_1.assert(!model.isUnit()); + chai_1.assert(model.isFacet()); + chai_1.assert(!model.isLayer()); + }); + describe('initFacet', function () { + it('should drop unsupported channel and throws warning', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseFacetModel({ + facet: ({ + shape: { field: 'a', type: 'quantitative' } + }), + spec: { + mark: 'point', + encoding: {} + } + }); + chai_1.assert.equal(model.facet['shape'], undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.incompatibleChannel(channel_1.SHAPE, 'facet')); + }); + }); + it('should drop channel without field and value and throws warning', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseFacetModel({ + facet: { + row: { type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + chai_1.assert.equal(model.facet.row, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: type_1.ORDINAL }, channel_1.ROW)); + }); + }); + it('should drop channel without field and value and throws warning', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'quantitative' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + chai_1.assert.deepEqual(model.facet.row, { field: 'a', type: 'quantitative' }); + chai_1.assert.equal(localLogger.warns[0], log.message.facetChannelShouldBeDiscrete(channel_1.ROW)); + }); + }); + }); + describe('spacing', function () { + it('should return specified spacing if specified', function () { + chai_1.assert.equal(facet.spacing({ spacing: 123 }, null, null), 123); + }); + it('should return default facetSpacing if there is a subplot and no specified spacing', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + } + }); + chai_1.assert.equal(facet.spacing({}, model, config_1.defaultConfig), config_1.defaultConfig.scale.facetSpacing); + }); + it('should return 0 if it is a simple table without subplot with x/y and no specified spacing', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "color": { "field": "site", "type": "nominal" } + } + } + }); + chai_1.assert.equal(facet.spacing({}, model, config_1.defaultConfig), 0); + }); + }); + describe('dataTable', function () { + it('should return stacked if there is a stacked data component', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + } + }); + // Mock + model.component.data = { stack: {} }; + chai_1.assert.equal(model.dataTable(), 'stacked'); + }); + it('should return summary if there is a summary data component and no stacked', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" } + } + } + }); + // Mock + model.component.data = { summary: [{ + measures: { a: 1 } + }] }; + chai_1.assert.equal(model.dataTable(), 'summary'); + }); + it('should return source if there is no stacked nor summary data component', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "x": { "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" } + } + } + }); + // Mock + model.component.data = { summary: [] }; + chai_1.assert.equal(model.dataTable(), 'source'); + }); + }); +}); +describe('compile/facet', function () { + describe('assembleAxesGroupData', function () { + it('should output row-source when there is row', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + // HACK: mock that we have parsed its data and there is no stack and no summary + // This way, we won't have surge in test coverage for the parse methods. + model.component.data = {}; + model['hasSummary'] = function () { return false; }; + chai_1.assert.deepEqual(facet.assembleAxesGroupData(model, []), [{ + name: facet.ROW_AXES_DATA_PREFIX + 'source', + source: 'source', + transform: [{ + type: 'aggregate', + groupby: ['a'] + }] + }]); + }); + it('should output column-source when there is column', function () { + var model = util_1.parseFacetModel({ + facet: { + column: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + // HACK: mock that we have parsed its data and there is no stack and no summary + // This way, we won't have surge in test coverage for the parse methods. + model.component.data = {}; + model['hasSummary'] = function () { return false; }; + chai_1.assert.deepEqual(facet.assembleAxesGroupData(model, []), [{ + name: facet.COLUMN_AXES_DATA_PREFIX + 'source', + source: 'source', + transform: [{ + type: 'aggregate', + groupby: ['a'] + }] + }]); + }); + it('should output row- and column-source when there are both row and column', function () { + var model = util_1.parseFacetModel({ + facet: { + column: { field: 'a', type: 'ordinal' }, + row: { field: 'b', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: {} + } + }); + // HACK: mock that we have parsed its data and there is no stack and no summary + // This way, we won't have surge in test coverage for the parse methods. + model.component.data = {}; + model['hasSummary'] = function () { return false; }; + chai_1.assert.deepEqual(facet.assembleAxesGroupData(model, []), [{ + name: facet.COLUMN_AXES_DATA_PREFIX + 'source', + source: 'source', + transform: [{ + type: 'aggregate', + groupby: ['a'] + }] + }, { + name: facet.ROW_AXES_DATA_PREFIX + 'source', + source: 'source', + transform: [{ + type: 'aggregate', + groupby: ['b'] + }] + }]); + }); + }); + describe('getSharedAxisGroup', function () { + describe('column-only', function () { + var model = util_1.parseFacetModel({ + facet: { + column: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + // HACK: mock that we have parsed its data and there is no stack and no summary + // This way, we won't have surge in test coverage for the parse methods. + model.component.data = {}; + model['hasSummary'] = function () { return false; }; + describe('xAxisGroup', function () { + var xSharedAxisGroup = facet.getSharedAxisGroup(model, 'x'); + it('should have correct type, name, and data source', function () { + chai_1.assert.equal(xSharedAxisGroup.name, 'x-axes'); + chai_1.assert.equal(xSharedAxisGroup.type, 'group'); + chai_1.assert.deepEqual(xSharedAxisGroup.from, { data: 'column-source' }); + }); + it('should have width = child width, height = group height, x = column field', function () { + chai_1.assert.deepEqual(xSharedAxisGroup.encode.update.width, { field: { parent: 'child_width' } }); + chai_1.assert.deepEqual(xSharedAxisGroup.encode.update.height, { field: { group: 'height' } }); + chai_1.assert.deepEqual(xSharedAxisGroup.encode.update.x, { scale: 'column', field: 'a', offset: 8 }); + }); + }); + describe('yAxisGroup', function () { + var ySharedAxisGroup = facet.getSharedAxisGroup(model, 'y'); + it('should have correct type, name, and data source', function () { + chai_1.assert.equal(ySharedAxisGroup.name, 'y-axes'); + chai_1.assert.equal(ySharedAxisGroup.type, 'group'); + chai_1.assert.equal(ySharedAxisGroup.from, undefined); + }); + it('should have height = child height, width = group width, y = defaultFacetSpacing / 2.', function () { + chai_1.assert.deepEqual(ySharedAxisGroup.encode.update.height, { field: { parent: 'child_height' } }); + chai_1.assert.deepEqual(ySharedAxisGroup.encode.update.width, { field: { group: 'width' } }); + chai_1.assert.deepEqual(ySharedAxisGroup.encode.update.y, { value: 8 }); + }); + }); + }); + describe('row-only', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + x: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' } + } + } + }); + // HACK: mock that we have parsed its data and there is no stack and no summary + // This way, we won't have surge in test coverage for the parse methods. + model.component.data = {}; + model['hasSummary'] = function () { return false; }; + describe('yAxisGroup', function () { + var ySharedAxisGroup = facet.getSharedAxisGroup(model, 'y'); + it('should have correct type, name, and data source', function () { + chai_1.assert.equal(ySharedAxisGroup.name, 'y-axes'); + chai_1.assert.equal(ySharedAxisGroup.type, 'group'); + chai_1.assert.deepEqual(ySharedAxisGroup.from, { data: 'row-source' }); + }); + it('should have height = child height, width = group width, y= row field', function () { + chai_1.assert.deepEqual(ySharedAxisGroup.encode.update.height, { field: { parent: 'child_height' } }); + chai_1.assert.deepEqual(ySharedAxisGroup.encode.update.width, { field: { group: 'width' } }); + chai_1.assert.deepEqual(ySharedAxisGroup.encode.update.y, { scale: 'row', field: 'a', offset: 8 }); + }); + }); + describe('xAxisGroup', function () { + var xSharedAxisGroup = facet.getSharedAxisGroup(model, 'x'); + it('should have correct type, name, and data source', function () { + chai_1.assert.equal(xSharedAxisGroup.name, 'x-axes'); + chai_1.assert.equal(xSharedAxisGroup.type, 'group'); + chai_1.assert.equal(xSharedAxisGroup.from, undefined); + }); + it('should have width = child width, height = group height, x, x = defaultFacetSpacing / 2.', function () { + chai_1.assert.deepEqual(xSharedAxisGroup.encode.update.width, { field: { parent: 'child_width' } }); + chai_1.assert.deepEqual(xSharedAxisGroup.encode.update.height, { field: { group: 'height' } }); + chai_1.assert.deepEqual(xSharedAxisGroup.encode.update.x, { value: 8 }); + }); + }); + }); + }); + describe('initAxis', function () { + it('should include properties of VlOnlyAxisConfig in config.facet.axis', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + }, + }, + config: { "facet": { "axis": { "labelMaxLength": 123 } } } + }); + chai_1.assert.deepEqual(model.axis(channel_1.ROW), { "labelMaxLength": 123, "orient": "right", "labelAngle": 90 }); + }); + it('should not include properties of non-VlOnlyAxisConfig in config.facet.axis', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'ordinal' } + }, + spec: { + mark: 'point', + encoding: { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + }, + }, + config: { "facet": { "axis": { "domainWidth": 123 } } } + }); + chai_1.assert.deepEqual(model.axis(channel_1.ROW), { "orient": "right", "labelAngle": 90 }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjZXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvY29tcGlsZS9mYWNldC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUU1QixtQ0FBcUM7QUFFckMsaURBQW1EO0FBQ25ELCtDQUFpRDtBQUNqRCw2Q0FBNkM7QUFDN0MsMkNBQStDO0FBQy9DLHVDQUFxQztBQUdyQyx1Q0FBdUM7QUFDdkMsZ0NBQXdDO0FBRXhDLFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFDckIsRUFBRSxDQUFDLHdCQUF3QixFQUFFO1FBQzNCLElBQU0sS0FBSyxHQUFHLElBQUksa0JBQVUsQ0FBQyxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFO2dCQUM3QyxJQUFJLEVBQUUsWUFBSztnQkFDWCxRQUFRLEVBQUUsRUFBRTthQUNiLEVBQWMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDN0IsYUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDeEIsYUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3hCLGFBQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzNCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsb0RBQW9ELEVBQUU7WUFDdkQsR0FBRyxDQUFDLGNBQWMsQ0FBQyxVQUFDLFdBQVc7Z0JBQzdCLElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7b0JBQzVCLEtBQUssRUFBRSxDQUFDO3dCQUNOLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztxQkFDMUMsQ0FBVTtvQkFDWCxJQUFJLEVBQUU7d0JBQ0osSUFBSSxFQUFFLE9BQU87d0JBQ2IsUUFBUSxF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 \ No newline at end of file diff --git a/build/test/compile/layer.test.d.ts b/build/test/compile/layer.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/layer.test.js b/build/test/compile/layer.test.js new file mode 100644 index 0000000000..8d316d81df --- /dev/null +++ b/build/test/compile/layer.test.js @@ -0,0 +1,69 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var layer_1 = require("../../src/compile/layer"); +var util_1 = require("../util"); +describe('Layer', function () { + it('should say it is layer', function () { + var model = new layer_1.LayerModel({ layer: [] }, null, null); + chai_1.assert(!model.isUnit()); + chai_1.assert(!model.isFacet()); + chai_1.assert(model.isLayer()); + }); + describe('merge scale domains', function () { + it('should merge domains', function () { + var model = util_1.parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'ordinal' } + } + }] + }); + chai_1.assert.equal(model.children.length, 2); + model.parseScale(); + chai_1.assert.deepEqual(model.component.scales['x'].domain, { + fields: [{ + data: 'layer_0_source', + field: 'a' + }, { + data: 'layer_1_source', + field: 'b' + }], + sort: true + }); + }); + it('should union explicit and referenced domains', function () { + var model = util_1.parseLayerModel({ + layer: [{ + mark: 'point', + encoding: { + x: { scale: { domain: [1, 2, 3] }, field: 'b', type: 'ordinal' } + } + }, { + mark: 'point', + encoding: { + x: { field: 'b', type: 'ordinal' } + } + }] + }); + model.parseScale(); + chai_1.assert.deepEqual(model.component.scales['x'].domain, { + fields: [ + [1, 2, 3], + { + data: 'layer_1_source', + field: 'b' + } + ], + sort: true + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sYXllci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBRTVCLGlEQUFtRDtBQUVuRCxnQ0FBd0M7QUFFeEMsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixFQUFFLENBQUMsd0JBQXdCLEVBQUU7UUFDM0IsSUFBTSxLQUFLLEdBQUcsSUFBSSxrQkFBVSxDQUFDLEVBQUMsS0FBSyxFQUFFLEVBQUUsRUFBYyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNuRSxhQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN4QixhQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN6QixhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMscUJBQXFCLEVBQUU7UUFDOUIsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1lBQ3pCLElBQU0sS0FBSyxHQUFHLHNCQUFlLENBQUM7Z0JBQzVCLEtBQUssRUFBRSxDQUFDO3dCQUNOLElBQUksRUFBRSxPQUFPO3dCQUNiLFFBQVEsRUFBRTs0QkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7eUJBQ2pDO3FCQUNGLEVBQUM7d0JBQ0EsSUFBSSxFQUFFLE9BQU87d0JBQ2IsUUFBUSxFQUFFOzRCQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzt5QkFDakM7cUJBQ0YsQ0FBQzthQUNILENBQUMsQ0FBQztZQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdkMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRW5CLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUNuRCxNQUFNLEVBQUUsQ0FBQzt3QkFDUCxJQUFJLEVBQUUsZ0JBQWdCO3dCQUN0QixLQUFLLEVBQUUsR0FBRztxQkFDWCxFQUFDO3dCQUNBLElBQUksRUFBRSxnQkFBZ0I7d0JBQ3RCLEtBQUssRUFBRSxHQUFHO3FCQUNYLENBQUM7Z0JBQ0YsSUFBSSxFQUFFLElBQUk7YUFDWCxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxJQUFNLEtBQUssR0FBRyxzQkFBZSxDQUFDO2dCQUM1QixLQUFLLEVBQUUsQ0FBQzt3QkFDTixJQUFJLEVBQUUsT0FBTzt3QkFDYixRQUFRLEVBQUU7NEJBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQzt5QkFDN0Q7cUJBQ0YsRUFBQzt3QkFDQSxJQUFJLEVBQUUsT0FBTzt3QkFDYixRQUFRLEVBQUU7NEJBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO3lCQUNqQztxQkFDRixDQUFDO2FBQ0gsQ0FBQyxDQUFDO1lBQ0gsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRW5CLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUNuRCxNQUFNLEVBQUU7b0JBQ04sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDVDt3QkFDRSxJQUFJLEVBQUUsZ0JBQWdCO3dCQUN0QixLQUFLLEVBQUUsR0FBRztxQkFDWDtpQkFDRjtnQkFDRCxJQUFJLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/compile/layout.test.d.ts b/build/test/compile/layout.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/layout.test.js b/build/test/compile/layout.test.js new file mode 100644 index 0000000000..9d3bfec598 --- /dev/null +++ b/build/test/compile/layout.test.js @@ -0,0 +1,148 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../util"); +var log = require("../../src/log"); +var channel_1 = require("../../src/channel"); +var layout_1 = require("../../src/compile/layout"); +describe('compile/layout', function () { + describe('cardinalityExpr', function () { + it('should return correct cardinality expr by default', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var expr = layout_1.cardinalityExpr(model, channel_1.X); + chai_1.assert.equal(expr, 'datum["distinct_a"]'); + }); + it('should return domain length if custom domain is provided', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { domain: ['a', 'b'] } } + } + }); + var expr = layout_1.cardinalityExpr(model, channel_1.X); + chai_1.assert.equal(expr, '2'); + }); + }); + describe('unitSizeExpr', function () { + it('should return correct formula for ordinal-point scale', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, 'max(datum["distinct_a"] - 1 + 2*0.5, 0) * 21'); + }); + it('should return correct formula for ordinal-band scale with custom padding', function () { + var model = util_1.parseUnitModel({ + mark: 'rect', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { padding: 0.3 } }, + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, 'max(datum["distinct_a"] - 0.3 + 2*0.3, 0) * 21'); + }); + it('should return correct formula for ordinal-band scale with custom paddingInner', function () { + var model = util_1.parseUnitModel({ + mark: 'rect', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { paddingInner: 0.3 } }, + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, 'max(datum["distinct_a"] - 0.3 + 2*0.15, 0) * 21'); + }); + it('should return static cell size for ordinal x-scale with null', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: null } } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, '200'); + }); + it('should return static cell size for ordinal y-scale with null', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + y: { field: 'a', type: 'ordinal', scale: { rangeStep: null } } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.Y); + chai_1.assert.equal(sizeExpr, '200'); + }); + it('should return static cell size for ordinal scale with top-level width', function () { + var model = util_1.parseUnitModel({ + width: 205, + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, '205'); + }); + it('should return static cell size for ordinal scale with top-level width even if there is numeric rangeStep', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + width: 205, + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: 21 } } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, '205'); + chai_1.assert.equal(localLogger.warns[0], log.message.rangeStepDropped(channel_1.X)); + }); + }); + it('should return static cell width for non-ordinal x-scale', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, '200'); + }); + it('should return static cell size for non-ordinal y-scale', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + y: { field: 'a', type: 'quantitative' } + } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.Y); + chai_1.assert.equal(sizeExpr, '200'); + }); + it('should return default rangeStep if axis is not mapped', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: {}, + config: { scale: { rangeStep: 17 } } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, '17'); + }); + it('should return textXRangeStep if axis is not mapped for X of text mark', function () { + var model = util_1.parseUnitModel({ + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + var sizeExpr = layout_1.unitSizeExpr(model, channel_1.X); + chai_1.assert.equal(sizeExpr, '91'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5b3V0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2NvbXBpbGUvbGF5b3V0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLGdDQUF1QztBQUd2QyxtQ0FBcUM7QUFDckMsNkNBQXVDO0FBQ3ZDLG1EQUF1RTtBQUV2RSxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7SUFDekIsUUFBUSxDQUFDLGlCQUFpQixFQUFFO1FBQzFCLEVBQUUsQ0FBQyxtREFBbUQsRUFBRTtZQUN0RCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO2lCQUNqQzthQUNGLENBQUMsQ0FBQztZQUVILElBQU0sSUFBSSxHQUFHLHdCQUFlLENBQUMsS0FBSyxFQUFFLFdBQUMsQ0FBQyxDQUFDO1lBQ3ZDLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMERBQTBELEVBQUU7WUFDN0QsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsSUFBSSxFQUFFLE9BQU87Z0JBQ2IsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUMsRUFBQztpQkFDOUQ7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFNLElBQUksR0FBRyx3QkFBZSxDQUFDLEtBQUssRUFBRSxXQUFDLENBQUMsQ0FBQztZQUN2QyxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUks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 \ No newline at end of file diff --git a/build/test/compile/legend/encode.test.d.ts b/build/test/compile/legend/encode.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/legend/encode.test.js b/build/test/compile/legend/encode.test.js new file mode 100644 index 0000000000..8ab98e250c --- /dev/null +++ b/build/test/compile/legend/encode.test.js @@ -0,0 +1,73 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var channel_1 = require("../../../src/channel"); +var encode = require("../../../src/compile/legend/encode"); +var timeunit_1 = require("../../../src/timeunit"); +var type_1 = require("../../../src/type"); +describe('compile/legend', function () { + describe('encode.symbols', function () { + it('should not have strokeDash and strokeDashOffset', function () { + var symbol = encode.symbols({ field: 'a' }, {}, util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { field: "a", type: "nominal" } + } + }), channel_1.COLOR); + chai_1.assert.isUndefined((symbol || {}).strokeDash); + chai_1.assert.isUndefined((symbol || {}).strokeDashOffset); + }); + it('should return not override size of the symbol for shape channel', function () { + var symbol = encode.symbols({ field: 'a' }, {}, util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + shape: { field: "b", type: "nominal", legend: { "shape": "circle" } } + } + }), channel_1.SHAPE); + chai_1.assert.isUndefined(symbol.size); + }); + it('should return specific symbols.shape.value if user has specified', function () { + var symbol = encode.symbols({ field: 'a' }, {}, util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + shape: { value: "square" } + } + }), channel_1.COLOR); + chai_1.assert.deepEqual(symbol.shape.value, 'square'); + }); + }); + describe('encode.labels', function () { + it('should return correct expression for the timeUnit: TimeUnit.MONTH', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal" }, + color: { field: "a", type: "temporal", timeUnit: "month" } + } + }); + var fieldDef = { field: 'a', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.MONTH }; + var label = encode.labels(fieldDef, {}, model, channel_1.COLOR); + var expected = "timeFormat(datum.value, '%b')"; + chai_1.assert.deepEqual(label.text.signal, expected); + }); + it('should return correct expression for the timeUnit: TimeUnit.QUARTER', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "temporal" }, + color: { field: "a", type: "temporal", timeUnit: "quarter" } + } + }); + var fieldDef = { field: 'a', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.QUARTER }; + var label = encode.labels(fieldDef, {}, model, channel_1.COLOR); + var expected = "'Q' + quarter(datum.value)"; + chai_1.assert.deepEqual(label.text.signal, expected); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jb2RlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbGVnZW5kL2VuY29kZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsZ0RBQWtEO0FBQ2xELDJEQUE2RDtBQUM3RCxrREFBK0M7QUFDL0MsMENBQTJDO0FBRTNDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUN6QixRQUFRLENBQUMsZ0JBQWdCLEVBQUU7UUFDekIsRUFBRSxDQUFDLGlEQUFpRCxFQUFFO1lBQ3BELElBQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDLEVBQUUsRUFBRSxFQUFFLHFCQUFjLENBQUM7Z0JBQzNELElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7b0JBQ2hDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQztpQkFDckM7YUFDRixDQUFDLEVBQUUsZUFBSyxDQUFDLENBQUM7WUFDWCxhQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxJQUFFLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzVDLGFBQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLElBQUUsRUFBRSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpRUFBaUUsRUFBRTtZQUNwRSxJQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxFQUFFLEVBQUUsRUFBRSxxQkFBYyxDQUFDO2dCQUMzRCxJQUFJLEVB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 \ No newline at end of file diff --git a/build/test/compile/legend/parse.test.d.ts b/build/test/compile/legend/parse.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/legend/parse.test.js b/build/test/compile/legend/parse.test.js new file mode 100644 index 0000000000..e0fe757f52 --- /dev/null +++ b/build/test/compile/legend/parse.test.js @@ -0,0 +1,40 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var channel_1 = require("../../../src/channel"); +var legendParse = require("../../../src/compile/legend/parse"); +describe('compile/legend', function () { + describe('parseLegend()', function () { + it('should produce a Vega legend object with correct type and scale for color', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: "a", type: "nominal" }, + color: { field: "a", type: "nominal" } + } + }); + var def = legendParse.parseLegend(model, channel_1.COLOR); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.title, 'a'); + chai_1.assert.equal(def.stroke, 'color'); + }); + [channel_1.SIZE, channel_1.SHAPE, channel_1.OPACITY].forEach(function (channel) { + it("should produce a Vega legend object with correct type and scale for " + channel, function () { + var s = { + mark: "point", + encoding: { + x: { field: "a", type: "nominal" } + } + }; + s.encoding[channel] = { field: "a", type: "nominal" }; + var model = util_1.parseUnitModel(s); + var def = legendParse.parseLegend(model, channel); + chai_1.assert.isObject(def); + chai_1.assert.equal(def.title, "a"); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sZWdlbmQvcGFyc2UudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQTBDO0FBQzFDLGdEQUFpRTtBQUNqRSwrREFBaUU7QUFHakUsUUFBUSxDQUFDLGdCQUFnQixFQUFFO0lBQ3pCLFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFDLDJFQUEyRSxFQUFFO1lBQzlFLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQzNCLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUM7b0JBQ2hDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQztpQkFDckM7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxlQUFLLENBQUMsQ0FBQztZQUNsRCxhQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUM3QixhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxDQUFDLGNBQUksRUFBRSxlQUFLLEVBQUUsaUJBQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFBLE9BQU87WUFDcEMsRUFBRSxDQUFDLHlFQUF1RSxPQUFTLEVBQUU7Z0JBQ25GLElBQU0sQ0FBQyxHQUFhO29CQUNsQixJQUFJLEVBQUUsT0FBTztvQkFDYixRQUFRLEVBQUU7d0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO3FCQUNqQztpQkFDRixDQUFDO2dCQUNGLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUMsQ0FBQztnQkFDcEQsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFaEMsSUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ3BELGFBQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3JCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMvQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/compile/legend/rules.test.d.ts b/build/test/compile/legend/rules.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/legend/rules.test.js b/build/test/compile/legend/rules.test.js new file mode 100644 index 0000000000..36fa274373 --- /dev/null +++ b/build/test/compile/legend/rules.test.js @@ -0,0 +1,52 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var config_1 = require("../../../src/config"); +var rules = require("../../../src/compile/legend/rules"); +var type_1 = require("../../../src/type"); +describe('compile/legend', function () { + describe('title()', function () { + it('should add explicitly specified title', function () { + var title = rules.title({ title: 'Custom' }, { field: 'a' }, config_1.defaultConfig); + chai_1.assert.equal(title, 'Custom'); + }); + it('should add return fieldTitle by default', function () { + var title = rules.title({}, { field: 'a' }, config_1.defaultConfig); + chai_1.assert.equal(title, 'a'); + }); + }); + describe('values()', function () { + it('should return correct timestamp values for DateTimes', function () { + var values = rules.values({ values: [{ year: 1970 }, { year: 1980 }] }); + chai_1.assert.deepEqual(values, [ + new Date(1970, 0, 1).getTime(), + new Date(1980, 0, 1).getTime() + ]); + }); + it('should simply return values for non-DateTime', function () { + var values = rules.values({ values: [1, 2, 3, 4] }); + chai_1.assert.deepEqual(values, [1, 2, 3, 4]); + }); + }); + describe('type()', function () { + it('should return gradient type for color scale', function () { + var t = rules.type({}, { type: type_1.QUANTITATIVE }, channel_1.COLOR); + chai_1.assert.equal(t, 'gradient'); + }); + it('should not return gradient type for size scale', function () { + var t = rules.type({}, { type: type_1.QUANTITATIVE }, channel_1.SIZE); + chai_1.assert.equal(t, undefined); + }); + it('should be able to override default', function () { + var t = rules.type({ type: 'symbol' }, { type: type_1.QUANTITATIVE }, channel_1.COLOR); + chai_1.assert.equal(t, 'symbol'); + }); + it('should return no type for color scale with bin', function () { + var t = rules.type({}, { type: type_1.QUANTITATIVE, bin: true }, channel_1.COLOR); + chai_1.assert.equal(t, undefined); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9sZWdlbmQvcnVsZXMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsZ0RBQWlEO0FBQ2pELDhDQUFrRDtBQUNsRCx5REFBMkQ7QUFDM0QsMENBQStDO0FBRS9DLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUN6QixRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRTtZQUMxQyxJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxFQUFFLHNCQUFhLENBQUMsQ0FBQztZQUMxRSxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRTtZQUM1QyxJQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsRUFBRSxzQkFBYSxDQUFDLENBQUM7WUFDM0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsRUFBRSxDQUFDLHNEQUFzRCxFQUFFO1lBQ3pELElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUVwRSxhQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtnQkFDdkIsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUU7Z0JBQzlCLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFO2FBQy9CLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7WUFFakQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO0lBRUwsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsUUFBUSxFQUFFO1FBQ2pCLEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxJQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFDLElBQUksRUFBRSxtQkFBWSxFQUFDLEVBQUUsZUFBSyxDQUFDLENBQUM7WUFDdEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsSUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBQyxJQUFJLEVBQUUsbUJBQVksRUFBQyxFQUFFLGNBQUksQ0FBQyxDQUFDO1lBQ3JELGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9DQUFvQyxFQUFFO1lBQ3ZDLElBQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBQyxJQUFJLEVBQUUsUUFBUSxFQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUUsbUJBQVksRUFBQyxFQUFFLGVBQUssQ0FBQyxDQUFDO1lBQ3BFLGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFO1lBQ25ELElBQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUMsSUFBSSxFQUFFLG1CQUFZLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBQyxFQUFFLGVBQUssQ0FBQyxDQUFDO1lBQ2pFLGFBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/compile/mark/area.test.d.ts b/build/test/compile/mark/area.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/area.test.js b/build/test/compile/mark/area.test.js new file mode 100644 index 0000000000..d287a2b88a --- /dev/null +++ b/build/test/compile/mark/area.test.js @@ -0,0 +1,191 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var util_2 = require("../../../src/util"); +var channel_1 = require("../../../src/channel"); +var area_1 = require("../../../src/compile/mark/area"); +describe('Mark: Area', function () { + function verticalArea(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "area", + "encoding": util_2.extend({ + "x": { "timeUnit": "year", "field": "Year", "type": "temporal" }, + "y": { "aggregate": "count", "type": "quantitative" } + }, moreEncoding), + "data": { "url": "data/cars.json" } + }; + } + describe('vertical area, with log', function () { + var model = util_1.parseUnitModel({ + "mark": "area", + "encoding": { + "x": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "y": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + }); + it('should has no height', function () { + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical area, with zero=false', function () { + var model = util_1.parseUnitModel({ + "mark": "area", + "encoding": { + "x": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "y": { "scale": { "zero": false }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + }); + it('should has no height', function () { + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical area', function () { + var model = util_1.parseUnitModel(verticalArea()); + var props = area_1.area.encodeEntry(model); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year_Year' }); + }); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'count_*' }); + }); + it('should have the correct value for y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('vertical stacked area with color', function () { + var model = util_1.parseUnitModel(verticalArea({ + "color": { "field": "Origin", "type": "quantitative" } + })); + var props = area_1.area.encodeEntry(model); + it('should have the correct value for y and y2', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'count_*_end' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'count_*_start' }); + }); + it('should have correct orient', function () { + chai_1.assert.deepEqual(props.orient, { value: 'vertical' }); + }); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.fill, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); + function horizontalArea(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "area", + "encoding": util_2.extend({ + "y": { "timeUnit": "year", "field": "Year", "type": "temporal" }, + "x": { "aggregate": "count", "type": "quantitative" } + }, moreEncoding), + "data": { "url": "data/cars.json" } + }; + } + describe('horizontal area', function () { + var model = util_1.parseUnitModel(horizontalArea()); + var props = area_1.area.encodeEntry(model); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'year_Year' }); + }); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'count_*' }); + }); + it('should have the correct value for x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + }); + }); + describe('horizontal area, with log', function () { + var model = util_1.parseUnitModel({ + "mark": "area", + "encoding": { + "y": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "x": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + }); + it('should have no width', function () { + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal area, with zero=false', function () { + var model = util_1.parseUnitModel({ + "mark": "area", + "encoding": { + "y": { "bin": true, "type": "quantitative", "field": "IMDB_Rating" }, + "x": { "scale": { "zero": false }, "type": "quantitative", "field": 'US_Gross', "aggregate": "mean" } + }, + "data": { "url": 'data/movies.json' } + }); + var props = area_1.area.encodeEntry(model); + it('should end on axis', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + }); + it('should have no width', function () { + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal stacked area with color', function () { + var model = util_1.parseUnitModel(horizontalArea({ + "color": { "field": "Origin", "type": "nominal" } + })); + var props = area_1.area.encodeEntry(model); + it('should have the correct value for x and x2', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'count_*_end' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'count_*_start' }); + }); + it('should have correct orient', function () { + chai_1.assert.deepEqual(props.orient, { value: 'horizontal' }); + }); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.fill, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); + describe('ranged area', function () { + it('vertical area should work with aggregate', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/cars.json" }, + "mark": "area", + "encoding": { + "x": { "timeUnit": "year", "field": "Year", "type": "temporal" }, + "y": { "aggregate": "min", "field": "Weight_in_lbs", "type": "quantitative" }, + "y2": { "aggregate": "max", "field": "Weight_in_lbs", "type": "quantitative" } + } + }); + var props = area_1.area.encodeEntry(model); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'year_Year' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'min_Weight_in_lbs' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'max_Weight_in_lbs' }); + }); + it('horizontal area should work with aggregate', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/cars.json" }, + "mark": "area", + "encoding": { + "y": { "timeUnit": "year", "field": "Year", "type": "temporal" }, + "x": { "aggregate": "min", "field": "Weight_in_lbs", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "Weight_in_lbs", "type": "quantitative" } + } + }); + var props = area_1.area.encodeEntry(model); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'year_Year' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'min_Weight_in_lbs' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'max_Weight_in_lbs' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJlYS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvYXJlYS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsMENBQXlDO0FBQ3pDLGdEQUFpRDtBQUNqRCx1REFBb0Q7QUFHcEQsUUFBUSxDQUFDLFlBQVksRUFBRTtJQUNyQixzQkFBc0IsWUFBaUI7UUFBakIsNkJBQUEsRUFBQSxpQkFBaUI7UUFDckMsTUFBTSxDQUFDO1lBQ0wsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUUsYUFBTSxDQUNoQjtnQkFDRSxHQUFHLEVBQUUsRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBQztnQkFDOUQsR0FBRyxFQUFFLEVBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2FBQ3BELEVBQ0QsWUFBWSxDQUNiO1lBQ0QsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO1NBQ2xDLENBQUM7SUFDSixDQUFDO0lBRUQsUUFBUSxDQUFDLHlCQUF5QixFQUFFO1FBQ2xDLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUM7Z0JBQ2xFLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBQzthQUNsRztZQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFB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 \ No newline at end of file diff --git a/build/test/compile/mark/bar.test.d.ts b/build/test/compile/mark/bar.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/bar.test.js b/build/test/compile/mark/bar.test.js new file mode 100644 index 0000000000..6905e5ae0c --- /dev/null +++ b/build/test/compile/mark/bar.test.js @@ -0,0 +1,409 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var mark_1 = require("../../../src/mark"); +var scale_1 = require("../../../src/scale"); +var bar_1 = require("../../../src/compile/mark/bar"); +describe('Mark: Bar', function () { + describe('simple vertical', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar, with y from zero to field value and x with center position and width = rangeStep - 1', function () { + chai_1.assert.deepEqual(props.xc, { scale: 'x', field: 'Origin' }); + chai_1.assert.deepEqual(props.width, { value: scale_1.defaultScaleConfig.rangeStep - 1 }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('simple horizontal', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar from zero to field value and y with center position and height = rangeStep - 1', function () { + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { value: scale_1.defaultScaleConfig.rangeStep - 1 }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal binned', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_Horsepower_start' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_Horsepower_end', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical binned', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_Horsepower_start', offset: mark_1.defaultBarConfig.binSpacing }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_Horsepower_end' }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal binned with no spacing', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + }, + "config": { "bar": { "binSpacing": 0 } } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_Horsepower_start' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_Horsepower_end' }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical binned with no spacing', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + }, + "config": { "bar": { "binSpacing": 0 } } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_Horsepower_start' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_Horsepower_end' }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple horizontal binned with size', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar with y centered on bin_mid and height = size field', function () { + chai_1.assert.deepEqual(props.yc, { signal: '(scale("y", datum["bin_Horsepower_start"]) + scale("y", datum["bin_Horsepower_end"]))/2' }); + chai_1.assert.deepEqual(props.height, { scale: 'size', field: 'mean_Acceleration' }); + }); + }); + describe('vertical binned with size', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" }, + "size": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should draw bar with x centered on bin_mid and width = size field', function () { + chai_1.assert.deepEqual(props.xc, { signal: '(scale("x", datum["bin_Horsepower_start"]) + scale("x", datum["bin_Horsepower_end"]))/2' }); + chai_1.assert.deepEqual(props.width, { scale: 'size', field: 'mean_Acceleration' }); + }); + }); + describe('vertical, with log', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should end on axis and has no height', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('horizontal, with log', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "scale": { "type": 'log' }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should end on axis and has no width', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('vertical, with fit mode', function () { + var model = util_1.parseUnitModel({ + "width": 120, + "height": 120, + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should use x and with band true', function () { + chai_1.assert.deepEqual(props.x, { + scale: 'x', + field: 'Origin', + }); + chai_1.assert.deepEqual(props.width, { + scale: 'x', + band: true, + }); + }); + }); + describe('horizontal, with fit mode', function () { + var model = util_1.parseUnitModel({ + "width": 120, + "height": 120, + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should use y with band true', function () { + chai_1.assert.deepEqual(props.y, { + scale: 'y', + field: 'Origin', + }); + chai_1.assert.deepEqual(props.height, { + scale: 'y', + band: true, + }); + }); + }); + describe('vertical with zero=false', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "scale": { "zero": false }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should end on axis nad have no height', function () { + chai_1.assert.deepEqual(props.y2, { field: { group: 'height' } }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('horizontal with zero=false', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "scale": { "zero": false }, "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should end on axis and have no width', function () { + chai_1.assert.deepEqual(props.x2, { value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('1D vertical', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } }, + "data": { "url": 'data/movies.json' } + }); + var props = bar_1.bar.encodeEntry(model); + it('should have y end on axis, have no-height and have x-offset', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'sum_US_Gross' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + chai_1.assert.isUndefined(props.height); + chai_1.assert.deepEqual(props.xc, { + value: 10.5, + offset: 1 + }); + }); + }); + describe('1D vertical with size value', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" }, + "size": { "value": 5 } + }, + "data": { "url": 'data/movies.json' } + }); + var props = bar_1.bar.encodeEntry(model); + it('should have width = 5', function () { + chai_1.assert.deepEqual(props.width, { value: 5 }); + }); + }); + describe('1D vertical with barSize config', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/movies.json' }, + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": 'US_Gross', "aggregate": "sum" } + }, + "config": { + "bar": { "discreteBandSize": 5 } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should have width = 5', function () { + chai_1.assert.deepEqual(props.width, { value: 5 }); + }); + }); + describe('1D horizontal', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { "x": { "type": "quantitative", "field": 'US_Gross', "aggregate": 'sum' } }, + "data": { "url": 'data/movies.json' } + }); + var props = bar_1.bar.encodeEntry(model); + it('should end on axis, have no width, and have y-offset', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'sum_US_Gross' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + chai_1.assert.deepEqual(props.yc, { value: 10.5 }); + }); + }); + describe('QxQ horizontal', function () { + // This is generally a terrible idea, but we should still test + // if the output show expected results + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Acceleration', "type": "quantitative" }, + "y": { "field": 'Horsepower', "type": "quantitative" } + }, + "config": { + "mark": { "orient": "horizontal" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should produce horizontal bar using x, x2', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'Horsepower' }); + chai_1.assert.deepEqual(props.height, { value: mark_1.defaultBarConfig.continuousBandSize }); + }); + }); + describe('QxQ vertical', function () { + // This is generally a terrible idea, but we should still test + // if the output show expected results + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Acceleration', "type": "quantitative" }, + "y": { "field": 'Horsepower', "type": "quantitative" } + }, + "config": { + "mark": { "orient": "vertical" } + } + }); + var props = bar_1.bar.encodeEntry(model); + it('should produce horizontal bar using x, x2', function () { + chai_1.assert.deepEqual(props.xc, { scale: 'x', field: 'Acceleration' }); + chai_1.assert.deepEqual(props.width, { value: mark_1.defaultBarConfig.continuousBandSize }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Horsepower' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + }); + }); + describe('OxN', function () { + // This is generally a terrible idea, but we should still test + // if the output show expected results + it('should produce vertical bar using x, x2', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "bar", + "encoding": { + "x": { "field": 'Origin', "type": "nominal" }, + "y": { "field": 'Cylinders', "type": "ordinal" } + } + }); + var props = bar_1.bar.encodeEntry(model); + chai_1.assert.deepEqual(props.xc, { scale: 'x', field: 'Origin' }); + chai_1.assert.deepEqual(props.width, { value: 20 }); + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'Cylinders' }); + chai_1.assert.deepEqual(props.height, { value: 20 }); + }); + }); + describe('ranged bar', function () { + // TODO: gantt chart with temporal + // TODO: gantt chart with ordinal + it('vertical bars should work with aggregate', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/population.json" }, + "mark": "bar", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { "field": "people", "aggregate": "q1", "type": "quantitative" }, + "y2": { "field": "people", "aggregate": "q3", "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + chai_1.assert.deepEqual(props.xc, { scale: 'x', field: 'age' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'q1_people' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'q3_people' }); + }); + it('horizontal bars should work with aggregate', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/population.json" }, + "mark": "bar", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { "field": "people", "aggregate": "q1", "type": "quantitative" }, + "x2": { "field": "people", "aggregate": "q3", "type": "quantitative" } + } + }); + var props = bar_1.bar.encodeEntry(model); + chai_1.assert.deepEqual(props.yc, { scale: 'y', field: 'age' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'q1_people' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'q3_people' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbWFyay9iYXIudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQTBDO0FBQzFDLDBDQUFtRDtBQUNuRCw0Q0FBc0Q7QUFDdEQscURBQWtEO0FBRWxELFFBQVEsQ0FBQyxXQUFXLEVBQUU7SUFDcEIsUUFBUSxDQUFDLGlCQUFpQixFQUFFO1FBQzFCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO1lBQ2pDLE1BQU0sRUFBRSxLQUFLO1lBQ2IsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDM0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUM7YUFDNUU7U0FDRixDQUFDLENBQUM7UUFDSCxJQUFNLEtBQUssR0FBRyxTQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXJDLEVBQUUsQ0FBQyx1R0FBdUcsRUFBRTtZQUMxRyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDO1lBQzFELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSwwQkFBa0IsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUN6RSxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUss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 \ No newline at end of file diff --git a/build/test/compile/mark/init.test.d.ts b/build/test/compile/mark/init.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/init.test.js b/build/test/compile/mark/init.test.js new file mode 100644 index 0000000000..05277e5b59 --- /dev/null +++ b/build/test/compile/mark/init.test.js @@ -0,0 +1,208 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../../src/log"); +var chai_1 = require("chai"); +var mark_1 = require("../../../src/mark"); +var util_1 = require("../../util"); +describe('compile/mark/init', function () { + describe('orient', function () { + it('should return correct default for QxQ', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + chai_1.assert.equal(localLogger.warns[0], log.message.unclearOrientContinuous(mark_1.BAR)); + }); + }); + it('should return correct default for empty plot', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + "mark": "bar", + encoding: {} + }); + chai_1.assert.equal(model.markDef.orient, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.unclearOrientDiscreteOrEmpty(mark_1.BAR)); + }); + }); + it('should return correct orient for bar with both axes discrete', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "type": "ordinal", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.unclearOrientDiscreteOrEmpty(mark_1.BAR)); + }); + }); + it('should return correct orient for vertical bar', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal bar', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical bar with raw temporal dimension', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "temporal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal bar with raw temporal dimension', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "temporal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical tick', function () { + var model = util_1.parseUnitModel({ + "mark": "tick", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical tick with bin', function () { + var model = util_1.parseUnitModel({ + "mark": "tick", + "encoding": { + "x": { "type": "quantitative", "field": "foo" }, + "y": { "type": "quantitative", "field": "bar", "bin": true } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical tick of continuous timeUnit dotplot', function () { + var model = util_1.parseUnitModel({ + "mark": "tick", + "encoding": { + "x": { "type": "temporal", "field": "foo", "timeUnit": "yearmonthdate" }, + "y": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal tick', function () { + var model = util_1.parseUnitModel({ + "mark": "tick", + "encoding": { + "y": { "type": "quantitative", "field": "foo" }, + "x": { "type": "ordinal", "field": "bar" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rule', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "value": 0 }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal rule', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "value": 0 }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for horizontal rules without x2 ', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "field": "b", "type": "quantitative" }, + "y": { "field": "a", "type": "ordinal" }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rules without y2 ', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "field": "b", "type": "quantitative" }, + "x": { "field": "a", "type": "ordinal" }, + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for vertical rule with range', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "type": "ordinal", "field": "foo" }, + "y": { "type": "quantitative", "field": "bar" }, + "y2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + it('should return correct orient for horizontal rule with range', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "type": "ordinal", "field": "foo" }, + "x": { "type": "quantitative", "field": "bar" }, + "x2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for horizontal rule with range and no ordinal', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "type": "quantitative", "field": "bar" }, + "x2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + }); + it('should return correct orient for vertical rule with range and no ordinal', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "type": "quantitative", "field": "bar" }, + "y2": { "type": "quantitative", "field": "baz" } + }, + }); + chai_1.assert.equal(model.markDef.orient, 'vertical'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvaW5pdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLHNDQUF3QztBQUV4Qyw2QkFBNEI7QUFDNUIsMENBQXNDO0FBQ3RDLG1DQUEwQztBQUUxQyxRQUFRLENBQUMsbUJBQW1CLEVBQUU7SUFDNUIsUUFBUSxDQUFDLFFBQVEsRUFBRTtRQUNqQixFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxVQUFDLFdBQVc7Z0JBQzdCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7b0JBQzNCLE1BQU0sRUFBRSxLQUFLO29CQUNiLFVBQVUsRUFBRTt3QkFDVixHQUFHLEVBQUUsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUM7d0JBQzdDLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBQztxQkFDOUM7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7Z0JBQy9DLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLHVCQUF1QixDQUFDLFVBQUcsQ0FBQyxDQUFDLENBQUM7WUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxHQUFHLENBQUMsY0FBYyxDQUFDLFVBQUMsV0FBVztnQkFDN0IsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztvQkFDM0IsTUFBTSxFQUFFLEtBQUs7b0JBQ2IsUUFBUSxFQUFFLEVBQUU7aUJB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 \ No newline at end of file diff --git a/build/test/compile/mark/line.test.d.ts b/build/test/compile/mark/line.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/line.test.js b/build/test/compile/mark/line.test.js new file mode 100644 index 0000000000..3d4a823300 --- /dev/null +++ b/build/test/compile/mark/line.test.js @@ -0,0 +1,110 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var log = require("../../../src/log"); +var channel_1 = require("../../../src/channel"); +var mark_1 = require("../../../src/mark"); +var line_1 = require("../../../src/compile/mark/line"); +describe('Mark: Line', function () { + describe('with x, y', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative" } + } + }); + var props = line_1.line.encodeEntry(model); + it('should have scale for x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year' }); + }); + it('should have scale for y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'yield' }); + }); + }); + describe('with x, y, color', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative" }, + "color": { "field": "Acceleration", "type": "quantitative" } + } + }); + var props = line_1.line.encodeEntry(model); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'Acceleration' }); + }); + }); + describe('with x, y, size', function () { + it('should have scale for size', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative", "aggregate": "mean" }, + "size": { "field": "variety", "type": "nominal" } + } + }); + var props = line_1.line.encodeEntry(model); + chai_1.assert.deepEqual(props.strokeWidth, { scale: 'size', field: 'variety' }); + }); + }); + it('should drop aggregate size field', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative", "aggregate": "mean" }, + "size": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" } + } + }); + var props = line_1.line.encodeEntry(model); + // If size field is dropped, then strokeWidth only have value + chai_1.assert.isNotOk(props.strokeWidth && props.strokeWidth.scale); + chai_1.assert.equal(localLogger.warns[0], log.message.incompatibleChannel(channel_1.SIZE, mark_1.LINE, 'when the field is aggregated.')); + }); + }); + }); + describe('with stacked y', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative", "aggregate": "sum" }, + "color": { "field": "a", "type": "nominal" } + }, + "config": { "stack": "zero" } + }); + var props = line_1.line.encodeEntry(model); + it('should use y_end', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'sum_yield_end' }); + }); + }); + describe('with stacked x', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "line", + "encoding": { + "y": { "field": "year", "type": "ordinal" }, + "x": { "field": "yield", "type": "quantitative", "aggregate": "sum" }, + "color": { "field": "a", "type": "nominal" } + }, + "config": { "stack": "zero" } + }); + var props = line_1.line.encodeEntry(model); + it('should use x_end', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'sum_yield_end' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvbGluZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFFMUMsc0NBQXdDO0FBRXhDLGdEQUF1RDtBQUN2RCwwQ0FBdUM7QUFDdkMsdURBQW9EO0FBRXBELFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFFckIsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1lBQzNCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztZQUNuQyxNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFBRTtnQkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7Z0JBQ3pDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQzthQUNoRDtTQUNGLENBQUMsQ0FBQztRQUNILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLHlCQUF5QixFQUFFO1lBQzVCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUJBQXlCLEVBQUU7WUFDNUIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztRQUN4RCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGtCQUFrQixFQUFFO1FBQzNCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDO1lBQ25DLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDekMsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO2dCQUMvQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7YUFDM0Q7U0FDRixDQUFDLENBQUM7UUFDSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtZQUNoQyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsZUFBSyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFHSCxRQUFRLENBQUMsaUJBQWlCLEVBQUU7UUFDMUIsRUFBRSxDQUFDLDRCQUE0QixFQUFFO1lBQy9CLEdBQUcsQ0FBQyxjQUFjLENBQUMsVUFBQyxXQUFXO2dCQUM3QixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO29CQUMzQixNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUM7b0JBQ25DLE1BQU0sRUFBRSxNQUFNO29CQUNkLFVBQVUsRUFBRTt3QkFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7d0JBQ3pDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFDO3dCQUNwRSxNQUFNLEVBQUUsRUFBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7cUJBQ2hEO2lCQUNGLENBQUMsQ0FBQztnQkFDSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUV0QyxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFDO1lBQ3pFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUU7WUFDckMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxVQUFDLFdBQVc7Z0JBQzdCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7b0JBQzNCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztvQkFDbkMsTUFBTSxFQUFFLE1BQU07b0JBQ2QsVUFBVSxFQUFFO3dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzt3QkFDekMsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUM7d0JBQ3BFLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFDO3FCQUMvRTtpQkFDRixDQUFDLENBQUM7Z0JBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFdEMsNkRBQTZEO2dCQUM3RCxhQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDN0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsY0FBSSxFQUFFLFdBQUksRUFBRSwrQkFBK0IsQ0FBQyxDQUFDLENBQUM7WUFDbkgsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1FBQ3pCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDO1lBQ25DLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDekMsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUM7Z0JBQ25FLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzthQUMzQztZQUNELFFBQVEsRUFBRSxFQUFDLE9BQU8sRUFBRyxNQUFNLEVBQUM7U0FDN0IsQ0FBQyxDQUFDO1FBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMsa0JBQWtCLEVBQUU7WUFDckIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQUMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFDLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1FBQ3pCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDO1lBQ25DLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDekMsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUM7Z0JBQ25FLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzthQUMzQztZQUNELFFBQVEsRUFBRSxFQUFDLE9BQU8sRUFBRyxNQUFNLEVBQUM7U0FDN0IsQ0FBQyxDQUFDO1FBQ0gsSUFBTSxLQUFLLEdBQUcsV0FBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxFQUFFLENBQUMsa0JBQWtCLEVBQUU7WUFDckIsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQUMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFDLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/mark/mark.test.d.ts b/build/test/compile/mark/mark.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/mark.test.js b/build/test/compile/mark/mark.test.js new file mode 100644 index 0000000000..84c81f3b2f --- /dev/null +++ b/build/test/compile/mark/mark.test.js @@ -0,0 +1,99 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var mark_1 = require("../../../src/compile/mark/mark"); +describe('Mark', function () { + describe('parseMark', function () { + // PATH + describe('Multi-series Line', function () { + it('should have a facet directive and a nested mark group that uses the faceted data.', function () { + var model = util_1.parseUnitModel({ + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal", "axis": { "format": "%Y" } }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + } + }); + var markGroup = mark_1.parseMark(model)[0]; + chai_1.assert.equal(markGroup.name, 'pathgroup'); + chai_1.assert.deepEqual(markGroup.from, { + facet: { + name: 'faceted-path-source', + data: 'source', + groupby: ['symbol'] + } + }); + var submarkGroup = markGroup.marks[0]; + chai_1.assert.equal(submarkGroup.name, 'marks'); + chai_1.assert.equal(submarkGroup.type, 'line'); + chai_1.assert.equal(submarkGroup.from.data, 'faceted-path-source'); + }); + }); + describe('Single Line', function () { + it('should have a facet directive and a nested mark group', function () { + var model = util_1.parseUnitModel({ + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal", "axis": { "format": "%Y" } }, + "y": { "field": "price", "type": "quantitative" } + } + }); + var markGroup = mark_1.parseMark(model)[0]; + chai_1.assert.equal(markGroup.name, 'marks'); + chai_1.assert.equal(markGroup.type, 'line'); + chai_1.assert.equal(markGroup.from.data, 'source'); + }); + }); + // NON-PATH + describe('Aggregated Bar with a color with binned x', function () { + it(' should use stacked data source', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" }, + "color": { "type": "ordinal", "field": "Effect__Amount_of_damage" } + } + }); + var markGroup = mark_1.parseMark(model); + chai_1.assert.equal(markGroup[0].from.data, 'stacked'); + }); + }); + describe('Faceted aggregated Bar with a color with binned x', function () { + it('should use faceted data source', function () { + var model = util_1.parseFacetModel({ + facet: { + row: { field: 'a', type: 'nominal' } + }, + spec: { + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" }, + "color": { "type": "ordinal", "field": "Effect__Amount_of_damage" } + } + } + }); + var markGroup = mark_1.parseMark(model.child); + chai_1.assert.equal(markGroup[0].from.data, 'faceted-data'); + }); + }); + describe('Aggregated bar', function () { + it('should use summary data source', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { "type": "quantitative", "field": "Cost__Other", "aggregate": "sum" }, + "y": { "bin": true, "type": "quantitative", "field": "Cost__Total_$" } + } + }); + var markGroup = mark_1.parseMark(model); + chai_1.assert.equal(markGroup[0].from.data, 'summary'); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFyay50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvbWFyay50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUU1QixtQ0FBMkQ7QUFDM0QsdURBQXlEO0FBR3pELFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLE9BQU87UUFDUCxRQUFRLENBQUMsbUJBQW1CLEVBQUU7WUFDNUIsRUFBRSxDQUFDLG1GQUFtRixFQUFFO2dCQUN0RixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO29CQUMzQixNQUFNLEVBQUUsTUFBTTtvQkFDZCxVQUFVLEVBQUU7d0JBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUMsRUFBQzt3QkFDcEUsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO3dCQUMvQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7cUJBQ2hEO2lCQUNGLENBQUMsQ0FBQztnQkFDSCxJQUFNLFNBQVMsR0FBRyxnQkFBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0QyxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7Z0JBQzFDLGFBQU0sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTtvQkFDL0IsS0FBSyxFQUFFO3dCQUNMLElBQUksRUFBRSxxQkFBcUI7d0JBQzNCLElBQUksRUFBRSxRQUFRO3dCQUNkLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQztxQkFDcEI7aUJBQ0YsQ0FB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 \ No newline at end of file diff --git a/build/test/compile/mark/mixins.test.d.ts b/build/test/compile/mark/mixins.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/mixins.test.js b/build/test/compile/mark/mixins.test.js new file mode 100644 index 0000000000..b68d2e3890 --- /dev/null +++ b/build/test/compile/mark/mixins.test.js @@ -0,0 +1,50 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var mixins_1 = require("../../../src/compile/mark/mixins"); +describe('compile/mark/mixins', function () { + describe('color()', function () { + it('color should be mapped to fill for bar', function () { + var model = util_1.parseUnitModel({ + "mark": "bar", + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "color": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = mixins_1.color(model); + chai_1.assert.deepEqual(colorMixins.fill, { "field": "gender", "scale": "color" }); + }); + it('color should be mapped to stroke for point', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "x": { + "field": "gender", "type": "nominal", + "scale": { "rangeStep": 6 }, + "axis": null + }, + "color": { + "field": "gender", "type": "nominal", + "scale": { "range": ["#EA98D2", "#659CCA"] } + } + }, + "data": { "url": "data/population.json" } + }); + var colorMixins = mixins_1.color(model); + chai_1.assert.deepEqual(colorMixins.stroke, { "field": "gender", "scale": "color" }); + chai_1.assert.deepEqual(colorMixins.fill.value, "transparent"); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWl4aW5zLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvbWFyay9taXhpbnMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQTBDO0FBQzFDLDJEQUF1RDtBQUV2RCxRQUFRLENBQUMscUJBQXFCLEVBQUU7SUFDOUIsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRTt3QkFDSCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTO3dCQUNwQyxPQUFPLEVBQUUsRUFBQyxXQUFXLEVBQUUsQ0FBQyxFQUFDO3dCQUN6QixNQUFNLEVBQUUsSUFBSTtxQkFDYjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUzt3QkFDcEMsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxFQUFDO3FCQUMzQztpQkFDRjtnQkFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsc0JBQXNCLEVBQUM7YUFDeEMsQ0FBQyxDQUFDO1lBRUgsSUFBTSxXQUFXLEdBQUcsY0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pDLGFBQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFDNUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNENBQTRDLEVBQUU7WUFDL0MsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztnQkFDM0IsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsVUFBVSxFQUFFO29CQUNWLEdBQUcsRUFBRTt3QkFDSCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTO3dCQUNwQyxPQUFPLEVBQUUsRUFBQyxXQUFXLEVBQUUsQ0FBQyxFQUFDO3dCQUN6QixNQUFNLEVBQUUsSUFBSTtxQkFDYjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUzt3QkFDcEMsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxFQUFDO3FCQUMzQztpQkFDRjtnQkFDRCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsc0JBQXNCLEVBQUM7YUFDeEMsQ0FBQyxDQUFDO1lBRUgsSUFBTSxXQUFXLEdBQUcsY0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pDLGFBQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7WUFDNUUsYUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsQ0FBQztRQUMxRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/mark/point.test.d.ts b/build/test/compile/mark/point.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/point.test.js b/build/test/compile/mark/point.test.js new file mode 100644 index 0000000000..9dd6714669 --- /dev/null +++ b/build/test/compile/mark/point.test.js @@ -0,0 +1,260 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var util_2 = require("../../../src/util"); +var channel_1 = require("../../../src/channel"); +var mark_1 = require("../../../src/mark"); +var point_1 = require("../../../src/compile/mark/point"); +describe('Mark: Point', function () { + function pointXY(moreEncoding) { + if (moreEncoding === void 0) { moreEncoding = {}; } + return { + "mark": "point", + "encoding": util_2.extend({ + "x": { "field": "year", "type": "ordinal" }, + "y": { "field": "yield", "type": "quantitative" } + }, moreEncoding), + "data": { "url": "data/barley.json" } + }; + } + describe('with x', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { "x": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = point_1.point.encodeEntry(model); + it('should be centered on y', function () { + chai_1.assert.deepEqual(props.y, { value: 21 / 2 }); + }); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year' }); + }); + }); + describe('with stacked x', function () { + // This is a simplified example for stacked point. + // In reality this will be used as stacked's overlayed marker + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = point_1.point.encodeEntry(model); + it('should use stack_end on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'sum_a_end' }); + }); + }); + describe('with y', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { "y": { "field": "year", "type": "ordinal" } }, + "data": { "url": "data/barley.json" } + }); + var props = point_1.point.encodeEntry(model); + it('should be centered on x', function () { + chai_1.assert.deepEqual(props.x, { value: 21 / 2 }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'year' }); + }); + }); + describe('with stacked y', function () { + // This is a simplified example for stacked point. + // In reality this will be used as stacked's overlayed marker + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "y": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = point_1.point.encodeEntry(model); + it('should use stack_end on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'sum_a_end' }); + }); + }); + describe('with x and y', function () { + var model = util_1.parseUnitModel(pointXY()); + var props = point_1.point.encodeEntry(model); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'year' }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'yield' }); + }); + it('should be an unfilled circle', function () { + chai_1.assert.deepEqual(props.fill, { value: 'transparent' }); + chai_1.assert.deepEqual(props.stroke, { value: mark_1.defaultMarkConfig.color }); + }); + }); + describe('with band x and quantitative y', function () { + it('should offset band position by half band', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/barley.json" }, + "mark": "point", + "encoding": { + "x": { "field": "year", "type": "ordinal", "scale": { "type": "band" } }, + "y": { "field": "yield", "type": "quantitative" } + } + }); + var props = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'year', offset: { scale: 'x', band: 0.5 } }); + }); + }); + describe('with x, y, size', function () { + var model = util_1.parseUnitModel(pointXY({ + "size": { "aggregate": "count", "type": "quantitative" } + })); + var props = point_1.point.encodeEntry(model); + it('should have scale for size', function () { + chai_1.assert.deepEqual(props.size, { scale: channel_1.SIZE, field: 'count_*' }); + }); + }); + describe('with x, y, color', function () { + var model = util_1.parseUnitModel(pointXY({ + "color": { "field": "yield", "type": "quantitative" } + })); + var props = point_1.point.encodeEntry(model); + it('should have scale for color', function () { + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'yield' }); + }); + }); + describe('with x, y, shape', function () { + var model = util_1.parseUnitModel(pointXY({ + "shape": { "field": "site", "type": "nominal" } + })); + var props = point_1.point.encodeEntry(model); + it('should have scale for shape', function () { + chai_1.assert.deepEqual(props.shape, { scale: channel_1.SHAPE, field: 'site' }); + }); + }); + describe('with constant color, shape, and size', function () { + var model = util_1.parseUnitModel(pointXY({ + "shape": { "value": "circle" }, + "color": { "value": "red" }, + "size": { "value": 23 } + })); + var props = point_1.point.encodeEntry(model); + it('should correct shape, color and size', function () { + chai_1.assert.deepEqual(props.shape, { value: "circle" }); + chai_1.assert.deepEqual(props.stroke, { value: "red" }); + chai_1.assert.deepEqual(props.size, { value: 23 }); + }); + }); + describe('with configs', function () { + it('should apply color from mark-specific config over general mark config', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "mark": { "color": "blue" }, "point": { "color": "red" } } + }); + var props = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.stroke, { value: "red" }); + }); + it('should apply color config and not apply stroke config', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "mark": { "color": "red", "stroke": "blue" } } + }); + var props = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.stroke, { value: "red" }); + }); + it('should not apply stroke config but instead output default color', function () { + var model = util_1.parseUnitModel({ + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + }, + "config": { "mark": { "stroke": "red" } } + }); + var props = point_1.point.encodeEntry(model); + chai_1.assert.deepEqual(props.stroke, { value: mark_1.defaultMarkConfig.color }); + }); + }); +}); +describe('Mark: Square', function () { + it('should have correct shape', function () { + var model = util_1.parseUnitModel({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = point_1.square.encodeEntry(model); + chai_1.assert.equal(props.shape.value, 'square'); + }); + it('should be filled by default', function () { + var model = util_1.parseUnitModel({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = point_1.square.encodeEntry(model); + chai_1.assert.equal(props.fill.value, 'blue'); + }); + it('with config.mark.filled:false should have transparent fill', function () { + var model = util_1.parseUnitModel({ + "mark": "square", + "encoding": { + "color": { "value": "blue" } + }, + "config": { + "mark": { + "filled": false + } + } + }); + var props = point_1.square.encodeEntry(model); + chai_1.assert.equal(props.stroke.value, 'blue'); + chai_1.assert.equal(props.fill.value, 'transparent'); + }); +}); +describe('Mark: Circle', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "color": { "value": "blue" } + } + }); + var props = point_1.circle.encodeEntry(model); + it('should have correct shape', function () { + chai_1.assert.equal(props.shape.value, 'circle'); + }); + it('should be filled by default', function () { + chai_1.assert.equal(props.fill.value, 'blue'); + }); + it('with config.mark.filled:false should have transparent fill', function () { + var filledCircleModel = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "color": { "value": "blue" } + }, + "config": { + "mark": { + "filled": false + } + } + }); + var filledCircleProps = point_1.circle.encodeEntry(filledCircleModel); + chai_1.assert.equal(filledCircleProps.stroke.value, 'blue'); + chai_1.assert.equal(filledCircleProps.fill.value, 'transparent'); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9pbnQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9tYXJrL3BvaW50LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLG1DQUEwQztBQUMxQywwQ0FBeUM7QUFDekMsZ0RBQThEO0FBQzlELDBDQUFvRDtBQUNwRCx5REFBc0U7QUFHdEUsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUV0QixpQkFBaUIsWUFBaUI7UUFBakIsNkJBQUEsRUFBQSxpQkFBaUI7UUFDaEMsTUFBTSxDQUFDO1lBQ0wsTUFBTSxFQUFFLE9BQU87WUFDZixVQUFVLEVBQUUsYUFBTSxDQUNoQjtnQkFDRSxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7Z0JBQ3pDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQzthQUNoRCxFQUNELFlBQVksQ0FDYjtZQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztTQUNwQyxDQUFDO0lBQ0osQ0FBQztJQUVELFFBQVEsQ0FBQyxRQUFRLEVBQUU7UUFDakIsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztZQUMzQixNQUFNLEVBQUUsT0FBTztZQUNmLFVBQVUsRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQyxFQUFDO1lBQ3ZELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztTQUNwQyxDQUFDLENBQUM7UUFFSCxJQUFNLEtBQUssR0FBRyxhQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXZDLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxD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 \ No newline at end of file diff --git a/build/test/compile/mark/rect.test.d.ts b/build/test/compile/mark/rect.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/rect.test.js b/build/test/compile/mark/rect.test.js new file mode 100644 index 0000000000..63894ce80d --- /dev/null +++ b/build/test/compile/mark/rect.test.js @@ -0,0 +1,114 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var rect_1 = require("../../../src/compile/mark/rect"); +describe('Mark: Rect', function () { + describe('simple vertical', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "x": { "field": "Origin", "type": "nominal" }, + "y": { "type": "quantitative", "field": 'Acceleration', "aggregate": "mean" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw bar, with y from zero to field value and x band', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Origin' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', value: 0 }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('simple horizontal', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "field": "Origin", "type": "nominal" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw bar from zero to field value and y band', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'mean_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', value: 0 }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('horizontal binned', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw bar with y and y2', function () { + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'bin_Horsepower_start' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'bin_Horsepower_end' }); + chai_1.assert.isUndefined(props.height); + }); + }); + describe('vertical binned', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "x": { "bin": true, "field": 'Horsepower', "type": "quantitative" }, + "y": { "aggregate": "mean", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw bar with x and x2', function () { + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'bin_Horsepower_start' }); + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'bin_Horsepower_end' }); + chai_1.assert.isUndefined(props.width); + }); + }); + describe('simple ranged', function () { + var model = util_1.parseUnitModel({ + "data": { "url": 'data/cars.json' }, + "mark": "rect", + "encoding": { + "y": { "aggregate": "min", "field": 'Horsepower', "type": "quantitative" }, + "y2": { "aggregate": "max", "field": 'Horsepower', "type": "quantitative" }, + "x": { "aggregate": "min", "field": 'Acceleration', "type": "quantitative" }, + "x2": { "aggregate": "max", "field": 'Acceleration', "type": "quantitative" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw rectange with x, x2, y, y2', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'min_Acceleration' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'max_Acceleration' }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'min_Horsepower' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'max_Horsepower' }); + }); + }); + describe('simple heatmap', function () { + var model = util_1.parseUnitModel({ + "data": { "url": "data/cars.json" }, + "mark": "rect", + "encoding": { + "y": { "field": "Origin", "type": "ordinal" }, + "x": { "field": "Cylinders", "type": "ordinal" }, + "color": { "aggregate": "mean", "field": "Horsepower", "type": "quantitative" } + } + }); + var props = rect_1.rect.encodeEntry(model); + it('should draw rect with x and y bands', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'Cylinders' }); + chai_1.assert.deepEqual(props.width, { scale: 'x', band: true }); + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'Origin' }); + chai_1.assert.deepEqual(props.height, { scale: 'y', band: true }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvcmVjdC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsdURBQW9EO0FBRXBELFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFDckIsUUFBUSxDQUFDLGlCQUFpQixFQUFFO1FBQzFCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFDO1lBQ2pDLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztnQkFDM0MsR0FBRyxFQUFFLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUM7YUFDNUU7U0FDRixDQUFDLENBQUM7UUFDSCxJQUFNLEtBQUssR0FBRyxXQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLEVBQUUsQ0FBQyw2REFBNkQsRUFBRTtZQUNoRSxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFDO1lBQ3pELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUM7WUFDeEQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsbUJBQW1CLEVBQUMsQ0FBQyxDQUFD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 \ No newline at end of file diff --git a/build/test/compile/mark/rule.test.d.ts b/build/test/compile/mark/rule.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/rule.test.js b/build/test/compile/mark/rule.test.js new file mode 100644 index 0000000000..7cc62db2a2 --- /dev/null +++ b/build/test/compile/mark/rule.test.js @@ -0,0 +1,166 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var channel_1 = require("../../../src/channel"); +var rule_1 = require("../../../src/compile/mark/rule"); +describe('Mark: Rule', function () { + describe('with x-only', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { "x": { "field": "a", "type": "quantitative" } } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create vertical rule that fits height', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.y, { field: { group: 'height' } }); + chai_1.assert.deepEqual(props.y2, { value: 0 }); + }); + }); + describe('with y-only', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { "y": { "field": "a", "type": "quantitative" } } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rule that fits height', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + chai_1.assert.deepEqual(props.x, { value: 0 }); + chai_1.assert.deepEqual(props.x2, { field: { group: 'width' } }); + }); + }); + describe('with x and x2 only', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rule on the axis', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.x2, { scale: channel_1.X, field: 'a2' }); + chai_1.assert.deepEqual(props.y, { field: { group: 'height' } }); + }); + }); + describe('with y and y2 only', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "quantitative" }, + "y2": { "field": "a2", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rules on the axis', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + chai_1.assert.deepEqual(props.y2, { scale: channel_1.Y, field: 'a2' }); + chai_1.assert.deepEqual(props.x, { value: 0 }); + }); + }); + describe('with x, x2, and y', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "quantitative" }, + "x2": { "field": "a2", "type": "quantitative" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rules', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.x2, { scale: channel_1.X, field: 'a2' }); + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'b' }); + }); + }); + describe('with y, y2, and x', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "quantitative" }, + "y2": { "field": "a2", "type": "quantitative" }, + "x": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create vertical rules', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + chai_1.assert.deepEqual(props.y2, { scale: channel_1.Y, field: 'a2' }); + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'b' }); + }); + }); + describe('with nominal x, quantitative y with no y2', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create vertical rule that emulates bar chart', function () { + chai_1.assert.equal(model.markDef.orient, 'vertical'); + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'a' }); + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'b' }); + chai_1.assert.deepEqual(props.y2, { scale: channel_1.Y, value: 0 }); + }); + }); + describe('with nominal y, quantitative x with no y2', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "ordinal" }, + "x": { "field": "b", "type": "quantitative" } + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should create horizontal rule that emulates bar chart', function () { + chai_1.assert.equal(model.markDef.orient, 'horizontal'); + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'b' }); + chai_1.assert.deepEqual(props.x2, { scale: channel_1.X, value: 0 }); + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'a' }); + }); + }); + describe('horizontal stacked rule with color', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "y": { "field": "a", "type": "ordinal" }, + "x": { "aggregate": "sum", "field": "b", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + }, + "config": { + "stack": "zero" + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should have the correct value for x, x2, and color', function () { + chai_1.assert.deepEqual(props.x, { scale: 'x', field: 'sum_b_end' }); + chai_1.assert.deepEqual(props.x2, { scale: 'x', field: 'sum_b_start' }); + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); + describe('vertical stacked rule with color', function () { + var model = util_1.parseUnitModel({ + "mark": "rule", + "encoding": { + "x": { "field": "a", "type": "ordinal" }, + "y": { "aggregate": "sum", "field": "b", "type": "quantitative" }, + "color": { "field": "Origin", "type": "nominal" } + }, + "config": { + "stack": "zero" + } + }); + var props = rule_1.rule.encodeEntry(model); + it('should have the correct value for y, y2, and color', function () { + chai_1.assert.deepEqual(props.y, { scale: 'y', field: 'sum_b_end' }); + chai_1.assert.deepEqual(props.y2, { scale: 'y', field: 'sum_b_start' }); + chai_1.assert.deepEqual(props.stroke, { scale: channel_1.COLOR, field: 'Origin' }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvcnVsZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsZ0RBQWlEO0FBQ2pELHVEQUFvRDtBQUVwRCxRQUFRLENBQUMsWUFBWSxFQUFFO0lBRXJCLFFBQVEsQ0FBQyxhQUFhLEVBQUU7UUFDdEIsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztZQUMzQixNQUFNLEVBQUUsTUFBTTtZQUNkLFVBQVUsRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBQyxFQUFDO1NBQzFELENBQUMsQ0FBQztRQUVILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLENBQUM7WUFDbEQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQyxFQUFDLENBQUMsQ0FBQztZQUN0RCxhQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1lBQzNCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsVUFBVSxFQUFFLEVB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 \ No newline at end of file diff --git a/build/test/compile/mark/text.test.d.ts b/build/test/compile/mark/text.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/text.test.js b/build/test/compile/mark/text.test.js new file mode 100644 index 0000000000..8ad313c44f --- /dev/null +++ b/build/test/compile/mark/text.test.js @@ -0,0 +1,133 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var text_1 = require("../../../src/compile/mark/text"); +var channel_1 = require("../../../src/channel"); +describe('Mark: Text', function () { + describe('with stacked x', function () { + // This is a simplified example for stacked text. + // In reality this will be used as stacked's overlayed marker + var model = util_1.parseUnitModel({ + "mark": "text", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = text_1.text.encodeEntry(model); + it('should use stack_end on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'sum_a_end' }); + }); + }); + describe('with stacked y', function () { + // This is a simplified example for stacked text. + // In reality this will be used as stacked's overlayed marker + var model = util_1.parseUnitModel({ + "mark": "text", + "encoding": { + "y": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = text_1.text.encodeEntry(model); + it('should use stack_end on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'sum_a_end' }); + }); + }); + describe('with quantitative and format', function () { + var spec = { + "mark": "text", + "encoding": { + "text": { "field": "foo", "type": "quantitative", "format": "d" } + } + }; + var model = util_1.parseUnitModel(spec); + var props = text_1.text.encodeEntry(model); + it('should use number template', function () { + chai_1.assert.deepEqual(props.text, { signal: "format(datum[\"foo\"], 'd')" }); + }); + }); + describe('with temporal', function () { + var spec = { + "mark": "text", + "encoding": { + "text": { "field": "foo", "type": "temporal" } + } + }; + var model = util_1.parseUnitModel(spec); + var props = text_1.text.encodeEntry(model); + it('should use date template', function () { + chai_1.assert.deepEqual(props.text, { signal: "timeFormat(datum[\"foo\"], '%b %d, %Y')" }); + }); + }); + describe('with x, y, text (ordinal)', function () { + var spec = { + "mark": "text", + "encoding": { + "x": { "field": "Acceleration", "type": "ordinal" }, + "y": { "field": "Displacement", "type": "quantitative" }, + "text": { "field": "Origin", "type": "ordinal" }, + }, + "data": { "url": "data/cars.json" } + }; + var model = util_1.parseUnitModel(spec); + var props = text_1.text.encodeEntry(model); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.x, { scale: channel_1.X, field: 'Acceleration' }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.y, { scale: channel_1.Y, field: 'Displacement' }); + }); + it('should be centered', function () { + chai_1.assert.deepEqual(props.align, { value: "center" }); + }); + it('should map text without template', function () { + chai_1.assert.deepEqual(props.text, { field: "Origin" }); + }); + }); + describe('with row, column, text, and color', function () { + var spec = { + "mark": "text", + "encoding": { + "row": { "field": "Origin", "type": "ordinal" }, + "column": { "field": "Cylinders", "type": "ordinal" }, + "text": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" }, + "color": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" }, + "size": { "field": "Acceleration", "type": "quantitative", "aggregate": "mean" } + }, + "data": { "url": "data/cars.json" } + }; + var model = util_1.parseModel(spec); + var props = text_1.text.encodeEntry(model.children[0]); + it('should fit cell on x', function () { + chai_1.assert.deepEqual(props.x, { field: { group: 'width' }, offset: -5 }); + }); + it('should center on y', function () { + chai_1.assert.deepEqual(props.y, { value: 10.5 }); + }); + it('should map text to expression', function () { + chai_1.assert.deepEqual(props.text, { + signal: "format(datum[\"mean_Acceleration\"], 's')" + }); + }); + it('should map color to fill', function () { + chai_1.assert.deepEqual(props.fill, { + scale: 'child_color', + field: 'mean_Acceleration' + }); + }); + it('should map size to fontSize', function () { + chai_1.assert.deepEqual(props.fontSize, { + scale: 'child_size', + field: 'mean_Acceleration' + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvdGV4dC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBc0Q7QUFDdEQsdURBQW9EO0FBQ3BELGdEQUEwQztBQUcxQyxRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixpREFBaUQ7UUFDakQsNkRBQTZEO1FBQzdELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7Z0JBQy9ELE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzthQUMzQztZQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztZQUNuQyxRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUcsTUFBTSxFQUFDO1NBQzdCLENBQUMsQ0FBQztRQUVILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLDJCQUEyQixFQUFFO1lBQzlCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBQyxDQUFDLENBQUM7UUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixpREFBaUQ7UUFDakQsNkRBQTZEO1FBQzdELElBQU0sS0FBSyxHQUFHLHFCQUFjLENB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 \ No newline at end of file diff --git a/build/test/compile/mark/tick.test.d.ts b/build/test/compile/mark/tick.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/mark/tick.test.js b/build/test/compile/mark/tick.test.js new file mode 100644 index 0000000000..7ef90b73b8 --- /dev/null +++ b/build/test/compile/mark/tick.test.js @@ -0,0 +1,138 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// TODO: +// test mark-tick with the following test cases, +// looking at mark-point.test.ts as inspiration +// +// After finishing all test, make sure all lines in mark-tick.ts is tested +// (except the scaffold labels() method) +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var channel_1 = require("../../../src/channel"); +var tick_1 = require("../../../src/compile/mark/tick"); +describe('Mark: Tick', function () { + describe('with stacked x', function () { + // This is a simplified example for stacked tick. + // In reality this will be used as stacked's overlayed marker + var model = util_1.parseUnitModel({ + "mark": "tick", + "encoding": { + "x": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = tick_1.tick.encodeEntry(model); + it('should use stack_end on x', function () { + chai_1.assert.deepEqual(props.xc, { scale: channel_1.X, field: 'sum_a_end' }); + }); + }); + describe('with stacked y', function () { + // This is a simplified example for stacked tick. + // In reality this will be used as stacked's overlayed marker + var model = util_1.parseUnitModel({ + "mark": "tick", + "encoding": { + "y": { "aggregate": "sum", "field": "a", "type": "quantitative" }, + "color": { "field": "b", "type": "ordinal" } + }, + "data": { "url": "data/barley.json" }, + "config": { "stack": "zero" } + }); + var props = tick_1.tick.encodeEntry(model); + it('should use stack_end on y', function () { + chai_1.assert.deepEqual(props.yc, { scale: channel_1.Y, field: 'sum_a_end' }); + }); + }); + describe('with quantitative x', function () { + var model = util_1.parseUnitModel({ + 'mark': 'tick', + 'encoding': { 'x': { 'field': 'Horsepower', 'type': 'quantitative' } }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick_1.tick.encodeEntry(model); + it('should be centered on y', function () { + chai_1.assert.deepEqual(props.yc, { value: 10.5 }); + }); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.xc, { scale: channel_1.X, field: 'Horsepower' }); + }); + it('width should tick thickness with orient vertical', function () { + chai_1.assert.deepEqual(props.width, { value: 1 }); + }); + }); + describe('with quantitative y', function () { + var model = util_1.parseUnitModel({ + 'mark': 'tick', + 'encoding': { 'y': { 'field': 'Cylinders', 'type': 'quantitative' } }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick_1.tick.encodeEntry(model); + it('should be centered on x', function () { + chai_1.assert.deepEqual(props.xc, { value: 10.5 }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.yc, { scale: channel_1.Y, field: 'Cylinders' }); + }); + it('height should tick thickness with orient horizontal', function () { + chai_1.assert.deepEqual(props.height, { value: 1 }); + }); + }); + describe('with quantitative x and ordinal y', function () { + var model = util_1.parseUnitModel({ + 'mark': 'tick', + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' } + }, + 'data': { 'url': 'data/cars.json' } + }); + var props = tick_1.tick.encodeEntry(model); + it('should scale on x', function () { + chai_1.assert.deepEqual(props.xc, { scale: channel_1.X, field: 'Horsepower' }); + }); + it('should scale on y', function () { + chai_1.assert.deepEqual(props.yc, { scale: channel_1.Y, field: 'Cylinders' }); + }); + it('wiidth should be tick thickness with default orient vertical', function () { + chai_1.assert.deepEqual(props.width, { value: 1 }); + }); + it('height should be matched to field with default orient vertical', function () { + chai_1.assert.deepEqual(props.height, { value: 14 }); + }); + }); + describe('width should be mapped to size', function () { + var model = util_1.parseUnitModel({ + 'mark': 'tick', + 'config': { 'mark': { 'orient': 'vertical' } }, + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' }, + 'size': { 'field': 'Acceleration', 'type': 'quantitative' } + }, + 'data': { 'url': 'data/cars.json' }, + }); + var props = tick_1.tick.encodeEntry(model); + it('width should change with size field', function () { + chai_1.assert.deepEqual(props.height, { 'field': 'Acceleration', 'scale': channel_1.SIZE }); + }); + }); + describe('height should be mapped to size', function () { + var model = util_1.parseUnitModel({ + 'mark': 'tick', + 'encoding': { + 'x': { 'field': 'Horsepower', 'type': 'quantitative' }, + 'y': { 'field': 'Cylinders', 'type': 'ordinal' }, + 'size': { 'field': 'Acceleration', 'type': 'quantitative' } + }, + 'data': { 'url': 'data/cars.json' }, + }); + var props = tick_1.tick.encodeEntry(model); + it('height should change with size field', function () { + chai_1.assert.deepEqual(props.height, { 'field': 'Acceleration', 'scale': channel_1.SIZE }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGljay50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL21hcmsvdGljay50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRzlCLFFBQVE7QUFDUixnREFBZ0Q7QUFDaEQsK0NBQStDO0FBQy9DLEVBQUU7QUFDRiwwRUFBMEU7QUFDMUUsd0NBQXdDO0FBQ3hDLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsZ0RBQWdEO0FBQ2hELHVEQUFvRDtBQUVwRCxRQUFRLENBQUMsWUFBWSxFQUFFO0lBQ3JCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixpREFBaUQ7UUFDakQsNkRBQTZEO1FBQzdELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7WUFDM0IsTUFBTSxFQUFFLE1BQU07WUFDZCxVQUFVLEVBQUU7Z0JBQ1YsR0FBRyxFQUFFLEVBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUM7Z0JBQy9ELE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQzthQUMzQztZQUNELE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztZQUNuQyxRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUcsTUFBTSxFQUFDO1NBQzdCLENBQUMsQ0FBQztRQUVILElBQU0sS0FBSyxHQUFHLFdBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFdEMsRUFBRSxDQUFDLDJCQUEyQixFQUFFO1lBQzlCLGFBQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxXQUFDLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBQyxDQUFDLENBQUM7UUFDN0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUdILFFBQVEs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 \ No newline at end of file diff --git a/build/test/compile/model.test.d.ts b/build/test/compile/model.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/model.test.js b/build/test/compile/model.test.js new file mode 100644 index 0000000000..1a5ffba085 --- /dev/null +++ b/build/test/compile/model.test.js @@ -0,0 +1,90 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../util"); +var model_1 = require("../../src/compile/model"); +describe('Model', function () { + describe('NameMap', function () { + it('should rename correctly', function () { + var map = new model_1.NameMap(); + chai_1.assert.equal(map.get('a'), 'a'); + map.rename('a', 'b'); + chai_1.assert.equal(map.get('a'), 'b'); + chai_1.assert.equal(map.get('b'), 'b'); + map.rename('b', 'c'); + chai_1.assert.equal(map.get('a'), 'c'); + chai_1.assert.equal(map.get('b'), 'c'); + chai_1.assert.equal(map.get('c'), 'c'); + map.rename('z', 'a'); + chai_1.assert.equal(map.get('a'), 'c'); + chai_1.assert.equal(map.get('b'), 'c'); + chai_1.assert.equal(map.get('c'), 'c'); + chai_1.assert.equal(map.get('z'), 'c'); + }); + }); + describe('hasDescendantWithFieldOnChannel', function () { + it('should return true if a child plot has a field on x', function () { + var model = util_1.parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + } + }); + chai_1.assert(model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return true if a descendant plot has x', function () { + var model = util_1.parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + layer: [{ + mark: 'point', + encoding: { + x: { field: 'x', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + },] + } + }); + chai_1.assert(model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return false if no descendant plot has a field on x', function () { + var model = util_1.parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + } + }); + chai_1.assert(!model.hasDescendantWithFieldOnChannel('x')); + }); + it('should return false if no descendant plot has a field on x', function () { + var model = util_1.parseFacetModel({ + facet: { row: { field: 'a', type: 'nominal' } }, + spec: { + layer: [{ + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + }, { + mark: 'point', + encoding: { + color: { field: 'x', type: 'quantitative' } + } + },] + } + }); + chai_1.assert(!model.hasDescendantWithFieldOnChannel('x')); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvY29tcGlsZS9tb2RlbC50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLGdDQUF3QztBQUN4QyxpREFBZ0Q7QUFFaEQsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixRQUFRLENBQUMsU0FBUyxFQUFFO1FBQ2xCLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRTtZQUM1QixJQUFNLEdBQUcsR0FBRyxJQUFJLGVBQU8sRUFBRSxDQUFDO1lBQzFCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUVoQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNyQixhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRWhDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLGFBQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNoQyxhQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEMsYUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRWhDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3JC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 \ No newline at end of file diff --git a/build/test/compile/scale/domain.test.d.ts b/build/test/compile/scale/domain.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/scale/domain.test.js b/build/test/compile/scale/domain.test.js new file mode 100644 index 0000000000..38c6b4ee49 --- /dev/null +++ b/build/test/compile/scale/domain.test.js @@ -0,0 +1,272 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var domain_1 = require("../../../src/compile/scale/domain"); +var data_1 = require("../../../src/data"); +var log = require("../../../src/log"); +var util_1 = require("../../util"); +describe('compile/scale', function () { + describe('parseDomain()', function () { + it('should have correct domain with x and x2 channel', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { field: 'a', type: 'quantitative' }, + x2: { field: 'b', type: 'quantitative' }, + y: { field: 'c', type: 'quantitative' }, + y2: { field: 'd', type: 'quantitative' } + } + }); + var xDomain = domain_1.parseDomain(model, 'x'); + chai_1.assert.deepEqual(xDomain, { data: 'source', fields: ['a', 'b'] }); + var yDomain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(yDomain, { data: 'source', fields: ['c', 'd'] }); + }); + it('should have correct domain for color', function () { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + color: { field: 'a', type: 'quantitative' }, + } + }); + var xDomain = domain_1.parseDomain(model, 'color'); + chai_1.assert.deepEqual(xDomain, { data: 'source', field: 'a' }); + }); + it('should return domain for stack', function () { + var model = util_1.parseUnitModel({ + mark: "bar", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + type: 'quantitative' + }, + x: { field: 'x', type: "ordinal" }, + color: { field: 'color', type: "ordinal" } + } + }); + chai_1.assert.deepEqual(domain_1.parseDomain(model, 'y'), { + data: 'stacked', + fields: ['sum_origin_start', 'sum_origin_end'] + }); + }); + describe('for quantitative', function () { + it('should return the right domain for binned Q', log.wrap(function (localLogger) { + var fieldDef = { + bin: { maxbins: 15 }, + field: 'origin', + scale: { domain: 'unaggregated' }, + type: 'quantitative' + }; + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: fieldDef + } + }); + chai_1.assert.deepEqual(domain_1.parseDomain(model, 'y'), { + signal: 'sequence(origin_bins.start, origin_bins.stop + origin_bins.step, origin_bins.step)' + }); + chai_1.assert.equal(localLogger.warns[0], log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)); + })); + it('should return the unaggregated domain if requested for non-bin, non-sum Q', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'mean', + field: 'acceleration', + scale: { domain: 'unaggregated' }, + type: "quantitative" + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain.data, data_1.SUMMARY); + chai_1.assert.deepEqual(_domain.fields, ['min_acceleration', 'max_acceleration']); + }); + it('should return the aggregated domain for sum Q', log.wrap(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'sum', + field: 'origin', + scale: { domain: 'unaggregated' }, + type: "quantitative" + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain.data, data_1.SUMMARY); + chai_1.assert.equal(localLogger.warns[0], log.message.unaggregateDomainWithNonSharedDomainOp('sum')); + })); + it('should return the right custom domain', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'horsepower', + type: "quantitative", + scale: { domain: [0, 200] } + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain, [0, 200]); + }); + it('should return the aggregated domain if we do not overrride it', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'min', + field: 'origin', + type: "quantitative" + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain.data, data_1.SUMMARY); + }); + it('should return the aggregated domain if specified in config', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + aggregate: 'min', + field: 'acceleration', + type: "quantitative" + } + }, + config: { + scale: { + useUnaggregatedDomain: true + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain.data, data_1.SUMMARY); + chai_1.assert.deepEqual(_domain.fields, ['min_acceleration', 'max_acceleration']); + }); + }); + describe('for time', function () { + it('should return the correct domain for month T', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "temporal", + timeUnit: 'month' + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain, { data: 'source', field: 'month_origin', sort: { field: 'month_origin', op: 'min', } }); + }); + it('should return the correct domain for yearmonth T', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'origin', + type: "temporal", + timeUnit: 'yearmonth' + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain, { + data: 'source', field: 'yearmonth_origin', + sort: { field: 'yearmonth_origin', op: 'min' } + }); + }); + it('should return the right custom domain with DateTime objects', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { + field: 'year', + type: "temporal", + scale: { domain: [{ year: 1970 }, { year: 1980 }] } + } + } + }); + var _domain = domain_1.parseDomain(model, 'y'); + chai_1.assert.deepEqual(_domain, [ + new Date(1970, 0, 1).getTime(), + new Date(1980, 0, 1).getTime() + ]); + }); + }); + describe('for ordinal', function () { + it('should return correct domain with the provided sort property', function () { + var sortDef = { op: 'min', field: 'Acceleration' }; + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "ordinal", sort: sortDef } + } + }); + chai_1.assert.deepEqual(domain_1.parseDomain(model, 'y'), { + data: "source", + field: 'origin', + sort: sortDef + }); + }); + it('should return correct domain without sort if sort is not provided', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + y: { field: 'origin', type: "ordinal" } + } + }); + chai_1.assert.deepEqual(domain_1.parseDomain(model, 'y'), { + data: "source", + field: 'origin', + sort: true + }); + }); + }); + }); + describe('unionDomains()', function () { + it('should union field and data ref union domains', function () { + var domain1 = { + data: 'foo', + fields: ['a', 'b'] + }; + var domain2 = { + fields: [{ + data: 'foo', + field: 'b' + }, { + data: 'foo', + field: 'c' + }] + }; + var unioned = domain_1.unionDomains(domain1, domain2); + chai_1.assert.deepEqual(unioned, { + data: 'foo', + fields: ['a', 'b', 'c'] + }); + }); + it('should union data ref union domains', function () { + var domain1 = { + data: 'foo', + fields: ['a', 'b'] + }; + var domain2 = { + data: 'foo', + fields: ['b', 'c'] + }; + var unioned = domain_1.unionDomains(domain1, domain2); + chai_1.assert.deepEqual(unioned, { + data: 'foo', + fields: ['a', 'b', 'c'] + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2NhbGUvZG9tYWluLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFHOUIsNkJBQTRCO0FBQzVCLDREQUE0RTtBQUM1RSwwQ0FBMEM7QUFDMUMsc0NBQXdDO0FBQ3hDLG1DQUEwQztBQUkxQyxRQUFRLENBQUMsZUFBZSxFQUFFO0lBQ3hCLFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFDLGtEQUFrRCxFQUFFO1lBQ3JELElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7Z0JBQ3pCLElBQUksRUFBRSxLQUFLO2dCQUNYLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7b0JBQ3JDLEVBQUUsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBQztvQkFDdEMsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO29CQUNyQyxFQUFFLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUM7aUJBQ3ZDO2FBQ0YsQ0FBQyxDQUFDO1lBRUwsSUFBTSxPQUFPLEdBQUcsb0JBQVcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDeEMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBQyxDQUFDLENBQUM7WUFFaEUsSUFBTSxPQUFPLEdBQUcsb0JBQVcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDeEMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBQyxJ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 \ No newline at end of file diff --git a/build/test/compile/scale/init.test.d.ts b/build/test/compile/scale/init.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/scale/init.test.js b/build/test/compile/scale/init.test.js new file mode 100644 index 0000000000..78da313734 --- /dev/null +++ b/build/test/compile/scale/init.test.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var init_1 = require("../../../src/compile/scale/init"); +var init_2 = require("../../../src/compile/scale/init"); +var scale_1 = require("../../../src/scale"); +var config_1 = require("../../../src/config"); +var util_1 = require("../../../src/util"); +describe('compile/scale', function () { + it('NON_TYPE_RANGE_SCALE_PROPERTIES should be SCALE_PROPERTIES wihtout type and range properties', function () { + chai_1.assert.deepEqual(util_1.toSet(init_2.NON_TYPE_RANGE_SCALE_PROPERTIES), util_1.toSet(util_1.without(scale_1.SCALE_PROPERTIES, ['type', 'range', 'rangeStep', 'scheme']))); + }); + describe('init', function () { + it('should output only padding without default paddingInner and paddingOuter if padding is specified for a band scale', function () { + var scale = init_1.default('x', { field: 'a', type: 'ordinal', scale: { type: 'band', padding: 0.6 } }, config_1.defaultConfig, 'bar', 100, []); + chai_1.assert.equal(scale.padding, 0.6); + chai_1.assert.isUndefined(scale.paddingInner); + chai_1.assert.isUndefined(scale.paddingOuter); + }); + it('should output default paddingInner and paddingOuter = paddingInner/2 if none of padding properties is specified for a band scale', function () { + var scale = init_1.default('x', { field: 'a', type: 'ordinal', scale: { type: 'band' } }, { scale: { bandPaddingInner: 0.3 } }, 'bar', 100, []); + chai_1.assert.equal(scale.paddingInner, 0.3); + chai_1.assert.equal(scale.paddingOuter, 0.15); + chai_1.assert.isUndefined(scale.padding); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NjYWxlL2luaXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUU1Qix3REFBd0Q7QUFDeEQsd0RBQWdGO0FBRWhGLDRDQUFvRDtBQUNwRCw4Q0FBa0Q7QUFDbEQsMENBQWlEO0FBRWpELFFBQVEsQ0FBQyxlQUFlLEVBQUU7SUFDeEIsRUFBRSxDQUFDLDhGQUE4RixFQUFFO1FBQ2pHLGFBQU0sQ0FBQyxTQUFTLENBQ2QsWUFBSyxDQUFDLHNDQUErQixDQUFDLEVBQ3RDLFlBQUssQ0FBQyxjQUFPLENBQUMsd0JBQWdCLEVBQUUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQzNFLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxNQUFNLEVBQUU7UUFDZixFQUFFLENBQUMsbUhBQW1ILEVBQUU7WUFDdEgsSUFBTSxLQUFLLEdBQUcsY0FBUyxDQUNyQixHQUFHLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFDLEVBQUMsRUFBRSxzQkFBYSxFQUN0RixLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FDZixDQUFDO1lBQ0YsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2pDLGFBQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3ZDLGFBQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtJQUFrSSxFQUFFO1lBQ3JJLElBQU0sS0FBSyxHQUFHLGNBQVMsQ0FDckIsR0FBRyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxFQUFDLElBQUksRUFBRSxNQUFNLEVBQUMsRUFBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEVBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFDLEVBQUMsRUFDM0YsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQ2YsQ0FBQztZQUNGLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN0QyxhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDdkMsYUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/test/compile/scale/parse.test.d.ts b/build/test/compile/scale/parse.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/scale/parse.test.js b/build/test/compile/scale/parse.test.js new file mode 100644 index 0000000000..472d4810e7 --- /dev/null +++ b/build/test/compile/scale/parse.test.js @@ -0,0 +1,151 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var parse_1 = require("../../../src/compile/scale/parse"); +var parse_2 = require("../../../src/compile/scale/parse"); +var util_1 = require("../../util"); +var scale_1 = require("../../../src/scale"); +; +var util_2 = require("../../../src/util"); +describe('src/compile', function () { + it('NON_TYPE_RANGE_SCALE_PROPERTIES should be SCALE_PROPERTIES wihtout type, domain, and range properties', function () { + chai_1.assert.deepEqual(util_2.toSet(parse_2.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES), util_2.toSet(util_2.without(scale_1.SCALE_PROPERTIES, ['type', 'domain', 'range', 'rangeStep', 'scheme']))); + }); + describe('parseScale', function () { + describe('x ordinal point', function () { + it('should create an x point scale with rangeStep and no range', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + x: { field: 'origin', type: "nominal" } + } + }); + var scales = parse_1.parseScale(model, 'x'); + chai_1.assert.equal(scales.type, 'point'); + chai_1.assert.deepEqual(scales.range, { step: 21 }); + }); + }); + describe('nominal with color', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + color: { field: 'origin', type: "nominal" } + } + }); + var scales = parse_1.parseScale(model, 'color'); + it('should create correct color scale', function () { + chai_1.assert.equal(scales.name, 'color'); + chai_1.assert.equal(scales.type, 'ordinal'); + chai_1.assert.deepEqual(scales.domain, { + data: 'source', + field: 'origin', + sort: true + }); + chai_1.assert.equal(scales.range, 'category'); + }); + }); + describe('ordinal with color', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + color: { field: 'origin', type: "ordinal" } + } + }); + var scales = parse_1.parseScale(model, 'color'); + it('should create ordinal color scale', function () { + chai_1.assert.equal(scales.name, 'color'); + chai_1.assert.equal(scales.type, 'ordinal'); + chai_1.assert.deepEqual(scales.domain, { + data: 'source', + field: 'origin', + sort: true + }); + }); + }); + describe('quantitative with color', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + color: { field: "origin", type: "quantitative" } + } + }); + var scales = parse_1.parseScale(model, 'color'); + it('should create linear color scale', function () { + chai_1.assert.equal(scales.name, 'color'); + chai_1.assert.equal(scales.type, 'sequential'); + chai_1.assert.equal(scales.range, 'ramp'); + chai_1.assert.deepEqual(scales.domain, { + data: 'source', + field: 'origin' + }); + }); + }); + describe('color with bin', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + color: { field: "origin", type: "quantitative", bin: true } + } + }); + var scales = parse_1.parseScale(model, 'color'); + it('should add correct scales', function () { + chai_1.assert.equal(scales.name, 'color'); + chai_1.assert.equal(scales.type, 'bin-ordinal'); + }); + }); + describe('ordinal color with bin', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + color: { field: "origin", type: "ordinal", bin: true } + } + }); + var scales = parse_1.parseScale(model, 'color'); + it('should add correct scales', function () { + chai_1.assert.equal(scales.name, 'color'); + chai_1.assert.equal(scales.type, 'ordinal'); + }); + }); + describe('opacity with bin', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + opacity: { field: "origin", type: "quantitative", bin: true } + } + }); + var scales = parse_1.parseScale(model, 'opacity'); + it('should add correct scales', function () { + chai_1.assert.equal(scales.name, 'opacity'); + chai_1.assert.equal(scales.type, 'bin-linear'); + }); + }); + describe('size with bin', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + size: { field: "origin", type: "quantitative", bin: true } + } + }); + var scales = parse_1.parseScale(model, 'size'); + it('should add correct scales', function () { + chai_1.assert.equal(scales.name, 'size'); + chai_1.assert.equal(scales.type, 'bin-linear'); + }); + }); + describe('color with time unit', function () { + var model = util_1.parseUnitModel({ + mark: "point", + encoding: { + color: { field: 'origin', type: "temporal", timeUnit: "year" } + } + }); + var scales = parse_1.parseScale(model, 'color'); + it('should add correct scales', function () { + chai_1.assert.equal(scales.name, 'color'); + chai_1.assert.equal(scales.type, 'sequential'); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zY2FsZS9wYXJzZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUU1QiwwREFBNEQ7QUFDNUQsMERBQTZGO0FBQzdGLG1DQUEwQztBQUcxQyw0Q0FBb0Q7QUFBQSxDQUFDO0FBQ3JELDBDQUFpRDtBQUVqRCxRQUFRLENBQUMsYUFBYSxFQUFFO0lBQ3RCLEVBQUUsQ0FBQyx1R0FBdUcsRUFBRTtRQUMxRyxhQUFNLENBQUMsU0FBUyxDQUNkLFlBQUssQ0FBQyxtREFBMkMsQ0FBQyxFQUNsRCxZQUFLLENBQUMsY0FBTyxDQUFDLHdCQUFnQixFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FDckYsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixRQUFRLENBQUMsaUJBQWlCLEVBQUU7WUFDMUIsRUFBRSxDQUFDLDREQUE0RCxFQUFFO2dCQUMvRCxJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO29CQUMzQixJQUFJLEVBQUUsT0FBTztvQkFDYixRQUFRLEVBQUU7d0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDO3FCQUN0QztpQkFDRixDQUFDLENBQUM7Z0JBQ0gsSUFBTSxNQUFNLEdBQUcsa0JBQVUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3RDLGFBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDbkMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFFLEVBQUUsRUFBQyxD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 \ No newline at end of file diff --git a/build/test/compile/scale/range.test.d.ts b/build/test/compile/scale/range.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/scale/range.test.js b/build/test/compile/scale/range.test.js new file mode 100644 index 0000000000..75bc5f7a89 --- /dev/null +++ b/build/test/compile/scale/range.test.js @@ -0,0 +1,223 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var range_1 = require("../../../src/compile/scale/range"); +var config_1 = require("../../../src/config"); +var log = require("../../../src/log"); +var scale_1 = require("../../../src/scale"); +var type_1 = require("../../../src/type"); +describe('compile/scale', function () { + describe('parseRange()', function () { + it('should return correct range.step', function () { + chai_1.assert.deepEqual(range_1.parseRange({ rangeStep: 123 }), { step: 123 }); + }); + it('should return correct range.scheme', function () { + chai_1.assert.deepEqual(range_1.parseRange({ scheme: 'viridis' }), { scheme: 'viridis' }); + }); + it('should return correct range scheme object with count', function () { + chai_1.assert.deepEqual(range_1.parseRange({ scheme: { name: 'viridis', count: 6 } }), { scheme: 'viridis', count: 6 }); + }); + it('should return correct range scheme object with extent', function () { + chai_1.assert.deepEqual(range_1.parseRange({ scheme: { name: 'viridis', extent: [0.1, 0.9] } }), { scheme: 'viridis', extent: [0.1, 0.9] }); + }); + it('should return correct range', function () { + chai_1.assert.deepEqual(range_1.parseRange({ range: 'category' }), 'category'); + }); + }); + describe('rangeMixins()', function () { + describe('row', function () { + it('should always return {range: height}.', function () { + chai_1.assert.deepEqual(range_1.default('row', 'point', type_1.NOMINAL, {}, config_1.defaultConfig, false, undefined, undefined, []), { range: 'height' }); + }); + }); + describe('column', function () { + it('should always return {range: width}.', function () { + chai_1.assert.deepEqual(range_1.default('column', 'point', type_1.NOMINAL, {}, config_1.defaultConfig, false, undefined, undefined, []), { range: 'width' }); + }); + }); + describe('x/y', function () { + it('should return config.cell.width for x-continous scales by default.', function () { + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_1 = scale_1.CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_1.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_1[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, 'point', undefined, []), { range: [0, 200] }); + } + }); + it('should return config.cell.height for y-continous scales by default.', function () { + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_2 = scale_1.CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_2.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_2[_i]; + chai_1.assert.deepEqual(range_1.default('y', scaleType, type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, 'point', undefined, []), { range: [200, 0] }); + } + }); + it('should not support custom range.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(range_1.default('x', 'linear', type_1.QUANTITATIVE, { range: [0, 100] }, config_1.defaultConfig, true, 'point', undefined, []), { range: [0, 200] }); + chai_1.assert(localLogger.warns[0], log.message.CANNOT_USE_RANGE_WITH_POSITION); + })); + it('should return config.scale.rangeStep for band/point scales by default.', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, {}, config_1.defaultConfig, undefined, 'point', undefined, []), { rangeStep: 21 }); + } + }); + it('should return config.scale.textXRangeStep by default for text mark\'s x band/point scales.', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, {}, { scale: { textXRangeStep: 55 } }, undefined, 'text', undefined, []), { rangeStep: 55 }); + } + }); + it('should return specified rangeStep if topLevelSize is undefined for band/point scales', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, { rangeStep: 23 }, config_1.defaultConfig, undefined, 'text', undefined, []), { rangeStep: 23 }); + } + }); + it('should drop rangeStep if topLevelSize is specified for band/point scales', log.wrap(function (localLogger) { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, { rangeStep: 23 }, config_1.defaultConfig, undefined, 'text', 123, []), { range: [0, 123] }); + } + chai_1.assert.equal(localLogger.warns[0], log.message.rangeStepDropped('x')); + })); + it('should return default topLevelSize if rangeStep is null for band/point scales', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, { rangeStep: null }, config_1.defaultConfig, undefined, 'text', undefined, []), { range: [0, 200] }); + } + }); + it('should return default topLevelSize if rangeStep config is null', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, {}, { cell: { width: 200 }, scale: { rangeStep: null } }, undefined, 'point', undefined, []), { range: [0, 200] }); + } + }); + it('should return default topLevelSize for text if textXRangeStep config is null', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.NOMINAL, {}, { cell: { width: 200 }, scale: { textXRangeStep: null } }, undefined, 'text', undefined, []), { range: [0, 200] }); + } + }); + it('should drop rangeStep for continuous scales', function () { + var _loop_1 = function (scaleType) { + log.wrap(function (localLogger) { + chai_1.assert.deepEqual(range_1.default('x', scaleType, type_1.QUANTITATIVE, { rangeStep: 23 }, config_1.defaultConfig, undefined, 'text', 123, []), { range: [0, 123] }); + chai_1.assert.equal(localLogger.warns[0], log.message.scalePropertyNotWorkWithScaleType(scaleType, 'rangeStep', 'x')); + })(); + }; + for (var _i = 0, CONTINUOUS_TO_CONTINUOUS_SCALES_3 = scale_1.CONTINUOUS_TO_CONTINUOUS_SCALES; _i < CONTINUOUS_TO_CONTINUOUS_SCALES_3.length; _i++) { + var scaleType = CONTINUOUS_TO_CONTINUOUS_SCALES_3[_i]; + _loop_1(scaleType); + } + }); + }); + describe('color', function () { + it('should use the specified scheme for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'ordinal', type_1.NOMINAL, { scheme: 'warm' }, config_1.defaultConfig, undefined, 'point', undefined, []), { scheme: 'warm' }); + }); + it('should use the specified scheme with extent for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'ordinal', type_1.NOMINAL, { scheme: { name: 'warm', extent: [0.2, 1] } }, config_1.defaultConfig, undefined, 'point', undefined, []), { scheme: { name: 'warm', extent: [0.2, 1] } }); + }); + it('should use the specified range for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'ordinal', type_1.NOMINAL, { range: ['red', 'green', 'blue'] }, config_1.defaultConfig, undefined, 'point', undefined, []), { range: ['red', 'green', 'blue'] }); + }); + it('should use default category range in Vega for a nominal color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'ordinal', type_1.NOMINAL, {}, config_1.defaultConfig, undefined, 'point', undefined, []), { range: 'category' }); + }); + it('should use default ordinal range in Vega for an ordinal color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'ordinal', type_1.ORDINAL, {}, config_1.defaultConfig, undefined, 'point', undefined, []), { range: 'ordinal' }); + }); + it('should use default ramp range in Vega for a temporal/quantitative color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'sequential', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'point', undefined, []), { range: 'ramp' }); + }); + it('should use the specified scheme with count for a quantitative color field.', function () { + chai_1.assert.deepEqual(range_1.default('color', 'ordinal', type_1.QUANTITATIVE, { scheme: { name: 'viridis', count: 3 } }, config_1.defaultConfig, undefined, 'point', undefined, []), { scheme: { name: 'viridis', count: 3 } }); + }); + }); + describe('opacity', function () { + it('should use default opacityRange as opacity\'s scale range.', function () { + chai_1.assert.deepEqual(range_1.default('opacity', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'point', undefined, []), { range: [config_1.defaultConfig.scale.minOpacity, config_1.defaultConfig.scale.maxOpacity] }); + }); + }); + describe('size', function () { + describe('bar', function () { + it('should return [minBandSize, maxBandSize] if both are specified', function () { + var config = { + scale: { minBandSize: 2, maxBandSize: 9 } + }; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config, undefined, 'bar', undefined, []), { range: [2, 9] }); + }); + it('should return [continuousBandSize, xRangeStep-1] by default since min/maxSize config are not specified', function () { + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'bar', undefined, []), { range: [config_1.defaultConfig.bar.continuousBandSize, config_1.defaultConfig.scale.rangeStep - 1] }); + }); + }); + describe('tick', function () { + it('should return [minBandSize, maxBandSize] if both are specified', function () { + var config = { + scale: { minBandSize: 4, maxBandSize: 9 } + }; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config, undefined, 'tick', undefined, []), { range: [4, 9] }); + }); + it('should return [(default)minBandSize, rangeStep-1] by default since maxSize config is not specified', function () { + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'tick', undefined, []), { range: [config_1.defaultConfig.scale.minBandSize, config_1.defaultConfig.scale.rangeStep - 1] }); + }); + }); + describe('text', function () { + it('should return [minFontSize, maxFontSize]', function () { + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'text', undefined, []), { range: [config_1.defaultConfig.scale.minFontSize, config_1.defaultConfig.scale.maxFontSize] }); + }); + }); + describe('rule', function () { + it('should return [minStrokeWidth, maxStrokeWidth]', function () { + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'rule', undefined, []), { range: [config_1.defaultConfig.scale.minStrokeWidth, config_1.defaultConfig.scale.maxStrokeWidth] }); + }); + }); + describe('point, square, circle', function () { + it('should return [minSize, maxSize]', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + var config = { + scale: { + minSize: 5, + maxSize: 25 + } + }; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config, undefined, m, undefined, []), { range: [5, 25] }); + } + }); + it('should return [0, (minBandSize-2)^2] if both x and y are discrete and size is quantitative (thus use zero=true, by default)', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, m, undefined, [11, 13] // xyRangeSteps + ), { range: [0, 81] }); + } + }); + it('should return [9, (minBandSize-2)^2] if both x and y are discrete and size is not quantitative (thus use zero=false, by default)', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, false, m, undefined, [11, 13] // xyRangeSteps + ), { range: [9, 81] }); + } + }); + it('should return [9, (minBandSize-2)^2] if both x and y are discrete and size is quantitative but use zero=false', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, false, m, undefined, [11, 13] // xyRangeSteps + ), { range: [9, 81] }); + } + }); + it('should return [0, (xRangeStep-2)^2] if x is discrete and y is continuous and size is quantitative (thus use zero=true, by default)', function () { + for (var _i = 0, _a = ['point', 'square', 'circle']; _i < _a.length; _i++) { + var m = _a[_i]; + chai_1.assert.deepEqual(range_1.default('size', 'linear', type_1.QUANTITATIVE, {}, config_1.defaultConfig, true, m, undefined, [11] // xyRangeSteps only have one value + ), { range: [0, 81] }); + } + }); + }); + }); + describe('shape', function () { + it('should use default symbol range in Vega as shape\'s scale range.', function () { + chai_1.assert.deepEqual(range_1.default('shape', 'ordinal', type_1.QUANTITATIVE, {}, config_1.defaultConfig, undefined, 'point', undefined, []), { range: 'symbol' }); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zY2FsZS9yYW5nZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUU1QiwwREFBb0Y7QUFFcEYsOENBQWtEO0FBQ2xELHNDQUF3QztBQUV4Qyw0Q0FBOEU7QUFDOUUsMENBQWlFO0FBRWpFLFFBQVEsQ0FBQyxlQUFlLEVBQUU7SUFDeEIsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMsa0NBQWtDLEVBQUU7WUFDckMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQkFBVSxDQUFDLEVBQUMsU0FBUyxFQUFFLEdBQUcsRUFBQyxDQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUUsR0FBRyxFQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtZQUN2QyxhQUFNLENBQUMsU0FBUyxDQUFDLGtCQUFVLENBQUMsRUFBQyxNQUFNLEVBQUUsU0FBUyxFQUFDLENBQUMsRUFBRSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUMsQ0FBQyxDQUFDO1FBQ3pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNEQUFzRCxFQUFFO1lBQ3pELGFBQU0sQ0FBQyxTQUFTLENBQUMsa0JBQVUsQ0FBQyxFQUFDLE1BQU0sRUFBRSxFQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFHLENBQUMsRUFBQyxFQUFDLENBQUMsRUFBRSxFQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDdEcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQkFBVSxDQUFDLEVBQUMsTUFBTSxFQUFFLEVBQUMsSUFBSSxFQUFFLFNB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 \ No newline at end of file diff --git a/build/test/compile/scale/rules.test.d.ts b/build/test/compile/scale/rules.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/scale/rules.test.js b/build/test/compile/scale/rules.test.js new file mode 100644 index 0000000000..88f3b1a87e --- /dev/null +++ b/build/test/compile/scale/rules.test.js @@ -0,0 +1,108 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var channel_1 = require("../../../src/channel"); +var rules = require("../../../src/compile/scale/rules"); +describe('compile/scale', function () { + describe('nice', function () { + // TODO: + }); + describe('padding', function () { + it('should be pointPadding for point scale if channel is x or y and padding is not specified.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + chai_1.assert.equal(rules.padding(c, 'point', { pointPadding: 13 }), 13); + } + }); + }); + describe('paddingInner', function () { + it('should be undefined if padding is specified.', function () { + chai_1.assert.equal(rules.paddingInner(10, 'x', {}), undefined); + }); + it('should be bandPaddingInner if channel is x or y and padding is not specified.', function () { + chai_1.assert.equal(rules.paddingInner(undefined, 'x', { bandPaddingInner: 15 }), 15); + chai_1.assert.equal(rules.paddingInner(undefined, 'y', { bandPaddingInner: 15 }), 15); + }); + it('should be undefined for non-xy channels.', function () { + for (var _i = 0, NONSPATIAL_SCALE_CHANNELS_1 = channel_1.NONSPATIAL_SCALE_CHANNELS; _i < NONSPATIAL_SCALE_CHANNELS_1.length; _i++) { + var c = NONSPATIAL_SCALE_CHANNELS_1[_i]; + chai_1.assert.equal(rules.paddingInner(undefined, c, { bandPaddingInner: 15 }), undefined); + } + }); + }); + describe('paddingOuter', function () { + it('should be undefined if padding is specified.', function () { + for (var _i = 0, _a = ['point', 'band']; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert.equal(rules.paddingOuter(10, 'x', scaleType, 0, {}), undefined); + } + }); + it('should be config.scale.bandPaddingOuter for band scale if channel is x or y and padding is not specified and config.scale.bandPaddingOuter.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + chai_1.assert.equal(rules.paddingOuter(undefined, c, 'band', 0, { bandPaddingOuter: 16 }), 16); + } + }); + it('should be paddingInner/2 for band scale if channel is x or y and padding is not specified and config.scale.bandPaddingOuter.', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var c = _a[_i]; + chai_1.assert.equal(rules.paddingOuter(undefined, c, 'band', 10, {}), 5); + } + }); + it('should be undefined for non-xy channels.', function () { + for (var _i = 0, NONSPATIAL_SCALE_CHANNELS_2 = channel_1.NONSPATIAL_SCALE_CHANNELS; _i < NONSPATIAL_SCALE_CHANNELS_2.length; _i++) { + var c = NONSPATIAL_SCALE_CHANNELS_2[_i]; + for (var _a = 0, _b = ['point', 'band']; _a < _b.length; _a++) { + var scaleType = _b[_a]; + chai_1.assert.equal(rules.paddingOuter(undefined, c, scaleType, 0, {}), undefined); + } + } + }); + }); + describe('round', function () { + it('should return scaleConfig.round for x, y, row, column.', function () { + for (var _i = 0, _a = ['x', 'y', 'row', 'column']; _i < _a.length; _i++) { + var c = _a[_i]; + chai_1.assert(rules.round(c, { round: true })); + chai_1.assert(!rules.round(c, { round: false })); + } + }); + it('should return undefined other channels (not x, y, row, column).', function () { + for (var _i = 0, NONSPATIAL_SCALE_CHANNELS_3 = channel_1.NONSPATIAL_SCALE_CHANNELS; _i < NONSPATIAL_SCALE_CHANNELS_3.length; _i++) { + var c = NONSPATIAL_SCALE_CHANNELS_3[_i]; + chai_1.assert.isUndefined(rules.round(c, { round: true })); + chai_1.assert.isUndefined(rules.round(c, { round: false })); + } + }); + }); + describe('zero', function () { + it('should return true when mapping a quantitative field to size', function () { + chai_1.assert(rules.zero({}, 'size', { field: 'a', type: 'quantitative' })); + }); + it('should return false when mapping a ordinal field to size', function () { + chai_1.assert(!rules.zero({}, 'size', { field: 'a', type: 'ordinal' })); + }); + it('should return true when mapping a non-binned quantitative field to x/y', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(rules.zero({}, channel, { field: 'a', type: 'quantitative' })); + } + }); + it('should return false when mapping a binned quantitative field to x/y', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(!rules.zero({}, channel, { bin: true, field: 'a', type: 'quantitative' })); + } + }); + it('should return false when mapping a non-binned quantitative field with custom domain to x/y', function () { + for (var _i = 0, _a = ['x', 'y']; _i < _a.length; _i++) { + var channel = _a[_i]; + chai_1.assert(!rules.zero({ domain: [1, 5] }, channel, { + bin: true, field: 'a', type: 'quantitative' + })); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zY2FsZS9ydWxlcy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUU1QixnREFBd0U7QUFHeEUsd0RBQTBEO0FBRTFELFFBQVEsQ0FBQyxlQUFlLEVBQUU7SUFDeEIsUUFBUSxDQUFDLE1BQU0sRUFBRTtRQUNmLFFBQVE7SUFDVixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxTQUFTLEVBQUU7UUFDbEIsRUFBRSxDQUFDLDJGQUEyRixFQUFFO1lBQzlGLEdBQUcsQ0FBQyxDQUFVLFVBQXVCLEVBQXZCLEtBQUEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFjLEVBQXZCLGNBQXVCLEVBQXZCLElBQXVCO2dCQUFoQyxJQUFJLENBQUMsU0FBQTtnQkFDUixhQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxFQUFDLFlBQVksRUFBRSxFQUFFLEVBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ2pFO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDdkIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtFQUErRSxFQUFFO1lBQ2xGLGFBQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLEVBQUMsZ0JBQWdCLEVBQUUsRUFBRSxFQUFDLENBQUMsRUFBRSxFQUFFLENB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 \ No newline at end of file diff --git a/build/test/compile/scale/type.test.d.ts b/build/test/compile/scale/type.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/scale/type.test.js b/build/test/compile/scale/type.test.js new file mode 100644 index 0000000000..fadd976c04 --- /dev/null +++ b/build/test/compile/scale/type.test.js @@ -0,0 +1,190 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../../../src/log"); +var config_1 = require("../../../src/config"); +var channel_1 = require("../../../src/channel"); +var mark_1 = require("../../../src/mark"); +var scale_1 = require("../../../src/scale"); +var type_1 = require("../../../src/type"); +var type_2 = require("../../../src/compile/scale/type"); +var timeunit_1 = require("../../../src/timeunit"); +var util = require("../../../src/util"); +describe('compile/scale', function () { + describe('type()', function () { + it('should return null for channel without scale', function () { + chai_1.assert.deepEqual(type_2.default(undefined, 'detail', { type: 'temporal', timeUnit: 'yearmonth' }, 'point', undefined, undefined, config_1.defaultConfig), null); + }); + it('should show warning if users try to override the scale and use bin', function () { + log.runLocalLogger(function (localLogger) { + chai_1.assert.deepEqual(type_2.default('point', 'color', { type: 'quantitative', bin: 'true' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.BIN_ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.cannotOverrideBinScaleType('color', 'bin-ordinal')); + }); + }); + describe('row/column', function () { + it('should return band for row/column', function () { + [channel_1.ROW, channel_1.COLUMN].forEach(function (channel) { + chai_1.assert.deepEqual(type_2.default(undefined, channel, { type: 'temporal', timeUnit: 'yearmonth' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.BAND); + }); + }); + it('should return band for row/column even if other type is specified', function () { + [channel_1.ROW, channel_1.COLUMN].forEach(function (channel) { + [scale_1.ScaleType.LINEAR, scale_1.ScaleType.ORDINAL, scale_1.ScaleType.POINT].forEach(function (badScaleType) { + log.runLocalLogger(function (localLogger) { + chai_1.assert.deepEqual(type_2.default(badScaleType, channel, { type: 'temporal', timeUnit: 'yearmonth' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.BAND); + chai_1.assert.equal(localLogger.warns[0], log.message.scaleTypeNotWorkWithChannel(channel, badScaleType, 'band')); + }); + }); + }); + }); + }); + describe('nominal/ordinal', function () { + describe('color', function () { + it('should return ordinal scale for nominal data by default.', function () { + chai_1.assert.equal(type_2.default(undefined, 'color', { type: 'nominal' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + }); + it('should return ordinal scale for ordinal data.', function () { + chai_1.assert.equal(type_2.default(undefined, 'color', { type: 'nominal' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + }); + }); + describe('discrete channel (shape)', function () { + it('should return ordinal for nominal field', function () { + chai_1.assert.deepEqual(type_2.default(undefined, 'shape', { type: 'nominal' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + }); + it('should return ordinal even if other type is specified', function () { + [scale_1.ScaleType.LINEAR, scale_1.ScaleType.BAND, scale_1.ScaleType.POINT].forEach(function (badScaleType) { + log.runLocalLogger(function (localLogger) { + chai_1.assert.deepEqual(type_2.default(badScaleType, 'shape', { type: 'nominal' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.scaleTypeNotWorkWithChannel('shape', badScaleType, 'ordinal')); + }); + }); + }); + it('should return ordinal for an ordinal field and throw a warning.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(type_2.default(undefined, 'shape', { type: 'ordinal' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'ordinal')); + })); + }); + describe('continuous', function () { + it('should return point scale for ordinal X,Y for marks others than rect and bar', function () { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + if (util.contains(['bar', 'rect'], mark)) { + return; + } + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_2.default(undefined, channel, { type: t }, mark, undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.POINT); + }); + }); + }); + }); + it('should return band scale for ordinal X,Y when mark is rect', function () { + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_2.default(undefined, channel, { type: t }, 'rect', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.BAND); + }); + }); + }); + it('should return band scale for X,Y when mark is bar and rangeStep is null (fit)', function () { + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_2.default(undefined, channel, { type: t }, 'bar', null, undefined, config_1.defaultConfig), scale_1.ScaleType.BAND); + }); + }); + }); + it('should return point scale for X,Y when mark is bar and rangeStep is defined', function () { + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_2.default(undefined, channel, { type: t }, 'bar', undefined, 21, config_1.defaultConfig), scale_1.ScaleType.POINT); + }); + }); + }); + it('should return point scale for X,Y when mark is point', function () { + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + chai_1.assert.equal(type_2.default(undefined, channel, { type: t }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.POINT); + }); + }); + }); + it('should return point scale for X,Y when mark is point when ORDINAL SCALE TYPE is specified and throw warning', function () { + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + [channel_1.X, channel_1.Y].forEach(function (channel) { + log.runLocalLogger(function (localLogger) { + chai_1.assert.equal(type_2.default('ordinal', channel, { type: t }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.POINT); + chai_1.assert.equal(localLogger.warns[0], log.message.scaleTypeNotWorkWithChannel(channel, 'ordinal', 'point')); + }); + }); + }); + }); + it('should return point scale for ordinal/nominal fields for continous channels other than x and y.', function () { + var OTHER_CONTINUOUS_CHANNELS = channel_1.CHANNELS.filter(function (c) { return channel_1.rangeType(c) === 'continuous' && !util.contains([channel_1.X, channel_1.Y, channel_1.ROW, channel_1.COLUMN], c); }); + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + [type_1.ORDINAL, type_1.NOMINAL].forEach(function (t) { + OTHER_CONTINUOUS_CHANNELS.forEach(function (channel) { + chai_1.assert.equal(type_2.default(undefined, channel, { type: t }, mark, undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.POINT, channel + ", " + mark + ", " + t + " " + type_2.default(undefined, channel, { type: t }, mark, undefined, undefined, config_1.defaultConfig)); + }); + }); + }); + }); + }); + }); + describe('temporal', function () { + it('should return sequential scale for temporal color field by default.', function () { + chai_1.assert.equal(type_2.default(undefined, 'color', { type: 'temporal' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.SEQUENTIAL); + }); + it('should return ordinal for temporal field and throw a warning.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(type_2.default(undefined, 'shape', { type: 'temporal', timeUnit: 'yearmonth' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'temporal')); + })); + it('should return time for most of time unit.', function () { + // See exception in the next test) + var TIMEUNITS = [ + timeunit_1.TimeUnit.YEAR, + timeunit_1.TimeUnit.DATE, + timeunit_1.TimeUnit.MINUTES, + timeunit_1.TimeUnit.SECONDS, + timeunit_1.TimeUnit.MILLISECONDS, + timeunit_1.TimeUnit.YEARMONTH, + timeunit_1.TimeUnit.YEARMONTHDATE, + timeunit_1.TimeUnit.YEARMONTHDATEHOURS, + timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTES, + timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, + timeunit_1.TimeUnit.HOURSMINUTES, + timeunit_1.TimeUnit.HOURSMINUTESSECONDS, + timeunit_1.TimeUnit.MINUTESSECONDS, + timeunit_1.TimeUnit.SECONDSMILLISECONDS, + timeunit_1.TimeUnit.YEARQUARTER, + timeunit_1.TimeUnit.QUARTERMONTH, + timeunit_1.TimeUnit.YEARQUARTERMONTH, + ]; + for (var _i = 0, TIMEUNITS_1 = TIMEUNITS; _i < TIMEUNITS_1.length; _i++) { + var timeUnit = TIMEUNITS_1[_i]; + chai_1.assert.deepEqual(type_2.default(undefined, channel_1.Y, { type: 'temporal', timeUnit: timeUnit }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.TIME); + } + }); + it('should return a discrete scale for hours, day, month, quarter for x-y', function () { + [timeunit_1.TimeUnit.MONTH, timeunit_1.TimeUnit.HOURS, timeunit_1.TimeUnit.DAY, timeunit_1.TimeUnit.QUARTER].forEach(function (timeUnit) { + chai_1.assert.deepEqual(type_2.default(undefined, channel_1.Y, { type: 'temporal', timeUnit: timeUnit }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.POINT); + }); + }); + }); + describe('quantitative', function () { + it('should return sequential scale for quantitative color field by default.', function () { + chai_1.assert.equal(type_2.default(undefined, 'color', { type: 'quantitative' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.SEQUENTIAL); + }); + it('should return ordinal bin scale for quantitative color field with binning.', function () { + chai_1.assert.equal(type_2.default(undefined, 'color', { type: 'quantitative', bin: true }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.BIN_ORDINAL); + }); + it('should return ordinal for encoding quantitative field with a discrete channel and throw a warning.', log.wrap(function (localLogger) { + chai_1.assert.deepEqual(type_2.default(undefined, 'shape', { type: 'quantitative' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.ORDINAL); + chai_1.assert.equal(localLogger.warns[0], log.message.discreteChannelCannotEncode('shape', 'quantitative')); + })); + it('should return linear scale for quantitative by default.', function () { + chai_1.assert.equal(type_2.default(undefined, 'x', { type: 'quantitative' }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.LINEAR); + }); + it('should return bin linear scale for quantitative by default.', function () { + chai_1.assert.equal(type_2.default(undefined, 'x', { type: 'quantitative', bin: true }, 'point', undefined, undefined, config_1.defaultConfig), scale_1.ScaleType.BIN_LINEAR); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NjYWxlL3R5cGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUU1QixzQ0FBd0M7QUFFeEMsOENBQWtEO0FBQ2xELGdEQUE0RTtBQUM1RSwwQ0FBa0Q7QUFDbEQsNENBQTZDO0FBQzdDLDBDQUFtRDtBQUNuRCx3REFBd0Q7QUFDeEQsa0RBQStDO0FBQy9DLHdDQUEwQztBQUUxQyxRQUFRLENBQUMsZUFBZSxFQUFFO0lBQ3hCLFFBQVEsQ0FBQyxRQUFRLEVBQUU7UUFDakIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELGFBQU0sQ0FBQyxTQUFTLENBQ2QsY0FBUyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsRUFBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxzQkFBYSxDQUFDLEVBQ3ZILElBQUksQ0FDTCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0VBQW9FLEVBQUU7WUFDdkUsR0FBRyxDQUFDLGNBQWMsQ0FBQyxVQUFDLFdBQVc7Z0JBQzdCLGFBQU0sQ0FBQyxTQUFTLENBQ2QsY0FBUyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUUsY0FBYyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxzQkFBYSxDQUFDLEVBQzlHLGlCQUFTLENBQUMsV0FBVyxDQUN0QixDQUFDO2dCQUNGLGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDO1lB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 \ No newline at end of file diff --git a/build/test/compile/selection/inputs.test.d.ts b/build/test/compile/selection/inputs.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/inputs.test.js b/build/test/compile/selection/inputs.test.js new file mode 100644 index 0000000000..4a7afdece5 --- /dev/null +++ b/build/test/compile/selection/inputs.test.js @@ -0,0 +1,160 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var selection = require("../../../src/compile/selection/selection"); +var inputs_1 = require("../../../src/compile/selection/transforms/inputs"); +describe('Inputs Selection Transform', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + model.parseScale(); + var selCmpts = selection.parseUnitSelection(model, { + "one": { + "type": "single", + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + "two": { + "type": "single", + "fields": ["Cylinders", "Horsepower"], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + "three": { + "type": "single", + "fields": ["Cylinders", "Origin"], + "bind": { + "Horsepower": { "input": "range", "min": 0, "max": 10, "step": 1 }, + "Origin": { "input": "select", "options": ["Japan", "USA", "Europe"] } + } + }, + "four": { + "type": "multi", + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + "five": { + "type": "interval", + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + "six": { + "type": "interval", + "bind": "scales" + }, + "seven": { + "type": "single", + "bind": "scales" + } + }); + it('identifies transform invocation', function () { + chai_1.assert.isTrue(inputs_1.default.has(selCmpts['one'])); + chai_1.assert.isTrue(inputs_1.default.has(selCmpts['two'])); + chai_1.assert.isTrue(inputs_1.default.has(selCmpts['three'])); + chai_1.assert.isFalse(inputs_1.default.has(selCmpts['four'])); + chai_1.assert.isFalse(inputs_1.default.has(selCmpts['five'])); + chai_1.assert.isFalse(inputs_1.default.has(selCmpts['six'])); + chai_1.assert.isFalse(inputs_1.default.has(selCmpts['four'])); + }); + it('adds widget binding for default projection', function () { + model.component.selection = { one: selCmpts['one'] }; + chai_1.assert.includeDeepMembers(selection.assembleUnitSignals(model, []), [ + { + "name": "one", + "update": "{fields: [\"_id\"], values: [one__id]}" + } + ]); + chai_1.assert.includeDeepMembers(selection.assembleTopLevelSignals(model), [ + { + "name": "one__id", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "(item().isVoronoi ? datum.datum : datum)[\"_id\"]" + } + ], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + } + ]); + }); + it('adds single widget binding for compound projection', function () { + model.component.selection = { two: selCmpts['two'] }; + chai_1.assert.includeDeepMembers(selection.assembleUnitSignals(model, []), [ + { + "name": "two", + "update": "{fields: [\"Cylinders\", \"Horsepower\"], values: [two_Cylinders, two_Horsepower]}" + } + ]); + chai_1.assert.includeDeepMembers(selection.assembleTopLevelSignals(model), [ + { + "name": "two_Horsepower", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "(item().isVoronoi ? datum.datum : datum)[\"Horsepower\"]" + } + ], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + }, + { + "name": "two_Cylinders", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "(item().isVoronoi ? datum.datum : datum)[\"Cylinders\"]" + } + ], + "bind": { "input": "range", "min": 0, "max": 10, "step": 1 } + } + ]); + }); + it('adds projection-specific widget bindings', function () { + model.component.selection = { three: selCmpts['three'] }; + chai_1.assert.includeDeepMembers(selection.assembleUnitSignals(model, []), [ + { + "name": "three", + "update": "{fields: [\"Cylinders\", \"Origin\"], values: [three_Cylinders, three_Origin]}" + } + ]); + chai_1.assert.includeDeepMembers(selection.assembleTopLevelSignals(model), [ + { + "name": "three_Origin", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "(item().isVoronoi ? datum.datum : datum)[\"Origin\"]" + } + ], + "bind": { + "input": "select", + "options": ["Japan", "USA", "Europe"] + } + }, + { + "name": "three_Cylinders", + "value": "", + "on": [ + { + "events": [{ "source": "scope", "type": "click" }], + "update": "(item().isVoronoi ? datum.datum : datum)[\"Cylinders\"]" + } + ], + "bind": { + "Horsepower": { "input": "range", "min": 0, "max": 10, "step": 1 }, + "Origin": { + "input": "select", + "options": ["Japan", "USA", "Europe"] + } + } + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL2lucHV0cy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsb0VBQXNFO0FBQ3RFLDJFQUFzRTtBQUV0RSxRQUFRLENBQUMsNEJBQTRCLEVBQUU7SUFDckMsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDO1NBQzFDO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLElBQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDbkQsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLFFBQVE7WUFDaEIsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBQztTQUMzRDtRQUNELEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLFFBQVEsRUFBRSxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUM7WUFDckMsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFF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 \ No newline at end of file diff --git a/build/test/compile/selection/interval.test.d.ts b/build/test/compile/selection/interval.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/interval.test.js b/build/test/compile/selection/interval.test.js new file mode 100644 index 0000000000..4193a5fa6b --- /dev/null +++ b/build/test/compile/selection/interval.test.js @@ -0,0 +1,347 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var selection = require("../../../src/compile/selection/selection"); +var interval_1 = require("../../../src/compile/selection/interval"); +describe('Interval Selections', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + model.parseScale(); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "interval", "encodings": ["x"], "translate": false, "zoom": false }, + "two": { + "type": "interval", + "encodings": ["y"], + "bind": "scales", + "translate": false, + "zoom": false + }, + "three": { + "type": "interval", + "on": "[mousedown, mouseup] > mousemove, [keydown, keyup] > keypress", + "translate": false, + "zoom": false + } + }); + describe('Trigger Signals', function () { + it('builds projection signals', function () { + var oneSg = interval_1.default.signals(model, selCmpts['one']); + chai_1.assert.includeDeepMembers(oneSg, [{ + "name": "one_x", + "value": [], + "on": [ + { + "events": event_selector_1.default('mousedown', 'scope')[0], + "update": "invert(\"x\", [x(unit), x(unit)])" + }, + { + "events": event_selector_1.default('[mousedown, window:mouseup] > window:mousemove!', 'scope')[0], + "update": "[one_x[0], invert(\"x\", clamp(x(unit), 0, width))]" + } + ] + }]); + var twoSg = interval_1.default.signals(model, selCmpts['two']); + chai_1.assert.includeDeepMembers(twoSg, [{ + "name": "two_y", + "on": [], + "value": [] + }]); + var threeSg = interval_1.default.signals(model, selCmpts['three']); + chai_1.assert.includeDeepMembers(threeSg, [ + { + "name": "three_x", + "value": [], + "on": [ + { + "events": event_selector_1.default('mousedown', 'scope')[0], + "update": "invert(\"x\", [x(unit), x(unit)])" + }, + { + "events": event_selector_1.default('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "[three_x[0], invert(\"x\", clamp(x(unit), 0, width))]" + }, + { + "events": event_selector_1.default('keydown', 'scope')[0], + "update": "invert(\"x\", [x(unit), x(unit)])" + }, + { + "events": event_selector_1.default('[keydown, keyup] > keypress', 'scope')[0], + "update": "[three_x[0], invert(\"x\", clamp(x(unit), 0, width))]" + } + ] + }, + { + "name": "three_y", + "value": [], + "on": [ + { + "events": event_selector_1.default('mousedown', 'scope')[0], + "update": "invert(\"y\", [y(unit), y(unit)])" + }, + { + "events": event_selector_1.default('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "[three_y[0], invert(\"y\", clamp(y(unit), 0, height))]" + }, + { + "events": event_selector_1.default('keydown', 'scope')[0], + "update": "invert(\"y\", [y(unit), y(unit)])" + }, + { + "events": event_selector_1.default('[keydown, keyup] > keypress', 'scope')[0], + "update": "[three_y[0], invert(\"y\", clamp(y(unit), 0, height))]" + } + ] + } + ]); + }); + it('builds size signals', function () { + var oneSg = interval_1.default.signals(model, selCmpts['one']); + chai_1.assert.includeDeepMembers(oneSg, [{ + "name": "one_size", + "value": [], + "on": [ + { + "events": event_selector_1.default('mousedown', 'scope')[0], + "update": "{x: x(unit), y: y(unit), width: 0, height: 0}" + }, + { + "events": event_selector_1.default('[mousedown, window:mouseup] > window:mousemove!', 'scope')[0], + "update": "{x: one_size.x, y: one_size.y, width: abs(x(unit) - one_size.x), height: abs(y(unit) - one_size.y)}" + } + ] + }]); + // Skip twoSg because bindScales should remove the size. + var threeSg = interval_1.default.signals(model, selCmpts['three']); + chai_1.assert.includeDeepMembers(threeSg, [{ + "name": "three_size", + "value": [], + "on": [ + { + "events": event_selector_1.default('mousedown', 'scope')[0], + "update": "{x: x(unit), y: y(unit), width: 0, height: 0}" + }, + { + "events": event_selector_1.default('[mousedown, mouseup] > mousemove', 'scope')[0], + "update": "{x: three_size.x, y: three_size.y, width: abs(x(unit) - three_size.x), height: abs(y(unit) - three_size.y)}" + }, + { + "events": event_selector_1.default('keydown', 'scope')[0], + "update": "{x: x(unit), y: y(unit), width: 0, height: 0}" + }, + { + "events": event_selector_1.default('[keydown, keyup] > keypress', 'scope')[0], + "update": "{x: three_size.x, y: three_size.y, width: abs(x(unit) - three_size.x), height: abs(y(unit) - three_size.y)}" + } + ] + }]); + }); + it('builds trigger signals', function () { + var oneSg = interval_1.default.signals(model, selCmpts['one']); + chai_1.assert.includeDeepMembers(oneSg, [ + { + "name": "one", + "update": "[{field: \"Horsepower\", extent: one_x}]" + } + ]); + var twoSg = interval_1.default.signals(model, selCmpts['two']); + chai_1.assert.includeDeepMembers(twoSg, [ + { + "name": "two", + "update": "[{field: \"Miles_per_Gallon\", extent: two_y}]" + } + ]); + var threeSg = interval_1.default.signals(model, selCmpts['three']); + chai_1.assert.includeDeepMembers(threeSg, [ + { + "name": "three", + "update": "[{field: \"Horsepower\", extent: three_x}, {field: \"Miles_per_Gallon\", extent: three_y}]" + } + ]); + }); + }); + it('builds tuple signals', function () { + var oneExpr = interval_1.default.tupleExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'intervals: one'); + var twoExpr = interval_1.default.tupleExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'intervals: two'); + var threeExpr = interval_1.default.tupleExpr(model, selCmpts['three']); + chai_1.assert.equal(threeExpr, 'intervals: three'); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "one_tuple", + "on": [ + { + "events": { "signal": "one" }, + "update": "{unit: unit.datum && unit.datum._id, " + oneExpr + "}" + } + ] + }, + { + "name": "two_tuple", + "on": [ + { + "events": { "signal": "two" }, + "update": "{unit: unit.datum && unit.datum._id, " + twoExpr + "}" + } + ] + }, + { + "name": "three_tuple", + "on": [ + { + "events": { "signal": "three" }, + "update": "{unit: unit.datum && unit.datum._id, " + threeExpr + "}" + } + ] + } + ]); + }); + it('builds modify signals', function () { + var oneExpr = interval_1.default.modifyExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'one_tuple, {unit: one_tuple.unit}'); + var twoExpr = interval_1.default.modifyExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'two_tuple, {unit: two_tuple.unit}'); + var threeExpr = interval_1.default.modifyExpr(model, selCmpts['three']); + chai_1.assert.equal(threeExpr, 'three_tuple, {unit: three_tuple.unit}'); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "one_modify", + "on": [ + { + "events": { "signal": "one" }, + "update": "modify(\"one_store\", " + oneExpr + ")" + } + ] + }, + { + "name": "two_modify", + "on": [ + { + "events": { "signal": "two" }, + "update": "modify(\"two_store\", " + twoExpr + ")" + } + ] + }, + { + "name": "three_modify", + "on": [ + { + "events": { "signal": "three" }, + "update": "modify(\"three_store\", " + threeExpr + ")" + } + ] + } + ]); + }); + it('builds brush mark', function () { + var marks = [{ hello: "world" }]; + chai_1.assert.sameDeepMembers(interval_1.default.marks(model, selCmpts['one'], marks), [ + { + "name": undefined, + "type": "rect", + "encode": { + "enter": { "fill": { "value": "#eee" } }, + "update": { + "x": { + "scale": "x", + "signal": "one[0].extent[0]" + }, + "x2": { + "scale": "x", + "signal": "one[0].extent[1]" + }, + "y": { "value": 0 }, + "y2": { "field": { "group": "height" } } + } + } + }, + { "hello": "world" }, + { + "name": "one_brush", + "type": "rect", + "encode": { + "enter": { "fill": { "value": "transparent" } }, + "update": { + "x": { + "scale": "x", + "signal": "one[0].extent[0]" + }, + "x2": { + "scale": "x", + "signal": "one[0].extent[1]" + }, + "y": { "value": 0 }, + "y2": { "field": { "group": "height" } } + } + } + } + ]); + // Scale-bound interval selections should not add a brush mark. + chai_1.assert.sameDeepMembers(interval_1.default.marks(model, selCmpts['two'], marks), marks); + chai_1.assert.sameDeepMembers(interval_1.default.marks(model, selCmpts['three'], marks), [ + { + "name": undefined, + "type": "rect", + "encode": { + "enter": { "fill": { "value": "#eee" } }, + "update": { + "x": { + "scale": "x", + "signal": "three[0].extent[0]" + }, + "x2": { + "scale": "x", + "signal": "three[0].extent[1]" + }, + "y": { + "scale": "y", + "signal": "three[1].extent[0]" + }, + "y2": { + "scale": "y", + "signal": "three[1].extent[1]" + } + } + } + }, + { "hello": "world" }, + { + "name": "three_brush", + "type": "rect", + "encode": { + "enter": { "fill": { "value": "transparent" } }, + "update": { + "x": { + "scale": "x", + "signal": "three[0].extent[0]" + }, + "x2": { + "scale": "x", + "signal": "three[0].extent[1]" + }, + "y": { + "scale": "y", + "signal": "three[1].extent[0]" + }, + "y2": { + "scale": "y", + "signal": "three[1].extent[1]" + } + } + } + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJ2YWwudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vaW50ZXJ2YWwudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQTBDO0FBQzFDLHlFQUFnRjtBQUNoRixvRUFBc0U7QUFDdEUsb0VBQStEO0FBRS9ELFFBQVEsQ0FBQyxxQkFBcUIsRUFBRTtJQUM5QixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1FBQzNCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRTtZQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUNuRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUN6RCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUM7U0FDMUM7S0FDRixDQUFDLENBQUM7SUFDSCxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7SUFFbkIsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRTtRQUMvRSxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQztRQUNsRixLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsVUFBVTtZQUNsQixXQUFXLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDbEIsTUFBTSxFQUFFLFFBQVE7WUFDaEIsV0FBVyxFQUFFLEtBQUs7WUFDbEIsTUFBTSxFQUFFLEtBQUs7U0FDZDtRQUNELE9BQU8sRUFBRTtZQUNQLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLElBQUksRUFBRSwrREFBK0Q7WUFDckUsV0FBVyxFQUFFLEtBQUs7WUFDbEIsTUFBTSxFQUFFLEtBQUs7U0FDZDtLQUNGLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtRQUMxQixFQUFFLENBQUMsMkJBQTJCLEVBQUU7WUFDOUIsSUFBTSxLQUFLLEdBQUcsa0JBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELGFBQU0sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDaEMsTUFBTSxFQUFFLE9BQU87b0JBQ2YsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsSUFBSSxFQUFFO3dCQUNKOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ2hELFFBQVEsRUFBRSxtQ0FBbUM7eUJBQzlDO3dCQUNEOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLGlEQUFpRCxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDdEYsUUFBUSxFQUFFLHFEQUFxRDt5QkFDaEU7cUJBQ0Y7aUJBQ0YsQ0FBQyxDQUFDLENBQUM7WUFFSixJQUFNLEtBQUssR0FBRyxrQkFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDdkQsYUFBTSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNoQyxNQUFNLEVBQUUsT0FBTztvQkFDZixJQUFJLEVBQUUsRUFBRTtvQkFDUixPQUFPLEVBQUUsRUFBRTtpQkFDWixDQUFDLENBQUMsQ0FBQztZQUVKLElBQU0sT0FBTyxHQUFHLGtCQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUMzRCxhQUFNLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFO2dCQUNqQztvQkFDRSxNQUFNLEVBQUUsU0FBUztvQkFDakIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsSUFBSSxFQUFFO3dCQUNKOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ2hELFFBQVEsRUFBRSxtQ0FBbUM7eUJBQzlDO3dCQUNEOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLGtDQUFrQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDdkUsUUFBUSxFQUFFLHVEQUF1RDt5QkFDbEU7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDOUMsUUFBUSxFQUFFLG1DQUFtQzt5QkFDOUM7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsNkJBQTZCLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNsRSxRQUFRLEVBQUUsdURBQXVEO3lCQUNsRTtxQkFDRjtpQkFDRjtnQkFDRDtvQkFDRSxNQUFNLEVBQUUsU0FBUztvQkFDakIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsSUFBSSxFQUFFO3dCQUNKOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ2hELFFBQVEsRUFBRSxtQ0FBbUM7eUJBQzlDO3dCQUNEOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLGtDQUFrQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDdkUsUUFBUSxFQUFFLHdEQUF3RDt5QkFDbkU7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDOUMsUUFBUSxFQUFFLG1DQUFtQzt5QkFDOUM7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsNkJBQTZCLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNsRSxRQUFRLEVBQUUsd0RBQXdEO3lCQUNuRTtxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFCQUFxQixFQUFFO1lBQ3hCLElBQU0sS0FBSyxHQUFHLGtCQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN2RCxhQUFNLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2hDLE1BQU0sRUFBRSxVQUFVO29CQUNsQixPQUFPLEVBQUUsRUFBRTtvQkFDWCxJQUFJLEVBQUU7d0JBQ0o7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDaEQsUUFBUSxFQUFFLCtDQUErQzt5QkFDMUQ7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsaURBQWlELEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUN0RixRQUFRLEVBQUUscUdBQXFHO3lCQUNoSDtxQkFDRjtpQkFDRixDQUFDLENBQUMsQ0FBQztZQUVKLHdEQUF3RDtZQUV4RCxJQUFNLE9BQU8sR0FBRyxrQkFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDM0QsYUFBTSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNsQyxNQUFNLEVBQUUsWUFBWTtvQkFDcEIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsSUFBSSxFQUFFO3dCQUNKOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ2hELFFBQVEsRUFBRSwrQ0FBK0M7eUJBQzFEO3dCQUNEOzRCQUNFLFFBQVEsRUFBRSx3QkFBYSxDQUFDLGtDQUFrQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDdkUsUUFBUSxFQUFFLDZHQUE2Rzt5QkFDeEg7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDOUMsUUFBUSxFQUFFLCtDQUErQzt5QkFDMUQ7d0JBQ0Q7NEJBQ0UsUUFBUSxFQUFFLHdCQUFhLENBQUMsNkJBQTZCLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNsRSxRQUFRLEVBQUUsNkdBQTZHO3lCQUN4SDtxQkFDRjtpQkFDRixDQUFDLENBQUMsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdCQUF3QixFQUFFO1lBQzNCLElBQU0sS0FBSyxHQUFHLGtCQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN2RCxhQUFNLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO2dCQUMvQjtvQkFDRSxNQUFNLEVBQUUsS0FBSztvQkFDYixRQUFRLEVBQUUsMENBQTBDO2lCQUNyRDthQUNGLENBQUMsQ0FBQztZQUVILElBQU0sS0FBSyxHQUFHLGtCQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN2RCxhQUFNLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO2dCQUMvQjtvQkFDRSxNQUFNLEVBQUUsS0FBSztvQkFDYixRQUFRLEVBQUUsZ0RBQWdEO2lCQUMzRDthQUNGLENBQUMsQ0FBQztZQUVILElBQU0sT0FBTyxHQUFHLGtCQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUMzRCxhQUFNLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFO2dCQUNqQztvQkFDRSxNQUFNLEVBQUUsT0FBTztvQkFDZixRQUFRLEVBQUUsNEZBQTRGO2lCQUN2RzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsc0JBQXNCLEVBQUU7UUFDekIsSUFBTSxPQUFPLEdBQUcsa0JBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzNELGFBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFeEMsSUFBTSxPQUFPLEdBQUcsa0JBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzNELGFBQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLGdCQUFnQixDQUFDLENBQUM7UUFFeEMsSUFBTSxTQUFTLEdBQUcsa0JBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQy9ELGFBQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFFNUMsSUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN6RCxhQUFNLENBQUMsa0JBQWtCLENBQUMsT0FBTyxFQUFFO1lBQ2pDO2dCQUNFLE1BQU0sRUFBRSxXQUFXO2dCQUNuQixJQUFJLEVBQUU7b0JBQ0o7d0JBQ0UsUUFBUSxFQUFFLEVBQUMsUUFBUSxFQUFFLEtBQUssRUFBQzt3QkFDM0IsUUFBUSxFQUFFLDBDQUF3QyxPQUFPLE1BQUc7cUJBQzdEO2lCQUNGO2FBQ0Y7WUFDRDtnQkFDRSxNQUFNLEVBQUUsV0FBVztnQkFDbkIsSUFBSSxFQUFFO29CQUNKO3dCQUNFLFFBQVEsRUFBRSxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUM7d0JBQzNCLFFBQVEsRUFBRSwwQ0FBd0MsT0FBTyxNQUFHO3FCQUM3RDtpQkFDRjthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLGFBQWE7Z0JBQ3JCLElBQUksRUFBRTtvQkFDSjt3QkFDRSxRQUFRLEVBQUUsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDO3dCQUM3QixRQUFRLEVBQUUsMENBQXdDLFNBQVMsTUFBRztxQkFDL0Q7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHVCQUF1QixFQUFFO1FBQzFCLElBQU0sT0FBTyxHQUFHLGtCQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM1RCxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDO1FBRTNELElBQU0sT0FBTyxHQUFHLGtCQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM1RCxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDO1FBRTNELElBQU0sU0FBUyxHQUFHLGtCQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNoRSxhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1FBRWpFLElBQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDekQsYUFBTSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRTtZQUNqQztnQkFDRSxNQUFNLEVBQUUsWUFBWTtnQkFDcEIsSUFBSSxFQUFFO29CQUNKO3dCQUNFLFFBQVEsRUFBRSxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUM7d0JBQzNCLFFBQVEsRUFBRSwyQkFBeUIsT0FBTyxNQUFHO3FCQUM5QztpQkFDRjthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLFlBQVk7Z0JBQ3BCLElBQUksRUFBRTtvQkFDSjt3QkFDRSxRQUFRLEVBQUUsRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFDO3dCQUMzQixRQUFRLEVBQUUsMkJBQXlCLE9BQU8sTUFBRztxQkFDOUM7aUJBQ0Y7YUFDRjtZQUNEO2dCQUNFLE1BQU0sRUFBRSxjQUFjO2dCQUN0QixJQUFJLEVBQUU7b0JBQ0o7d0JBQ0UsUUFBUSxFQUFFLEVBQUMsUUFBUSxFQUFFLE9BQU8sRUFBQzt3QkFDN0IsUUFBUSxFQUFFLDZCQUEyQixTQUFTLE1BQUc7cUJBQ2xEO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxtQkFBbUIsRUFBRTtRQUN0QixJQUFNLEtBQUssR0FBVSxDQUFDLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFDeEMsYUFBTSxDQUFDLGVBQWUsQ0FBQyxrQkFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQ3BFO2dCQUNFLE1BQU0sRUFBRSxTQUFTO2dCQUNqQixNQUFNLEVBQUUsTUFBTTtnQkFDZCxRQUFRLEVBQUU7b0JBQ1IsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBQyxFQUFDO29CQUNwQyxRQUFRLEVBQUU7d0JBQ1IsR0FBRyxFQUFFOzRCQUNILE9BQU8sRUFBRSxHQUFHOzRCQUNaLFFBQVEsRUFBRSxrQkFBa0I7eUJBQzdCO3dCQUNELElBQUksRUFBRTs0QkFDSixPQUFPLEVBQUUsR0FBRzs0QkFDWixRQUFRLEVBQUUsa0JBQWtCO3lCQUM3Qjt3QkFDRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxFQUFDO3dCQUNqQixJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFDLEVBQUM7cUJBQ3JDO2lCQUNGO2FBQ0Y7WUFDRCxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUM7WUFDbEI7Z0JBQ0UsTUFBTSxFQUFFLFdBQVc7Z0JBQ25CLE1BQU0sRUFBRSxNQUFNO2dCQUNkLFFBQVEsRUFBRTtvQkFDUixPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDLEVBQUM7b0JBQzNDLFFBQVEsRUFBRTt3QkFDUixHQUFHLEVBQUU7NEJBQ0gsT0FBTyxFQUFFLEdBQUc7NEJBQ1osUUFBUSxFQUFFLGtCQUFrQjt5QkFDN0I7d0JBQ0QsSUFBSSxFQUFFOzRCQUNKLE9BQU8sRUFBRSxHQUFHOzRCQUNaLFFBQVEsRUFBRSxrQkFBa0I7eUJBQzdCO3dCQUNELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUM7d0JBQ2pCLElBQUksRUFBRSxFQUFDLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUMsRUFBQztxQkFDckM7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILCtEQUErRDtRQUMvRCxhQUFNLENBQUMsZUFBZSxDQUFDLGtCQUFRLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFN0UsYUFBTSxDQUFDLGVBQWUsQ0FBQyxrQkFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQ3RFO2dCQUNFLE1BQU0sRUFBRSxTQUFTO2dCQUNqQixNQUFNLEVBQUUsTUFBTTtnQkFDZCxRQUFRLEVBQUU7b0JBQ1IsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBQyxFQUFDO29CQUNwQyxRQUFRLEVBQUU7d0JBQ1IsR0FBRyxFQUFFOzRCQUNILE9BQU8sRUFBRSxHQUFHOzRCQUNaLFFBQVEsRUFBRSxvQkFBb0I7eUJBQy9CO3dCQUNELElBQUksRUFBRTs0QkFDSixPQUFPLEVBQUUsR0FBRzs0QkFDWixRQUFRLEVBQUUsb0JBQW9CO3lCQUMvQjt3QkFDRCxHQUFHLEVBQUU7NEJBQ0gsT0FBTyxFQUFFLEdBQUc7NEJBQ1osUUFBUSxFQUFFLG9CQUFvQjt5QkFDL0I7d0JBQ0QsSUFBSSxFQUFFOzRCQUNKLE9BQU8sRUFBRSxHQUFHOzRCQUNaLFFBQVEsRUFBRSxvQkFBb0I7eUJBQy9CO3FCQUNGO2lCQUNGO2FBQ0Y7WUFDRCxFQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUM7WUFDbEI7Z0JBQ0UsTUFBTSxFQUFFLGFBQWE7Z0JBQ3JCLE1BQU0sRUFBRSxNQUFNO2dCQUNkLFFBQVEsRUFBRTtvQkFDUixPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDLEVBQUM7b0JBQzNDLFFBQVEsRUFBRTt3QkFDUixHQUFHLEVBQUU7NEJBQ0gsT0FBTyxFQUFFLEdBQUc7NEJBQ1osUUFBUSxFQUFFLG9CQUFvQjt5QkFDL0I7d0JBQ0QsSUFBSSxFQUFFOzRCQUNKLE9BQU8sRUFBRSxHQUFHOzRCQUNaLFFBQVEsRUFBRSxvQkFBb0I7eUJBQy9CO3dCQUNELEdBQUcsRUFBRTs0QkFDSCxPQUFPLEVBQUUsR0FBRzs0QkFDWixRQUFRLEVBQUUsb0JBQW9CO3lCQUMvQjt3QkFDRCxJQUFJLEVBQUU7NEJBQ0osT0FBTyxFQUFFLEdBQUc7NEJBQ1osUUFBUSxFQUFFLG9CQUFvQjt5QkFDL0I7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/selection/multi.test.d.ts b/build/test/compile/selection/multi.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/multi.test.js b/build/test/compile/selection/multi.test.js new file mode 100644 index 0000000000..14f07d2836 --- /dev/null +++ b/build/test/compile/selection/multi.test.js @@ -0,0 +1,112 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var selection = require("../../../src/compile/selection/selection"); +var multi_1 = require("../../../src/compile/selection/multi"); +describe('Multi Selection', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "multi" }, + "two": { + "type": "multi", + "on": "mouseover", "toggle": "event.ctrlKey", "encodings": ["y", "color"] + } + }); + it('builds trigger signals', function () { + var oneSg = multi_1.default.signals(model, selCmpts['one']); + chai_1.assert.sameDeepMembers(oneSg, [{ + name: 'one', + value: {}, + on: [{ + events: selCmpts['one'].events, + update: "{fields: [\"_id\"], values: [(item().isVoronoi ? datum.datum : datum)[\"_id\"]]}" + }] + }]); + var twoSg = multi_1.default.signals(model, selCmpts['two']); + chai_1.assert.sameDeepMembers(twoSg, [{ + name: 'two', + value: {}, + on: [{ + events: selCmpts['two'].events, + update: "{fields: [\"Miles_per_Gallon\", \"Origin\"], values: [(item().isVoronoi ? datum.datum : datum)[\"Miles_per_Gallon\"], (item().isVoronoi ? datum.datum : datum)[\"Origin\"]]}" + }] + }]); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds tuple signals', function () { + var oneExpr = multi_1.default.tupleExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'fields: one.fields, values: one.values'); + var twoExpr = multi_1.default.tupleExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'fields: two.fields, values: two.values'); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "one_tuple", + "on": [ + { + "events": { "signal": "one" }, + "update": "{unit: unit.datum && unit.datum._id, " + oneExpr + "}" + } + ] + }, + { + "name": "two_tuple", + "on": [ + { + "events": { "signal": "two" }, + "update": "{unit: unit.datum && unit.datum._id, " + twoExpr + "}" + } + ] + } + ]); + }); + // Skipped because "toggle" transforms the modifyExpr. + it.skip('builds modify signals', function () { + var oneExpr = multi_1.default.modifyExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'one_tuple'); + var twoExpr = multi_1.default.modifyExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'two_tuple'); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "one_modify", + "on": [ + { + "events": { "signal": "one" }, + "update": "modify(\"one_store\", " + oneExpr + ")" + } + ] + }, + { + "name": "two_modify", + "on": [ + { + "events": { "signal": "two" }, + "update": "modify(\"two_store\", " + twoExpr + ")" + } + ] + } + ]); + }); + it('builds unit datasets', function () { + var data = []; + chai_1.assert.sameDeepMembers(selection.assembleUnitData(model, data), [ + { name: 'one_store' }, { name: 'two_store' } + ]); + }); + it('leaves marks alone', function () { + var marks = []; + chai_1.assert.equal(selection.assembleUnitMarks(model, marks), marks); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGkudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vbXVsdGkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQTBDO0FBQzFDLG9FQUFzRTtBQUN0RSw4REFBeUQ7QUFFekQsUUFBUSxDQUFDLGlCQUFpQixFQUFFO0lBQzFCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7UUFDM0IsTUFBTSxFQUFFLFFBQVE7UUFDaEIsVUFBVSxFQUFFO1lBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ25ELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ3pELE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBQztTQUMxQztLQUNGLENBQUMsQ0FBQztJQUVILElBQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDL0UsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQztRQUN4QixLQUFLLEVBQUU7WUFDTCxNQUFNLEVBQUUsT0FBTztZQUNmLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDO1NBQzFFO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHdCQUF3QixFQUFFO1FBQzNCLElBQU0sS0FBSyxHQUFHLGVBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3BELGFBQU0sQ0FBQyxlQUFlLENBQUMs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 \ No newline at end of file diff --git a/build/test/compile/selection/nearest.test.d.ts b/build/test/compile/selection/nearest.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/nearest.test.js b/build/test/compile/selection/nearest.test.js new file mode 100644 index 0000000000..d636de03cd --- /dev/null +++ b/build/test/compile/selection/nearest.test.js @@ -0,0 +1,158 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var selection = require("../../../src/compile/selection/selection"); +var nearest_1 = require("../../../src/compile/selection/transforms/nearest"); +function getModel(markType) { + var model = util_1.parseUnitModel({ + "mark": markType, + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "single", "nearest": true }, + "two": { "type": "multi", "nearest": true }, + "three": { "type": "interval", "nearest": true }, + "four": { "type": "single", "nearest": false }, + "five": { "type": "multi" } + }); + return model; +} +describe('Nearest Selection Transform', function () { + it('identifies transform invocation', function () { + var selCmpts = getModel('circle').component.selection; + chai_1.assert.isTrue(nearest_1.default.has(selCmpts['one'])); + chai_1.assert.isTrue(nearest_1.default.has(selCmpts['two'])); + chai_1.assert.isTrue(nearest_1.default.has(selCmpts['three'])); + chai_1.assert.isFalse(nearest_1.default.has(selCmpts['four'])); + chai_1.assert.isFalse(nearest_1.default.has(selCmpts['five'])); + }); + it('adds voronoi for non-path marks', function () { + var model = getModel('circle'), selCmpts = model.component.selection, marks = [{ hello: "world" }]; + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['one'], marks, marks), [ + { hello: "world" }, + { + "name": "voronoi", + "type": "path", + "from": { "data": "marks" }, + "encode": { + "enter": { + "fill": { "value": "transparent" }, + "strokeWidth": { "value": 0.35 }, + "stroke": { "value": "transparent" }, + "isVoronoi": { "value": true } + } + }, + "transform": [ + { + "type": "voronoi", + "x": "datum.x", + "y": "datum.y", + "size": [{ "signal": "width" }, { "signal": "height" }] + } + ] + } + ]); + }); + it('adds voronoi for path marks', function () { + var model = getModel('line'), selCmpts = model.component.selection, marks = [{ name: "pathgroup", hello: "world", marks: [{ foo: "bar" }] }]; + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['one'], marks, marks), [ + { + name: "pathgroup", + hello: "world", + marks: [ + { foo: "bar" }, + { + "name": "voronoi", + "type": "path", + "from": { "data": "marks" }, + "encode": { + "enter": { + "fill": { "value": "transparent" }, + "strokeWidth": { "value": 0.35 }, + "stroke": { "value": "transparent" }, + "isVoronoi": { "value": true } + } + }, + "transform": [ + { + "type": "voronoi", + "x": "datum.x", + "y": "datum.y", + "size": [{ "signal": "width" }, { "signal": "height" }] + } + ] + } + ] + } + ]); + }); + it('limits to a single voronoi per unit', function () { + var model = getModel('circle'), selCmpts = model.component.selection, marks = [{ hello: "world" }]; + var marks2 = nearest_1.default.marks(model, selCmpts['one'], marks, marks); + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['two'], marks, marks2), [ + { hello: "world" }, + { + "name": "voronoi", + "type": "path", + "from": { "data": "marks" }, + "encode": { + "enter": { + "fill": { "value": "transparent" }, + "strokeWidth": { "value": 0.35 }, + "stroke": { "value": "transparent" }, + "isVoronoi": { "value": true } + } + }, + "transform": [ + { + "type": "voronoi", + "x": "datum.x", + "y": "datum.y", + "size": [{ "signal": "width" }, { "signal": "height" }] + } + ] + } + ]); + model = getModel('line'); + selCmpts = model.component.selection; + marks = [{ name: "pathgroup", hello: "world", marks: [{ foo: "bar" }] }]; + marks2 = nearest_1.default.marks(model, selCmpts['one'], marks, marks); + chai_1.assert.sameDeepMembers(nearest_1.default.marks(model, selCmpts['two'], marks, marks2), [ + { + name: "pathgroup", + hello: "world", + marks: [ + { foo: "bar" }, + { + "name": "voronoi", + "type": "path", + "from": { "data": "marks" }, + "encode": { + "enter": { + "fill": { "value": "transparent" }, + "strokeWidth": { "value": 0.35 }, + "stroke": { "value": "transparent" }, + "isVoronoi": { "value": true } + } + }, + "transform": [ + { + "type": "voronoi", + "x": "datum.x", + "y": "datum.y", + "size": [{ "signal": "width" }, { "signal": "height" }] + } + ] + } + ] + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmVhcmVzdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NlbGVjdGlvbi9uZWFyZXN0LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLG1DQUEwQztBQUMxQyxvRUFBc0U7QUFDdEUsNkVBQXdFO0FBRXhFLGtCQUFrQixRQUFhO0lBQzdCLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7UUFDM0IsTUFBTSxFQUFFLFFBQVE7UUFDaEIsVUFBVSxFQUFFO1lBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ25ELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ3pELE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBQztTQUMxQztLQUNGLENBQUMsQ0FBQztJQUVILEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDOUQsS0FBSyxFQUFFLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFDO1FBQzFDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBQztRQUN6QyxPQUFPLEVBQUUsRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUM7UUFDOUMsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFDO1FBQzVDLE1BQU0sRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUM7S0FDMUIsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxRQUFRLENBQUMsNkJBQTZCLEVBQUU7SUFDdEMsRUFBRSxDQUFDLGlDQUFpQyxFQUFFO1FBQ3BDLElBQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1FBQ3hELGFBQU0sQ0FBQyxNQUFNLENBQUMsaUJBQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxhQUFNLENBQUMsTUFBTSxDQUFDLGlCQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUMsYUFBTSxDQUFDLE1BQU0sQ0FBQyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlDLGFBQU0sQ0FBQyxPQUFPLENBQUMsaUJBQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QyxhQUFNLENBQUMsT0FBTyxDQUFDLGlCQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUU7UUFDcEMsSUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUM5QixRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQ3BDLEtBQUssR0FBVSxDQUFDLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFFcEMsYUFBTSxDQUFDLGVBQWUsQ0FBQyxpQkFBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRTtZQUMxRSxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUM7WUFDaEI7Z0JBQ0UsTUFBTSxFQUFFLFNBQVM7Z0JBQ2pCLE1BQU0sRUFBRSxNQUFNO2dCQUNkLE1BQU0sRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUM7Z0JBQ3pCLFFBQVEsRUFBRTtvQkFDUixPQUFPLEVBQUU7d0JBQ1AsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLGFBQWEsRUFBQzt3QkFDaEMsYUFBYSxFQUFFLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQzt3QkFDOUIsUUFBUSxFQUFFLEVBQUMsT0FBTyxFQUFFLGFBQWEsRUFBQzt3QkFDbEMsV0FBVyxFQUFFLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQztxQkFDN0I7aUJBQ0Y7Z0JBQ0QsV0FBVyxFQUFFO29CQUNYO3dCQUNFLE1BQU0sRUFBRSxTQUFTO3dCQUNqQixHQUFHLEVBQUUsU0FBUzt3QkFDZCxHQUFHLEVBQUUsU0FBUzt3QkFDZCxNQUFNLEVBQUUsQ0FBQyxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUMsRUFBQyxFQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUMsQ0FBQztxQkFDbkQ7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1FBQ2hDLElBQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFDNUIsUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUNwQyxLQUFLLEdBQVUsQ0FBQyxFQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUU5RSxhQUFNLENBQUMsZUFBZSxDQUFDLGlCQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQzFFO2dCQUNFLElBQUksRUFBRSxXQUFXO2dCQUNqQixLQUFLLEVBQUUsT0FBTztnQkFDZCxLQUFLLEVBQUU7b0JBQ0wsRUFBQyxHQUFHLEVBQUUsS0FBSyxFQUFDO29CQUNaO3dCQUNFLE1BQU0sRUFBRSxTQUFTO3dCQUNqQixNQUFNLEVBQUUsTUFBTTt3QkFDZCxNQUFNLEVBQUUsRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDO3dCQUN6QixRQUFRLEVBQUU7NEJBQ1IsT0FBTyxFQUFFO2dDQUNQLE1BQU0sRUFBRSxFQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUM7Z0NBQ2hDLGFBQWEsRUFBRSxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUM7Z0NBQzlCLFFBQVEsRUFBRSxFQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUM7Z0NBQ2xDLFdBQVcsRUFBRSxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUM7NkJBQzdCO3lCQUNGO3dCQUNELFdBQVcsRUFBRTs0QkFDWDtnQ0FDRSxNQUFNLEVBQUUsU0FBUztnQ0FDakIsR0FBRyxFQUFFLFNBQVM7Z0NBQ2QsR0FBRyxFQUFFLFNBQVM7Z0NBQ2QsTUFBTSxFQUFFLENBQUMsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFDLEVBQUMsRUFBQyxRQUFRLEVBQUUsUUFBUSxFQUFDLENBQUM7NkJBQ25EO3lCQUNGO3FCQUNGO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRTtRQUN4QyxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQzVCLFFBQVEsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFDcEMsS0FBSyxHQUFVLENBQUMsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztRQUVwQyxJQUFJLE1BQU0sR0FBRyxpQkFBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNqRSxhQUFNLENBQUMsZUFBZSxDQUFDLGlCQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQzNFLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBQztZQUNoQjtnQkFDRSxNQUFNLEVBQUUsU0FBUztnQkFDakIsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQztnQkFDekIsUUFBUSxFQUFFO29CQUNSLE9BQU8sRUFBRTt3QkFDUCxNQUFNLEVBQUUsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDO3dCQUNoQyxhQUFhLEVBQUUsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFDO3dCQUM5QixRQUFRLEVBQUUsRUFBQyxPQUFPLEVBQUUsYUFBYSxFQUFDO3dCQUNsQyxXQUFXLEVBQUUsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFDO3FCQUM3QjtpQkFDRjtnQkFDRCxXQUFXLEVBQUU7b0JBQ1g7d0JBQ0UsTUFBTSxFQUFFLFNBQVM7d0JBQ2pCLEdBQUcsRUFBRSxTQUFTO3dCQUNkLEdBQUcsRUFBRSxTQUFTO3dCQUNkLE1BQU0sRUFBRSxDQUFDLEVBQUMsUUFBUSxFQUFFLE9BQU8sRUFBQyxFQUFDLEVBQUMsUUFBUSxFQUFFLFFBQVEsRUFBQyxDQUFDO3FCQUNuRDtpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QixRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7UUFDckMsS0FBSyxHQUFHLENBQUMsRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBQyxHQUFHLEVBQUUsS0FBSyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDckUsTUFBTSxHQUFHLGlCQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzdELGFBQU0sQ0FBQyxlQUFlLENBQUMsaUJBQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUU7WUFDM0U7Z0JBQ0UsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLEtBQUssRUFBRSxPQUFPO2dCQUNkLEtBQUssRUFBRTtvQkFDTCxFQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUM7b0JBQ1o7d0JBQ0UsTUFBTSxFQUFFLFNBQVM7d0JBQ2pCLE1BQU0sRUFBRSxNQUFNO3dCQUNkLE1BQU0sRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUM7d0JBQ3pCLFFBQVEsRUFBRTs0QkFDUixPQUFPLEVBQUU7Z0NBQ1AsTUFBTSxFQUFFLEVBQUMsT0FBTyxFQUFFLGFBQWEsRUFBQztnQ0FDaEMsYUFBYSxFQUFFLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQztnQ0FDOUIsUUFBUSxFQUFFLEVBQUMsT0FBTyxFQUFFLGFBQWEsRUFBQztnQ0FDbEMsV0FBVyxFQUFFLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQzs2QkFDN0I7eUJBQ0Y7d0JBQ0QsV0FBVyxFQUFFOzRCQUNYO2dDQUNFLE1BQU0sRUFBRSxTQUFTO2dDQUNqQixHQUFHLEVBQUUsU0FBUztnQ0FDZCxHQUFHLEVBQUUsU0FBUztnQ0FDZCxNQUFNLEVBQUUsQ0FBQyxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUMsRUFBQyxFQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUMsQ0FBQzs2QkFDbkQ7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMifQ== \ No newline at end of file diff --git a/build/test/compile/selection/parse.test.d.ts b/build/test/compile/selection/parse.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/parse.test.js b/build/test/compile/selection/parse.test.js new file mode 100644 index 0000000000..6c5d5222b1 --- /dev/null +++ b/build/test/compile/selection/parse.test.js @@ -0,0 +1,106 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var selection = require("../../../src/compile/selection/selection"); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +describe('Selection', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + it('parses default selection definitions', function () { + var component = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { "type": "multi" }, + "three": { "type": "interval" } + }); + chai_1.assert.sameMembers(Object.keys(component), ['one', 'two', 'three']); + chai_1.assert.deepPropertyVal(component, 'one.name', 'one'); + chai_1.assert.deepPropertyVal(component, 'one.type', 'single'); + chai_1.assert.sameDeepMembers(component['one'].project, [{ field: '_id', encoding: null }]); + chai_1.assert.sameDeepMembers(component['one'].events, event_selector_1.default('click', 'scope')); + chai_1.assert.deepPropertyVal(component, 'two.name', 'two'); + chai_1.assert.deepPropertyVal(component, 'two.type', 'multi'); + chai_1.assert.deepPropertyVal(component, 'two.toggle', 'event.shiftKey'); + chai_1.assert.sameDeepMembers(component['two'].project, [{ field: '_id', encoding: null }]); + chai_1.assert.sameDeepMembers(component['two'].events, event_selector_1.default('click', 'scope')); + chai_1.assert.deepPropertyVal(component, 'three.name', 'three'); + chai_1.assert.deepPropertyVal(component, 'three.type', 'interval'); + chai_1.assert.deepPropertyVal(component, 'three.translate', '[mousedown, window:mouseup] > window:mousemove!'); + chai_1.assert.deepPropertyVal(component, 'three.zoom', 'wheel'); + chai_1.assert.sameDeepMembers(component['three'].project, [{ field: 'Horsepower', encoding: 'x' }, { field: 'Miles_per_Gallon', encoding: 'y' }]); + chai_1.assert.sameDeepMembers(component['three'].events, event_selector_1.default('[mousedown, window:mouseup] > window:mousemove!', 'scope')); + }); + it('supports inline default overrides', function () { + var component = selection.parseUnitSelection(model, { + "one": { + "type": "single", + "on": "dblclick", "fields": ["Cylinders"] + }, + "two": { + "type": "multi", + "on": "mouseover", "toggle": "event.ctrlKey", "encodings": ["color"] + }, + "three": { + "type": "interval", + "on": "[mousedown[!event.shiftKey], mouseup] > mousemove", + "encodings": ["y"], "translate": false, "zoom": "wheel[event.altKey]" + } + }); + chai_1.assert.sameMembers(Object.keys(component), ['one', 'two', 'three']); + chai_1.assert.deepPropertyVal(component, 'one.name', 'one'); + chai_1.assert.deepPropertyVal(component, 'one.type', 'single'); + chai_1.assert.sameDeepMembers(component['one'].project, [{ field: 'Cylinders', encoding: null }]); + chai_1.assert.sameDeepMembers(component['one'].events, event_selector_1.default('dblclick', 'scope')); + chai_1.assert.deepPropertyVal(component, 'two.name', 'two'); + chai_1.assert.deepPropertyVal(component, 'two.type', 'multi'); + chai_1.assert.deepPropertyVal(component, 'two.toggle', 'event.ctrlKey'); + chai_1.assert.sameDeepMembers(component['two'].project, [{ field: 'Origin', encoding: 'color' }]); + chai_1.assert.sameDeepMembers(component['two'].events, event_selector_1.default('mouseover', 'scope')); + chai_1.assert.deepPropertyVal(component, 'three.name', 'three'); + chai_1.assert.deepPropertyVal(component, 'three.type', 'interval'); + chai_1.assert.deepPropertyVal(component, 'three.translate', false); + chai_1.assert.deepPropertyVal(component, 'three.zoom', 'wheel[event.altKey]'); + chai_1.assert.sameDeepMembers(component['three'].project, [{ field: 'Miles_per_Gallon', encoding: 'y' }]); + chai_1.assert.sameDeepMembers(component['three'].events, event_selector_1.default('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope')); + }); + it('respects selection configs', function () { + model.config.selection = { + single: { on: 'dblclick', fields: ['Cylinders'] }, + multi: { on: 'mouseover', encodings: ['color'], toggle: 'event.ctrlKey' }, + interval: { + on: '[mousedown[!event.shiftKey], mouseup] > mousemove', + encodings: ['y'], + zoom: 'wheel[event.altKey]' + } + }; + var component = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { "type": "multi" }, + "three": { "type": "interval" } + }); + chai_1.assert.sameMembers(Object.keys(component), ['one', 'two', 'three']); + chai_1.assert.deepPropertyVal(component, 'one.name', 'one'); + chai_1.assert.deepPropertyVal(component, 'one.type', 'single'); + chai_1.assert.sameDeepMembers(component['one'].project, [{ field: 'Cylinders', encoding: null }]); + chai_1.assert.sameDeepMembers(component['one'].events, event_selector_1.default('dblclick', 'scope')); + chai_1.assert.deepPropertyVal(component, 'two.name', 'two'); + chai_1.assert.deepPropertyVal(component, 'two.type', 'multi'); + chai_1.assert.deepPropertyVal(component, 'two.toggle', 'event.ctrlKey'); + chai_1.assert.sameDeepMembers(component['two'].project, [{ field: 'Origin', encoding: 'color' }]); + chai_1.assert.sameDeepMembers(component['two'].events, event_selector_1.default('mouseover', 'scope')); + chai_1.assert.deepPropertyVal(component, 'three.name', 'three'); + chai_1.assert.deepPropertyVal(component, 'three.type', 'interval'); + chai_1.assert.notDeepProperty(component, 'three.translate'); + chai_1.assert.deepPropertyVal(component, 'three.zoom', 'wheel[event.altKey]'); + chai_1.assert.sameDeepMembers(component['three'].project, [{ field: 'Miles_per_Gallon', encoding: 'y' }]); + chai_1.assert.sameDeepMembers(component['three'].events, event_selector_1.default('[mousedown[!event.shiftKey], mouseup] > mousemove', 'scope')); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvY29tcGlsZS9zZWxlY3Rpb24vcGFyc2UudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFDNUIsbUNBQTBDO0FBQzFDLG9FQUFzRTtBQUN0RSx5RUFBZ0Y7QUFFaEYsUUFBUSxDQUFDLFdBQVcsRUFBRTtJQUNwQixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO1FBQzNCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLFVBQVUsRUFBRTtZQUNWLEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUNuRCxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztZQUN6RCxPQUFPLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUM7U0FDMUM7S0FDRixDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsc0NBQXNDLEVBQUU7UUFDekMsSUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRTtZQUNwRCxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsUUFBUSxFQUFDO1lBQ3pCLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUM7WUFDeEIsT0FBTyxFQUFFLEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBQztTQUM5QixDQUFDLENBQUM7UUFFSCxhQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFcEUsYUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3JELGFBQU0s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 \ No newline at end of file diff --git a/build/test/compile/selection/predicate.test.d.ts b/build/test/compile/selection/predicate.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/predicate.test.js b/build/test/compile/selection/predicate.test.js new file mode 100644 index 0000000000..7e86a1363e --- /dev/null +++ b/build/test/compile/selection/predicate.test.js @@ -0,0 +1,78 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var selection = require("../../../src/compile/selection/selection"); +var mixins_1 = require("../../../src/compile/mark/mixins"); +function getModel(selectionDef) { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { + "field": "Cylinders", "type": "O", + "condition": { + "selection": "!one", + "value": "grey" + } + }, + "opacity": { + "field": "Origin", "type": "N", + "condition": { + "selection": "one", + "value": 0.5 + } + } + } + }); + model.component.selection = selection.parseUnitSelection(model, { + "one": selectionDef + }); + return model; +} +describe('Selection Predicate', function () { + it('generates Vega production rules', function () { + var single = getModel({ type: 'single' }); + chai_1.assert.deepEqual(mixins_1.nonPosition('color', single), { + color: [ + { test: "!vlPoint(\"one_store\", parent._id, datum, \"union\", \"all\")", value: "grey" }, + { scale: "color", field: "Cylinders" } + ] + }); + chai_1.assert.deepEqual(mixins_1.nonPosition('opacity', single), { + opacity: [ + { test: "vlPoint(\"one_store\", parent._id, datum, \"union\", \"all\")", value: 0.5 }, + { scale: "opacity", field: "Origin" } + ] + }); + var multi = getModel({ type: 'multi' }); + chai_1.assert.deepEqual(mixins_1.nonPosition('color', multi), { + color: [ + { test: "!vlPoint(\"one_store\", parent._id, datum, \"union\", \"all\")", value: "grey" }, + { scale: "color", field: "Cylinders" } + ] + }); + chai_1.assert.deepEqual(mixins_1.nonPosition('opacity', multi), { + opacity: [ + { test: "vlPoint(\"one_store\", parent._id, datum, \"union\", \"all\")", value: 0.5 }, + { scale: "opacity", field: "Origin" } + ] + }); + var interval = getModel({ type: 'interval' }); + chai_1.assert.deepEqual(mixins_1.nonPosition('color', interval), { + color: [ + { test: "!vlInterval(\"one_store\", parent._id, datum, \"union\", \"all\")", value: "grey" }, + { scale: "color", field: "Cylinders" } + ] + }); + chai_1.assert.deepEqual(mixins_1.nonPosition('opacity', interval), { + opacity: [ + { test: "vlInterval(\"one_store\", parent._id, datum, \"union\", \"all\")", value: 0.5 }, + { scale: "opacity", field: "Origin" } + ] + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJlZGljYXRlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3ByZWRpY2F0ZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsb0VBQXNFO0FBQ3RFLDJEQUE2RDtBQUU3RCxrQkFBa0IsWUFBaUI7SUFDakMsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFO2dCQUNQLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLEdBQUc7Z0JBQ2pDLFdBQVcsRUFBRTtvQkFDWCxXQUFXLEVBQUUsTUFBTTtvQkFDbkIsT0FBTyxFQUFFLE1BQU07aUJBQ2hCO2FBQ0Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRztnQkFDOUIsV0FBVyxFQUFFO29CQUNYLFdBQVcsRUFBRSxLQUFLO29CQUNsQixPQUFPLEVBQUUsR0FBRztpQkFDYjthQUNGO1NBQ0Y7S0FDRixDQUFDLENBQUM7SUFFSCxLQUFLLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO1FBQzlELEtBQUssRUFBRSxZQUFZO0tBQ3BCLENBQUMsQ0FBQztJQUVILE1BQU0sQ0FBQyxLQUFLLENBQUM7QUFDZixDQUFDO0FBR0QsUUFBUSxDQUFDLHFCQUFxQixFQUFFO0lBQzlCLEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRTtRQUNwQyxJQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsRUFBQyxJQUFJLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQztRQUMxQyxhQUFNLENBQUMsU0FBUyxDQUFDLG9CQUFXLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQzdDLEtBQUssRUFBRTtnQkFDTCxFQUFDLElBQUksRUFBRSxnRUFBZ0UsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDO2dCQUN2RixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBQzthQUNyQztTQUNGLENBQUMsQ0FBQztRQUVILGFBQU0sQ0FBQyxTQUFTLENBQUMsb0JBQVcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLEVBQUU7WUFDL0MsT0FBTyxFQUFFO2dCQUNQLEVBQUMsSUFBSSxFQUFFLCtEQUErRCxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUM7Z0JBQ25GLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFDO2FBQ3BDO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUM7UUFDeEMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxvQkFBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsRUFBRTtZQUM1QyxLQUFLLEVBQUU7Z0JBQ0wsRUFBQyxJQUFJLEVBQUUsZ0VBQWdFLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBQztnQkFDdkYsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUM7YUFDckM7U0FDRixDQUFDLENBQUM7UUFFSCxhQUFNLENBQUMsU0FBUyxDQUFDLG9CQUFXLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQzlDLE9BQU8sRUFBRTtnQkFDUCxFQUFDLElBQUksRUFBRSwrREFBK0QsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFDO2dCQUNuRixFQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBQzthQUNwQztTQUNGLENBQUMsQ0FBQztRQUVILElBQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUMsQ0FBQyxDQUFDO1FBQzlDLGFBQU0sQ0FBQyxTQUFTLENBQUMsb0JBQVcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEVBQUU7WUFDL0MsS0FBSyxFQUFFO2dCQUNMLEVBQUMsSUFBSSxFQUFFLG1FQUFtRSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUM7Z0JBQzFGLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFDO2FBQ3JDO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsYUFBTSxDQUFDLFNBQVMsQ0FBQyxvQkFBVyxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsRUFBRTtZQUNqRCxPQUFPLEVBQUU7Z0JBQ1AsRUFBQyxJQUFJLEVBQUUsa0VBQWtFLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBQztnQkFDdEYsRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUM7YUFDcEM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/test/compile/selection/single.test.d.ts b/build/test/compile/selection/single.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/single.test.js b/build/test/compile/selection/single.test.js new file mode 100644 index 0000000000..50cf702534 --- /dev/null +++ b/build/test/compile/selection/single.test.js @@ -0,0 +1,123 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var selection = require("../../../src/compile/selection/selection"); +var single_1 = require("../../../src/compile/selection/single"); +describe('Single Selection', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + var selCmpts = model.component.selection = selection.parseUnitSelection(model, { + "one": { "type": "single" }, + "two": { + "type": "single", + "on": "mouseover", "encodings": ["y", "color"] + } + }); + it('builds trigger signals', function () { + var oneSg = single_1.default.signals(model, selCmpts['one']); + chai_1.assert.sameDeepMembers(oneSg, [{ + name: 'one', + value: {}, + on: [{ + events: selCmpts['one'].events, + update: "{fields: [\"_id\"], values: [(item().isVoronoi ? datum.datum : datum)[\"_id\"]]}" + }] + }]); + var twoSg = single_1.default.signals(model, selCmpts['two']); + chai_1.assert.sameDeepMembers(twoSg, [{ + name: 'two', + value: {}, + on: [{ + events: selCmpts['two'].events, + update: "{fields: [\"Miles_per_Gallon\", \"Origin\"], values: [(item().isVoronoi ? datum.datum : datum)[\"Miles_per_Gallon\"], (item().isVoronoi ? datum.datum : datum)[\"Origin\"]]}" + }] + }]); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds tuple signals', function () { + var oneExpr = single_1.default.tupleExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'fields: one.fields, values: one.values, _id: one.values[0]'); + var twoExpr = single_1.default.tupleExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'fields: two.fields, values: two.values, Miles_per_Gallon: two.values[0], Origin: two.values[1]'); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "one_tuple", + "on": [ + { + "events": { "signal": "one" }, + "update": "{unit: unit.datum && unit.datum._id, " + oneExpr + "}" + } + ] + }, + { + "name": "two_tuple", + "on": [ + { + "events": { "signal": "two" }, + "update": "{unit: unit.datum && unit.datum._id, " + twoExpr + "}" + } + ] + } + ]); + }); + it('builds modify signals', function () { + var oneExpr = single_1.default.modifyExpr(model, selCmpts['one']); + chai_1.assert.equal(oneExpr, 'one_tuple, true'); + var twoExpr = single_1.default.modifyExpr(model, selCmpts['two']); + chai_1.assert.equal(twoExpr, 'two_tuple, true'); + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "one_modify", + "on": [ + { + "events": { "signal": "one" }, + "update": "modify(\"one_store\", " + oneExpr + ")" + } + ] + }, + { + "name": "two_modify", + "on": [ + { + "events": { "signal": "two" }, + "update": "modify(\"two_store\", " + twoExpr + ")" + } + ] + } + ]); + }); + it('builds top-level signals', function () { + var oneSg = single_1.default.topLevelSignals(model, selCmpts['one']); + chai_1.assert.sameDeepMembers(oneSg, [{ + name: 'one', update: 'data(\"one_store\")[0]' + }]); + var twoSg = single_1.default.topLevelSignals(model, selCmpts['two']); + chai_1.assert.sameDeepMembers(twoSg, [{ + name: 'two', update: 'data(\"two_store\")[0]' + }]); + var signals = selection.assembleTopLevelSignals(model); + chai_1.assert.includeDeepMembers(signals, oneSg.concat(twoSg)); + }); + it('builds unit datasets', function () { + var data = []; + chai_1.assert.sameDeepMembers(selection.assembleUnitData(model, data), [ + { name: 'one_store' }, { name: 'two_store' } + ]); + }); + it('leaves marks alone', function () { + var marks = []; + chai_1.assert.equal(selection.assembleUnitMarks(model, marks), marks); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2luZ2xlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3NpbmdsZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMsb0VBQXNFO0FBQ3RFLGdFQUEyRDtBQUUzRCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7SUFDM0IsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDO1NBQzFDO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsSUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRTtRQUMvRSxLQUFLLEVBQUUsRUFBQyxNQUFNLEVBQUUsUUFBUSxFQUFDO1FBQ3pCLEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLElBQUksRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQztTQUMvQztLQUNGLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx3QkFBd0IsRUFBRTtRQUMzQixJQUFNLEtBQUssR0FBRyxnQkFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckQsYUFBTSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsRUFBRSxFQUFFLENBQUM7d0JBQ0gsTUFBTSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNO3dCQUM5QixNQUFNLEVBQUUsa0ZBQWtGO3FCQUMzRixDQUFDO2FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFNLEtBQUssR0FBRyxnQkFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckQsYUFBTSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsS0FBSyxFQUFFLEVBQUU7Z0JBQ1QsRUFBRSxFQUFFLENBQUM7d0JBQ0gsTUFBTSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNO3dCQUM5QixNQUFNLEVBQUUsOEtBQThLO3FCQUN2TCxDQUFDO2FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELGFBQU0sQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1FBQ3pCLElBQU0sT0FBTyxHQUFHLGdCQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN6RCxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSw0REFBNEQsQ0FBQyxDQUFDO1FBRXBGLElBQU0sT0FBTyxHQUFHLGdCQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN6RCxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxnR0FBZ0csQ0FBQyxDQUFDO1FBRXhILElBQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDekQsYUFBTSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRTtZQUNqQztnQkFDRSxNQUFNLEVBQUUsV0FBVztnQkFDbkIsSUFBSSxFQUFFO29CQUNKO3dCQUNFLFFBQVEsRUFBRSxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUM7d0JBQzNCLFFBQVEsRUFBRSwwQ0FBd0MsT0FBTyxNQUFHO3FCQUM3RDtpQkFDRjthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLFdBQVc7Z0JBQ25CLElBQUksRUFBRTtvQkFDSjt3QkFDRSxRQUFRLEVBQUUsRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFDO3dCQUMzQixRQUFRLEVBQUUsMENBQXdDLE9BQU8sTUFBRztxQkFDN0Q7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHVCQUF1QixFQUFFO1FBQzFCLElBQU0sT0FBTyxHQUFHLGdCQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxRCxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBRXpDLElBQU0sT0FBTyxHQUFHLGdCQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxRCxhQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBRXpDLElBQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDekQsYUFBTSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRTtZQUNqQztnQkFDRSxNQUFNLEVBQUUsWUFBWTtnQkFDcEIsSUFBSSxFQUFFO29CQUNKO3dCQUNFLFFBQVEsRUFBRSxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUM7d0JBQzNCLFFBQVEsRUFBRSwyQkFBeUIsT0FBTyxNQUFHO3FCQUM5QztpQkFDRjthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFLFlBQVk7Z0JBQ3BCLElBQUksRUFBRTtvQkFDSjt3QkFDRSxRQUFRLEVBQUUsRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFDO3dCQUMzQixRQUFRLEVBQUUsMkJBQXlCLE9BQU8sTUFBRztxQkFDOUM7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBCQUEwQixFQUFFO1FBQzdCLElBQU0sS0FBSyxHQUFHLGdCQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUM3RCxhQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUM3QixJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSx3QkFBd0I7YUFDOUMsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFNLEtBQUssR0FBRyxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDN0QsYUFBTSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsd0JBQXdCO2FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBRUosSUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pELGFBQU0sQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNCQUFzQixFQUFFO1FBQ3pCLElBQU0sSUFBSSxHQUFVLEVBQUUsQ0FBQztRQUN2QixhQUFNLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDOUQsRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFDO1NBQ3pDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLG9CQUFvQixFQUFFO1FBQ3ZCLElBQU0sS0FBSyxHQUFVLEVBQUUsQ0FBQztRQUN4QixhQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDakUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/compile/selection/translate.test.d.ts b/build/test/compile/selection/translate.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/translate.test.js b/build/test/compile/selection/translate.test.js new file mode 100644 index 0000000000..b0370866d9 --- /dev/null +++ b/build/test/compile/selection/translate.test.js @@ -0,0 +1,167 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var selection = require("../../../src/compile/selection/selection"); +var translate_1 = require("../../../src/compile/selection/transforms/translate"); +describe('Translate Selection Transform', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + model.parseScale(); + var selCmpts = selection.parseUnitSelection(model, { + "one": { + "type": "single", + "translate": true + }, + "two": { + "type": "multi", + "translate": true + }, + "three": { + "type": "interval", + "translate": false + }, + "four": { + "type": "interval" + }, + "five": { + "type": "interval", + "translate": "[mousedown, mouseup] > mousemove, [keydown, keyup] > touchmove" + }, + "six": { + "type": "interval", + "bind": "scales" + } + }); + it('identifies transform invocation', function () { + chai_1.assert.isFalse(translate_1.default.has(selCmpts['one'])); + chai_1.assert.isFalse(translate_1.default.has(selCmpts['two'])); + chai_1.assert.isFalse(translate_1.default.has(selCmpts['three'])); + chai_1.assert.isTrue(translate_1.default.has(selCmpts['four'])); + chai_1.assert.isTrue(translate_1.default.has(selCmpts['five'])); + chai_1.assert.isTrue(translate_1.default.has(selCmpts['six'])); + }); + it('builds signals for default invocation', function () { + model.component.selection = { four: selCmpts['four'] }; + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "four_translate_anchor", + "value": {}, + "on": [ + { + "events": event_selector_1.default('@four_brush:mousedown', 'scope'), + "update": "{x: x(unit), y: y(unit), width: four_size.width, height: four_size.height, extent_x: slice(four_x), extent_y: slice(four_y), }" + } + ] + }, + { + "name": "four_translate_delta", + "value": {}, + "on": [ + { + "events": event_selector_1.default('[@four_brush:mousedown, window:mouseup] > window:mousemove!', 'scope'), + "update": "{x: x(unit) - four_translate_anchor.x, y: y(unit) - four_translate_anchor.y}" + } + ] + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_x'; })[0].on, [ + { + "events": { "signal": "four_translate_delta" }, + "update": "clampRange([four_translate_anchor.extent_x[0] + abs(span(four_translate_anchor.extent_x)) * four_translate_delta.x / four_translate_anchor.width, four_translate_anchor.extent_x[1] + abs(span(four_translate_anchor.extent_x)) * four_translate_delta.x / four_translate_anchor.width], invert(\"x\", 0), invert(\"x\", unit.width))" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_y'; })[0].on, [ + { + "events": { "signal": "four_translate_delta" }, + "update": "clampRange([four_translate_anchor.extent_y[0] - abs(span(four_translate_anchor.extent_y)) * four_translate_delta.y / four_translate_anchor.height, four_translate_anchor.extent_y[1] - abs(span(four_translate_anchor.extent_y)) * four_translate_delta.y / four_translate_anchor.height], invert(\"y\", unit.height), invert(\"y\", 0))" + } + ]); + }); + it('builds signals for custom events', function () { + model.component.selection = { five: selCmpts['five'] }; + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "five_translate_anchor", + "value": {}, + "on": [ + { + "events": event_selector_1.default('@five_brush:mousedown, @five_brush:keydown', 'scope'), + "update": "{x: x(unit), y: y(unit), width: five_size.width, height: five_size.height, extent_x: slice(five_x), extent_y: slice(five_y), }" + } + ] + }, + { + "name": "five_translate_delta", + "value": {}, + "on": [ + { + "events": event_selector_1.default('[@five_brush:mousedown, mouseup] > mousemove, [@five_brush:keydown, keyup] > touchmove', 'scope'), + "update": "{x: x(unit) - five_translate_anchor.x, y: y(unit) - five_translate_anchor.y}" + } + ] + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'five_x'; })[0].on, [ + { + "events": { "signal": "five_translate_delta" }, + "update": "clampRange([five_translate_anchor.extent_x[0] + abs(span(five_translate_anchor.extent_x)) * five_translate_delta.x / five_translate_anchor.width, five_translate_anchor.extent_x[1] + abs(span(five_translate_anchor.extent_x)) * five_translate_delta.x / five_translate_anchor.width], invert(\"x\", 0), invert(\"x\", unit.width))" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'five_y'; })[0].on, [ + { + "events": { "signal": "five_translate_delta" }, + "update": "clampRange([five_translate_anchor.extent_y[0] - abs(span(five_translate_anchor.extent_y)) * five_translate_delta.y / five_translate_anchor.height, five_translate_anchor.extent_y[1] - abs(span(five_translate_anchor.extent_y)) * five_translate_delta.y / five_translate_anchor.height], invert(\"y\", unit.height), invert(\"y\", 0))" + } + ]); + }); + it('builds signals for scale-bound translate', function () { + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "six_translate_anchor", + "value": {}, + "on": [ + { + "events": event_selector_1.default('mousedown', 'scope'), + "update": "{x: x(unit), y: y(unit), width: unit.width, height: unit.height, extent_x: domain(\"x\"), extent_y: domain(\"y\"), }" + } + ] + }, + { + "name": "six_translate_delta", + "value": {}, + "on": [ + { + "events": event_selector_1.default('[mousedown, window:mouseup] > window:mousemove!', 'scope'), + "update": "{x: x(unit) - six_translate_anchor.x, y: y(unit) - six_translate_anchor.y}" + } + ] + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_x'; })[0].on, [ + { + "events": { "signal": "six_translate_delta" }, + "update": "[six_translate_anchor.extent_x[0] - abs(span(six_translate_anchor.extent_x)) * six_translate_delta.x / six_translate_anchor.width, six_translate_anchor.extent_x[1] - abs(span(six_translate_anchor.extent_x)) * six_translate_delta.x / six_translate_anchor.width]" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_y'; })[0].on, [ + { + "events": { "signal": "six_translate_delta" }, + "update": "[six_translate_anchor.extent_y[0] + abs(span(six_translate_anchor.extent_y)) * six_translate_delta.y / six_translate_anchor.height, six_translate_anchor.extent_y[1] + abs(span(six_translate_anchor.extent_y)) * six_translate_delta.y / six_translate_anchor.height]" + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2NvbXBpbGUvc2VsZWN0aW9uL3RyYW5zbGF0ZS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhCQUE4Qjs7O0FBRTlCLDZCQUE0QjtBQUM1QixtQ0FBMEM7QUFDMUMseUVBQWdGO0FBQ2hGLG9FQUFzRTtBQUN0RSxpRkFBNEU7QUFFNUUsUUFBUSxDQUFDLCtCQUErQixFQUFFO0lBQ3hDLElBQU0sS0FBSyxHQUFHLHFCQUFjLENBQUM7UUFDM0IsTUFBTSxFQUFFLFFBQVE7UUFDaEIsVUFBVSxFQUFFO1lBQ1YsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ25ELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxrQkFBa0IsRUFBQyxNQUFNLEVBQUUsY0FBYyxFQUFDO1lBQ3pELE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBQztTQUMxQztLQUNGLENBQUMsQ0FBQztJQUVILEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNuQixJQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsa0JBQWtCLENBQUMsS0FBSyxFQUFFO1FBQ25ELEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLFdBQVcsRUFBRSxJQUFJO1NBQ2xCO1FBQ0QsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLE9BQU87WUFDZixXQUFXLEVBQUUsSUFBSTtTQUNsQjtRQUNELE9BQU8sRUFBRTtZQUNQLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLFdBQVcsRUFBRSxLQUFLO1NBQ25CO1FBQ0QsTUFBTSxFQUFFO1lBQ04sTUFBTSxFQUFFLFVBQVU7U0FDbkI7UUFDRCxNQUFNLEVBQUU7WUFDTixNQUFNLEVBQUUsVUFBVTtZQUNsQixXQUFXLEVBQUUsZ0VBQWdFO1NBQzlF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 \ No newline at end of file diff --git a/build/test/compile/selection/zoom.test.d.ts b/build/test/compile/selection/zoom.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/selection/zoom.test.js b/build/test/compile/selection/zoom.test.js new file mode 100644 index 0000000000..972ce22f82 --- /dev/null +++ b/build/test/compile/selection/zoom.test.js @@ -0,0 +1,176 @@ +/* tslint:disable quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var util_1 = require("../../util"); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var selection = require("../../../src/compile/selection/selection"); +var zoom_1 = require("../../../src/compile/selection/transforms/zoom"); +describe('Zoom Selection Transform', function () { + var model = util_1.parseUnitModel({ + "mark": "circle", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" }, + "color": { "field": "Origin", "type": "N" } + } + }); + model.parseScale(); + var selCmpts = selection.parseUnitSelection(model, { + "one": { + "type": "single", + "zoom": true + }, + "two": { + "type": "multi", + "zoom": true + }, + "three": { + "type": "interval", + "zoom": false + }, + "four": { + "type": "interval" + }, + "five": { + "type": "interval", + "zoom": "wheel, pinch" + }, + "six": { + "type": "interval", + "bind": "scales" + } + }); + it('identifies transform invocation', function () { + chai_1.assert.isFalse(zoom_1.default.has(selCmpts['one'])); + chai_1.assert.isFalse(zoom_1.default.has(selCmpts['two'])); + chai_1.assert.isFalse(zoom_1.default.has(selCmpts['three'])); + chai_1.assert.isTrue(zoom_1.default.has(selCmpts['four'])); + chai_1.assert.isTrue(zoom_1.default.has(selCmpts['five'])); + chai_1.assert.isTrue(zoom_1.default.has(selCmpts['six'])); + }); + it('builds signals for default invocation', function () { + model.component.selection = { four: selCmpts['four'] }; + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "four_zoom_anchor", + "on": [ + { + "events": event_selector_1.default('@four_brush:wheel', 'scope'), + "update": "{x: invert(\"x\", x(unit)), y: invert(\"y\", y(unit))}" + } + ] + }, + { + "name": "four_zoom_delta", + "on": [ + { + "events": event_selector_1.default('@four_brush:wheel', 'scope'), + "force": true, + "update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))" + } + ] + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_x'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "clampRange([four_zoom_anchor.x + (four_x[0] - four_zoom_anchor.x) * four_zoom_delta, four_zoom_anchor.x + (four_x[1] - four_zoom_anchor.x) * four_zoom_delta], invert(\"x\", 0), invert(\"x\", unit.width))" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_y'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "clampRange([four_zoom_anchor.y + (four_y[0] - four_zoom_anchor.y) * four_zoom_delta, four_zoom_anchor.y + (four_y[1] - four_zoom_anchor.y) * four_zoom_delta], invert(\"y\", unit.height), invert(\"y\", 0))" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'four_size'; })[0].on, [ + { + "events": { "signal": "four_zoom_delta" }, + "update": "{x: four_size.x, y: four_size.y, width: four_size.width * four_zoom_delta , height: four_size.height * four_zoom_delta}" + } + ]); + }); + it('builds signals for custom events', function () { + model.component.selection = { five: selCmpts['five'] }; + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "five_zoom_anchor", + "on": [ + { + "events": event_selector_1.default('@five_brush:wheel, @five_brush:pinch', 'scope'), + "update": "{x: invert(\"x\", x(unit)), y: invert(\"y\", y(unit))}" + } + ] + }, + { + "name": "five_zoom_delta", + "on": [ + { + "events": event_selector_1.default('@five_brush:wheel, @five_brush:pinch', 'scope'), + "force": true, + "update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))" + } + ] + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'five_x'; })[0].on, [ + { + "events": { "signal": "five_zoom_delta" }, + "update": "clampRange([five_zoom_anchor.x + (five_x[0] - five_zoom_anchor.x) * five_zoom_delta, five_zoom_anchor.x + (five_x[1] - five_zoom_anchor.x) * five_zoom_delta], invert(\"x\", 0), invert(\"x\", unit.width))" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'five_y'; })[0].on, [ + { + "events": { "signal": "five_zoom_delta" }, + "update": "clampRange([five_zoom_anchor.y + (five_y[0] - five_zoom_anchor.y) * five_zoom_delta, five_zoom_anchor.y + (five_y[1] - five_zoom_anchor.y) * five_zoom_delta], invert(\"y\", unit.height), invert(\"y\", 0))" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'five_size'; })[0].on, [ + { + "events": { "signal": "five_zoom_delta" }, + "update": "{x: five_size.x, y: five_size.y, width: five_size.width * five_zoom_delta , height: five_size.height * five_zoom_delta}" + } + ]); + }); + it('builds signals for scale-bound zoom', function () { + model.component.selection = { six: selCmpts['six'] }; + var signals = selection.assembleUnitSignals(model, []); + chai_1.assert.includeDeepMembers(signals, [ + { + "name": "six_zoom_anchor", + "on": [ + { + "events": event_selector_1.default('wheel', 'scope'), + "update": "{x: invert(\"x\", x(unit)), y: invert(\"y\", y(unit))}" + } + ] + }, + { + "name": "six_zoom_delta", + "on": [ + { + "events": event_selector_1.default('wheel', 'scope'), + "force": true, + "update": "pow(1.001, event.deltaY * pow(16, event.deltaMode))" + } + ] + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_x'; })[0].on, [ + { + "events": { "signal": "six_zoom_delta" }, + "update": "[six_zoom_anchor.x + (domain(\"x\")[0] - six_zoom_anchor.x) * six_zoom_delta, six_zoom_anchor.x + (domain(\"x\")[1] - six_zoom_anchor.x) * six_zoom_delta]" + } + ]); + chai_1.assert.includeDeepMembers(signals.filter(function (s) { return s.name === 'six_y'; })[0].on, [ + { + "events": { "signal": "six_zoom_delta" }, + "update": "[six_zoom_anchor.y + (domain(\"y\")[0] - six_zoom_anchor.y) * six_zoom_delta, six_zoom_anchor.y + (domain(\"y\")[1] - six_zoom_anchor.y) * six_zoom_delta]" + } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiem9vbS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9jb21waWxlL3NlbGVjdGlvbi96b29tLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBQzVCLG1DQUEwQztBQUMxQyx5RUFBZ0Y7QUFDaEYsb0VBQXNFO0FBQ3RFLHVFQUFrRTtBQUVsRSxRQUFRLENBQUMsMEJBQTBCLEVBQUU7SUFDbkMsSUFBTSxLQUFLLEdBQUcscUJBQWMsQ0FBQztRQUMzQixNQUFNLEVBQUUsUUFBUTtRQUNoQixVQUFVLEVBQUU7WUFDVixHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsWUFBWSxFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDbkQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7WUFDekQsT0FBTyxFQUFFLEVBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFDO1NBQzFDO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ25CLElBQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUU7UUFDbkQsS0FBSyxFQUFFO1lBQ0wsTUFBTSxFQUFFLFFBQVE7WUFDaEIsTUFBTSxFQUFFLElBQUk7U0FDYjtRQUNELEtBQUssRUFBRTtZQUNMLE1BQU0sRUFBRSxPQUFPO1lBQ2YsTUFBTSxFQUFFLElBQUk7U0FDYjtRQUNELE9BQU8sRUFBRTtZQUNQLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLE1BQU0sRUFBRSxLQUFLO1NBQ2Q7UUFDRCxNQUFNLEVBQUU7WUFDTixNQUFNLEVBQUUsVUFBVTtTQUNuQjtRQUNELE1BQU0sRUFBRTtZQUNOLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLE1BQU0sRUFBRSxjQUFjO1NBQ3ZCO1FBQ0QsS0FBSyxFQUFF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 \ No newline at end of file diff --git a/build/test/compile/unit.test.d.ts b/build/test/compile/unit.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/compile/unit.test.js b/build/test/compile/unit.test.js new file mode 100644 index 0000000000..93d84c2180 --- /dev/null +++ b/build/test/compile/unit.test.js @@ -0,0 +1,165 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../../src/log"); +var unit_1 = require("../../src/compile/unit"); +var channel_1 = require("../../src/channel"); +var mark_1 = require("../../src/mark"); +var type_1 = require("../../src/type"); +var util_1 = require("../util"); +describe('UnitModel', function () { + it('should say it is unit', function () { + var model = new unit_1.UnitModel({ mark: 'point' }, null, null); + chai_1.assert(model.isUnit()); + chai_1.assert(!model.isFacet()); + chai_1.assert(!model.isLayer()); + }); + describe('initEncoding', function () { + it('should drop unsupported channel and throws warning', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + shape: { field: 'a', type: 'quantitative' } + } + }); + chai_1.assert.equal(model.encoding.shape, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.incompatibleChannel(channel_1.SHAPE, mark_1.BAR)); + }); + }); + it('should drop channel without field and value and throws warning', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + x: { type: 'quantitative' } + } + }); + chai_1.assert.equal(model.encoding.x, undefined); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: type_1.QUANTITATIVE }, channel_1.X)); + }); + }); + it('should drop a fieldDef without field and value from the channel def list and throws warning', function () { + log.runLocalLogger(function (localLogger) { + var model = util_1.parseUnitModel({ + mark: 'bar', + encoding: { + detail: [ + { field: 'a', type: 'ordinal' }, + { value: 'b' }, + { type: 'quantitative' } + ] + } + }); + chai_1.assert.deepEqual(model.encoding.detail, [ + { field: 'a', type: 'ordinal' }, + { value: 'b' } + ]); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyFieldDef({ type: type_1.QUANTITATIVE }, channel_1.DETAIL)); + }); + }); + }); + describe('initSize', function () { + it('should have width, height = provided top-level width, height', function () { + var model = util_1.parseUnitModel({ + width: 123, + height: 456, + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + chai_1.assert.equal(model.width, 123); + chai_1.assert.equal(model.height, 456); + }); + it('should have width = default textXRangeStep for text mark without x', function () { + var model = util_1.parseUnitModel({ + mark: 'text', + encoding: {}, + config: { scale: { textXRangeStep: 91 } } + }); + chai_1.assert.equal(model.width, 91); + }); + it('should have width/height = config.scale.rangeStep for non-text mark without x,y', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: {}, + config: { scale: { rangeStep: 23 } } + }); + chai_1.assert.equal(model.width, 23); + chai_1.assert.equal(model.height, 23); + }); + it('should have width/height = config.cell.width/height for non-ordinal x,y', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'quantitative' }, + y: { field: 'b', type: 'quantitative' } + }, + config: { cell: { width: 123, height: 456 } } + }); + chai_1.assert.equal(model.width, 123); + chai_1.assert.equal(model.height, 456); + }); + it('should have width/height = config.cell.width/height for non-ordinal x,y', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', scale: { rangeStep: null } }, + y: { field: 'b', type: 'ordinal', scale: { rangeStep: null } } + }, + config: { cell: { width: 123, height: 456 } } + }); + chai_1.assert.equal(model.width, 123); + chai_1.assert.equal(model.height, 456); + }); + it('should have width/height = undefined for non-ordinal x,y', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { cell: { width: 123, height: 456 } } + }); + chai_1.assert.equal(model.width, undefined); + chai_1.assert.equal(model.height, undefined); + }); + }); + describe('initAxes', function () { + it('it should have axis.labelMaxLength = config.axis.labelMaxLength', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { axis: { labelMaxLength: 123 } } + }); + chai_1.assert.equal(model.axis(channel_1.X).labelMaxLength, 123); + chai_1.assert.equal(model.axis(channel_1.Y).labelMaxLength, 123); + }); + it('should not include properties of non-VlOnlyAxisConfig in config.facet.axis', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal' }, + y: { field: 'b', type: 'ordinal' } + }, + config: { axis: { domainWidth: 123 } } + }); + chai_1.assert.equal(model.axis(channel_1.X)['domainWidth'], undefined); + }); + it('it should have axis.offset = encode.x.axis.offset', function () { + var model = util_1.parseUnitModel({ + mark: 'point', + encoding: { + x: { field: 'a', type: 'ordinal', axis: { offset: 345 } }, + y: { field: 'b', type: 'ordinal' } + }, + config: { axis: { labelMaxLength: 123 } } + }); + chai_1.assert.equal(model.axis(channel_1.X).offset, 345); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC9jb21waWxlL3VuaXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUU1QixtQ0FBcUM7QUFDckMsK0NBQWlEO0FBQ2pELDZDQUFzRDtBQUN0RCx1Q0FBbUM7QUFFbkMsdUNBQTRDO0FBQzVDLGdDQUF1QztBQUV2QyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ3BCLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRTtRQUMxQixJQUFNLEtBQUssR0FBRyxJQUFJLGdCQUFTLENBQUMsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFhLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3JFLGFBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN2QixhQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN6QixhQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUMzQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDdkIsRUFBRSxDQUFDLG9EQUFvRCxFQUFFO1lBQ3ZELEdBQUcsQ0FBQyxjQUFjLENBQUMsVUFBQyxXQUFXO2dCQUM3QixJQUFNLEtBQUssR0FBRyxxQkFBYyxDQUFDO29CQUMzQixJQUFJLEVBQUUsS0FBSztvQkFDWCxRQUFRLEVBQUU7d0JBQ1IsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFDO3FCQUMxQztpQkFDRixDQUFDLENBQUM7Z0JBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDOUMsYUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FB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 \ No newline at end of file diff --git a/build/test/datetime.test.d.ts b/build/test/datetime.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/datetime.test.js b/build/test/datetime.test.js new file mode 100644 index 0000000000..4b3414855e --- /dev/null +++ b/build/test/datetime.test.js @@ -0,0 +1,117 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var datetime_1 = require("../src/datetime"); +var log = require("../src/log"); +describe('datetime', function () { + describe('dateTimeExpr', function () { + it('should drop day if day is combined with year/month/date', function () { + log.runLocalLogger(function (localLogger) { + var d = { + year: 2007, + day: 'monday' + }; + var expr = datetime_1.dateTimeExpr(d, true); + chai_1.assert.equal(expr, 'datetime(2007, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(localLogger.warns[0], log.message.droppedDay(d)); + }); + }); + it('should normalize numeric quarter correctly', function () { + var expr = datetime_1.dateTimeExpr({ + quarter: 2 + }, true); + chai_1.assert.equal(expr, 'datetime(0, 1*3, 1, 0, 0, 0, 0)'); + }); + it('should log warning for quarter > 4', function () { + log.runLocalLogger(function (localLogger) { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + quarter: 5 + }, true), 'datetime(0, 4*3, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(localLogger.warns[0], log.message.invalidTimeUnit('quarter', 5)); + }); + }); + it('should throw error for invalid quarter', function () { + chai_1.assert.throws(function () { + datetime_1.dateTimeExpr({ quarter: 'Q' }, true); + }, Error, log.message.invalidTimeUnit('quarter', 'Q')); + }); + it('should normalize numeric month correctly', function () { + var expr = datetime_1.dateTimeExpr({ + month: 1 + }, true); + chai_1.assert.equal(expr, 'datetime(0, 0, 1, 0, 0, 0, 0)'); + }); + it('should normalize month name correctly', function () { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'January' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'january' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'Jan' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + month: 'jan' + }, true), 'datetime(0, 0, 1, 0, 0, 0, 0)'); + }); + it('should throw error for invalid month', function () { + chai_1.assert.throws(function () { + datetime_1.dateTimeExpr({ month: 'J' }, true); + }, Error, log.message.invalidTimeUnit('month', 'J')); + }); + it('should normalize numeric day (of week) correctly', function () { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 0 + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 7 + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + }); + it('should normalize day name correctly and use year 2006 to ensure correct', function () { + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'Sunday' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'sunday' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'Sun' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + chai_1.assert.equal(datetime_1.dateTimeExpr({ + day: 'sun' + }, true), 'datetime(2006, 0, 0+1, 0, 0, 0, 0)'); + }); + it('should throw error for invalid day', function () { + chai_1.assert.throws(function () { + datetime_1.dateTimeExpr({ day: 'S' }, true); + }, Error, log.message.invalidTimeUnit('day', 'S')); + }); + // Note: Other part of coverage handled by timeUnit.fieldExpr's test + }); + describe('timestamp', function () { + it('should produce correct timestamp', function () { + chai_1.assert.equal(datetime_1.timestamp({ + year: 1234, + month: 'June', + date: 6, + hours: 7, + minutes: 8, + seconds: 9, + milliseconds: 123 + }, true), new Date(1234, 5, 6, 7, 8, 9, 123).getTime()); + }); + it('should produce correct timestamp for quarter', function () { + chai_1.assert.equal(datetime_1.timestamp({ + year: 1234, + quarter: 3, + }, true), new Date(1234, 6, 1).getTime()); + }); + it('should produce correct timestamp for day', function () { + chai_1.assert.equal(datetime_1.timestamp({ + day: 'monday' + }, true), new Date(2006, 0, 2).getTime()); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvZGF0ZXRpbWUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1Qiw0Q0FBd0Q7QUFDeEQsZ0NBQWtDO0FBRWxDLFFBQVEsQ0FBQyxVQUFVLEVBQUU7SUFDbkIsUUFBUSxDQUFDLGNBQWMsRUFBRTtRQUN2QixFQUFFLENBQUMseURBQXlELEVBQUU7WUFDNUQsR0FBRyxDQUFDLGNBQWMsQ0FBQyxVQUFDLFdBQVc7Z0JBQzdCLElBQU0sQ0FBQyxHQUFHO29CQUNSLElBQUksRUFBRSxJQUFJO29CQUNWLEdBQUcsRUFBRSxRQUFRO2lCQUNkLENBQUM7Z0JBQ0YsSUFBTSxJQUFJLEdBQUcsdUJBQVksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ25DLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLGtDQUFrQyxDQUFDLENBQUM7Z0JBQ3ZELGFBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNENBQTRDLEVBQUU7WUFDL0MsSUFBTSxJQUFJLEdBQUcsdUJBQVksQ0FBQztnQkFDeEIsT0FBTyxFQUFFLENBQUM7YUFDWCxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ1QsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztRQUN4RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtZQUN2QyxHQUFHLENBQUMsY0FBYyxDQUFDLFVBQUMsV0FBVztnQkFDN0IsYUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBWSxDQUFDO29CQUN4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 \ No newline at end of file diff --git a/build/test/fielddef.test.d.ts b/build/test/fielddef.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/fielddef.test.js b/build/test/fielddef.test.js new file mode 100644 index 0000000000..b6cc65d047 --- /dev/null +++ b/build/test/fielddef.test.js @@ -0,0 +1,130 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var fielddef_1 = require("../src/fielddef"); +var log = require("../src/log"); +var timeunit_1 = require("../src/timeunit"); +var type_1 = require("../src/type"); +describe('fieldDef', function () { + describe('defaultType()', function () { + it('should return temporal if there is timeUnit', function () { + chai_1.assert.equal(fielddef_1.defaultType({ timeUnit: 'month', field: 'a' }, 'x'), 'temporal'); + }); + it('should return quantitative if there is bin', function () { + chai_1.assert.equal(fielddef_1.defaultType({ bin: 'true', field: 'a' }, 'x'), 'quantitative'); + }); + it('should return quantitative for a channel that supports measure', function () { + for (var _i = 0, _a = ['x', 'y', 'size', 'opacity', 'order']; _i < _a.length; _i++) { + var c = _a[_i]; + chai_1.assert.equal(fielddef_1.defaultType({ field: 'a' }, c), 'quantitative', c); + } + }); + it('should return nominal for a channel that does not support measure', function () { + for (var _i = 0, _a = ['color', 'shape', 'row', 'column']; _i < _a.length; _i++) { + var c = _a[_i]; + chai_1.assert.equal(fielddef_1.defaultType({ field: 'a' }, c), 'nominal', c); + } + }); + }); + describe('normalize()', function () { + it('should return fieldDef with full type name.', function () { + var fieldDef = { field: 'a', type: 'q' }; + chai_1.assert.deepEqual(fielddef_1.normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + }); + it('should return fieldDef with default type and throw warning if type is missing.', log.wrap(function (localLogger) { + var fieldDef = { field: 'a' }; + chai_1.assert.deepEqual(fielddef_1.normalize(fieldDef, 'x'), { field: 'a', type: 'quantitative' }); + chai_1.assert.equal(localLogger.warns[0], log.message.emptyOrInvalidFieldType(undefined, 'x', 'quantitative')); + })); + }); + describe('channelCompatability', function () { + describe('row/column', function () { + it('is incompatible with continuous field', function () { + ['row', 'column'].forEach(function (channel) { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, channel).compatible); + }); + }); + it('is compatible with discrete field', function () { + ['row', 'column'].forEach(function (channel) { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + }); + }); + }); + describe('x/y/color/text/detail', function () { + it('is compatible with continuous field', function () { + ['x', 'y', 'color', 'text', 'detail'].forEach(function (channel) { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, channel).compatible); + }); + }); + it('is compatible with discrete field', function () { + ['x', 'y', 'color', 'text', 'detail'].forEach(function (channel) { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + }); + }); + }); + describe('opacity/size/x2/y2', function () { + it('is compatible with continuous field', function () { + ['opacity', 'size', 'x2', 'y2'].forEach(function (channel) { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, channel).compatible); + }); + }); + it('is compatible with binned field', function () { + ['opacity', 'size', 'x2', 'y2'].forEach(function (channel) { + chai_1.assert(fielddef_1.channelCompatibility({ bin: true, field: 'a', type: 'quantitative' }, channel).compatible); + }); + }); + it('is incompatible with discrete field', function () { + ['opacity', 'size', 'x2', 'y2'].forEach(function (channel) { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, channel).compatible); + }); + }); + }); + describe('shape', function () { + it('is compatible with nominal field', function () { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, 'shape').compatible); + }); + it('is incompatible with ordinal field', function () { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'ordinal' }, 'shape').compatible); + }); + it('is incompatible with quantitative field', function () { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, 'shape').compatible); + }); + }); + describe('order', function () { + it('is incompatible with nominal field', function () { + chai_1.assert(!fielddef_1.channelCompatibility({ field: 'a', type: 'nominal' }, 'order').compatible); + }); + it('is compatible with ordinal field', function () { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'ordinal' }, 'order').compatible); + }); + it('is compatible with quantitative field', function () { + chai_1.assert(fielddef_1.channelCompatibility({ field: 'a', type: 'quantitative' }, 'order').compatible); + }); + }); + }); + describe('title()', function () { + it('should return title if the fieldDef has title', function () { + var fieldDef = { field: '2', type: type_1.QUANTITATIVE, title: 'baz' }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'baz'); + }); + it('should return correct title for aggregate', function () { + chai_1.assert.equal(fielddef_1.title({ field: 'f', type: type_1.QUANTITATIVE, aggregate: 'mean' }, {}), 'MEAN(f)'); + }); + it('should return correct title for count', function () { + chai_1.assert.equal(fielddef_1.title({ field: '*', type: type_1.QUANTITATIVE, aggregate: 'count' }, { countTitle: 'baz!' }), 'baz!'); + }); + it('should return correct title for bin', function () { + var fieldDef = { field: 'f', type: type_1.QUANTITATIVE, bin: true }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'BIN(f)'); + }); + it('should return correct title for timeUnit', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL, timeUnit: timeunit_1.TimeUnit.MONTH }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'MONTH(f)'); + }); + it('should return correct title for raw field', function () { + var fieldDef = { field: 'f', type: type_1.TEMPORAL }; + chai_1.assert.equal(fielddef_1.title(fieldDef, {}), 'f'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRkZWYudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvZmllbGRkZWYudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUc1Qiw0Q0FBb0Y7QUFDcEYsZ0NBQWtDO0FBQ2xDLDRDQUF5QztBQUN6QyxvQ0FBbUQ7QUFFbkQsUUFBUSxDQUFDLFVBQVUsRUFBRTtJQUNuQixRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxhQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFXLENBQUMsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUM5RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRTtZQUMvQyxhQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFXLENBQUMsRUFBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnRUFBZ0UsRUFBRTtZQUNuRSxHQUFHLENBQUMsQ0FBVSxVQUFtRCxFQUFuRCxLQUFBLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBYyxFQUFuRCxjQUFtRCxFQUFuRCxJQUFtRDtnQkFBNUQsSUFBSSxDQUFDLFNBQUE7Z0JBQ1IsYUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBVyxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQzthQUMvRDtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1FQUFtRSxFQUFFO1lBQ3RF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 \ No newline at end of file diff --git a/build/test/filter.test.d.ts b/build/test/filter.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/filter.test.js b/build/test/filter.test.js new file mode 100644 index 0000000000..f6013ce2c0 --- /dev/null +++ b/build/test/filter.test.js @@ -0,0 +1,99 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var filter_1 = require("../src/filter"); +var timeunit_1 = require("../src/timeunit"); +describe('filter', function () { + var equalFilter = { field: 'color', equal: 'red' }; + var oneOfFilter = { field: 'color', oneOf: ['red', 'yellow'] }; + var rangeFilter = { field: 'x', range: [0, 5] }; + var exprFilter = 'datum["x"]===5'; + describe('isEqualFilter', function () { + it('should return true for an equal filter', function () { + chai_1.assert.isTrue(filter_1.isEqualFilter(equalFilter)); + }); + it('should return false for other filters', function () { + [oneOfFilter, rangeFilter, exprFilter].forEach(function (filter) { + chai_1.assert.isFalse(filter_1.isEqualFilter(filter)); + }); + }); + }); + describe('isOneOfFilter', function () { + it('should return true for an in filter', function () { + chai_1.assert.isTrue(filter_1.isOneOfFilter(oneOfFilter)); + }); + it('should return false for other filters', function () { + [equalFilter, rangeFilter, exprFilter].forEach(function (filter) { + chai_1.assert.isFalse(filter_1.isOneOfFilter(filter)); + }); + }); + }); + describe('isRangeFilter', function () { + it('should return true for a range filter', function () { + chai_1.assert.isTrue(filter_1.isRangeFilter(rangeFilter)); + }); + it('should return false for other filters', function () { + [oneOfFilter, equalFilter, exprFilter].forEach(function (filter) { + chai_1.assert.isFalse(filter_1.isRangeFilter(filter)); + }); + }); + }); + describe('expression', function () { + it('should return a correct expression for an EqualFilter', function () { + var expr = filter_1.expression({ field: 'color', equal: 'red' }); + chai_1.assert.equal(expr, 'datum["color"]==="red"'); + }); + it('should return a correct expression for an EqualFilter with datetime object', function () { + var expr = filter_1.expression({ + field: 'date', + equal: { + month: 'January' + } + }); + chai_1.assert.equal(expr, 'datum["date"]===time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an EqualFilter with time unit and datetime object', function () { + var expr = filter_1.expression({ + timeUnit: timeunit_1.TimeUnit.MONTH, + field: 'date', + equal: { + month: 'January' + } + }); + chai_1.assert.equal(expr, 'time(datetime(0, month(datum["date"]), 1, 0, 0, 0, 0))===time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an EqualFilter with datetime ojbect', function () { + var expr = filter_1.expression({ + timeUnit: timeunit_1.TimeUnit.MONTH, + field: 'date', + equal: 'January' + }); + chai_1.assert.equal(expr, 'time(datetime(0, month(datum["date"]), 1, 0, 0, 0, 0))===time(datetime(0, 0, 1, 0, 0, 0, 0))'); + }); + it('should return a correct expression for an InFilter', function () { + var expr = filter_1.expression({ field: 'color', oneOf: ['red', 'yellow'] }); + chai_1.assert.equal(expr, 'indexof(["red","yellow"], datum["color"]) !== -1'); + }); + it('should return a correct expression for a RangeFilter', function () { + var expr = filter_1.expression({ field: 'x', range: [0, 5] }); + chai_1.assert.equal(expr, 'inrange(datum["x"], 0, 5)'); + }); + it('should return a correct expression for a RangeFilter with no lower bound', function () { + var expr = filter_1.expression({ field: 'x', range: [null, 5] }); + chai_1.assert.equal(expr, 'datum["x"] <= 5'); + }); + it('should return a correct expression for a RangeFilter with no upper bound', function () { + var expr = filter_1.expression({ field: 'x', range: [0, null] }); + chai_1.assert.equal(expr, 'datum["x"] >= 0'); + }); + it('should return undefined for a RangeFilter with no bound', function () { + var expr = filter_1.expression({ field: 'x', range: [null, null] }); + chai_1.assert.equal(expr, undefined); + }); + it('should return a correct expression for an expression filter', function () { + var expr = filter_1.expression('datum["x"]===5'); + chai_1.assert.equal(expr, 'datum["x"]===5'); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L2ZpbHRlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLHdDQUFzRjtBQUN0Riw0Q0FBeUM7QUFFekMsUUFBUSxDQUFDLFFBQVEsRUFBRTtJQUNqQixJQUFNLFdBQVcsR0FBRyxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDO0lBQ25ELElBQU0sV0FBVyxHQUFHLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEVBQUMsQ0FBQztJQUMvRCxJQUFNLFdBQVcsR0FBRyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFDLENBQUM7SUFDaEQsSUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUM7SUFFcEMsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsYUFBTSxDQUFDLE1BQU0sQ0FBQyxzQkFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLE1BQU07Z0JBQ3BELGFBQU0sQ0FBQyxPQUFPLENBQUMsc0JBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFDLHFDQUFxQyxFQUFFO1lBQ3hDLGFBQU0sQ0FBQyxNQUFNLENBQUMsc0JBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVDQUF1QyxFQUFFO1lBQzFDLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxVQUFVLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBQyxNQUFNO2dCQUNwRCxhQUFNLENBQUMsT0FBTyxDQUFDLHNCQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRTtZQUMxQyxhQUFNLENBQUMsTUFBTSxDQUFDLHNCQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRTtZQUMxQyxDQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUUsVUFBVSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQUMsTUFBTTtnQkFDcEQsYUFBTSxDQUFDLE9BQU8sQ0FBQyxzQkFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDeEMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsSUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7WUFDeEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLENBQUMsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0RUFBNEUsRUFBRTtZQUMvRSxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDO2dCQUN0QixLQUFLLEVBQUUsTUFBTTtnQkFDYixLQUFLLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLFNBQVM7aUJBQ2pCO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUscURBQXFELENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwRkFBMEYsRUFBRTtZQUM3RixJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDO2dCQUN0QixRQUFRLEVBQUUsbUJBQVEsQ0FBQyxLQUFLO2dCQUN4QixLQUFLLEVBQUUsTUFBTTtnQkFDYixLQUFLLEVBQUU7b0JBQ0wsS0FBSyxFQUFFLFNBQVM7aUJBQ2pCO2FBQ0YsQ0FBQyxDQUFDO1lBQ0gsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsOEZBQThGLENBQUMsQ0FBQztRQUNySCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0RUFBNEUsRUFBRTtZQUMvRSxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDO2dCQUN0QixRQUFRLEVBQUUsbUJBQVEsQ0FBQyxLQUFLO2dCQUN4QixLQUFLLEVBQUUsTUFBTTtnQkFDYixLQUFLLEVBQUUsU0FBUzthQUNqQixDQUFDLENBQUM7WUFDSCxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSw4RkFBOEYsQ0FBQyxDQUFDO1FBQ3JILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9EQUFvRCxFQUFFO1lBQ3ZELElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsRUFBQyxDQUFDLENBQUM7WUFDcEUsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsa0RBQWtELENBQUMsQ0FBQztRQUN6RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRTtZQUN6RCxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQ3JELGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLDJCQUEyQixDQUFDLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMEVBQTBFLEVBQUU7WUFDN0UsSUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFDLENBQUMsQ0FBQztZQUN4RCxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBFQUEwRSxFQUFFO1lBQzdFLElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBQyxDQUFDLENBQUM7WUFDeEQsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztRQUdILEVBQUUsQ0FBQyx5REFBeUQsRUFBRTtZQUM1RCxJQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1lBQzNELGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO1lBQ2hFLElBQU0sSUFBSSxHQUFHLG1CQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUMxQyxhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/scale.test.d.ts b/build/test/scale.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/scale.test.js b/build/test/scale.test.js new file mode 100644 index 0000000000..5ee88f04ab --- /dev/null +++ b/build/test/scale.test.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale = require("../src/scale"); +var chai_1 = require("chai"); +var util_1 = require("../src/util"); +describe('scale', function () { + describe('scaleTypeSupportProperty', function () { + // Make sure we always edit this when we add new channel + it('should have at least one supported scale types for all scale properties', function () { + var _loop_1 = function (prop) { + chai_1.assert(util_1.some(scale.SCALE_TYPES, function (scaleType) { + return scale.scaleTypeSupportProperty(scaleType, prop); + })); + }; + for (var _i = 0, _a = scale.SCALE_PROPERTIES; _i < _a.length; _i++) { + var prop = _a[_i]; + _loop_1(prop); + } + }); + // TODO: write more test blindly (Don't look at our code, just look at D3 code.) + }); + describe('scaleTypes', function () { + it('should either hasContinuousDomain or hasDiscreteDomain', function () { + for (var _i = 0, _a = scale.SCALE_TYPES; _i < _a.length; _i++) { + var scaleType = _a[_i]; + chai_1.assert(scale.hasContinuousDomain(scaleType) !== scale.hasDiscreteDomain(scaleType)); + } + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3Qvc2NhbGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG9DQUFzQztBQUN0Qyw2QkFBNEI7QUFDNUIsb0NBQWlDO0FBRWpDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7SUFDaEIsUUFBUSxDQUFDLDBCQUEwQixFQUFFO1FBQ25DLHdEQUF3RDtRQUN4RCxFQUFFLENBQUMseUVBQXlFLEVBQUU7b0NBQ25FLElBQUk7Z0JBQ1gsYUFBTSxDQUFDLFdBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLFVBQUMsU0FBUztvQkFDdkMsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3pELENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDTixDQUFDO1lBSkQsR0FBRyxDQUFDLENBQWEsVUFBc0IsRUFBdEIsS0FBQSxLQUFLLENBQUMsZ0JBQWdCLEVBQXRCLGNBQXNCLEVBQXRCLElBQXNCO2dCQUFsQyxJQUFJLElBQUksU0FBQTt3QkFBSixJQUFJO2FBSVo7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILGdGQUFnRjtJQUNsRixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxZQUFZLEVBQUU7UUFDckIsRUFBRSxDQUFDLHdEQUF3RCxFQUFFO1lBQzNELEdBQUcsQ0FBQyxDQUFrQixVQUFpQixFQUFqQixLQUFBLEtBQUssQ0FBQyxXQUFXLEVBQWpCLGNBQWlCLEVBQWpCLElBQWlCO2dCQUFsQyxJQUFJLFNBQVMsU0FBQTtnQkFDaEIsYUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxLQUFLLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQzthQUNyRjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/schema.test.d.ts b/build/test/schema.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/schema.test.js b/build/test/schema.test.js new file mode 100644 index 0000000000..9d2d733781 --- /dev/null +++ b/build/test/schema.test.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var Ajv = require("ajv"); +var util_1 = require("util"); +var specSchema = require('../../build/vega-lite-schema.json'); +var metaSchema = require('ajv/lib/refs/json-schema-draft-04.json'); +describe('Schema', function () { + it('should be valid', function () { + var ajv = new Ajv({ + allErrors: true, + verbose: true + }); + ajv.addMetaSchema(metaSchema, 'http://json-schema.org/draft-04/schema#'); + // now validate our data against the schema + var valid = ajv.validateSchema(specSchema); + if (!valid) { + console.log(util_1.inspect(ajv.errors, { depth: 10, colors: true })); + } + chai_1.assert.equal(valid, true); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0L3NjaGVtYS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkJBQTRCO0FBQzVCLHlCQUEyQjtBQUMzQiw2QkFBNkI7QUFFN0IsSUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFDaEUsSUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7QUFFckUsUUFBUSxDQUFDLFFBQVEsRUFBRTtJQUNqQixFQUFFLENBQUMsaUJBQWlCLEVBQUU7UUFDcEIsSUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7WUFDbEIsU0FBUyxFQUFFLElBQUk7WUFDZixPQUFPLEVBQUUsSUFBSTtTQUNkLENBQUMsQ0FBQztRQUVILEdBQUcsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLHlDQUF5QyxDQUFDLENBQUM7UUFFekUsMkNBQTJDO1FBQzNDLElBQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFN0MsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBQ1gsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBQ0QsYUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/spec.test.d.ts b/build/test/spec.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/spec.test.js b/build/test/spec.test.js new file mode 100644 index 0000000000..5fd2c5525f --- /dev/null +++ b/build/test/spec.test.js @@ -0,0 +1,633 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var spec_1 = require("../src/spec"); +// describe('isStacked()') -- tested as part of stackOffset in stack.test.ts +describe('normalize()', function () { + describe('normalizeFacetedUnit', function () { + it('should convert single extended spec with column into a composite spec', function () { + var spec = { + "name": "faceted", + "width": 123, + "height": 234, + "description": "faceted spec", + "data": { "url": "data/movies.json" }, + "mark": "point", + "encoding": { + "column": { "field": "MPAA_Rating", "type": "ordinal" }, + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec), { + "width": 123, + "height": 234, + "name": "faceted", + "description": "faceted spec", + "data": { "url": "data/movies.json" }, + "facet": { + "column": { "field": "MPAA_Rating", "type": "ordinal" } + }, + "spec": { + "mark": "point", + "encoding": { + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + } + }); + }); + it('should convert single extended spec with row into a composite spec', function () { + var spec = { + "data": { "url": "data/movies.json" }, + "mark": "point", + "encoding": { + "row": { "field": "MPAA_Rating", "type": "ordinal" }, + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec), { + "data": { "url": "data/movies.json" }, + "facet": { + "row": { "field": "MPAA_Rating", "type": "ordinal" } + }, + "spec": { + "mark": "point", + "encoding": { + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + } + }); + }); + }); + describe('normalizeFacet', function () { + it('should produce correct layered specs for mean point and vertical error bar', function () { + chai_1.assert.deepEqual(spec_1.normalize({ + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": { "filter": "datum.year == 2000" }, + facet: { + "row": { "field": "MPAA_Rating", "type": "ordinal" } + }, + spec: { + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + mark: 'error-bar', + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + }, + "size": { "value": 5 } + } + } + ] + } + }), { + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": { "filter": "datum.year == 2000" }, + facet: { + "row": { "field": "MPAA_Rating", "type": "ordinal" } + }, + spec: { + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + "layer": [ + { + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "max", + "field": "people", + "type": "quantitative", + }, + "size": { "value": 5 } + } + } + ] + } + ] + } + }); + }); + }); + describe('normalizeLayer', function () { + it('should produce correct layered specs for mean point and vertical error bar', function () { + chai_1.assert.deepEqual(spec_1.normalize({ + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": { "filter": "datum.year == 2000" }, + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + mark: 'error-bar', + encoding: { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + }, + "size": { "value": 5 } + } + } + ] + }), { + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": { "filter": "datum.year == 2000" }, + layer: [ + { + "mark": "point", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "mean", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 2 } + } + }, + { + "layer": [ + { + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "y2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, + { + "mark": "tick", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { + "aggregate": "max", + "field": "people", + "type": "quantitative", + }, + "size": { "value": 5 } + } + } + ] + } + ] + }); + }); + }); + describe('normalizeErrorBar', function () { + it('should produce correct layered specs for horizontal error bar', function () { + chai_1.assert.deepEqual(spec_1.normalize({ + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": { "filter": "datum.year == 2000" }, + mark: 'error-bar', + encoding: { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + }, + "size": { "value": 5 } + } + }), { + "description": "A error bar plot showing mean, min, and max in the US population distribution of age groups in 2000.", + "data": { "url": "data/population.json" }, + "transform": { "filter": "datum.year == 2000" }, + "layer": [ + { + "mark": "rule", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "x2": { + "aggregate": "max", + "field": "people", + "type": "quantitative" + } + } + }, + { + "mark": "tick", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "min", + "field": "people", + "type": "quantitative", + "axis": { "title": "population" } + }, + "size": { "value": 5 } + } + }, + { + "mark": "tick", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { + "aggregate": "max", + "field": "people", + "type": "quantitative", + }, + "size": { "value": 5 } + } + } + ] + }); + }); + }); + describe('normalizeOverlay', function () { + describe('line', function () { + it('should be normalized correctly', function () { + var spec = { + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum[\"symbol\"]==='GOOG'" }, + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "overlay": { "line": true } } + }; + var normalizedSpec = spec_1.normalize(spec); + chai_1.assert.deepEqual(normalizedSpec, { + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum[\"symbol\"]==='GOOG'" }, + "layer": [ + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "mark": { "filled": true } } + } + ] + }); + }); + }); + describe('area', function () { + it('with linepoint should be normalized correctly', function () { + var spec = { + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum[\"symbol\"]==='GOOG'" }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "overlay": { "area": 'linepoint' } } + }; + var normalizedSpec = spec_1.normalize(spec); + chai_1.assert.deepEqual(normalizedSpec, { + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum[\"symbol\"]==='GOOG'" }, + "layer": [ + { + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "mark": { "filled": true } } + } + ] + }); + }); + it('with linepoint should be normalized correctly', function () { + var spec = { + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum[\"symbol\"]==='GOOG'" }, + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + }, + "config": { "overlay": { "area": 'line' } } + }; + var normalizedSpec = spec_1.normalize(spec); + chai_1.assert.deepEqual(normalizedSpec, { + "description": "Google's stock price over time.", + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum[\"symbol\"]==='GOOG'" }, + "layer": [ + { + "mark": "area", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + } + ] + }); + }); + }); + }); +}); +describe('normalizeRangedUnitSpec', function () { + it('should convert y2 -> y if there is no y in the encoding', function () { + var spec = { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "y2": { "field": "age", "type": "ordinal" }, + "x": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec), { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }); + }); + it('should do nothing if there is no missing x or y', function () { + var spec = { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "y": { "field": "age", "type": "ordinal" }, + "x": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "x2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec), spec); + }); + it('should convert x2 -> x if there is no x in the encoding', function () { + var spec = { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "x2": { "field": "age", "type": "ordinal" }, + "y": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "y2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }; + chai_1.assert.deepEqual(spec_1.normalize(spec), { + "data": { "url": "data/population.json" }, + "mark": "rule", + "encoding": { + "x": { "field": "age", "type": "ordinal" }, + "y": { "aggregate": "min", "field": "people", "type": "quantitative" }, + "y2": { "aggregate": "max", "field": "people", "type": "quantitative" } + } + }); + }); +}); +describe('fieldDefs()', function () { + it('should get all non-duplicate fieldDefs from an encoding', function () { + var spec = { + "data": { "url": "data/cars.json" }, + "mark": "point", + "encoding": { + "x": { "field": "Horsepower", "type": "quantitative" }, + "y": { "field": "Miles_per_Gallon", "type": "quantitative" } + } + }; + chai_1.assert.deepEqual(spec_1.fieldDefs(spec), [ + { "field": "Horsepower", "type": "quantitative" }, + { "field": "Miles_per_Gallon", "type": "quantitative" } + ]); + }); + it('should get all non-duplicate fieldDefs from all layer in a LayerSpec', function () { + var layerSpec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum.symbol==='GOOG'" }, + "layer": [ + { + "description": "Google's stock price over time.", + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "description": "Google's stock price over time.", + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "symbol", "type": "nominal" } + }, + "config": { "mark": { "filled": true } } + } + ] + }; + chai_1.assert.deepEqual(spec_1.fieldDefs(layerSpec), [ + { "field": "date", "type": "temporal" }, + { "field": "price", "type": "quantitative" }, + { "field": "symbol", "type": "nominal" } + ]); + }); + it('should get all non-duplicate fieldDefs from all layer in a LayerSpec (merging duplicate fields with different scale types)', function () { + var layerSpec = { + "data": { "url": "data/stocks.csv", "format": { "type": "csv" } }, + "transform": { "filter": "datum.symbol==='GOOG'" }, + "layer": [ + { + "description": "Google's stock price over time.", + "mark": "line", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" } + } + }, + { + "description": "Google's stock price over time.", + "mark": "point", + "encoding": { + "x": { "field": "date", "type": "temporal" }, + "y": { "field": "price", "type": "quantitative" }, + "color": { "field": "date", "type": "temporal", "scale": { "type": "pow" } } + }, + "config": { "mark": { "filled": true } } + } + ] + }; + chai_1.assert.deepEqual(spec_1.fieldDefs(layerSpec), [ + { "field": "date", "type": "temporal" }, + { "field": "price", "type": "quantitative" } + ]); + }); + it('should get all non-duplicate fieldDefs from facet and layer in a FacetSpec', function () { + var facetSpec = { + "data": { "url": "data/movies.json" }, + "facet": { "row": { "field": "MPAA_Rating", "type": "ordinal" } }, + "spec": { + "mark": "point", + "encoding": { + "x": { "field": "Worldwide_Gross", "type": "quantitative" }, + "y": { "field": "US_DVD_Sales", "type": "quantitative" } + } + } + }; + chai_1.assert.deepEqual(spec_1.fieldDefs(facetSpec), [ + { "field": "MPAA_Rating", "type": "ordinal" }, + { "field": "Worldwide_Gross", "type": "quantitative" }, + { "field": "US_DVD_Sales", "type": "quantitative" } + ]); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlYy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC9zcGVjLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsOEJBQThCOzs7QUFFOUIsNkJBQTRCO0FBRTVCLG9DQUFpRDtBQUVqRCw0RUFBNEU7QUFFNUUsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUN0QixRQUFRLENBQUMsc0JBQXNCLEVBQUU7UUFDL0IsRUFBRSxDQUFDLHVFQUF1RSxFQUFFO1lBQzFFLElBQU0sSUFBSSxHQUFRO2dCQUNoQixNQUFNLEVBQUUsU0FBUztnQkFDakIsT0FBTyxFQUFFLEdBQUc7Z0JBQ1osUUFBUSxFQUFFLEdBQUc7Z0JBQ2IsYUFBYSxFQUFFLGNBQWM7Z0JBQzdCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztnQkFDbkMsTUFBTSxFQUFFLE9BQU87Z0JBQ2YsVUFBVSxFQUFFO29CQUNWLFFBQVEsRUFBRSxFQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBQztvQkFDcEQsR0FBRyxFQUFFLEVBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFDLE1BQU0sRUFBRSxjQUFjLEVBQUM7b0JBQ3hELEdBQUcsRUFBRSxFQUFDLE9BQU8sRUFBRSxjQUFjLEVBQUMsTUFBTSxFQUFFLGNBQWMsRUFBQztpQkFDdEQ7YUFDRixDQUFDO1lBRUYsYUFBTSxDQUFDLFNBQVMsQ0FBQyxnQkFBUyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNoQyxPQUFPLEVBQUUsR0FBRztnQkFDWixRQUFRLEVBQUUsR0FBRztnQkFDYixNQUFNLEVBQUUsU0FBUztnQkFDakIsYUFBYSxFQUFFLGNBQWM7Z0JBQzdCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztnQkFDbkMsT0FBTyxFQUFFO29CQUNQLFFBQVEsRUFBRSxFQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBQztp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 \ No newline at end of file diff --git a/build/test/stack.test.d.ts b/build/test/stack.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/stack.test.js b/build/test/stack.test.js new file mode 100644 index 0000000000..e280d92ce5 --- /dev/null +++ b/build/test/stack.test.js @@ -0,0 +1,383 @@ +/* tslint:disable:quotemark */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../src/log"); +var channel_1 = require("../src/channel"); +var mark_1 = require("../src/mark"); +var scale_1 = require("../src/scale"); +var stack_1 = require("../src/stack"); +var spec_1 = require("../src/spec"); +describe('stack', function () { + var NON_STACKABLE_MARKS = [mark_1.RECT]; + it('should be disabled for non-stackable marks with at least of of the stack channel', function () { + [undefined, 'center', 'none', 'zero', 'normalize'].forEach(function (stacked) { + NON_STACKABLE_MARKS.forEach(function (nonStackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": nonStackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + }); + }); + }); + it('should always be disabled for raw plot', function () { + [undefined, 'center', 'none', 'zero', 'normalize'].forEach(function (stacked) { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + }); + }); + }); + it('should always be disabled if there is no stackby channel', function () { + [undefined, 'center', 'none', 'zero', 'normalize'].forEach(function (stacked) { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + }); + }); + }); + it('should always be disabled if the stackby channel is aggregated', function () { + [undefined, 'center', 'none', 'zero', 'normalize'].forEach(function (stacked) { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "aggregate": "count", "type": "quantitative" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + }); + }); + }); + it('can enabled if one of the stackby channels is not aggregated', function () { + [undefined, 'center', 'zero', 'normalize'].forEach(function (stacked) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "aggregate": "count", "type": "quantitative" }, + "detail": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + var _stack = stack_1.stack(spec.mark, spec.encoding, spec.config.stack); + chai_1.assert.isOk(_stack); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + chai_1.assert.equal(_stack.stackBy[0].channel, channel_1.DETAIL); + }); + }); + }); + it('can enabled if one of the stackby channels is not aggregated', function () { + [undefined, 'center', 'zero', 'normalize'].forEach(function (stacked) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative", "stack": stacked }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "aggregate": "count", "type": "quantitative" }, + "detail": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.isOk(_stack); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + chai_1.assert.equal(_stack.stackBy[0].channel, channel_1.DETAIL); + }); + }); + }); + it('should always be disabled if both x and y are aggregate', function () { + [undefined, 'center', 'none', 'zero', 'normalize'].forEach(function (stacked) { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "aggregate": "count", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + }); + }); + }); + it('should always be disabled if neither x nor y is aggregate', function () { + [undefined, 'center', 'none', 'zero', 'normalize'].forEach(function (stacked) { + mark_1.PRIMITIVE_MARKS.forEach(function (mark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "variety", "type": "nominal" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + }); + }); + }); + it('should always be disabled if there is both x and x2', function () { + [undefined, 'center', 'zero', 'normalize'].forEach(function (stacked) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + log.runLocalLogger(function (localLogger) { + var spec = { + "mark": mark, + "encoding": { + "x": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "x2": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + chai_1.assert.equal(localLogger.warns[0], log.message.cannotStackRangedMark(channel_1.X), JSON.stringify({ stacked: stacked, mark: mark })); + }); + }); + }); + }); + it('should always be disabled if there is both y and y2', function () { + [undefined, 'center', 'zero', 'normalize'].forEach(function (stacked) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + log.runLocalLogger(function (localLogger) { + var spec = { + "mark": mark, + "encoding": { + "y": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "y2": { "field": "a", "type": "quantitative", "aggregate": "sum" }, + "x": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + chai_1.assert.equal(localLogger.warns[0], log.message.cannotStackRangedMark(channel_1.Y), JSON.stringify({ stacked: stacked, mark: mark })); + }); + }); + }); + }); + it('should always be disabled if the aggregated axis has non-linear scale', function () { + [undefined, 'center', 'zero', 'normalize'].forEach(function (stacked) { + [scale_1.ScaleType.LOG, scale_1.ScaleType.POW, scale_1.ScaleType.SQRT].forEach(function (scaleType) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + log.runLocalLogger(function (localLogger) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "a", "type": "quantitative", "aggregate": "sum", "scale": { "type": scaleType } }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + chai_1.assert.equal(localLogger.warns[0], log.message.cannotStackNonLinearScale(scaleType)); + }); + }); + }); + }); + }); + it('should always be disabled if the aggregated axis has non-summative aggregate', function () { + [undefined, 'center', 'zero', 'normalize'].forEach(function (stacked) { + ['average', 'variance', 'q3'].forEach(function (aggregate) { + var marks = stacked === undefined ? stack_1.STACK_BY_DEFAULT_MARKS : stack_1.STACKABLE_MARKS; + marks.forEach(function (mark) { + log.runLocalLogger(function (localLogger) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": mark, + "encoding": { + "x": { "field": "a", "type": "quantitative", "aggregate": aggregate }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.isNull(stack_1.stack(spec.mark, spec.encoding, spec.config.stack)); + chai_1.assert.isFalse(spec_1.isStacked(spec)); + chai_1.assert.equal(localLogger.warns[0], log.message.cannotStackNonSummativeAggregate(aggregate)); + }); + }); + }); + }); + }); + describe('stack().groupbyChannel, .fieldChannel', function () { + it('should be correct for horizontal', function () { + [mark_1.BAR, mark_1.AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.X); + chai_1.assert.equal(_stack.groupbyChannel, channel_1.Y); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be correct for horizontal (single)', function () { + [mark_1.BAR, mark_1.AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.X); + chai_1.assert.equal(_stack.groupbyChannel, null); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be correct for vertical', function () { + [mark_1.BAR, mark_1.AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "y": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "x": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.Y); + chai_1.assert.equal(_stack.groupbyChannel, channel_1.X); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be correct for vertical (single)', function () { + [mark_1.BAR, mark_1.AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "y": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "color": { "field": "site", "type": "nominal" } + } + }; + var _stack = stack_1.stack(spec.mark, spec.encoding, undefined); + chai_1.assert.equal(_stack.fieldChannel, channel_1.Y); + chai_1.assert.equal(_stack.groupbyChannel, null); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + }); + describe('stack().offset', function () { + it('should be zero for stackable marks with at least of of the stack channel if stacked is unspecified', function () { + [mark_1.BAR, mark_1.AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + } + }; + chai_1.assert.equal(stack_1.stack(spec.mark, spec.encoding, undefined).offset, 'zero'); + chai_1.assert.isTrue(spec_1.isStacked(spec)); + }); + }); + it('should be the specified stacked for stackable marks with at least one of the stack channel', function () { + ['center', 'zero', 'normalize'].forEach(function (stacked) { + [mark_1.BAR, mark_1.AREA].forEach(function (stackableMark) { + var spec = { + "data": { "url": "data/barley.json" }, + "mark": stackableMark, + "encoding": { + "x": { "aggregate": "sum", "field": "yield", "type": "quantitative" }, + "y": { "field": "variety", "type": "nominal" }, + "color": { "field": "site", "type": "nominal" } + }, + "config": { + "stack": stacked + } + }; + chai_1.assert.equal(stack_1.stack(spec.mark, spec.encoding, spec.config.stack).offset, stacked); + chai_1.assert.equal(spec_1.isStacked(spec), true); + }); + }); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2sudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3Qvc3RhY2sudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4QkFBOEI7OztBQUU5Qiw2QkFBNEI7QUFFNUIsZ0NBQWtDO0FBR2xDLDBDQUE0QztBQUM1QyxvQ0FBNkQ7QUFDN0Qsc0NBQXVDO0FBQ3ZDLHNDQUF5RjtBQUN6RixvQ0FBZ0Q7QUFFaEQsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFNLG1CQUFtQixHQUFHLENBQUMsV0FBSSxDQUFDLENBQUM7SUFFbkMsRUFBRSxDQUFDLGtGQUFrRixFQUFFO1FBQ3JGLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFDLE9BQW9CO1lBQzlFLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxVQUFDLGdCQUFnQjtnQkFDM0MsSUFBTSxJQUFJLEdBQWE7b0JBQ3JCLE1BQU0sRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQztvQkFDbkMsTUFBTSxFQUFFLGdCQUFnQjtvQkFDeEIsVUFBVSxFQUFFO3dCQUNWLEdBQUcsRUFBRSxFQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDO3dCQUNuRSxHQUFHLEVBQUUsRUFBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUM7d0JBQzVDLE9BQU8sRUFBRSxFQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQztxQkFDOUM7b0JBQ0QsUUFBUSxFQUFFO3dCQUNSLE9BQU8sRUFBRSxPQUFPO3FCQUNqQjtpQkFDRixDQUFDO2dCQUNGLGFBQU0sQ0FBQyxNQUFNLENBQUMsYUFBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENB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 \ No newline at end of file diff --git a/build/test/timeunit.test.d.ts b/build/test/timeunit.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/timeunit.test.js b/build/test/timeunit.test.js new file mode 100644 index 0000000000..396739e895 --- /dev/null +++ b/build/test/timeunit.test.js @@ -0,0 +1,141 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var log = require("../src/log"); +var timeunit_1 = require("../src/timeunit"); +describe('timeUnit', function () { + describe('containsTimeUnit', function () { + it('should return true for quarter given quarter', function () { + var fullTimeUnit = timeunit_1.TimeUnit.QUARTER; + var timeUnit = timeunit_1.TimeUnit.QUARTER; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for yearquarter given quarter', function () { + var fullTimeUnit = timeunit_1.TimeUnit.YEARQUARTER; + var timeUnit = timeunit_1.TimeUnit.QUARTER; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for SECONDS and MILLISECONDS given SECONDSMILLISECONDS', function () { + var fullTimeUnit = timeunit_1.TimeUnit.SECONDSMILLISECONDS; + var timeUnit = timeunit_1.TimeUnit.SECONDS; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return true for MILLISECONDS given SECONDSMILLISECONDS', function () { + var fullTimeUnit = timeunit_1.TimeUnit.SECONDSMILLISECONDS; + var timeUnit = timeunit_1.TimeUnit.MILLISECONDS; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), true); + }); + it('should return false for quarter given year', function () { + var fullTimeUnit = timeunit_1.TimeUnit.YEAR; + var timeUnit = timeunit_1.TimeUnit.QUARTER; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), false); + }); + it('should return false for SECONDS given MILLISECONDS', function () { + var fullTimeUnit = timeunit_1.TimeUnit.MILLISECONDS; + var timeUnit = timeunit_1.TimeUnit.SECONDS; + chai_1.assert.equal(timeunit_1.containsTimeUnit(fullTimeUnit, timeUnit), false); + }); + }); + describe('fieldExpr', function () { + it('should return correct field expression for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, 'x'), 'datetime(year(datum["x"]), month(datum["x"]), date(datum["x"]), hours(datum["x"]), minutes(datum["x"]), seconds(datum["x"]), 0)'); + }); + it('should automatically correct YEARMONTHDAY to be YEARMONTHDATE', function () { + log.runLocalLogger(function (localLogger) { + chai_1.assert.equal(timeunit_1.fieldExpr('yearmonthday', 'x'), 'datetime(year(datum["x"]), month(datum["x"]), date(datum["x"]), 0, 0, 0, 0)'); + chai_1.assert.equal(localLogger.warns[0], log.message.dayReplacedWithDate('yearmonthday')); + }); + }); + it('should return correct field expression for QUARTER', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.QUARTER, 'x'), 'datetime(0, (quarter(datum["x"])-1)*3, 1, 0, 0, 0, 0)'); + }); + it('should return correct field expression for DAY', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.DAY, 'x'), 'datetime(2006, 0, day(datum["x"])+1, 0, 0, 0, 0)'); + }); + it('should return correct field expression for MILLISECONDS', function () { + chai_1.assert.equal(timeunit_1.fieldExpr(timeunit_1.TimeUnit.MILLISECONDS, 'x'), 'datetime(0, 0, 1, 0, 0, 0, milliseconds(datum["x"]))'); + }); + }); + describe('convert', function () { + it('should throw an error for the DAY timeunit', function () { + chai_1.assert.throws(function () { + timeunit_1.convert(timeunit_1.TimeUnit.DAY, new Date(2000, 11, 2, 23, 59, 59, 999)); + }, Error, 'Cannot convert to TimeUnits containing \'day\''); + }); + it('should return expected result for YEARQUARTER', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARQUARTER, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 9, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARQUARTERMONTH', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARQUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTH', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATE', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATE, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATEHOURS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 0, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURSMINUTES', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 0, 0).getTime()); + }); + it('should return expected result for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(2000, 11, 2, 23, 59, 59, 0).getTime()); + }); + it('should return expected result for QUARTERMONTH', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.QUARTERMONTH, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 11, 1, 0, 0, 0, 0).getTime()); + }); + it('should return expected result for HOURSMINUTES', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.HOURSMINUTES, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 0, 0).getTime()); + }); + it('should return expected result for HOURSMINUTESSECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.HOURSMINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 23, 59, 59, 0).getTime()); + }); + it('should return expected result for MINUTESSECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.MINUTESSECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 59, 59, 0).getTime()); + }); + it('should return expected result for SECONDSMILLISECONDS', function () { + var date = timeunit_1.convert(timeunit_1.TimeUnit.SECONDSMILLISECONDS, new Date(2000, 11, 2, 23, 59, 59, 999)); + chai_1.assert.equal(date.getTime(), new Date(1900, 0, 1, 0, 0, 59, 999).getTime()); + }); + }); + describe('template', function () { + it('should return correct template for YEARMONTHDATEHOURSMINUTESSECONDS', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, 'datum.x', undefined), "timeFormat(datum.x, '%b %d, %Y %H:%M:%S')"); + }); + it('should return correct template for YEARMONTH (No comma)', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.YEARMONTH, 'datum.x', undefined), "timeFormat(datum.x, '%b %Y')"); + }); + it('should return correct template for DAY', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.DAY, 'datum.x', undefined), "timeFormat(datum.x, '%A')"); + }); + it('should return correct template for DAY (shortened)', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.DAY, 'datum.x', true), "timeFormat(datum.x, '%a')"); + }); + it('should return correct template for QUARTER', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.QUARTER, 'datum.x', undefined), "'Q' + quarter(datum.x)"); + }); + it('should return correct template for YEARQUARTER', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.YEARQUARTER, 'datum.x', undefined), "'Q' + quarter(datum.x) + ' ' + timeFormat(datum.x, '%Y')"); + }); + it('should return correct template for milliseconds', function () { + chai_1.assert.equal(timeunit_1.formatExpression(timeunit_1.TimeUnit.MILLISECONDS, 'datum.x', undefined), "timeFormat(datum.x, '%L')"); + }); + it('should return correct template for no timeUnit', function () { + chai_1.assert.equal(timeunit_1.formatExpression(undefined, 'datum.x', undefined), undefined); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXVuaXQudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdGltZXVuaXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUU1QixnQ0FBa0M7QUFFbEMsNENBQWlHO0FBR2pHLFFBQVEsQ0FBQyxVQUFVLEVBQUU7SUFDbkIsUUFBUSxDQUFDLGtCQUFrQixFQUFFO1FBQzNCLEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxJQUFNLFlBQVksR0FBRyxtQkFBUSxDQUFDLE9BQU8sQ0FBQztZQUN0QyxJQUFNLFFBQVEsR0FBRyxtQkFBUSxDQUFDLE9BQU8sQ0FBQztZQUNsQyxhQUFNLENBQUMsS0FBSyxDQUFDLDJCQUFnQixDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxJQUFNLFlBQVksR0FBRyxtQkFBUSxDQUFDLFdBQVcsQ0FBQztZQUMxQyxJQUFNLFFBQVEsR0FBRyxtQkFBUSxDQUFDLE9BQU8sQ0FBQztZQUNsQyxhQUFNLENBQUMsS0FBSyxDQUFDLDJCQUFnQixDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyRUFBMkUsRUFBRTtZQUM5RSxJQUFNLFlBQVksR0FBRyxtQkFBUSxDQUFDLG1CQUFtQixDQUFDO1lBQ2xELElBQU0sUUFBUSxHQUFHLG1CQUFRLENBQUMsT0FBTyxDQUFDO1lBQ2xDLGFBQU0sQ0FBQyxLQUFLLENBQUMsMkJBQWdCLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtEQUErRCxFQUFFO1lBQ2xFLElBQU0sWUFBWSxHQUFHLG1CQUFR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 \ No newline at end of file diff --git a/build/test/type.test.d.ts b/build/test/type.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/type.test.js b/build/test/type.test.js new file mode 100644 index 0000000000..42fe4c7af2 --- /dev/null +++ b/build/test/type.test.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var type = require("../src/type"); +describe('type', function () { + describe('getFullName()', function () { + it('should return correct lowercase, full type names.', function () { + for (var _i = 0, _a = ['q', 'Q', 'quantitative', 'QUANTITATIVE']; _i < _a.length; _i++) { + var t = _a[_i]; + chai_1.assert.equal(type.getFullName(t), 'quantitative'); + } + for (var _b = 0, _c = ['t', 'T', 'temporal', 'TEMPORAL']; _b < _c.length; _b++) { + var t = _c[_b]; + chai_1.assert.equal(type.getFullName(t), 'temporal'); + } + for (var _d = 0, _e = ['o', 'O', 'ordinal', 'ORDINAL']; _d < _e.length; _d++) { + var t = _e[_d]; + chai_1.assert.equal(type.getFullName(t), 'ordinal'); + } + for (var _f = 0, _g = ['n', 'N', 'nominal', 'NOMINAL']; _f < _g.length; _f++) { + var t = _g[_f]; + chai_1.assert.equal(type.getFullName(t), 'nominal'); + } + }); + it('should return undefined for invalid type', function () { + chai_1.assert.equal(type.getFullName('haha'), undefined); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdGVzdC90eXBlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw2QkFBNEI7QUFFNUIsa0NBQW9DO0FBRXBDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7SUFDZixRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyxtREFBbUQsRUFBRTtZQUN0RCxHQUFHLENBQUMsQ0FBVSxVQUEwQyxFQUExQyxNQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxFQUExQyxjQUEwQyxFQUExQyxJQUEwQztnQkFBbkQsSUFBSSxDQUFDLFNBQUE7Z0JBQ1IsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO2FBQ25EO1lBQ0QsR0FBRyxDQUFDLENBQVUsVUFBa0MsRUFBbEMsTUFBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsRUFBbEMsY0FBa0MsRUFBbEMsSUFBa0M7Z0JBQTNDLElBQUksQ0FBQyxTQUFBO2dCQUNSLGFBQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQzthQUMvQztZQUNELEdBQUcsQ0FBQyxDQUFVLFVBQWdDLEVBQWhDLE1BQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQWhDLGNBQWdDLEVBQWhDLElBQWdDO2dCQUF6QyxJQUFJLENBQUMsU0FBQTtnQkFDUixhQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7YUFDOUM7WUFDRCxHQUFHLENBQUMsQ0FBVSxVQUFnQyxFQUFoQyxNQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxFQUFoQyxjQUFnQyxFQUFoQyxJQUFnQztnQkFBekMsSUFBSSxDQUFDLFNBQUE7Z0JBQ1IsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQzlDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUU7WUFDN0MsYUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9 \ No newline at end of file diff --git a/build/test/util.d.ts b/build/test/util.d.ts new file mode 100644 index 0000000000..770fe2bdd7 --- /dev/null +++ b/build/test/util.d.ts @@ -0,0 +1,9 @@ +import { UnitModel } from '../src/compile/unit'; +import { FacetModel } from '../src/compile/facet'; +import { LayerModel } from '../src/compile/layer'; +import { UnitSpec, FacetSpec, LayerSpec, ExtendedSpec } from '../src/spec'; +import { Model } from '../src/compile/model'; +export declare function parseModel(inputSpec: ExtendedSpec): Model; +export declare function parseUnitModel(spec: UnitSpec): UnitModel; +export declare function parseLayerModel(spec: LayerSpec): LayerModel; +export declare function parseFacetModel(spec: FacetSpec): FacetModel; diff --git a/build/test/util.js b/build/test/util.js new file mode 100644 index 0000000000..f3702eb386 --- /dev/null +++ b/build/test/util.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("../src/compile/common"); +var unit_1 = require("../src/compile/unit"); +var facet_1 = require("../src/compile/facet"); +var layer_1 = require("../src/compile/layer"); +var spec_1 = require("../src/spec"); +function parseModel(inputSpec) { + var spec = spec_1.normalize(inputSpec); + return common_1.buildModel(spec, null, ''); +} +exports.parseModel = parseModel; +function parseUnitModel(spec) { + return new unit_1.UnitModel(spec, null, ''); +} +exports.parseUnitModel = parseUnitModel; +function parseLayerModel(spec) { + return new layer_1.LayerModel(spec, null, ''); +} +exports.parseLayerModel = parseLayerModel; +function parseFacetModel(spec) { + return new facet_1.FacetModel(spec, null, ''); +} +exports.parseFacetModel = parseFacetModel; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGdEQUFpRDtBQUNqRCw0Q0FBOEM7QUFDOUMsOENBQWdEO0FBQ2hELDhDQUFnRDtBQUNoRCxvQ0FBb0Y7QUFHcEYsb0JBQTJCLFNBQXVCO0lBQ2hELElBQU0sSUFBSSxHQUFHLGdCQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEMsTUFBTSxDQUFDLG1CQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBSEQsZ0NBR0M7QUFFRCx3QkFBK0IsSUFBYztJQUMzQyxNQUFNLENBQUMsSUFBSSxnQkFBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUZELHdDQUVDO0FBRUQseUJBQWdDLElBQWU7SUFDN0MsTUFBTSxDQUFDLElBQUksa0JBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3hDLENBQUM7QUFGRCwwQ0FFQztBQUVELHlCQUFnQyxJQUFlO0lBQzdDLE1BQU0sQ0FBQyxJQUFJLGtCQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN4QyxDQUFDO0FBRkQsMENBRUMifQ== \ No newline at end of file diff --git a/build/test/validate.test.d.ts b/build/test/validate.test.d.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build/test/validate.test.js b/build/test/validate.test.js new file mode 100644 index 0000000000..01c225772b --- /dev/null +++ b/build/test/validate.test.js @@ -0,0 +1,70 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var chai_1 = require("chai"); +var validate_1 = require("../src/validate"); +var mark_1 = require("../src/mark"); +describe('vl.validate', function () { + describe('getEncodingMappingError()', function () { + it('should return no error for valid specs', function () { + chai_1.assert.isNull(validate_1.getEncodingMappingError({ + mark: mark_1.BAR, + encoding: { + x: { field: 'a' } + } + })); + chai_1.assert.isNull(validate_1.getEncodingMappingError({ + mark: mark_1.LINE, + encoding: { + x: { field: 'b' }, + y: { field: 'a' } + } + })); + chai_1.assert.isNull(validate_1.getEncodingMappingError({ + mark: mark_1.AREA, + encoding: { + x: { field: 'a' }, + y: { field: 'b' } + } + })); + }); + it('should return error for invalid specs', function () { + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.LINE, + encoding: { + x: { field: 'b' } // missing y + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.AREA, + encoding: { + y: { field: 'b' } // missing x + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.TEXT, + encoding: { + y: { field: 'b' } // missing text + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.LINE, + encoding: { + shape: { field: 'b' } // using shape with line + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.AREA, + encoding: { + shape: { field: 'b' } // using shape with area + } + })); + chai_1.assert.isNotNull(validate_1.getEncodingMappingError({ + mark: mark_1.BAR, + encoding: { + shape: { field: 'b' } // using shape with bar + } + })); + }); + }); +}); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3QvdmFsaWRhdGUudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZCQUE0QjtBQUM1Qiw0Q0FBd0Q7QUFDeEQsb0NBQWtEO0FBRWxELFFBQVEsQ0FBQyxhQUFhLEVBQUU7SUFDdEIsUUFBUSxDQUFDLDJCQUEyQixFQUFFO1FBQ3BDLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRTtZQUMzQyxhQUFNLENBQUMsTUFBTSxDQUFDLGtDQUF1QixDQUFDO2dCQUNwQyxJQUFJLEVBQUUsVUFBRztnQkFDVCxRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztpQkFDaEI7YUFDRixDQUFDLENBQUMsQ0FBQztZQUVKLGFBQU0sQ0FBQyxNQUFNLENBQUMsa0NBQXVCLENBQUM7Z0JBQ3BDLElBQUksRUFBRSxXQUFJO2dCQUNWLFFBQVEsRUFBRTtvQkFDUixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDO29CQUNmLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUM7aUJBQ2hCO2FBQ0YsQ0FBQyxDQUFDLENBQUM7WUFFSixhQUFNLENBQUMsTUFBTSxDQUFDLGtDQUF1QixDQUFDO2dCQUNwQyxJQUFJLEVBQUUsV0FBSTtnQkFDVixRQUFRLEVBQUU7b0JBQ1IsQ0FBQyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQztvQkFDZixDQUFDLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDO2lCQUNoQjthQUNGLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsQ0FBQyxZQUFZO2lCQUM3QjthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsQ0FBQyxZQUFZO2lCQUM3QjthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLENBQUMsRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsQ0FBQyxlQUFlO2lCQUNoQzthQUNGLENBQUMsQ0FBQyxDQUFDO1lBRUosYUFBTSxDQUFDLFNBQVMsQ0FBQyxrQ0FBdUIsQ0FBQztnQkFDdkMsSUFBSSxFQUFFLFdBQUk7Z0JBQ1YsUUFBUSxFQUFFO29CQUNSLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxHQUFHLEVBQUMsQ0FBQyx3QkFBd0I7aUJBQzdDO2FBQ0YsQ0FBQyxDQUFDLENBQUM7WUFFSixhQUFNLENBQUMsU0FBUyxDQUFDLGtDQUF1QixDQUFDO2dCQUN2QyxJQUFJLEVBQUUsV0FBSTtnQkFDVixRQUFRLEVBQUU7b0JBQ1IsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLEdBQUcsRUFBQyxDQUFDLHdCQUF3QjtpQkFDN0M7YUFDRixDQUFDLENBQUMsQ0FBQztZQUVKLGFBQU0sQ0FBQyxTQUFTLENBQUMsa0NBQXVCLENBQUM7Z0JBQ3ZDLElBQUksRUFBRSxVQUFHO2dCQUNULFFBQVEsRUFBRTtvQkFDUixLQUFLLEVBQUUsRUFBQyxLQUFLLEVBQUUsR0FBRyxFQUFDLENBQUMsdUJBQXVCO2lCQUM1QzthQUNGLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0= \ No newline at end of file diff --git a/build/vega-lite.js b/build/vega-lite.js new file mode 100644 index 0000000000..c7c0b5caeb --- /dev/null +++ b/build/vega-lite.js @@ -0,0 +1,9656 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vl = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (!isFinite(number)) { + error("Bad number"); + } else { + return number; + } +}, + string = function string() { + // Parse a string value. + var hex, + i, + string = '', + uffff; + + // When parsing for string values, we must look for " and \ characters. + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error("Bad string"); +}, + white = function white() { + + // Skip whitespace. + + while (ch && ch <= ' ') { + next(); + } +}, + word = function word() { + + // true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error("Unexpected '" + ch + "'"); +}, + value, + // Place holder for the value function. + +array = function array() { + + // Parse an array value. + + var array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error("Bad array"); +}, + object = function object() { + + // Parse an object value. + + var key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("Bad object"); +}; + +value = function value() { + + // Parse a JSON value. It could be an object, an array, a string, a number, + // or a word. + + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } +}; + +// Return the json_parse function. It will have access to all of the above +// functions and variables. + +module.exports = function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } + + // If there is a reviver function, we recursively walk the new structure, + // passing each name/value pair to the reviver function for possible + // transformation, starting with a temporary root object that holds the result + // in an empty key. If there is not a reviver function, we simply return the + // result. + + return typeof reviver === 'function' ? function walk(holder, key) { + var k, + v, + value = holder[key]; + if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({ '': result }, '') : result; +}; + +},{}],4:[function(require,module,exports){ +'use strict'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"': '\\"', + '\\': '\\\\' +}, + rep; + +function quote(string) { + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; +} + +function str(key, holder) { + // Produce a string from holder[key]. + var i, + // The loop counter. + k, + // The member key. + v, + // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + // What happens next depends on the value's type. + switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) { + case 'string': + return quote(value); + + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + return String(value); + + case 'object': + if (!value) return 'null'; + gap += indent; + partial = []; + + // Array.isArray + if (Object.prototype.toString.apply(value) === '[object Array]') { + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + // Join all of the elements together, separated with commas, and + // wrap them in brackets. + v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be + // stringified. + if (rep && (typeof rep === 'undefined' ? 'undefined' : _typeof(rep)) === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + // Otherwise, iterate through all of the keys in the object. + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + + v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } +} + +module.exports = function (value, replacer, space) { + var i; + gap = ''; + indent = ''; + + // If the space parameter is a number, make an indent string containing that + // many spaces. + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + } + // If the space parameter is a string, it will be used as the indent string. + else if (typeof space === 'string') { + indent = space; + } + + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + rep = replacer; + if (replacer && typeof replacer !== 'function' && ((typeof replacer === 'undefined' ? 'undefined' : _typeof(replacer)) !== 'object' || typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + return str('', { '': value }); +}; + +},{}],5:[function(require,module,exports){ +(function (global){ +"use strict"; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global global, define, System, Reflect, Promise */ +var __extends; +var __assign; +var __rest; +var __decorate; +var __param; +var __metadata; +var __awaiter; +var __generator; +var __exportStar; +var __values; +var __read; +var __spread; +var __asyncGenerator; +var __asyncDelegator; +var __asyncValues; +(function (factory) { + var root = (typeof global === "undefined" ? "undefined" : _typeof(global)) === "object" ? global : (typeof self === "undefined" ? "undefined" : _typeof(self)) === "object" ? self : _typeof(this) === "object" ? this : {}; + if (typeof define === "function" && define.amd) { + define("tslib", ["exports"], function (exports) { + factory(createExporter(root, createExporter(exports))); + }); + } else if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") { + factory(createExporter(root, createExporter(module.exports))); + } else { + factory(createExporter(root)); + } + function createExporter(exports, previous) { + return function (id, v) { + return exports[id] = previous ? previous(id, v) : v; + }; + } +})(function (exporter) { + var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) { + d.__proto__ = b; + } || function (d, b) { + for (var p in b) { + if (b.hasOwnProperty(p)) d[p] = b[p]; + } + }; + + __extends = function __extends(d, b) { + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + + __assign = Object.assign || function (t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) { + if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + } + return t; + }; + + __rest = function __rest(s, e) { + var t = {}; + for (var p in s) { + if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; + }if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; + }return t; + }; + + __decorate = function __decorate(decorators, target, key, desc) { + var c = arguments.length, + r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, + d; + if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) { + if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + }return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + + __param = function __param(paramIndex, decorator) { + return function (target, key) { + decorator(target, key, paramIndex); + }; + }; + + __metadata = function __metadata(metadataKey, metadataValue) { + if ((typeof Reflect === "undefined" ? "undefined" : _typeof(Reflect)) === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + }; + + __awaiter = function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : new P(function (resolve) { + resolve(result.value); + }).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + + __generator = function __generator(thisArg, body) { + var _ = { label: 0, sent: function sent() { + if (t[0] & 1) throw t[1];return t[1]; + }, trys: [], ops: [] }, + f, + y, + t, + g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { + return this; + }), g; + function verb(n) { + return function (v) { + return step([n, v]); + }; + } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) { + try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0:case 1: + t = op;break; + case 4: + _.label++;return { value: op[1], done: false }; + case 5: + _.label++;y = op[1];op = [0];continue; + case 7: + op = _.ops.pop();_.trys.pop();continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0;continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1];break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1];t = op;break; + } + if (t && _.label < t[2]) { + _.label = t[2];_.ops.push(op);break; + } + if (t[2]) _.ops.pop(); + _.trys.pop();continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e];y = 0; + } finally { + f = t = 0; + } + }if (op[0] & 5) throw op[1];return { value: op[0] ? op[1] : void 0, done: true }; + } + }; + + __exportStar = function __exportStar(m, exports) { + for (var p in m) { + if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + }; + + __values = function __values(o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], + i = 0; + if (m) return m.call(o); + return { + next: function next() { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + }; + + __read = function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), + r, + ar = [], + e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) { + ar.push(r.value); + } + } catch (error) { + e = { error: error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } finally { + if (e) throw e.error; + } + } + return ar; + }; + + __spread = function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) { + ar = ar.concat(__read(arguments[i])); + }return ar; + }; + + __asyncGenerator = function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), + q = [], + c, + i; + return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { + return this; + }, i; + function verb(n) { + return function (v) { + return new Promise(function (a, b) { + q.push([n, v, a, b]), next(); + }); + }; + } + function next() { + if (!c && q.length) resume((c = q.shift())[0], c[1]); + } + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(c[3], e); + } + } + function step(r) { + r.done ? settle(c[2], r) : r.value[0] === "yield" ? settle(c[2], { value: r.value[1], done: false }) : Promise.resolve(r.value[1]).then(r.value[0] === "delegate" ? delegate : fulfill, reject); + } + function delegate(r) { + step(r.done ? r : { value: ["yield", r.value], done: false }); + } + function fulfill(value) { + resume("next", value); + } + function reject(value) { + resume("throw", value); + } + function settle(f, v) { + c = void 0, f(v), next(); + } + }; + + __asyncDelegator = function __asyncDelegator(o) { + var i = { next: verb("next"), "throw": verb("throw", function (e) { + throw e; + }), "return": verb("return", function (v) { + return { value: v, done: true }; + }) }; + return o = __asyncValues(o), i[Symbol.iterator] = function () { + return this; + }, i; + function verb(n, f) { + return function (v) { + return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; + }; + } + }; + + __asyncValues = function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator]; + return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); + }; + + exporter("__extends", __extends); + exporter("__assign", __assign); + exporter("__rest", __rest); + exporter("__decorate", __decorate); + exporter("__param", __param); + exporter("__metadata", __metadata); + exporter("__awaiter", __awaiter); + exporter("__generator", __generator); + exporter("__exportStar", __exportStar); + exporter("__values", __values); + exporter("__read", __read); + exporter("__spread", __spread); + exporter("__asyncGenerator", __asyncGenerator); + exporter("__asyncDelegator", __asyncDelegator); + exporter("__asyncValues", __asyncValues); +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],6:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +exports.default = function (selector, source) { + DEFAULT_SOURCE = source || VIEW; + return parseMerge(selector.trim()).map(parseSelector); +}; + +var _marktypes = require('./marks/marktypes'); + +var VIEW = 'view', + LBRACK = '[', + RBRACK = ']', + LBRACE = '{', + RBRACE = '}', + COLON = ':', + COMMA = ',', + NAME = '@', + GT = '>'; + +/** + * Parse an event selector string. + * Returns an array of event stream definitions. + */ + + +var ILLEGAL = /[\[\]\{\}]/, + DEFAULT_SOURCE; + +function find(s, i, endChar, pushChar, popChar) { + var count = 0, + n = s.length, + c; + for (; i < n; ++i) { + c = s[i]; + if (!count && c === endChar) return i;else if (popChar && popChar.indexOf(c) >= 0) --count;else if (pushChar && pushChar.indexOf(c) >= 0) ++count; + } + return i; +} + +function parseMerge(s) { + var output = [], + start = 0, + n = s.length, + i = 0; + + while (i < n) { + i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE); + output.push(s.substring(start, i).trim()); + start = ++i; + } + + if (output.length === 0) { + throw 'Empty event selector: ' + s; + } + return output; +} + +function parseSelector(s) { + return s[0] === '[' ? parseBetween(s) : parseStream(s); +} + +function parseBetween(s) { + var start = 1, + n = s.length, + i = 1, + b, + stream; + + i = find(s, i, RBRACK, LBRACK, RBRACK); + if (i === n) { + throw 'Empty between selector: ' + s; + } + + b = parseMerge(s.substring(start, i)); + if (b.length !== 2) { + throw 'Between selector must have two elements: ' + s; + } + + s = s.slice(i + 1).trim(); + if (s[0] !== GT) { + throw 'Expected \'>\' after between selector: ' + s; + } + + b = b.map(parseSelector); + + stream = parseSelector(s.slice(1).trim()); + if (stream.between) { + return { + between: b, + stream: stream + }; + } else { + stream.between = b; + } + + return stream; +} + +function parseStream(s) { + var stream = { source: DEFAULT_SOURCE }, + source = [], + throttle = [0, 0], + markname = 0, + start = 0, + n = s.length, + i = 0, + j, + filter; + + // extract throttle from end + if (s[n - 1] === RBRACE) { + i = s.lastIndexOf(LBRACE); + if (i >= 0) { + try { + throttle = parseThrottle(s.substring(i + 1, n - 1)); + } catch (e) { + throw 'Invalid throttle specification: ' + s; + } + s = s.slice(0, i).trim(); + n = s.length; + } else throw 'Unmatched right brace: ' + s; + i = 0; + } + + if (!n) throw s; + + // set name flag based on first char + if (s[0] === NAME) markname = ++i; + + // extract first part of multi-part stream selector + j = find(s, i, COLON); + if (j < n) { + source.push(s.substring(start, j).trim()); + start = i = ++j; + } + + // extract remaining part of stream selector + i = find(s, i, LBRACK); + if (i === n) { + source.push(s.substring(start, n).trim()); + } else { + source.push(s.substring(start, i).trim()); + filter = []; + start = ++i; + if (start === n) throw 'Unmatched left bracket: ' + s; + } + + // extract filters + while (i < n) { + i = find(s, i, RBRACK); + if (i === n) throw 'Unmatched left bracket: ' + s; + filter.push(s.substring(start, i).trim()); + if (i < n - 1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s; + start = ++i; + } + + // marshall event stream specification + if (!(n = source.length) || ILLEGAL.test(source[n - 1])) { + throw 'Invalid event selector: ' + s; + } + + if (n > 1) { + stream.type = source[1]; + if (markname) { + stream.markname = source[0].slice(1); + } else if ((0, _marktypes.isMarkType)(source[0])) { + stream.marktype = source[0]; + } else { + stream.source = source[0]; + } + } else { + stream.type = source[0]; + } + if (stream.type.slice(-1) === '!') { + stream.consume = true; + stream.type = stream.type.slice(0, -1); + } + if (filter != null) stream.filter = filter; + if (throttle[0]) stream.throttle = throttle[0]; + if (throttle[1]) stream.debounce = throttle[1]; + + return stream; +} + +function parseThrottle(s) { + var a = s.split(COMMA); + if (!s.length || a.length > 2) throw s; + return a.map(function (_) { + var x = +_; + if (x !== x) throw s; + return x; + }); +} + +},{"./marks/marktypes":7}],7:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.marktypes = exports.TextMark = exports.SymbolMark = exports.ShapeMark = exports.RuleMark = exports.RectMark = exports.PathMark = exports.LineMark = exports.ImageMark = exports.GroupMark = exports.AreaMark = exports.ArcMark = undefined; +exports.isMarkType = isMarkType; + +var _vegaUtil = require('vega-util'); + +var ArcMark = exports.ArcMark = 'arc'; +var AreaMark = exports.AreaMark = 'area'; +var GroupMark = exports.GroupMark = 'group'; +var ImageMark = exports.ImageMark = 'image'; +var LineMark = exports.LineMark = 'line'; +var PathMark = exports.PathMark = 'path'; +var RectMark = exports.RectMark = 'rect'; +var RuleMark = exports.RuleMark = 'rule'; +var ShapeMark = exports.ShapeMark = 'shape'; +var SymbolMark = exports.SymbolMark = 'symbol'; +var TextMark = exports.TextMark = 'text'; + +var marktypes = exports.marktypes = (0, _vegaUtil.toSet)(['*', 'arc', 'area', 'group', 'image', 'line', 'path', 'rect', 'rule', 'shape', 'symbol', 'text']); + +function isMarkType(type) { + return marktypes.hasOwnProperty(type); +} + +},{"vega-util":8}],8:[function(require,module,exports){ +'use strict'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +(function (global, factory) { + (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : factory(global.vega = global.vega || {}); +})(undefined, function (exports) { + 'use strict'; + + var accessor = function accessor(fn, fields, name) { + return fn.fields = fields || [], fn.fname = name, fn; + }; + + function accessorName(fn) { + return fn == null ? null : fn.fname; + } + + function accessorFields(fn) { + return fn == null ? null : fn.fields; + } + + var error = function error(message) { + throw Error(message); + }; + + var splitAccessPath = function splitAccessPath(p) { + var path = [], + q = null, + b = 0, + n = p.length, + s = '', + i, + j, + c; + + p = p + ''; + + function push() { + path.push(s + p.substring(i, j)); + s = ''; + i = j + 1; + } + + for (i = j = 0; j < n; ++j) { + c = p[j]; + if (c === '\\') s += p.substring(i, j), i = ++j;else if (c === q) push(), q = null, b = -1;else if (q) continue;else if (i === b && c === '"') i = j + 1, q = c;else if (i === b && c === "'") i = j + 1, q = c;else if (c === '.' && !b) j > i ? push() : i = j + 1;else if (c === '[') { + if (j > i) push(); + b = i = j + 1; + } else if (c === ']') { + if (!b) error('Access path missing open bracket: ' + p); + if (b > 0) push(); + b = 0; + i = j + 1; + } + } + + if (b) error('Access path missing closing bracket: ' + p); + if (q) error('Access path missing closing quote: ' + p); + if (j > i) ++j, push(); + return path; + }; + + var isArray = Array.isArray; + + var isObject = function isObject(_) { + return _ === Object(_); + }; + + var isString = function isString(_) { + return typeof _ === 'string'; + }; + + function $(x) { + return isArray(x) ? '[' + x.map($) + ']' : isObject(x) || isString(x) ? + // Output valid JSON and JS source strings. + // See http://timelessrepo.com/json-isnt-a-javascript-subset + JSON.stringify(x).replace('\u2028', '\\u2028').replace('\u2029', '\\u2029') : x; + } + + var field = function field(_field, name) { + var path = splitAccessPath(_field), + code = 'return _[' + path.map($).join('][') + '];'; + + return accessor(Function('_', code), [_field = path.length === 1 ? path[0] : _field], name || _field); + }; + + var empty = []; + + var id = field('id'); + + var identity = accessor(function (_) { + return _; + }, empty, 'identity'); + + var zero = accessor(function () { + return 0; + }, empty, 'zero'); + + var one = accessor(function () { + return 1; + }, empty, 'one'); + + var truthy = accessor(function () { + return true; + }, empty, 'true'); + + var falsy = accessor(function () { + return false; + }, empty, 'false'); + + function log(method, level, input) { + var args = [level].concat([].slice.call(input)); + console[method].apply(console, args); // eslint-disable-line no-console + } + + var None = 0; + var Warn = 1; + var Info = 2; + var Debug = 3; + + var logger = function logger(_) { + var _level = _ || None; + return { + level: function level(_) { + return arguments.length ? (_level = +_, this) : _level; + }, + warn: function warn() { + if (_level >= Warn) log('warn', 'WARN', arguments); + return this; + }, + info: function info() { + if (_level >= Info) log('log', 'INFO', arguments); + return this; + }, + debug: function debug() { + if (_level >= Debug) log('log', 'DEBUG', arguments); + return this; + } + }; + }; + + var array = function array(_) { + return _ != null ? isArray(_) ? _ : [_] : []; + }; + + var compare = function compare(fields, orders) { + var idx = [], + cmp = (fields = array(fields)).map(function (f, i) { + return f == null ? null : (idx.push(i), splitAccessPath(f).map($).join('][')); + }), + n = idx.length - 1, + ord = array(orders), + code = 'var u,v;return ', + i, + j, + f, + u, + v, + d, + lt, + gt; + + if (n < 0) return null; + + for (j = 0; j <= n; ++j) { + i = idx[j]; + f = cmp[i]; + u = '(u=a[' + f + '])'; + v = '(v=b[' + f + '])'; + d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))'; + lt = ord[i] !== 'descending' ? (gt = 1, -1) : (gt = -1, 1); + code += '(' + u + '<' + v + '||u==null)&&v!=null?' + lt + ':(u>v||v==null)&&u!=null?' + gt + ':' + d + '!==u&&v===v?' + lt + ':v!==v&&u===u?' + gt + (i < n ? ':' : ':0'); + } + + return accessor(Function('a', 'b', code + ';'), fields.filter(function (_) { + return _ != null; + })); + }; + + var isFunction = function isFunction(_) { + return typeof _ === 'function'; + }; + + var constant = function constant(_) { + return isFunction(_) ? _ : function () { + return _; + }; + }; + + var extend = function extend(_) { + for (var x, k, i = 1, len = arguments.length; i < len; ++i) { + x = arguments[i]; + for (k in x) { + _[k] = x[k]; + } + } + return _; + }; + + var extentIndex = function extentIndex(array, f) { + var i = -1, + n = array.length, + a, + b, + c, + u, + v; + + if (f == null) { + while (++i < n) { + if ((b = array[i]) != null && b >= b) { + a = c = b;break; + } + }u = v = i; + while (++i < n) { + if ((b = array[i]) != null) { + if (a > b) a = b, u = i; + if (c < b) c = b, v = i; + } + } + } else { + while (++i < n) { + if ((b = f(array[i], i, array)) != null && b >= b) { + a = c = b;break; + } + }u = v = i; + while (++i < n) { + if ((b = f(array[i], i, array)) != null) { + if (a > b) a = b, u = i; + if (c < b) c = b, v = i; + } + } + } + + return [u, v]; + }; + + var NULL = {}; + + var fastmap = function fastmap(input) { + var obj = {}, + map, + _test; + + function has(key) { + return obj.hasOwnProperty(key) && obj[key] !== NULL; + } + + map = { + size: 0, + empty: 0, + object: obj, + has: has, + get: function get(key) { + return has(key) ? obj[key] : undefined; + }, + set: function set(key, value) { + if (!has(key)) { + ++map.size; + if (obj[key] === NULL) --map.empty; + } + obj[key] = value; + return this; + }, + delete: function _delete(key) { + if (has(key)) { + --map.size; + ++map.empty; + obj[key] = NULL; + } + return this; + }, + clear: function clear() { + map.size = map.empty = 0; + map.object = obj = {}; + }, + test: function test(_) { + return arguments.length ? (_test = _, map) : _test; + }, + clean: function clean() { + var next = {}, + size = 0, + key, + value; + for (key in obj) { + value = obj[key]; + if (value !== NULL && (!_test || !_test(value))) { + next[key] = value; + ++size; + } + } + map.size = size; + map.empty = 0; + map.object = obj = next; + } + }; + + if (input) Object.keys(input).forEach(function (key) { + map.set(key, input[key]); + }); + + return map; + }; + + var inherits = function inherits(child, parent) { + var proto = child.prototype = Object.create(parent.prototype); + proto.constructor = child; + return proto; + }; + + var isNumber = function isNumber(_) { + return typeof _ === 'number'; + }; + + var key = function key(fields) { + fields = fields ? array(fields) : fields; + var fn = !(fields && fields.length) ? function () { + return ''; + } : Function('_', 'return \'\'+' + fields.map(function (f) { + return '_[' + splitAccessPath(f).map($).join('][') + ']'; + }).join('+\'|\'+') + ';'); + return accessor(fn, fields, 'key'); + }; + + var merge = function merge(compare, array0, array1, output) { + var n0 = array0.length, + n1 = array1.length; + + if (!n1) return array0; + if (!n0) return array1; + + var merged = output || new array0.constructor(n0 + n1), + i0 = 0, + i1 = 0, + i = 0; + + for (; i0 < n0 && i1 < n1; ++i) { + merged[i] = compare(array0[i0], array1[i1]) > 0 ? array1[i1++] : array0[i0++]; + } + + for (; i0 < n0; ++i0, ++i) { + merged[i] = array0[i0]; + } + + for (; i1 < n1; ++i1, ++i) { + merged[i] = array1[i1]; + } + + return merged; + }; + + var repeat = function repeat(str, reps) { + var s = ''; + while (--reps >= 0) { + s += str; + }return s; + }; + + var pad = function pad(str, length, padchar, align) { + var c = padchar || ' ', + s = str + '', + n = length - s.length; + + return n <= 0 ? s : align === 'left' ? repeat(c, n) + s : align === 'center' ? repeat(c, ~~(n / 2)) + s + repeat(c, Math.ceil(n / 2)) : s + repeat(c, n); + }; + + var peek = function peek(array) { + return array[array.length - 1]; + }; + + var toSet = function toSet(_) { + for (var s = {}, i = 0, n = _.length; i < n; ++i) { + s[_[i]] = 1; + }return s; + }; + + var truncate = function truncate(str, length, align, ellipsis) { + var e = ellipsis != null ? ellipsis : '\u2026', + s = str + '', + n = s.length, + l = Math.max(0, length - e.length); + + return n <= length ? s : align === 'left' ? e + s.slice(n - l) : align === 'center' ? s.slice(0, Math.ceil(l / 2)) + e + s.slice(n - ~~(l / 2)) : s.slice(0, l) + e; + }; + + var visitArray = function visitArray(array, filter, visitor) { + if (array) { + var i = 0, + n = array.length, + t; + if (filter) { + for (; i < n; ++i) { + if (t = filter(array[i])) visitor(t, i, array); + } + } else { + array.forEach(visitor); + } + } + }; + + exports.accessor = accessor; + exports.accessorName = accessorName; + exports.accessorFields = accessorFields; + exports.id = id; + exports.identity = identity; + exports.zero = zero; + exports.one = one; + exports.truthy = truthy; + exports.falsy = falsy; + exports.logger = logger; + exports.None = None; + exports.Warn = Warn; + exports.Info = Info; + exports.Debug = Debug; + exports.array = array; + exports.compare = compare; + exports.constant = constant; + exports.error = error; + exports.extend = extend; + exports.extentIndex = extentIndex; + exports.fastmap = fastmap; + exports.field = field; + exports.inherits = inherits; + exports.isArray = isArray; + exports.isFunction = isFunction; + exports.isNumber = isNumber; + exports.isObject = isObject; + exports.isString = isString; + exports.key = key; + exports.merge = merge; + exports.pad = pad; + exports.peek = peek; + exports.repeat = repeat; + exports.splitAccessPath = splitAccessPath; + exports.stringValue = $; + exports.toSet = toSet; + exports.truncate = truncate; + exports.visitArray = visitArray; + + Object.defineProperty(exports, '__esModule', { value: true }); +}); + +},{}],9:[function(require,module,exports){ +module.exports={ + "name": "vega-lite", + "author": "Jeffrey Heer, Dominik Moritz, Kanit \"Ham\" Wongsuphasawat", + "version": "2.0.0-alpha.6", + "collaborators": [ + "Kanit Wongsuphasawat (http://kanitw.yellowpigz.com)", + "Dominik Moritz (https://www.domoritz.de)", + "Jeffrey Heer (http://jheer.org)" + ], + "homepage": "https://vega.github.io/vega-lite/", + "description": "Vega-lite provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.", + "main": "build/src/vl.js", + "types": "build/src/vl.d.ts", + "bin": { + "vl2png": "./bin/vl2png", + "vl2svg": "./bin/vl2svg", + "vl2vg": "./bin/vl2vg" + }, + "directories": { + "test": "test" + }, + "scripts": { + "prebuild": "mkdir -p build/site build/examples/images build/test-gallery", + "build": "tsc && cp package.json build && browserify src/vl.ts -p tsify -g [ babelify ] -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js", + "postbuild": "uglifyjs build/vega-lite.js -cm --in-source-map build/vega-lite.js.map --source-map build/vega-lite.min.js.map > build/vega-lite.min.js && npm run schema", + "build:images": "npm run data && scripts/generate-images.sh", + "build:toc": "bundle exec jekyll build -q && scripts/generate-toc", + "build:site": "browserify site/static/main.ts -p [tsify -p site] -d > build/site/main.js", + "build:versions": "scripts/update-version.sh", + "build:test-gallery": "browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js", + "checkschema": "scripts/check-schema.sh", + "clean": "rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\.(js|js.map|d.ts)' -delete & rm -rf examples/_diff examples/_original examples/_output examples/images && rm -rf data", + "data": "rsync -r node_modules/vega-datasets/data/* data", + + "deploy": "scripts/deploy.sh", + "deploy:gh": "scripts/deploy-gh.sh", + "deploy:schema": "scripts/deploy-schema.sh", + + "prestart": "npm run data && npm run build && scripts/index-examples", + "start": "nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'", + "poststart": "rm examples/all-examples.json", + + "preschema": "npm run prebuild", + "schema": "typescript-json-schema --required true --noExtraProps true src/spec.ts ExtendedSpec > build/vega-lite-schema.json", + + "presite": "npm run build && npm run data && npm run build:site && npm run build:toc && npm run build:versions", + "site": "bundle exec jekyll serve", + + "lint": "tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'", + + "test": "tsc && npm run schema && npm run data && npm run test:nocompile", + "test:nocompile": "npm run test:only && npm run lint && npm run mocha:examples", + "test:only": "nyc --reporter=html --reporter=text-summary npm run mocha:test", + "test:debug": "tsc && npm run schema && npm run data && mocha --recursive --require ./test/babel.ts --debug-brk build/test build/examples", + "mocha:test": "mocha --reporter dot --recursive build/test", + "mocha:examples": "mocha --require ./test/babel.ts --reporter dot --recursive build/examples", + + "codecov": "nyc report --reporter=json && codecov -f coverage/*.json", + "watch:build": "watchify src/vl.ts -p tsify -g [ babelify ] -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'", + "watch:test": "nodemon -x 'npm test'", + "watch": "nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build", + "x-compile": "./scripts/examples-compile.sh", + "x-diff": "./scripts/examples-diff.sh" + }, + "repository": { + "type": "git", + "url": "https://github.com/vega/vega-lite.git" + }, + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/vega/vega-lite/issues" + }, + "devDependencies": { + "@types/chai": "^3.4.35", + "@types/highlight.js": "^9.1.9", + "@types/d3": "^4.5.0", + "@types/json-stable-stringify": "^1.0.30", + "@types/mocha": "^2.2.39", + "@types/node": "^7.0.5", + "ajv": "5.0.1-beta.1", + "babel-preset-es2015": "^6.22.0", + "babelify": "^7.3.0", + "browser-sync": "~2.18.8", + "browserify": "~14.1.0", + "browserify-shim": "^3.8.13", + "chai": "~3.5.0", + "cheerio": "~0.22.0", + "codecov": "~1.0.1", + "d3": "^4.7.0", + "exorcist": "~0.4.0", + "highlight.js": "^9.9.0", + "mocha": "~3.2.0", + "nodemon": "~1.11.0", + "nyc": "~10.1.2", + "source-map-support": "~0.4.11", + "tsify": "~3.0.1", + "tslint": "~4.5.1", + "tslint-eslint-rules": "^3.4.0", + "typescript": "^2.2.1", + "typescript-json-schema": "^0.10.0", + "uglify-js": "~2.8.4", + "vega": "3.0.0-beta.25", + "vega-datasets": "vega/vega-datasets#gh-pages", + "vega-embed": "3.0.0-beta.5", + "vega-parser": "^1.0.0-beta.38", + "watchify": "~3.9.0", + "yaml-front-matter": "~3.4.0" + }, + "dependencies": { + "json-stable-stringify": "~1.0.1", + "tslib": "^1.6.0", + "vega-util": "~1.1.4", + "yargs": "~6.6.0" + } +} + +},{}],10:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AGGREGATE_OPS = [ + 'values', + 'count', + 'valid', + 'missing', + 'distinct', + 'sum', + 'mean', + 'average', + 'variance', + 'variancep', + 'stdev', + 'stdevp', + 'median', + 'q1', + 'q3', + 'modeskew', + 'min', + 'max', + 'argmin', + 'argmax', +]; +/** Additive-based aggregation operations. These can be applied to stack. */ +exports.SUM_OPS = [ + 'count', + 'sum', + 'distinct', + 'valid', + 'missing' +]; +/** + * Aggregation operators that always produce values within the range [domainMin, domainMax]. + */ +exports.SHARED_DOMAIN_OPS = [ + 'mean', + 'average', + 'median', + 'q1', + 'q3', + 'min', + 'max', +]; + +},{}],11:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultAxisConfig = { + labelMaxLength: 25, +}; +exports.AXIS_PROPERTIES = [ + 'domain', 'format', 'grid', 'labelPadding', 'labels', 'maxExtent', 'minExtent', 'offset', 'orient', 'position', 'tickCount', 'ticks', 'tickSize', 'title', 'titlePadding', 'values', 'zindex' +]; +exports.VL_ONLY_AXIS_PROPERTIES = ['labelMaxLength']; + +},{}],12:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +function autoMaxBins(channel) { + switch (channel) { + case channel_1.ROW: + case channel_1.COLUMN: + case channel_1.SIZE: + // Facets and Size shouldn't have too many bins + // We choose 6 like shape to simplify the rule + case channel_1.SHAPE: + return 6; // Vega's "shape" has 6 distinct values + default: + return 10; + } +} +exports.autoMaxBins = autoMaxBins; + +},{"./channel":13}],13:[function(require,module,exports){ +/* + * Constants and utilities for encoding channels (Visual variables) + * such as 'x', 'y', 'color'. + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("./scale"); +var util_1 = require("./util"); +var Channel; +(function (Channel) { + // Facet + Channel.ROW = 'row'; + Channel.COLUMN = 'column'; + // Position + Channel.X = 'x'; + Channel.Y = 'y'; + Channel.X2 = 'x2'; + Channel.Y2 = 'y2'; + // Mark property with scale + Channel.COLOR = 'color'; + Channel.SHAPE = 'shape'; + Channel.SIZE = 'size'; + Channel.OPACITY = 'opacity'; + // Non-scale channel + Channel.TEXT = 'text'; + Channel.ORDER = 'order'; + Channel.DETAIL = 'detail'; +})(Channel = exports.Channel || (exports.Channel = {})); +exports.X = Channel.X; +exports.Y = Channel.Y; +exports.X2 = Channel.X2; +exports.Y2 = Channel.Y2; +exports.ROW = Channel.ROW; +exports.COLUMN = Channel.COLUMN; +exports.SHAPE = Channel.SHAPE; +exports.SIZE = Channel.SIZE; +exports.COLOR = Channel.COLOR; +exports.TEXT = Channel.TEXT; +exports.DETAIL = Channel.DETAIL; +exports.ORDER = Channel.ORDER; +exports.OPACITY = Channel.OPACITY; +exports.CHANNELS = [exports.X, exports.Y, exports.X2, exports.Y2, exports.ROW, exports.COLUMN, exports.SIZE, exports.SHAPE, exports.COLOR, exports.ORDER, exports.OPACITY, exports.TEXT, exports.DETAIL]; +// CHANNELS without COLUMN, ROW +exports.UNIT_CHANNELS = [exports.X, exports.Y, exports.X2, exports.Y2, exports.SIZE, exports.SHAPE, exports.COLOR, exports.ORDER, exports.OPACITY, exports.TEXT, exports.DETAIL]; +// UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT +exports.UNIT_SCALE_CHANNELS = [exports.X, exports.Y, exports.SIZE, exports.SHAPE, exports.COLOR, exports.OPACITY]; +// UNIT_SCALE_CHANNELS with ROW, COLUMN +exports.SCALE_CHANNELS = [exports.X, exports.Y, exports.SIZE, exports.SHAPE, exports.COLOR, exports.OPACITY, exports.ROW, exports.COLUMN]; +// UNIT_CHANNELS without X, Y, X2, Y2; +exports.NONSPATIAL_CHANNELS = [exports.SIZE, exports.SHAPE, exports.COLOR, exports.ORDER, exports.OPACITY, exports.TEXT, exports.DETAIL]; +// UNIT_SCALE_CHANNELS without X, Y; +exports.NONSPATIAL_SCALE_CHANNELS = [exports.SIZE, exports.SHAPE, exports.COLOR, exports.OPACITY]; +/** Channels that can serve as groupings for stacked charts. */ +exports.STACK_GROUP_CHANNELS = [exports.COLOR, exports.DETAIL, exports.ORDER, exports.OPACITY, exports.SIZE]; +; +/** + * Return whether a channel supports a particular mark type. + * @param channel channel name + * @param mark the mark type + * @return whether the mark supports the channel + */ +function supportMark(channel, mark) { + return mark in getSupportedMark(channel); +} +exports.supportMark = supportMark; +/** + * Return a dictionary showing whether a channel supports mark type. + * @param channel + * @return A dictionary mapping mark types to boolean values. + */ +function getSupportedMark(channel) { + switch (channel) { + case exports.X: + case exports.Y: + case exports.COLOR: + case exports.DETAIL: + case exports.ORDER: // TODO: revise (order might not support rect, which is not stackable?) + case exports.OPACITY: + case exports.ROW: + case exports.COLUMN: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, rect: true, line: true, area: true, text: true + }; + case exports.X2: + case exports.Y2: + return { + rule: true, bar: true, rect: true, area: true + }; + case exports.SIZE: + return { + point: true, tick: true, rule: true, circle: true, square: true, + bar: true, text: true, line: true + }; + case exports.SHAPE: + return { point: true }; + case exports.TEXT: + return { text: true }; + } + return {}; +} +exports.getSupportedMark = getSupportedMark; +function hasScale(channel) { + return !util_1.contains([exports.DETAIL, exports.TEXT, exports.ORDER], channel); +} +exports.hasScale = hasScale; +// Position does not work with ordinal (lookup) scale and sequential (which is only for color) +var POSITION_SCALE_TYPE_INDEX = util_1.toSet(util_1.without(scale_1.SCALE_TYPES, ['ordinal', 'sequential'])); +function supportScaleType(channel, scaleType) { + switch (channel) { + case exports.ROW: + case exports.COLUMN: + return scaleType === 'band'; // row / column currently supports band only + case exports.X: + case exports.Y: + case exports.SIZE: // TODO: size and opacity can support ordinal with more modification + case exports.OPACITY: + // Although it generally doesn't make sense to use band with size and opacity, + // it can also work since we use band: 0.5 to get midpoint. + return scaleType in POSITION_SCALE_TYPE_INDEX; + case exports.COLOR: + return scaleType !== 'band'; // band does not make sense with color + case exports.SHAPE: + return scaleType === 'ordinal'; // shape = lookup only + } + /* istanbul ignore next: it should never reach here */ + return false; +} +exports.supportScaleType = supportScaleType; +function rangeType(channel) { + switch (channel) { + case exports.X: + case exports.Y: + case exports.SIZE: + case exports.OPACITY: + return 'continuous'; + case exports.ROW: + case exports.COLUMN: + case exports.SHAPE: + return 'discrete'; + // Color can be either continuous or discrete, depending on scale type. + case exports.COLOR: + return 'flexible'; + // No scale, no range type. + case exports.X2: + case exports.Y2: + case exports.DETAIL: + case exports.TEXT: + case exports.ORDER: + return undefined; + } + /* istanbul ignore next: should never reach here. */ + throw new Error('getSupportedRole not implemented for ' + channel); +} +exports.rangeType = rangeType; + +},{"./scale":80,"./util":88}],14:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function labels(model, channel, labelsSpec, def) { + var fieldDef = model.fieldDef(channel); + var axis = model.axis(channel); + var config = model.config; + // Text + if (util_1.contains([type_1.NOMINAL, type_1.ORDINAL], fieldDef.type) && axis.labelMaxLength) { + // TODO replace this with Vega's labelMaxLength once it is introduced + labelsSpec = util_1.extend({ + text: { + signal: "truncate(datum.value, " + axis.labelMaxLength + ")" + } + }, labelsSpec || {}); + } + else if (fieldDef.type === type_1.TEMPORAL) { + labelsSpec = util_1.extend({ + text: { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat) + } + }, labelsSpec); + } + // Label Angle + if (axis.labelAngle !== undefined) { + labelsSpec.angle = { value: axis.labelAngle }; + } + else { + // auto rotate for X + if (channel === channel_1.X && (util_1.contains([type_1.NOMINAL, type_1.ORDINAL], fieldDef.type) || !!fieldDef.bin || fieldDef.type === type_1.TEMPORAL)) { + labelsSpec.angle = { value: 270 }; + } + } + // Auto set align if rotated + // TODO: consider other value besides 270, 90 + if (labelsSpec.angle) { + if (labelsSpec.angle.value === 270) { + labelsSpec.align = { + value: def.orient === 'top' ? 'left' : + (channel === channel_1.X || channel === channel_1.COLUMN) ? 'right' : + 'center' + }; + } + else if (labelsSpec.angle.value === 90) { + labelsSpec.align = { value: 'center' }; + } + } + if (labelsSpec.angle) { + // Auto set baseline if rotated + // TODO: consider other value besides 270, 90 + if (labelsSpec.angle.value === 270) { + labelsSpec.baseline = { value: (channel === channel_1.X || channel === channel_1.COLUMN) ? 'middle' : 'bottom' }; + } + else if (labelsSpec.angle.value === 90) { + labelsSpec.baseline = { value: 'bottom' }; + } + } + return util_1.keys(labelsSpec).length === 0 ? undefined : labelsSpec; +} +exports.labels = labels; + +},{"../../channel":13,"../../type":87,"../../util":88,"../common":17}],15:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var axis_1 = require("../../axis"); +var encode = require("./encode"); +var rules = require("./rules"); +var util_1 = require("../../util"); +var AXIS_PARTS = ['domain', 'grid', 'labels', 'ticks', 'title']; +function parseAxisComponent(model, axisChannels) { + return axisChannels.reduce(function (axis, channel) { + var vgAxes = []; + if (model.axis(channel)) { + var main = parseMainAxis(channel, model); + if (main && isVisibleAxis(main)) { + vgAxes.push(main); + } + var grid = parseGridAxis(channel, model); + if (grid && isVisibleAxis(grid)) { + vgAxes.push(grid); + } + if (vgAxes.length > 0) { + axis[channel] = vgAxes; + } + } + return axis; + }, {}); +} +exports.parseAxisComponent = parseAxisComponent; +function isFalseOrNull(v) { + return v === false || v === null; +} +/** + * Return if an axis is visible (shows at least one part of the axis). + */ +function isVisibleAxis(axis) { + return util_1.some(AXIS_PARTS, function (part) { return hasAxisPart(axis, part); }); +} +function hasAxisPart(axis, part) { + // FIXME this method can be wrong if users use a Vega theme. + // (Not sure how to correctly handle that yet.). + if (part === 'grid' || part === 'title') { + return !!axis[part]; + } + // Other parts are enabled by default, so they should not be false or null. + return !isFalseOrNull(axis[part]); +} +/** + * Make an inner axis for showing grid for shared axis. + */ +function parseGridAxis(channel, model) { + // FIXME: support adding ticks for grid axis that are inner axes of faceted plots. + return parseAxis(channel, model, true); +} +exports.parseGridAxis = parseGridAxis; +function parseMainAxis(channel, model) { + return parseAxis(channel, model, false); +} +exports.parseMainAxis = parseMainAxis; +function parseAxis(channel, model, isGridAxis) { + var axis = model.axis(channel); + var vgAxis = { + scale: model.scaleName(channel) + }; + // 1.2. Add properties + axis_1.AXIS_PROPERTIES.forEach(function (property) { + var value = getSpecifiedOrDefaultValue(property, axis, channel, model, isGridAxis); + if (value !== undefined) { + vgAxis[property] = value; + } + }); + // Special case for gridScale since gridScale is not a Vega-Lite Axis property. + var gridScale = getSpecifiedOrDefaultValue('gridScale', axis, channel, model, isGridAxis); + if (gridScale !== undefined) { + vgAxis.gridScale = gridScale; + } + // 2) Add guide encode definition groups + var encodeSpec = axis.encode || {}; + AXIS_PARTS.forEach(function (part) { + if (!hasAxisPart(vgAxis, part)) { + // No need to create encode for a disabled part. + return; + } + // TODO(@yuhanlu): instead of calling encode[part], break this line based on part type + // as different require different parameters. + var value; + if (part === 'labels') { + value = encode.labels(model, channel, encodeSpec.labels || {}, vgAxis); + } + else { + value = encodeSpec[part] || {}; + } + if (value !== undefined && util_1.keys(value).length > 0) { + vgAxis.encode = vgAxis.encode || {}; + vgAxis.encode[part] = { update: value }; + } + }); + return vgAxis; +} +function getSpecifiedOrDefaultValue(property, specifiedAxis, channel, model, isGridAxis) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'labels': + return isGridAxis ? false : specifiedAxis[property]; + case 'domain': + return rules.domain(property, specifiedAxis, isGridAxis, channel); + case 'ticks': + return rules.ticks(property, specifiedAxis, isGridAxis, channel); + case 'format': + return rules.format(specifiedAxis, channel, fieldDef, model.config); + case 'grid': + return rules.grid(model, channel, isGridAxis); // FIXME: refactor this + case 'gridScale': + return rules.gridScale(model, channel, isGridAxis); + case 'orient': + return rules.orient(specifiedAxis, channel); + case 'tickCount': + return rules.tickCount(specifiedAxis, channel, fieldDef); // TODO: scaleType + case 'title': + return rules.title(specifiedAxis, fieldDef, model.config, isGridAxis); + case 'values': + return rules.values(specifiedAxis); + case 'zindex': + return rules.zindex(specifiedAxis, isGridAxis); + } + // Otherwise, return specified property. + return specifiedAxis[property]; +} + +},{"../../axis":11,"../../util":88,"./encode":14,"./rules":16}],16:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function format(specifiedAxis, channel, fieldDef, config) { + return common_1.numberFormat(fieldDef, specifiedAxis.format, config, channel); +} +exports.format = format; +// TODO: we need to refactor this method after we take care of config refactoring +/** + * Default rules for whether to show a grid should be shown for a channel. + * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned + */ +function gridShow(model, channel) { + var grid = model.axis(channel).grid; + if (grid !== undefined) { + return grid; + } + return !model.hasDiscreteScale(channel) && !model.fieldDef(channel).bin; +} +exports.gridShow = gridShow; +function grid(model, channel, isGridAxis) { + if (channel === channel_1.ROW || channel === channel_1.COLUMN) { + // never apply grid for ROW and COLUMN since we manually create rule-group for them + return false; + } + if (!isGridAxis) { + return undefined; + } + return gridShow(model, channel); +} +exports.grid = grid; +function gridScale(model, channel, isGridAxis) { + if (isGridAxis) { + var gridChannel = channel === 'x' ? 'y' : 'x'; + if (model.scale(gridChannel)) { + return model.scaleName(gridChannel); + } + } + return undefined; +} +exports.gridScale = gridScale; +function orient(specifiedAxis, channel) { + var orient = specifiedAxis.orient; + if (orient) { + return orient; + } + switch (channel) { + case channel_1.COLUMN: + // FIXME test and decide + return 'top'; + case channel_1.X: + return 'bottom'; + case channel_1.ROW: + case channel_1.Y: + return 'left'; + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS); +} +exports.orient = orient; +function tickCount(specifiedAxis, channel, fieldDef) { + var count = specifiedAxis.tickCount; + if (count !== undefined) { + return count; + } + // FIXME depends on scale type too + if (channel === channel_1.X && !fieldDef.bin) { + // Vega's default tickCount often lead to a lot of label occlusion on X without 90 degree rotation + return 5; + } + return undefined; +} +exports.tickCount = tickCount; +function title(specifiedAxis, fieldDef, config, isGridAxis) { + if (isGridAxis) { + return undefined; + } + if (specifiedAxis.title !== undefined) { + return specifiedAxis.title; + } + // if not defined, automatically determine axis title from field def + var fieldTitle = fielddef_1.title(fieldDef, config); + var maxLength = specifiedAxis.titleMaxLength; + return maxLength ? util_1.truncate(fieldTitle, maxLength) : fieldTitle; +} +exports.title = title; +function values(specifiedAxis) { + var vals = specifiedAxis.values; + if (specifiedAxis.values && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return datetime_1.timestamp(dt, true); + }); + } + return vals; +} +exports.values = values; +function zindex(specifiedAxis, isGridAxis) { + var z = specifiedAxis.zindex; + if (z !== undefined) { + return z; + } + if (isGridAxis) { + // if grid is true, need to put layer on the back so that grid is behind marks + return 0; + } + return 1; // otherwise return undefined and use Vega's default. +} +exports.zindex = zindex; +; +function domainAndTicks(property, specifiedAxis, isGridAxis, channel) { + if (isGridAxis || channel === channel_1.ROW || channel === channel_1.COLUMN) { + return false; + } + return specifiedAxis[property]; +} +exports.domainAndTicks = domainAndTicks; +exports.domain = domainAndTicks; +exports.ticks = domainAndTicks; + +},{"../../channel":13,"../../datetime":72,"../../fielddef":75,"../../log":78,"../../util":88,"../common":17}],17:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var channel_1 = require("../channel"); +var fielddef_1 = require("../fielddef"); +var type_1 = require("../type"); +var util_1 = require("../util"); +var facet_1 = require("./facet"); +var layer_1 = require("./layer"); +var timeunit_1 = require("../timeunit"); +var unit_1 = require("./unit"); +var spec_1 = require("../spec"); +function buildModel(spec, parent, parentGivenName) { + if (spec_1.isFacetSpec(spec)) { + return new facet_1.FacetModel(spec, parent, parentGivenName); + } + if (spec_1.isLayerSpec(spec)) { + return new layer_1.LayerModel(spec, parent, parentGivenName); + } + if (spec_1.isUnitSpec(spec)) { + return new unit_1.UnitModel(spec, parent, parentGivenName); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.buildModel = buildModel; +function applyConfig(e, config, // TODO(#1842): consolidate MarkConfig | TextConfig? + propsList) { + propsList.forEach(function (property) { + var value = config[property]; + if (value !== undefined) { + e[property] = { value: value }; + } + }); + return e; +} +exports.applyConfig = applyConfig; +function applyMarkConfig(e, model, propsList) { + propsList.forEach(function (property) { + var value = getMarkConfig(property, model.mark(), model.config); + if (value !== undefined) { + e[property] = { value: value }; + } + }); + return e; +} +exports.applyMarkConfig = applyMarkConfig; +/** + * Return value mark specific config property if exists. + * Otherwise, return general mark specific config. + */ +function getMarkConfig(prop, mark, config) { + var markSpecificConfig = config[mark]; + if (markSpecificConfig[prop] !== undefined) { + return markSpecificConfig[prop]; + } + return config.mark[prop]; +} +exports.getMarkConfig = getMarkConfig; +/** + * Returns number format for a fieldDef + * + * @param format explicitly specified format + */ +function numberFormat(fieldDef, format, config, channel) { + if (fieldDef.type === type_1.QUANTITATIVE) { + // add number format for quantitative type only + if (format) { + return format; + } + else if (fieldDef.aggregate === 'count' && channel === channel_1.TEXT) { + // FIXME: need a more holistic way to deal with this. + return 'd'; + } + // TODO: need to make this work correctly for numeric ordinal / nominal type + return config.numberFormat; + } + return undefined; +} +exports.numberFormat = numberFormat; +/** + * Returns the time expression used for axis/legend labels or text mark for a temporal field + */ +function timeFormatExpression(field, timeUnit, format, shortTimeLabels, timeFormatConfig) { + if (!timeUnit || format) { + // If there is not time unit, or if user explicitly specify format for axis/legend/text. + var _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit. + return "timeFormat(" + field + ", '" + _format + "')"; + } + else { + return timeunit_1.formatExpression(timeUnit, field, shortTimeLabels); + } +} +exports.timeFormatExpression = timeFormatExpression; +/** + * Return Vega sort parameters (tuple of field and order). + */ +function sortParams(orderDef) { + return (util_1.isArray(orderDef) ? orderDef : [orderDef]).reduce(function (s, orderChannelDef) { + s.field.push(fielddef_1.field(orderChannelDef, { binSuffix: 'start' })); + s.order.push(orderChannelDef.sort || 'ascending'); + return s; + }, { field: [], order: [] }); +} +exports.sortParams = sortParams; + +},{"../channel":13,"../fielddef":75,"../log":78,"../spec":83,"../timeunit":85,"../type":87,"../util":88,"./facet":31,"./layer":32,"./unit":68}],18:[function(require,module,exports){ +/** + * Module for compiling Vega-lite spec into Vega spec. + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../data"); +var log = require("../log"); +var spec_1 = require("../spec"); +var util_1 = require("../util"); +var selection_1 = require("./selection/selection"); +var common_1 = require("./common"); +function compile(inputSpec, logger) { + if (logger) { + // set the singleton logger to the provided logger + log.set(logger); + } + try { + // 1. Convert input spec into a normal form + // (Decompose all extended unit specs into composition of unit spec.) + var spec = spec_1.normalize(inputSpec); + // 2. Instantiate the model with default properties + var model = common_1.buildModel(spec, null, ''); + // 3. Parse each part of the model to produce components that will be assembled later + // We traverse the whole tree to parse once for each type of components + // (e.g., data, layout, mark, scale). + // Please see inside model.parse() for order for compilation. + model.parse(); + // 4. Assemble a Vega Spec from the parsed components in 3. + return assemble(model); + } + finally { + // Reset the singleton logger if a logger is provided + if (logger) { + log.reset(); + } + } +} +exports.compile = compile; +function assemble(model) { + // TODO: change type to become VgSpec + var output = util_1.extend({ + $schema: 'http://vega.github.io/schema/vega/v3.0.json', + }, topLevelBasicProperties(model), { + // Map calculated layout width and height to width and height signals. + signals: [ + { + name: 'width', + update: "data('layout')[0].width" + }, + { + name: 'height', + update: "data('layout')[0].height" + } + ].concat(selection_1.assembleTopLevelSignals(model)) + }, { + data: [].concat(model.assembleData([]), model.assembleLayout([]), model.assembleSelectionData([])), + marks: [assembleRootGroup(model)] + }); + return { + spec: output + // TODO: add warning / errors here + }; +} +function topLevelBasicProperties(model) { + var config = model.config; + return util_1.extend( + // TODO: Add other top-level basic properties (#1778) + { padding: model.padding || config.padding }, { autosize: 'pad' }, config.viewport ? { viewport: config.viewport } : {}, config.background ? { background: config.background } : {}); +} +exports.topLevelBasicProperties = topLevelBasicProperties; +function assembleRootGroup(model) { + var rootGroup = util_1.extend({ + name: model.getName('main'), + type: 'group', + }, model.description ? { description: model.description } : {}, { + from: { data: model.getName(data_1.LAYOUT + '') }, + encode: { + update: util_1.extend({ + width: { field: model.getName('width') }, + height: { field: model.getName('height') } + }, model.assembleParentGroupProperties(model.config.cell)) + } + }); + return util_1.extend(rootGroup, model.assembleGroup()); +} +exports.assembleRootGroup = assembleRootGroup; + +},{"../data":71,"../log":78,"../spec":83,"../util":88,"./common":17,"./selection/selection":58}],19:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bin_1 = require("../../bin"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var scale_1 = require("../../scale"); +function numberFormatExpr(expr, format) { + return "format(" + expr + ", '" + format + "')"; +} +function parse(model) { + return model.reduceFieldDef(function (binComponent, fieldDef, channel) { + var bin = model.fieldDef(channel).bin; + if (bin) { + var binTrans = util_1.extend({ + type: 'bin', + field: fieldDef.field, + as: [fielddef_1.field(fieldDef, { binSuffix: 'start' }), fielddef_1.field(fieldDef, { binSuffix: 'end' })], + signal: model.getName(fieldDef.field + '_bins') + }, + // if bin is an object, load parameter here! + typeof bin === 'boolean' ? {} : bin); + var transform = []; + if (!binTrans.extent) { + var extentSignal = model.getName(fieldDef.field + '_extent'); + transform.push({ + type: 'extent', + field: fieldDef.field, + signal: extentSignal + }); + binTrans.extent = { signal: extentSignal }; + } + if (!binTrans.maxbins && !binTrans.step) { + // if both maxbins and step are not specified, need to automatically determine bin + binTrans.maxbins = bin_1.autoMaxBins(channel); + } + transform.push(binTrans); + var discreteDomain = scale_1.hasDiscreteDomain(model.scale(channel).type); + if (discreteDomain) { + // read format from axis or legend, if there is no format then use config.numberFormat + var format = (model.axis(channel) || model.legend(channel) || {}).format || + model.config.numberFormat; + var startField = fielddef_1.field(fieldDef, { datum: true, binSuffix: 'start' }); + var endField = fielddef_1.field(fieldDef, { datum: true, binSuffix: 'end' }); + transform.push({ + type: 'formula', + as: fielddef_1.field(fieldDef, { binSuffix: 'range' }), + expr: numberFormatExpr(startField, format) + " + ' - ' + " + numberFormatExpr(endField, format) + }); + } + // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color + var key = util_1.hash(bin) + '_' + fieldDef.field + 'oc:' + discreteDomain; + binComponent[key] = transform; + } + return binComponent; + }, {}); +} +exports.bin = { + parseUnit: parse, + parseFacet: function (model) { + var binComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color + util_1.extend(binComponent, childDataComponent.bin); + delete childDataComponent.bin; + } + return binComponent; + }, + parseLayer: function (model) { + var binComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(binComponent, childDataComponent.bin); + delete childDataComponent.bin; + } + }); + return binComponent; + }, + assemble: function (component) { + return util_1.flatten(util_1.vals(component)); + } +}; + +},{"../../bin":12,"../../fielddef":75,"../../scale":80,"../../util":88}],20:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var source_1 = require("./source"); +var formatparse_1 = require("./formatparse"); +var nullfilter_1 = require("./nullfilter"); +var filter_1 = require("./filter"); +var bin_1 = require("./bin"); +var formula_1 = require("./formula"); +var pathorder_1 = require("./pathorder"); +var nonpositivefilter_1 = require("./nonpositivefilter"); +var summary_1 = require("./summary"); +var stack_1 = require("./stack"); +var timeunit_1 = require("./timeunit"); +// TODO: split this file into multiple files and remove this linter flag +/* tslint:disable:no-use-before-declare */ +function parseUnitData(model) { + return { + formatParse: formatparse_1.formatParse.parseUnit(model), + nullFilter: nullfilter_1.nullFilter.parseUnit(model), + filter: filter_1.filter.parseUnit(model), + nonPositiveFilter: nonpositivefilter_1.nonPositiveFilter.parseUnit(model), + pathOrder: pathorder_1.pathOrder.parseUnit(model), + source: source_1.source.parseUnit(model), + bin: bin_1.bin.parseUnit(model), + calculate: formula_1.formula.parseUnit(model), + timeUnit: timeunit_1.timeUnit.parseUnit(model), + summary: summary_1.summary.parseUnit(model), + stack: stack_1.stack.parseUnit(model) + }; +} +exports.parseUnitData = parseUnitData; +function parseFacetData(model) { + return { + formatParse: formatparse_1.formatParse.parseFacet(model), + nullFilter: nullfilter_1.nullFilter.parseFacet(model), + filter: filter_1.filter.parseFacet(model), + nonPositiveFilter: nonpositivefilter_1.nonPositiveFilter.parseFacet(model), + pathOrder: pathorder_1.pathOrder.parseFacet(model), + source: source_1.source.parseFacet(model), + bin: bin_1.bin.parseFacet(model), + calculate: formula_1.formula.parseFacet(model), + timeUnit: timeunit_1.timeUnit.parseFacet(model), + summary: summary_1.summary.parseFacet(model), + stack: stack_1.stack.parseFacet(model) + }; +} +exports.parseFacetData = parseFacetData; +function parseLayerData(model) { + return { + // filter and formatParse could cause us to not be able to merge into parent + // so let's parse them first + filter: filter_1.filter.parseLayer(model), + formatParse: formatparse_1.formatParse.parseLayer(model), + nullFilter: nullfilter_1.nullFilter.parseLayer(model), + nonPositiveFilter: nonpositivefilter_1.nonPositiveFilter.parseLayer(model), + pathOrder: pathorder_1.pathOrder.parseLayer(model), + // everything after here does not affect whether we can merge child data into parent or not + source: source_1.source.parseLayer(model), + bin: bin_1.bin.parseLayer(model), + calculate: formula_1.formula.parseLayer(model), + timeUnit: timeunit_1.timeUnit.parseLayer(model), + summary: summary_1.summary.parseLayer(model), + stack: stack_1.stack.parseLayer(model) + }; +} +exports.parseLayerData = parseLayerData; +/* tslint:enable:no-use-before-declare */ +/** + * Creates Vega Data array from a given compiled model and append all of them to the given array + * + * @param model + * @param data array + * @return modified data array + */ +function assembleData(model, data) { + var dataComponent = model.component.data; + var sourceData = source_1.source.assemble(dataComponent); + if (sourceData) { + data.push(sourceData); + } + summary_1.summary.assemble(dataComponent.summary || [], model.dataName(data_1.SOURCE)).forEach(function (summaryData) { + data.push(summaryData); + }); + // nonPositiveFilter + var nonPositiveFilterTransform = nonpositivefilter_1.nonPositiveFilter.assemble(dataComponent.nonPositiveFilter); + if (nonPositiveFilterTransform.length > 0) { + if (data.length > 0) { + var dataTable = data[data.length - 1]; + dataTable.transform = (dataTable.transform || []).concat(nonPositiveFilterTransform); + } + else { + throw new Error('Invalid nonPositiveFilter not merged'); + } + } + // stack + var stackData = stack_1.stack.assemble(dataComponent.stack); + if (stackData) { + data.push(stackData); + } + // Path Order + var pathOrderCollectTransform = pathorder_1.pathOrder.assemble(dataComponent.pathOrder); + if (pathOrderCollectTransform) { + var dataTable = data[data.length - 1]; + if (data.length > 0) { + dataTable.transform = (dataTable.transform || []).concat([pathOrderCollectTransform]); + } + else { + throw new Error('Invalid path order collect transform not added'); + } + } + return data; +} +exports.assembleData = assembleData; + +},{"../../data":71,"./bin":19,"./filter":21,"./formatparse":22,"./formula":23,"./nonpositivefilter":24,"./nullfilter":25,"./pathorder":26,"./source":27,"./stack":28,"./summary":29,"./timeunit":30}],21:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var filter_1 = require("../../filter"); +var util_1 = require("../../util"); +/** + * @param v value to be converted into Vega Expression + * @param timeUnit + * @return Vega Expression of the value v. This could be one of: + * - a timestamp value of datetime object + * - a timestamp value of casted single time unit value + * - stringified value + */ +function parse(model) { + var filter = model.filter(); + if (util_1.isArray(filter)) { + return '(' + + filter.map(function (f) { return filter_1.expression(f); }) + .filter(function (f) { return f !== undefined; }) + .join(') && (') + + ')'; + } + else if (filter) { + return filter_1.expression(filter); + } + return undefined; +} +exports.filter = { + parseUnit: parse, + parseFacet: function (model) { + var filterComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source but has filter, then merge + if (!childDataComponent.source && childDataComponent.filter) { + // merge by adding && + filterComponent = + (filterComponent ? filterComponent + ' && ' : '') + + childDataComponent.filter; + delete childDataComponent.filter; + } + return filterComponent; + }, + parseLayer: function (model) { + // Note that this `filter.parseLayer` method is called before `source.parseLayer` + var filterComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && childDataComponent.filter && childDataComponent.filter === filterComponent) { + // same filter in child so we can just delete it + delete childDataComponent.filter; + } + }); + return filterComponent; + }, + assemble: function (filterComponent) { + return filterComponent ? [{ + type: 'filter', + expr: filterComponent + }] : []; + } +}; + +},{"../../filter":76,"../../util":88}],22:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("../../datetime"); +var data_1 = require("../../data"); +var fielddef_1 = require("../../fielddef"); +var filter_1 = require("../../filter"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function parse(model) { + var calcFieldMap = (model.calculate() || []).reduce(function (fieldMap, formula) { + fieldMap[formula.as] = true; + return fieldMap; + }, {}); + var parseComponent = {}; + // Parse filter fields + var filter = model.filter(); + if (!util_1.isArray(filter)) { + filter = [filter]; + } + filter.forEach(function (f) { + var val = null; + // For EqualFilter, just use the equal property. + // For RangeFilter and OneOfFilter, all array members should have + // the same type, so we only use the first one. + if (filter_1.isEqualFilter(f)) { + val = f.equal; + } + else if (filter_1.isRangeFilter(f)) { + val = f.range[0]; + } + else if (filter_1.isOneOfFilter(f)) { + val = (f.oneOf || f['in'])[0]; + } // else -- for filter expression, we can't infer anything + if (!!val) { + if (datetime_1.isDateTime(val)) { + parseComponent[f['field']] = 'date'; + } + else if (util_1.isNumber(val)) { + parseComponent[f['field']] = 'number'; + } + else if (util_1.isString(val)) { + parseComponent[f['field']] = 'string'; + } + } + }); + // Parse encoded fields + model.forEachFieldDef(function (fieldDef) { + if (fieldDef.type === type_1.TEMPORAL) { + parseComponent[fieldDef.field] = 'date'; + } + else if (fieldDef.type === type_1.QUANTITATIVE) { + if (fielddef_1.isCount(fieldDef) || calcFieldMap[fieldDef.field]) { + return; + } + parseComponent[fieldDef.field] = 'number'; + } + }); + // Custom parse should override inferred parse + var data = model.data; + if (data && data_1.isUrlData(data) && data.format && data.format.parse) { + var parse_1 = data.format.parse; + util_1.keys(parse_1).forEach(function (field) { + parseComponent[field] = parse_1[field]; + }); + } + return parseComponent; +} +exports.formatParse = { + parseUnit: parse, + parseFacet: function (model) { + var parseComponent = parse(model); + // If child doesn't have its own data source, but has its own parse, then merge + var childDataComponent = model.child.component.data; + if (!childDataComponent.source && childDataComponent.formatParse) { + util_1.extend(parseComponent, childDataComponent.formatParse); + delete childDataComponent.formatParse; + } + return parseComponent; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + var parseComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && !util_1.differ(childDataComponent.formatParse, parseComponent)) { + // merge parse up if the child does not have an incompatible parse + util_1.extend(parseComponent, childDataComponent.formatParse); + delete childDataComponent.formatParse; + } + }); + return parseComponent; + }, + // identity function + assemble: function (x) { return x; } +}; + +},{"../../data":71,"../../datetime":72,"../../fielddef":75,"../../filter":76,"../../type":87,"../../util":88}],23:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +function parse(model) { + return (model.calculate() || []).reduce(function (formulaComponent, formula) { + formulaComponent[util_1.hash(formula)] = formula; + return formulaComponent; + }, {}); +} +exports.formula = { + parseUnit: parse, + parseFacet: function (model) { + var formulaComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(formulaComponent, childDataComponent.calculate); + delete childDataComponent.calculate; + } + return formulaComponent; + }, + parseLayer: function (model) { + var formulaComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (!childDataComponent.source && childDataComponent.calculate) { + util_1.extend(formulaComponent || {}, childDataComponent.calculate); + delete childDataComponent.calculate; + } + }); + return formulaComponent; + }, + assemble: function (component) { + return util_1.vals(component).reduce(function (transform, f) { + transform.push(util_1.extend({ type: 'formula' }, f)); + return transform; + }, []); + } +}; + +},{"../../util":88}],24:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +exports.nonPositiveFilter = { + parseUnit: function (model) { + return model.channels().reduce(function (nonPositiveComponent, channel) { + var scale = model.scale(channel); + if (!model.field(channel) || !scale) { + // don't set anything + return nonPositiveComponent; + } + nonPositiveComponent[model.field(channel)] = scale.type === scale_1.ScaleType.LOG; + return nonPositiveComponent; + }, {}); + }, + parseFacet: function (model) { + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then consider merging + if (!childDataComponent.source) { + // For now, let's assume it always has union scale + var nonPositiveFilterComponent = childDataComponent.nonPositiveFilter; + delete childDataComponent.nonPositiveFilter; + return nonPositiveFilterComponent; + } + return {}; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + var nonPositiveFilterComponent = {}; + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && !util_1.differ(childDataComponent.nonPositiveFilter, nonPositiveFilterComponent)) { + util_1.extend(nonPositiveFilterComponent, childDataComponent.nonPositiveFilter); + delete childDataComponent.nonPositiveFilter; + } + }); + return nonPositiveFilterComponent; + }, + assemble: function (nonPositiveFilterComponent) { + if (nonPositiveFilterComponent) { + return util_1.keys(nonPositiveFilterComponent).filter(function (field) { + // Only filter fields (keys) with value = true + return nonPositiveFilterComponent[field]; + }).map(function (field) { + return { + type: 'filter', + expr: 'datum["' + field + '"] > 0' + }; + }); + } + return []; + } +}; + +},{"../../scale":80,"../../util":88}],25:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var DEFAULT_NULL_FILTERS = { + nominal: false, + ordinal: false, + quantitative: true, + temporal: true +}; +/** Return Hashset of fields for null filtering (key=field, value = true). */ +function parse(model) { + var filterInvalid = model.filterInvalid(); + return model.reduceFieldDef(function (aggregator, fieldDef) { + if (fieldDef.field !== '*') { + if (filterInvalid || + (filterInvalid === undefined && fieldDef.field && DEFAULT_NULL_FILTERS[fieldDef.type])) { + aggregator[fieldDef.field] = fieldDef; + } + else { + // define this so we know that we don't filter nulls for this field + // this makes it easier to merge into parents + aggregator[fieldDef.field] = null; + } + } + return aggregator; + }, {}); +} +exports.nullFilter = { + parseUnit: parse, + parseFacet: function (model) { + var nullFilterComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(nullFilterComponent, childDataComponent.nullFilter); + delete childDataComponent.nullFilter; + } + return nullFilterComponent; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + // FIXME: null filters are not properly propagated right now + var nullFilterComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && !util_1.differ(childDataComponent.nullFilter, nullFilterComponent)) { + util_1.extend(nullFilterComponent, childDataComponent.nullFilter); + delete childDataComponent.nullFilter; + } + }); + return nullFilterComponent; + }, + assemble: function (component) { + var filters = util_1.keys(component).reduce(function (_filters, field) { + var fieldDef = component[field]; + if (fieldDef !== null) { + _filters.push('datum["' + fieldDef.field + '"] !== null'); + if (util_1.contains([type_1.QUANTITATIVE, type_1.TEMPORAL], fieldDef.type)) { + // TODO(https://github.com/vega/vega-lite/issues/1436): + // We can be even smarter and add NaN filter for N,O that are numbers + // based on the `parse` property once we have it. + _filters.push('!isNaN(datum["' + fieldDef.field + '"])'); + } + } + return _filters; + }, []); + return filters.length > 0 ? + [{ + type: 'filter', + expr: filters.join(' && ') + }] : []; + } +}; + +},{"../../type":87,"../../util":88}],26:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var encoding_1 = require("../../encoding"); +var fielddef_1 = require("../../fielddef"); +var sort_1 = require("../../sort"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +exports.pathOrder = { + parseUnit: function (model) { + if (util_1.contains(['line', 'area'], model.mark())) { + if (model.mark() === 'line' && model.channelHasField('order')) { + // For only line, sort by the order field if it is specified. + return common_1.sortParams(model.encoding.order); + } + else { + // For both line and area, we sort values based on dimension by default + var dimensionChannel = model.markDef.orient === 'horizontal' ? 'y' : 'x'; + var sort = model.sort(dimensionChannel); + var sortField = sort_1.isSortField(sort) ? + fielddef_1.field({ + // FIXME: this op might not already exist? + // FIXME: what if dimensionChannel (x or y) contains custom domain? + aggregate: encoding_1.isAggregate(model.encoding) ? sort.op : undefined, + field: sort.field + }) : + model.field(dimensionChannel, { binSuffix: 'start' }); + return { + field: sortField, + order: 'descending' + }; + } + } + return null; + }, + parseFacet: function (model) { + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then consider merging + if (!childDataComponent.source) { + // For now, let's assume it always has union scale + var pathOrderComponent = childDataComponent.pathOrder; + delete childDataComponent.pathOrder; + return pathOrderComponent; + } + return null; + }, + parseLayer: function (model) { + // note that we run this before source.parseLayer + var pathOrderComponent = null; + var stringifiedPathOrder = null; + for (var _i = 0, _a = model.children; _i < _a.length; _i++) { + var child = _a[_i]; + var childDataComponent = child.component.data; + if (model.compatibleSource(child) && childDataComponent.pathOrder !== null) { + if (pathOrderComponent === null) { + pathOrderComponent = childDataComponent.pathOrder; + stringifiedPathOrder = stringify(pathOrderComponent); + } + else if (stringifiedPathOrder !== stringify(childDataComponent.pathOrder)) { + pathOrderComponent = null; + break; + } + } + } + if (pathOrderComponent !== null) { + // If we merge pathOrderComponent, remove them from children. + for (var _b = 0, _c = model.children; _b < _c.length; _b++) { + var child = _c[_b]; + delete child.component.data.pathOrder; + } + } + return pathOrderComponent; + }, + assemble: function (pathOrderComponent) { + if (pathOrderComponent) { + return { + type: 'collect', + sort: pathOrderComponent + }; + } + return null; + } +}; + +},{"../../encoding":73,"../../fielddef":75,"../../sort":82,"../../util":88,"../common":17,"json-stable-stringify":1}],27:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var util_1 = require("../../util"); +var nullfilter_1 = require("./nullfilter"); +var filter_1 = require("./filter"); +var bin_1 = require("./bin"); +var formula_1 = require("./formula"); +var timeunit_1 = require("./timeunit"); +var source; +(function (source) { + function parse(model) { + var data = model.data; + if (data) { + // If data is explicitly provided + var sourceData = { name: model.dataName(data_1.SOURCE) }; + if (data_1.isInlineData(data)) { + sourceData.values = data.values; + sourceData.format = { type: 'json' }; + } + else if (data_1.isUrlData(data)) { + sourceData.url = data.url; + // Extract extension from URL using snippet from + // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript + var defaultExtension = /(?:\.([^.]+))?$/.exec(sourceData.url)[1]; + if (!util_1.contains(['json', 'csv', 'tsv', 'topojson'], defaultExtension)) { + defaultExtension = 'json'; + } + var dataFormat = data.format || {}; + // For backward compatibility for former `data.formatType` property + var formatType = dataFormat.type || data['formatType']; + sourceData.format = + util_1.extend({ type: formatType ? formatType : defaultExtension }, dataFormat.property ? { property: dataFormat.property } : {}, + // Feature and mesh are two mutually exclusive properties + dataFormat.feature ? + { feature: dataFormat.feature } : + dataFormat.mesh ? + { mesh: dataFormat.mesh } : + {}); + } + else if (data_1.isNamedData(data)) { + return { name: data.name }; + } + return sourceData; + } + else if (!model.parent) { + // If data is not explicitly provided but the model is a root, + // need to produce a source as well + return { name: model.dataName(data_1.SOURCE) }; + } + return undefined; + } + source.parseUnit = parse; + function parseFacet(model) { + var sourceData = parse(model); + if (!model.child.component.data.source) { + // If the child does not have its own source, have to rename its source. + model.child.renameData(model.child.dataName(data_1.SOURCE), model.dataName(data_1.SOURCE)); + } + return sourceData; + } + source.parseFacet = parseFacet; + function parseLayer(model) { + var sourceData = parse(model); + model.children.forEach(function (child) { + var childData = child.component.data; + if (model.compatibleSource(child)) { + // we cannot merge if the child has filters defined even after we tried to move them up + var canMerge = !childData.filter && !childData.formatParse && !childData.nullFilter; + if (canMerge) { + // rename source because we can just remove it + child.renameData(child.dataName(data_1.SOURCE), model.dataName(data_1.SOURCE)); + delete childData.source; + } + else { + // child does not have data defined or the same source so just use the parents source + childData.source = { + name: child.dataName(data_1.SOURCE), + source: model.dataName(data_1.SOURCE) + }; + } + } + }); + return sourceData; + } + source.parseLayer = parseLayer; + function assemble(component) { + if (component.source) { + var sourceData = component.source; + if (component.formatParse) { + component.source.format = component.source.format || {}; + component.source.format.parse = component.formatParse; + } + sourceData.transform = [].concat(formula_1.formula.assemble(component.calculate), nullfilter_1.nullFilter.assemble(component.nullFilter), filter_1.filter.assemble(component.filter), bin_1.bin.assemble(component.bin), timeunit_1.timeUnit.assemble(component.timeUnit)); + return sourceData; + } + return null; + } + source.assemble = assemble; +})(source = exports.source || (exports.source = {})); + +},{"../../data":71,"../../util":88,"./bin":19,"./filter":21,"./formula":23,"./nullfilter":25,"./timeunit":30}],28:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var common_1 = require("../common"); +var data_1 = require("../../data"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +function getStackByFields(model) { + return model.stack.stackBy.reduce(function (fields, by) { + var channel = by.channel; + var fieldDef = by.fieldDef; + var scale = model.scale(channel); + var _field = fielddef_1.field(fieldDef, { + binSuffix: scale && scale_1.hasDiscreteDomain(scale.type) ? 'range' : 'start' + }); + if (!!_field) { + fields.push(_field); + } + return fields; + }, []); +} +/** + * Stack data compiler + */ +exports.stack = { + parseUnit: function (model) { + var stackProperties = model.stack; + if (!stackProperties) { + return undefined; + } + var groupby = []; + if (stackProperties.groupbyChannel) { + var groupbyFieldDef = model.fieldDef(stackProperties.groupbyChannel); + if (groupbyFieldDef.bin) { + // For Bin, we need to add both start and end to ensure that both get imputed + // and included in the stack output (https://github.com/vega/vega-lite/issues/1805). + groupby.push(model.field(stackProperties.groupbyChannel, { binSuffix: 'start' })); + groupby.push(model.field(stackProperties.groupbyChannel, { binSuffix: 'end' })); + } + else { + groupby.push(model.field(stackProperties.groupbyChannel)); + } + } + var stackby = getStackByFields(model); + var orderDef = model.encoding.order; + var sort; + if (orderDef) { + sort = common_1.sortParams(orderDef); + } + else { + // default = descending by stackFields + // FIXME is the default here correct for binned fields? + sort = stackby.reduce(function (s, field) { + s.field.push(field); + s.order.push('descending'); + return s; + }, { field: [], order: [] }); + } + return { + name: model.dataName(data_1.STACKED), + source: model.dataName(data_1.SUMMARY), + groupby: groupby, + field: model.field(stackProperties.fieldChannel), + stackby: stackby, + sort: sort, + offset: stackProperties.offset, + impute: util_1.contains(['area', 'line'], model.mark()) + }; + }, + parseLayer: function (model) { + // FIXME: merge if identical + // FIXME: Correctly support facet of layer of stack. + return undefined; + }, + parseFacet: function (model) { + var child = model.child; + var childDataComponent = child.component.data; + // FIXME: Correctly support facet of layer of stack. + if (childDataComponent.stack) { + var stackComponent = childDataComponent.stack; + var newName = model.dataName(data_1.STACKED); + child.renameData(stackComponent.name, newName); + stackComponent.name = newName; + // Refer to facet's summary instead (always summary because stacked only works with aggregation) + stackComponent.source = model.dataName(data_1.SUMMARY); + // Add faceted field to groupby + stackComponent.groupby = model.reduceFieldDef(function (groupby, fieldDef) { + var facetedField = fielddef_1.field(fieldDef, { binSuffix: 'start' }); + if (!util_1.contains(groupby, facetedField)) { + groupby.push(facetedField); + } + return groupby; + }, stackComponent.groupby); + delete childDataComponent.stack; + return stackComponent; + } + return undefined; + }, + assemble: function (stackComponent) { + if (!stackComponent) { + return undefined; + } + var transform = []; + // Impute + if (stackComponent.impute) { + transform.push({ + type: 'impute', + field: stackComponent.field, + groupby: stackComponent.stackby, + orderby: stackComponent.groupby, + method: 'value', + value: 0 + }); + } + // Stack + transform.push({ + type: 'stack', + groupby: stackComponent.groupby, + field: stackComponent.field, + sort: stackComponent.sort, + as: [ + stackComponent.field + '_start', + stackComponent.field + '_end' + ], + offset: stackComponent.offset + }); + return { + name: stackComponent.name, + source: stackComponent.source, + transform: transform + }; + } +}; + +},{"../../data":71,"../../fielddef":75,"../../scale":80,"../../util":88,"../common":17}],29:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var data_1 = require("../../data"); +var fielddef_1 = require("../../fielddef"); +var util_1 = require("../../util"); +var summary; +(function (summary) { + function addDimension(dims, fieldDef) { + if (fieldDef.bin) { + dims[fielddef_1.field(fieldDef, { binSuffix: 'start' })] = true; + dims[fielddef_1.field(fieldDef, { binSuffix: 'end' })] = true; + // const scale = model.scale(channel); + // if (scaleType(scale, fieldDef, channel, model.mark()) === ScaleType.ORDINAL) { + // also produce bin_range if the binned field use ordinal scale + dims[fielddef_1.field(fieldDef, { binSuffix: 'range' })] = true; + // } + } + else { + dims[fielddef_1.field(fieldDef)] = true; + } + return dims; + } + function parseUnit(model) { + /* string set for dimensions */ + var dims = {}; + /* dictionary mapping field name => dict set of aggregation functions */ + var meas = {}; + model.forEachFieldDef(function (fieldDef, channel) { + if (fieldDef.aggregate) { + if (fieldDef.aggregate === 'count') { + meas['*'] = meas['*'] || {}; + /* tslint:disable:no-string-literal */ + meas['*']['count'] = true; + /* tslint:enable:no-string-literal */ + } + else { + meas[fieldDef.field] = meas[fieldDef.field] || {}; + meas[fieldDef.field][fieldDef.aggregate] = true; + // add min/max so we can use their union as unaggregated domain + var scale = model.scale(channel); + if (scale && scale.domain === 'unaggregated') { + meas[fieldDef.field]['min'] = true; + meas[fieldDef.field]['max'] = true; + } + } + } + else { + addDimension(dims, fieldDef); + } + ; + }); + return [{ + name: model.dataName(data_1.SUMMARY), + dimensions: dims, + measures: meas + }]; + } + summary.parseUnit = parseUnit; + function parseFacet(model) { + var childDataComponent = model.child.component.data; + // FIXME: this could be incorrect for faceted layer charts. + // If child doesn't have its own data source but has a summary data source, merge + if (!childDataComponent.source && childDataComponent.summary) { + var summaryComponents = childDataComponent.summary.map(function (summaryComponent) { + // add facet fields as dimensions + summaryComponent.dimensions = model.reduceFieldDef(addDimension, summaryComponent.dimensions); + var summaryNameWithoutPrefix = summaryComponent.name.substr(model.child.getName('').length); + model.child.renameData(summaryComponent.name, summaryNameWithoutPrefix); + summaryComponent.name = summaryNameWithoutPrefix; + return summaryComponent; + }); + delete childDataComponent.summary; + return summaryComponents; + } + return []; + } + summary.parseFacet = parseFacet; + function mergeMeasures(parentMeasures, childMeasures) { + for (var field_1 in childMeasures) { + if (childMeasures.hasOwnProperty(field_1)) { + // when we merge a measure, we either have to add an aggregation operator or even a new field + var ops = childMeasures[field_1]; + for (var op in ops) { + if (ops.hasOwnProperty(op)) { + if (field_1 in parentMeasures) { + // add operator to existing measure field + parentMeasures[field_1][op] = true; + } + else { + parentMeasures[field_1] = { op: true }; + } + } + } + } + } + } + function parseLayer(model) { + // Index by the fields we are grouping by + var summaries = {}; + // Combine summaries for children that don't have a distinct source + // (either having its own data source, or its own tranformation of the same data source). + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (!childDataComponent.source && childDataComponent.summary) { + // Merge the summaries if we can + childDataComponent.summary.forEach(function (childSummary) { + // The key is a hash based on the dimensions; + // we use it to find out whether we have a summary that uses the same group by fields. + var key = util_1.hash(childSummary.dimensions); + if (key in summaries) { + // yes, there is a summary hat we need to merge into + // we know that the dimensions are the same so we only need to merge the measures + mergeMeasures(summaries[key].measures, childSummary.measures); + } + else { + // give the summary a new name + childSummary.name = model.dataName(data_1.SUMMARY) + '_' + util_1.keys(summaries).length; + summaries[key] = childSummary; + } + // remove summary from child + child.renameData(child.dataName(data_1.SUMMARY), summaries[key].name); + delete childDataComponent.summary; + }); + } + }); + return util_1.vals(summaries); + } + summary.parseLayer = parseLayer; + /** + * Assemble the summary. Needs a rename function because we cannot guarantee that the + * parent data before the children data. + */ + function assemble(component, sourceName) { + return component.reduce(function (summaryData, summaryComponent) { + var dims = summaryComponent.dimensions; + var meas = summaryComponent.measures; + if (util_1.keys(meas).length > 0) { + var groupby = util_1.keys(dims); + var transform = util_1.reduce(meas, function (t, fnDictSet, field) { + var ops = util_1.keys(fnDictSet); + for (var _i = 0, ops_1 = ops; _i < ops_1.length; _i++) { + var op = ops_1[_i]; + t.fields.push(field); + t.ops.push(op); + } + return t; + }, { + type: 'aggregate', + groupby: groupby, + fields: [], + ops: [] + }); + summaryData.push({ + name: summaryComponent.name, + source: sourceName, + transform: [transform] + }); + } + return summaryData; + }, []); + } + summary.assemble = assemble; +})(summary = exports.summary || (exports.summary = {})); + +},{"../../data":71,"../../fielddef":75,"../../util":88}],30:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var fielddef_1 = require("../../fielddef"); +var timeunit_1 = require("../../timeunit"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function parse(model) { + return model.reduceFieldDef(function (timeUnitComponent, fieldDef) { + if (fieldDef.type === type_1.TEMPORAL && fieldDef.timeUnit) { + var f = fielddef_1.field(fieldDef); + timeUnitComponent[f] = { + type: 'formula', + as: f, + expr: timeunit_1.fieldExpr(fieldDef.timeUnit, fieldDef.field) + }; + } + return timeUnitComponent; + }, {}); +} +exports.timeUnit = { + parseUnit: parse, + parseFacet: function (model) { + var timeUnitComponent = parse(model); + var childDataComponent = model.child.component.data; + // If child doesn't have its own data source, then merge + if (!childDataComponent.source) { + util_1.extend(timeUnitComponent, childDataComponent.timeUnit); + delete childDataComponent.timeUnit; + } + return timeUnitComponent; + }, + parseLayer: function (model) { + var timeUnitComponent = parse(model); + model.children.forEach(function (child) { + var childDataComponent = child.component.data; + if (!childDataComponent.source) { + util_1.extend(timeUnitComponent, childDataComponent.timeUnit); + delete childDataComponent.timeUnit; + } + }); + return timeUnitComponent; + }, + assemble: function (component) { + // just join the values, which are already transforms + return util_1.vals(component); + } +}; + +},{"../../fielddef":75,"../../timeunit":85,"../../type":87,"../../util":88}],31:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var log = require("../log"); +var axis_1 = require("../axis"); +var channel_1 = require("../channel"); +var config_1 = require("../config"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var rules_1 = require("./axis/rules"); +var common_1 = require("./common"); +var data_1 = require("./data/data"); +var layout_1 = require("./layout"); +var model_1 = require("./model"); +var init_1 = require("./scale/init"); +var parse_2 = require("./scale/parse"); +/** + * Prefix for special data sources for driving column's axis group. + */ +exports.COLUMN_AXES_DATA_PREFIX = 'column-'; +/** + * Prefix for special data sources for driving row's axis group. + */ +exports.ROW_AXES_DATA_PREFIX = 'row-'; +var FacetModel = (function (_super) { + tslib_1.__extends(FacetModel, _super); + function FacetModel(spec, parent, parentGivenName) { + var _this = _super.call(this, spec, parent, parentGivenName) || this; + _this.scales = {}; + _this.axes = {}; + _this.legends = {}; + _this.stack = null; + _this._spacing = {}; + // Config must be initialized before child as it gets cascaded to the child + var config = _this.config = _this.initConfig(spec.config, parent); + var child = _this.child = common_1.buildModel(spec.spec, _this, _this.getName('child')); + _this.children = [child]; + var facet = _this.facet = _this.initFacet(spec.facet); + _this.scales = _this.initScalesAndSpacing(facet, config); + _this.axes = _this.initAxis(facet, config, child); + _this.legends = {}; + return _this; + } + FacetModel.prototype.initConfig = function (specConfig, parent) { + return util_1.mergeDeep(util_1.duplicate(config_1.defaultConfig), parent ? parent.config : {}, specConfig); + }; + FacetModel.prototype.initFacet = function (facet) { + // clone to prevent side effect to the original spec + facet = util_1.duplicate(facet); + encoding_1.forEach(facet, function (fieldDef, channel) { + if (!util_1.contains([channel_1.ROW, channel_1.COLUMN], channel)) { + // Drop unsupported channel + log.warn(log.message.incompatibleChannel(channel, 'facet')); + delete facet[channel]; + return; + } + // TODO: array of row / column ? + if (fieldDef.field === undefined) { + log.warn(log.message.emptyFieldDef(fieldDef, channel)); + delete facet[channel]; + return; + } + // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + fielddef_1.normalize(fieldDef, channel); + }); + return facet; + }; + FacetModel.prototype.initScalesAndSpacing = function (facet, config) { + var model = this; + return [channel_1.ROW, channel_1.COLUMN].reduce(function (_scale, channel) { + if (facet[channel]) { + _scale[channel] = init_1.default(channel, facet[channel], config, undefined, // Facet doesn't have one single mark + undefined, // TODO(#1647): support width / height here + [] // There is no xyRangeSteps here and there is no need to input + ); + model._spacing[channel] = spacing(facet[channel].scale || {}, model, config); + } + return _scale; + }, {}); + }; + FacetModel.prototype.initAxis = function (facet, config, child) { + var model = this; + return [channel_1.ROW, channel_1.COLUMN].reduce(function (_axis, channel) { + if (facet[channel]) { + var axisSpec = facet[channel].axis; + if (axisSpec !== false) { + var vlOnlyAxisProperties_1 = {}; + axis_1.VL_ONLY_AXIS_PROPERTIES.forEach(function (property) { + if (config.facet.axis[property] !== undefined) { + vlOnlyAxisProperties_1[property] = config.facet.axis[property]; + } + }); + var modelAxis = _axis[channel] = tslib_1.__assign({}, vlOnlyAxisProperties_1, axisSpec); + if (channel === channel_1.ROW) { + var yAxis = child.axis(channel_1.Y); + if (yAxis && yAxis.orient !== 'right' && !modelAxis.orient) { + modelAxis.orient = 'right'; + } + if (model.hasDescendantWithFieldOnChannel(channel_1.X) && !modelAxis.labelAngle) { + modelAxis.labelAngle = modelAxis.orient === 'right' ? 90 : 270; + } + } + } + } + return _axis; + }, {}); + }; + FacetModel.prototype.channelHasField = function (channel) { + return !!this.facet[channel]; + }; + FacetModel.prototype.hasSummary = function () { + var summary = this.component.data.summary; + for (var _i = 0, summary_1 = summary; _i < summary_1.length; _i++) { + var s = summary_1[_i]; + if (util_1.keys(s.measures).length > 0) { + return true; + } + } + return false; + }; + FacetModel.prototype.facetedTable = function () { + // FIXME: revise if the suffix should be 'data' + return 'faceted-' + this.getName('data'); + }; + FacetModel.prototype.dataTable = function () { + // FIXME: shouldn't we apply data renaming here? + if (this.component.data.stack) { + return 'stacked'; + } + if (this.hasSummary()) { + return 'summary'; + } + return 'source'; + }; + FacetModel.prototype.fieldDef = function (channel) { + return this.facet[channel]; + }; + FacetModel.prototype.parseData = function () { + this.child.parseData(); + this.component.data = data_1.parseFacetData(this); + }; + FacetModel.prototype.parseSelection = function () { + // TODO: @arvind can write this + // We might need to split this into compileSelectionData and compileSelectionSignals? + }; + FacetModel.prototype.parseLayoutData = function () { + this.child.parseLayoutData(); + this.component.layout = layout_1.parseFacetLayout(this); + }; + FacetModel.prototype.parseScale = function () { + var child = this.child; + var model = this; + child.parseScale(); + // TODO: support scales for field reference of parent data (e.g., for SPLOM) + // First, add scale for row and column. + var scaleComponent = this.component.scales = parse_2.default(this); + // Then, move shared/union from its child spec. + util_1.keys(child.component.scales).forEach(function (channel) { + // TODO: correctly implement independent scale + if (true) { + var scale = scaleComponent[channel] = child.component.scales[channel]; + var scaleNameWithoutPrefix = scale.name.substr(child.getName('').length); + var newName = model.scaleName(scaleNameWithoutPrefix, true); + child.renameScale(scale.name, newName); + // Once put in parent, just remove the child's scale. + delete child.component.scales[channel]; + } + }); + }; + FacetModel.prototype.parseMark = function () { + this.child.parseMark(); + this.component.mark = util_1.extend({ + name: this.getName('cell'), + type: 'group', + from: util_1.extend({ + facet: { + name: this.facetedTable(), + data: this.dataTable(), + groupby: [].concat(this.channelHasField(channel_1.ROW) ? [this.field(channel_1.ROW)] : [], this.channelHasField(channel_1.COLUMN) ? [this.field(channel_1.COLUMN)] : []) + } + }), + encode: { + update: getFacetGroupProperties(this) + } + }, + // FIXME: move this call to assembleMarks() + // Call child's assembleGroup to add marks, scales, axes, and legends. + // Note that we can call child's assembleGroup() here because parseMark() + // is the last method in compile() and thus the child is completely compiled + // at this point. + this.child.assembleGroup()); + }; + FacetModel.prototype.parseAxis = function () { + this.child.parseAxis(); + this.component.axes = parse_1.parseAxisComponent(this, [channel_1.ROW, channel_1.COLUMN]); + }; + FacetModel.prototype.parseAxisGroup = function () { + // TODO: with nesting, we might need to consider calling child + // this.child.parseAxisGroup(); + var xAxisGroup = parseAxisGroups(this, channel_1.X); + var yAxisGroup = parseAxisGroups(this, channel_1.Y); + this.component.axisGroups = util_1.extend(xAxisGroup ? { x: xAxisGroup } : {}, yAxisGroup ? { y: yAxisGroup } : {}); + }; + FacetModel.prototype.parseGridGroup = function () { + // TODO: with nesting, we might need to consider calling child + // this.child.parseGridGroup(); + var child = this.child; + this.component.gridGroups = util_1.extend(!child.channelHasField(channel_1.X) && this.channelHasField(channel_1.COLUMN) ? { column: getColumnGridGroups(this) } : {}, !child.channelHasField(channel_1.Y) && this.channelHasField(channel_1.ROW) ? { row: getRowGridGroups(this) } : {}); + }; + FacetModel.prototype.parseLegend = function () { + this.child.parseLegend(); + // TODO: support legend for independent non-position scale across facets + // TODO: support legend for field reference of parent data (e.g., for SPLOM) + // For now, assuming that non-positional scales are always shared across facets + // Thus, just move all legends from its child + this.component.legends = this.child.component.legends; + this.child.component.legends = {}; + }; + FacetModel.prototype.assembleParentGroupProperties = function () { + return null; + }; + FacetModel.prototype.assembleSignals = function (signals) { + return []; + }; + FacetModel.prototype.assembleSelectionData = function (data) { + return []; + }; + FacetModel.prototype.assembleData = function (data) { + // Prefix traversal – parent data might be referred by children data + data_1.assembleData(this, data); + this.child.assembleData(data); + assembleAxesGroupData(this, data); + return data; + }; + FacetModel.prototype.assembleLayout = function (layoutData) { + // Postfix traversal – layout is assembled bottom-up + this.child.assembleLayout(layoutData); + return layout_1.assembleLayout(this, layoutData); + }; + FacetModel.prototype.assembleMarks = function () { + return [].concat( + // axisGroup is a mapping to VgMarkGroup + util_1.vals(this.component.axisGroups), util_1.flatten(util_1.vals(this.component.gridGroups)), this.component.mark); + }; + FacetModel.prototype.channels = function () { + return [channel_1.ROW, channel_1.COLUMN]; + }; + FacetModel.prototype.getMapping = function () { + return this.facet; + }; + FacetModel.prototype.spacing = function (channel) { + return this._spacing[channel]; + }; + FacetModel.prototype.isFacet = function () { + return true; + }; + return FacetModel; +}(model_1.Model)); +exports.FacetModel = FacetModel; +function hasSubPlotWithXy(model) { + return model.hasDescendantWithFieldOnChannel('x') || + model.hasDescendantWithFieldOnChannel('y'); +} +exports.hasSubPlotWithXy = hasSubPlotWithXy; +function spacing(scale, model, config) { + if (scale.spacing !== undefined) { + return scale.spacing; + } + if (!hasSubPlotWithXy(model)) { + // If there is no subplot with x/y, it's a simple table so there should be no spacing. + return 0; + } + return config.scale.facetSpacing; +} +exports.spacing = spacing; +function getFacetGroupProperties(model) { + var child = model.child; + var mergedCellConfig = util_1.extend({}, child.config.cell, child.config.facet.cell); + return util_1.extend({ + x: model.channelHasField(channel_1.COLUMN) ? { + scale: model.scaleName(channel_1.COLUMN), + field: model.field(channel_1.COLUMN), + // offset by the spacing / 2 + offset: model.spacing(channel_1.COLUMN) / 2 + } : { value: model.config.scale.facetSpacing / 2 }, + y: model.channelHasField(channel_1.ROW) ? { + scale: model.scaleName(channel_1.ROW), + field: model.field(channel_1.ROW), + // offset by the spacing / 2 + offset: model.spacing(channel_1.ROW) / 2 + } : { value: model.config.scale.facetSpacing / 2 }, + width: { field: { parent: model.child.sizeName('width') } }, + height: { field: { parent: model.child.sizeName('height') } } + }, hasSubPlotWithXy(model) ? child.assembleParentGroupProperties(mergedCellConfig) : {}); +} +// TODO: move the rest of the file src/compile/facet/*.ts +/** + * Add data for driving row/column axes when there are both row and column + * Note that we don't have to deal with these in the parse step at all + * because these items never get merged with any other items. + */ +function assembleAxesGroupData(model, data) { + if (model.facet.column) { + data.push({ + name: exports.COLUMN_AXES_DATA_PREFIX + model.dataTable(), + source: model.dataTable(), + transform: [{ + type: 'aggregate', + groupby: [model.field(channel_1.COLUMN)] + }] + }); + } + if (model.facet.row) { + data.push({ + name: exports.ROW_AXES_DATA_PREFIX + model.dataTable(), + source: model.dataTable(), + transform: [{ + type: 'aggregate', + groupby: [model.field(channel_1.ROW)] + }] + }); + } + return data; +} +exports.assembleAxesGroupData = assembleAxesGroupData; +function parseAxisGroups(model, channel) { + // TODO: add a case where inner spec is not a unit (facet/layer/concat) + var axisGroup = null; + var child = model.child; + if (child.channelHasField(channel)) { + if (child.axis(channel)) { + if (true) { + // add a group for the shared axes + axisGroup = getSharedAxisGroup(model, channel); + if (child.axis(channel) && rules_1.gridShow(child, channel)) { + // add inner axis (aka axis that shows only grid to ) + child.component.axes[channel] = [parse_1.parseGridAxis(channel, child)]; + } + else { + // Delete existing child axes + delete child.component.axes[channel]; + } + } + else { + // TODO: implement independent axes support + } + } + } + return axisGroup; +} +function getSharedAxisGroup(model, channel) { + var isX = channel === 'x'; + var facetChannel = isX ? 'column' : 'row'; + var hasFacet = !!model.facet[facetChannel]; + var dataPrefix = isX ? exports.COLUMN_AXES_DATA_PREFIX : exports.ROW_AXES_DATA_PREFIX; + var axesGroup = { + name: model.getName(channel + '-axes'), + type: 'group' + }; + if (hasFacet) { + // Need to drive this with special data source that has one item for each column/row value. + // TODO: We might only need to drive this with special data source if there are both row and column + // However, it might be slightly difficult as we have to merge this with the main group. + axesGroup.from = { data: dataPrefix + model.dataTable() }; + } + if (isX) { + axesGroup.encode = { + update: { + width: { field: { parent: model.child.sizeName('width') } }, + height: { field: { group: 'height' } }, + x: hasFacet ? { + scale: model.scaleName(channel_1.COLUMN), + field: model.field(channel_1.COLUMN), + // offset by the spacing + offset: model.spacing(channel_1.COLUMN) / 2 + } : { + // TODO: support custom spacing here + // offset by the spacing + value: model.config.scale.facetSpacing / 2 + } + } + }; + } + else { + axesGroup.encode = { + update: { + width: { field: { group: 'width' } }, + height: { field: { parent: model.child.sizeName('height') } }, + y: hasFacet ? { + scale: model.scaleName(channel_1.ROW), + field: model.field(channel_1.ROW), + // offset by the spacing + offset: model.spacing(channel_1.ROW) / 2 + } : { + // offset by the spacing + value: model.config.scale.facetSpacing / 2 + } + } + }; + } + axesGroup.axes = [parse_1.parseMainAxis(channel, model.child)]; + return axesGroup; +} +exports.getSharedAxisGroup = getSharedAxisGroup; +function getRowGridGroups(model) { + var facetGridConfig = model.config.facet.grid; + var rowGrid = { + name: model.getName('row-grid'), + type: 'rule', + from: { + data: exports.ROW_AXES_DATA_PREFIX + model.dataTable() + }, + encode: { + update: { + y: { + scale: model.scaleName(channel_1.ROW), + field: model.field(channel_1.ROW) + }, + x: { value: 0, offset: -facetGridConfig.offset }, + x2: { field: { group: 'width' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }; + return [rowGrid, { + name: model.getName('row-grid-end'), + type: 'rule', + encode: { + update: { + y: { field: { group: 'height' } }, + x: { value: 0, offset: -facetGridConfig.offset }, + x2: { field: { group: 'width' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }]; +} +function getColumnGridGroups(model) { + var facetGridConfig = model.config.facet.grid; + var columnGrid = { + name: model.getName('column-grid'), + type: 'rule', + from: { + data: exports.COLUMN_AXES_DATA_PREFIX + model.dataTable() + }, + encode: { + update: { + x: { + scale: model.scaleName(channel_1.COLUMN), + field: model.field(channel_1.COLUMN) + }, + y: { value: 0, offset: -facetGridConfig.offset }, + y2: { field: { group: 'height' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }; + return [columnGrid, { + name: model.getName('column-grid-end'), + type: 'rule', + encode: { + update: { + x: { field: { group: 'width' } }, + y: { value: 0, offset: -facetGridConfig.offset }, + y2: { field: { group: 'height' }, offset: facetGridConfig.offset }, + stroke: { value: facetGridConfig.color }, + strokeOpacity: { value: facetGridConfig.opacity }, + strokeWidth: { value: 0.5 } + } + } + }]; +} + +},{"../axis":11,"../channel":13,"../config":70,"../encoding":73,"../fielddef":75,"../log":78,"../util":88,"./axis/parse":15,"./axis/rules":16,"./common":17,"./data/data":20,"./layout":33,"./model":49,"./scale/init":51,"./scale/parse":52,"tslib":5}],32:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var config_1 = require("../config"); +var mark_1 = require("../mark"); +var util_1 = require("../util"); +var vega_schema_1 = require("../vega.schema"); +var data_1 = require("../data"); +var data_2 = require("./data/data"); +var common_1 = require("./common"); +var layout_1 = require("./layout"); +var model_1 = require("./model"); +var domain_1 = require("./scale/domain"); +var LayerModel = (function (_super) { + tslib_1.__extends(LayerModel, _super); + function LayerModel(spec, parent, parentGivenName) { + var _this = _super.call(this, spec, parent, parentGivenName) || this; + _this.scales = {}; + _this.axes = {}; + _this.legends = {}; + _this.stack = null; + _this.width = spec.width; + _this.height = spec.height; + _this.config = _this.initConfig(spec.config, parent); + _this.children = spec.layer.map(function (layer, i) { + // we know that the model has to be a unit model because we pass in a unit spec + return common_1.buildModel(layer, _this, _this.getName('layer_' + i)); + }); + return _this; + } + LayerModel.prototype.initConfig = function (specConfig, parent) { + return util_1.mergeDeep(util_1.duplicate(config_1.defaultConfig), specConfig, parent ? parent.config : {}); + }; + LayerModel.prototype.channelHasField = function (channel) { + // layer does not have any channels + return false; + }; + LayerModel.prototype.hasDiscreteScale = function (channel) { + // since we assume shared scales we can just ask the first child + return this.children[0].hasDiscreteScale(channel); + }; + LayerModel.prototype.dataTable = function () { + // FIXME: don't just use the first child + return this.children[0].dataTable(); + }; + LayerModel.prototype.fieldDef = function (channel) { + return null; // layer does not have field defs + }; + LayerModel.prototype.parseData = function () { + this.children.forEach(function (child) { + child.parseData(); + }); + this.component.data = data_2.parseLayerData(this); + }; + LayerModel.prototype.parseSelection = function () { + // TODO: @arvind can write this + // We might need to split this into compileSelectionData and compileSelectionSignals? + }; + LayerModel.prototype.parseLayoutData = function () { + // TODO: correctly union ordinal scales rather than just using the layout of the first child + this.children.forEach(function (child) { + child.parseLayoutData(); + }); + this.component.layout = layout_1.parseLayerLayout(this); + }; + LayerModel.prototype.parseScale = function () { + var model = this; + var scaleComponent = this.component.scales = {}; + this.children.forEach(function (child) { + child.parseScale(); + // FIXME(#1602): correctly implement independent scale + // Also need to check whether the scales are actually compatible, e.g. use the same sort or throw error + if (true) { + util_1.keys(child.component.scales).forEach(function (channel) { + var childScale = child.component.scales[channel]; + var modelScale = scaleComponent[channel]; + if (!childScale || vega_schema_1.isSignalRefDomain(childScale.domain) || (modelScale && vega_schema_1.isSignalRefDomain(modelScale.domain))) { + // TODO: merge signal ref domains + return; + } + if (modelScale) { + modelScale.domain = domain_1.unionDomains(modelScale.domain, childScale.domain); + } + else { + scaleComponent[channel] = childScale; + } + // rename child scale to parent scales + var scaleNameWithoutPrefix = childScale.name.substr(child.getName('').length); + var newName = model.scaleName(scaleNameWithoutPrefix, true); + child.renameScale(childScale.name, newName); + // remove merged scales from children + delete child.component.scales[channel]; + }); + } + }); + }; + LayerModel.prototype.parseMark = function () { + this.children.forEach(function (child) { + child.parseMark(); + }); + }; + LayerModel.prototype.parseAxis = function () { + var axisComponent = this.component.axes = {}; + this.children.forEach(function (child) { + child.parseAxis(); + // TODO: correctly implement independent axes + if (true) { + util_1.keys(child.component.axes).forEach(function (channel) { + // TODO: support multiple axes for shared scale + // just use the first axis definition for each channel + if (!axisComponent[channel]) { + axisComponent[channel] = child.component.axes[channel]; + } + }); + } + }); + }; + LayerModel.prototype.parseAxisGroup = function () { + return null; + }; + LayerModel.prototype.parseGridGroup = function () { + return null; + }; + LayerModel.prototype.parseLegend = function () { + var legendComponent = this.component.legends = {}; + this.children.forEach(function (child) { + child.parseLegend(); + // TODO: correctly implement independent axes + if (true) { + util_1.keys(child.component.legends).forEach(function (channel) { + // just use the first legend definition for each channel + if (!legendComponent[channel]) { + legendComponent[channel] = child.component.legends[channel]; + } + }); + } + }); + }; + LayerModel.prototype.assembleParentGroupProperties = function (cellConfig) { + return common_1.applyConfig({}, cellConfig, mark_1.FILL_STROKE_CONFIG.concat(['clip'])); + }; + LayerModel.prototype.assembleSignals = function (signals) { + return []; + }; + LayerModel.prototype.assembleSelectionData = function (data) { + return []; + }; + LayerModel.prototype.assembleScales = function () { + // combine with scales from children + return this.children.reduce(function (scales, c) { + return scales.concat(c.assembleScales()); + }, _super.prototype.assembleScales.call(this)); + }; + LayerModel.prototype.assembleData = function (data) { + // Prefix traversal – parent data might be referred to by children data + data_2.assembleData(this, data); + this.children.forEach(function (child) { + child.assembleData(data); + }); + return data; + }; + LayerModel.prototype.assembleLayout = function (layoutData) { + // Postfix traversal – layout is assembled bottom-up + this.children.forEach(function (child) { + child.assembleLayout(layoutData); + }); + return layout_1.assembleLayout(this, layoutData); + }; + LayerModel.prototype.assembleMarks = function () { + // only children have marks + return util_1.flatten(this.children.map(function (child) { + return child.assembleMarks(); + })); + }; + LayerModel.prototype.channels = function () { + return []; + }; + LayerModel.prototype.getMapping = function () { + return null; + }; + LayerModel.prototype.isLayer = function () { + return true; + }; + /** + * Returns true if the child either has no source defined or uses the same url. + * This is useful if you want to know whether it is possible to move a filter up. + * + * This function can only be called once th child has been parsed. + */ + LayerModel.prototype.compatibleSource = function (child) { + var data = this.data; + var childData = child.component.data; + var compatible = !childData.source || (data && data_1.isUrlData(data) && data.url === childData.source.url); + return compatible; + }; + return LayerModel; +}(model_1.Model)); +exports.LayerModel = LayerModel; + +},{"../config":70,"../data":71,"../mark":79,"../util":88,"../vega.schema":90,"./common":17,"./data/data":20,"./layout":33,"./model":49,"./scale/domain":50,"tslib":5}],33:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../channel"); +var data_1 = require("../data"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +function assembleLayout(model, layoutData) { + var layoutComponent = model.component.layout; + if (!layoutComponent.width && !layoutComponent.height) { + return layoutData; // Do nothing + } + if (true) { + var distinctFields = util_1.keys(util_1.extend(layoutComponent.width.distinct, layoutComponent.height.distinct)); + var formula = layoutComponent.width.formula.concat(layoutComponent.height.formula) + .map(function (f) { return util_1.extend({ type: 'formula' }, f); }); + return [ + distinctFields.length > 0 ? { + name: model.dataName(data_1.LAYOUT), + source: model.dataTable(), + transform: [{ + type: 'aggregate', + fields: distinctFields, + ops: distinctFields.map(function () { return 'distinct'; }) + }].concat(formula) + } : { + name: model.dataName(data_1.LAYOUT), + values: [{}], + transform: formula + } + ]; + } + // FIXME: implement + // otherwise, we need to join width and height (cross) +} +exports.assembleLayout = assembleLayout; +// FIXME: for nesting x and y, we need to declare x,y layout separately before joining later +// For now, let's always assume shared scale +function parseUnitLayout(model) { + return { + width: parseUnitSizeLayout(model, channel_1.X), + height: parseUnitSizeLayout(model, channel_1.Y) + }; +} +exports.parseUnitLayout = parseUnitLayout; +function parseUnitSizeLayout(model, channel) { + return { + distinct: getDistinct(model, channel), + formula: [{ + as: model.channelSizeName(channel), + expr: unitSizeExpr(model, channel) + }] + }; +} +function unitSizeExpr(model, channel) { + var scale = model.scale(channel); + if (scale) { + if (scale_1.hasDiscreteDomain(scale.type) && scale.rangeStep) { + // If the spec has top level size or specified rangeStep = fit, it will be undefined here. + var cardinality = cardinalityExpr(model, channel); + var paddingOuter = scale.paddingOuter !== undefined ? scale.paddingOuter : scale.padding; + var paddingInner = scale.type === 'band' ? + // only band has real paddingInner + (scale.paddingInner !== undefined ? scale.paddingInner : scale.padding) : + // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128, + // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points. + 1; + var space = cardinality + + (paddingInner ? " - " + paddingInner : '') + + (paddingOuter ? " + 2*" + paddingOuter : ''); + // This formula is equivalent to + // space = count - inner + outer * 2 + // range = rangeStep * (space > 0 ? space : 0) + // in https://github.com/vega/vega-encode/blob/master/src/Scale.js#L112 + return "max(" + space + ", 0) * " + scale.rangeStep; + } + } + return (channel === channel_1.X ? model.width : model.height) + ''; +} +exports.unitSizeExpr = unitSizeExpr; +function parseFacetLayout(model) { + return { + width: parseFacetSizeLayout(model, channel_1.COLUMN), + height: parseFacetSizeLayout(model, channel_1.ROW) + }; +} +exports.parseFacetLayout = parseFacetLayout; +function parseFacetSizeLayout(model, channel) { + var childLayoutComponent = model.child.component.layout; + var sizeType = channel === channel_1.ROW ? 'height' : 'width'; + var childSizeComponent = childLayoutComponent[sizeType]; + if (true) { + // For shared scale, we can simply merge the layout into one data source + var distinct = util_1.extend(getDistinct(model, channel), childSizeComponent.distinct); + var formula = childSizeComponent.formula.concat([{ + as: model.channelSizeName(channel), + expr: facetSizeFormula(model, channel, model.child.channelSizeName(channel)) + }]); + delete childLayoutComponent[sizeType]; + return { + distinct: distinct, + formula: formula + }; + } + // FIXME implement independent scale as well + // TODO: - also consider when children have different data source +} +function facetSizeFormula(model, channel, innerSize) { + if (model.channelHasField(channel)) { + return '(datum["' + innerSize + '"] + ' + model.spacing(channel) + ')' + ' * ' + cardinalityExpr(model, channel); + } + else { + return 'datum["' + innerSize + '"] + ' + model.config.scale.facetSpacing; // need to add outer padding for facet + } +} +function parseLayerLayout(model) { + return { + width: parseLayerSizeLayout(model, channel_1.X), + height: parseLayerSizeLayout(model, channel_1.Y) + }; +} +exports.parseLayerLayout = parseLayerLayout; +function parseLayerSizeLayout(model, channel) { + if (true) { + // For shared scale, we can simply merge the layout into one data source + // TODO: don't just take the layout from the first child + var childLayoutComponent = model.children[0].component.layout; + var sizeType_1 = channel === channel_1.Y ? 'height' : 'width'; + var childSizeComponent = childLayoutComponent[sizeType_1]; + var distinct = childSizeComponent.distinct; + var formula = [{ + as: model.channelSizeName(channel), + expr: childSizeComponent.formula[0].expr + }]; + model.children.forEach(function (child) { + delete child.component.layout[sizeType_1]; + }); + return { + distinct: distinct, + formula: formula + }; + } +} +function getDistinct(model, channel) { + if (model.channelHasField(channel) && model.hasDiscreteScale(channel)) { + var scale = model.scale(channel); + if (scale_1.hasDiscreteDomain(scale.type) && !(scale.domain instanceof Array)) { + // if explicit domain is declared, use array length + var distinctField = model.field(channel); + var distinct = {}; + distinct[distinctField] = true; + return distinct; + } + } + return {}; +} +function cardinalityExpr(model, channel) { + var scale = model.scale(channel); + if (scale.domain instanceof Array) { + return scale.domain.length + ''; + } + return model.field(channel, { datum: true, prefix: 'distinct' }); +} +exports.cardinalityExpr = cardinalityExpr; + +},{"../channel":13,"../data":71,"../scale":80,"../util":88}],34:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var mark_1 = require("../../mark"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +function symbols(fieldDef, symbolsSpec, model, channel) { + var symbols = {}; + var mark = model.mark(); + switch (mark) { + case mark_1.BAR: + case mark_1.TICK: + case mark_1.TEXT: + symbols.shape = { value: 'square' }; + break; + case mark_1.CIRCLE: + case mark_1.SQUARE: + symbols.shape = { value: mark }; + break; + case mark_1.POINT: + case mark_1.LINE: + case mark_1.AREA: + // use default circle + break; + } + var cfg = model.config; + var filled = model.markDef.filled; + var config = channel === channel_1.COLOR ? + /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */ + util_1.without(mark_1.FILL_STROKE_CONFIG, [filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) : + /* For other legend, no need to omit. */ + mark_1.FILL_STROKE_CONFIG; + config = util_1.without(config, ['strokeDash', 'strokeDashOffset']); + common_1.applyMarkConfig(symbols, model, config); + if (filled) { + symbols.strokeWidth = { value: 0 }; + } + var value; + var colorDef = model.encoding.color; + if (fielddef_1.isValueDef(colorDef)) { + value = { value: colorDef.value }; + } + if (value !== undefined) { + // apply the value + if (filled) { + symbols.fill = value; + } + else { + symbols.stroke = value; + } + } + else if (channel !== channel_1.COLOR) { + // For non-color legend, apply color config if there is no fill / stroke config. + // (For color, do not override scale specified!) + symbols[filled ? 'fill' : 'stroke'] = symbols[filled ? 'fill' : 'stroke'] || + { value: cfg.mark.color }; + } + if (symbols.fill === undefined) { + // fall back to mark config colors for legend fill + if (cfg.mark.fill !== undefined) { + symbols.fill = { value: cfg.mark.fill }; + } + else if (cfg.mark.stroke !== undefined) { + symbols.stroke = { value: cfg.mark.stroke }; + } + } + var shapeDef = model.encoding.shape; + if (channel !== channel_1.SHAPE) { + if (fielddef_1.isValueDef(shapeDef)) { + symbols.shape = { value: shapeDef.value }; + } + } + symbols = util_1.extend(symbols, symbolsSpec || {}); + return util_1.keys(symbols).length > 0 ? symbols : undefined; +} +exports.symbols = symbols; +function labels(fieldDef, labelsSpec, model, channel) { + var legend = model.legend(channel); + var config = model.config; + var labels = {}; + if (fieldDef.type === type_1.TEMPORAL) { + labelsSpec = util_1.extend({ + text: { + signal: common_1.timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat) + } + }, labelsSpec || {}); + } + labels = util_1.extend(labels, labelsSpec || {}); + return util_1.keys(labels).length > 0 ? labels : undefined; +} +exports.labels = labels; + +},{"../../channel":13,"../../fielddef":75,"../../mark":79,"../../type":87,"../../util":88,"../common":17}],35:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var util_1 = require("../../util"); +var legend_1 = require("../../legend"); +var common_1 = require("../common"); +var encode = require("./encode"); +var rules = require("./rules"); +function parseLegendComponent(model) { + return [channel_1.COLOR, channel_1.SIZE, channel_1.SHAPE, channel_1.OPACITY].reduce(function (legendComponent, channel) { + if (model.legend(channel)) { + legendComponent[channel] = parseLegend(model, channel); + } + return legendComponent; + }, {}); +} +exports.parseLegendComponent = parseLegendComponent; +function getLegendDefWithScale(model, channel) { + // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels + switch (channel) { + case channel_1.COLOR: + var scale = model.scaleName(channel_1.COLOR); + return model.markDef.filled ? { fill: scale } : { stroke: scale }; + case channel_1.SIZE: + return { size: model.scaleName(channel_1.SIZE) }; + case channel_1.SHAPE: + return { shape: model.scaleName(channel_1.SHAPE) }; + case channel_1.OPACITY: + return { opacity: model.scaleName(channel_1.OPACITY) }; + } + return null; +} +function parseLegend(model, channel) { + var fieldDef = model.fieldDef(channel); + var legend = model.legend(channel); + var def = getLegendDefWithScale(model, channel); + legend_1.LEGEND_PROPERTIES.forEach(function (property) { + var value = getSpecifiedOrDefaultValue(property, legend, channel, model); + if (value !== undefined) { + def[property] = value; + } + }); + // 2) Add mark property definition groups + var encodeSpec = legend.encode || {}; + ['labels', 'legend', 'title', 'symbols'].forEach(function (part) { + var value = encode[part] ? + encode[part](fieldDef, encodeSpec[part], model, channel) : + encodeSpec[part]; // no rule -- just default values + if (value !== undefined && util_1.keys(value).length > 0) { + def.encode = def.encode || {}; + def.encode[part] = { update: value }; + } + }); + return def; +} +exports.parseLegend = parseLegend; +function getSpecifiedOrDefaultValue(property, specifiedLegend, channel, model) { + var fieldDef = model.fieldDef(channel); + switch (property) { + case 'format': + return common_1.numberFormat(fieldDef, specifiedLegend.format, model.config, channel); + case 'title': + return rules.title(specifiedLegend, fieldDef, model.config); + case 'values': + return rules.values(specifiedLegend); + case 'type': + rules.type(specifiedLegend, fieldDef, channel); + } + // Otherwise, return specified property. + return specifiedLegend[property]; +} + +},{"../../channel":13,"../../legend":77,"../../util":88,"../common":17,"./encode":34,"./rules":36}],36:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var datetime_1 = require("../../datetime"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var util_1 = require("../../util"); +function title(legend, fieldDef, config) { + if (legend.title !== undefined) { + return legend.title; + } + return fielddef_1.title(fieldDef, config); +} +exports.title = title; +function values(legend) { + var vals = legend.values; + if (vals && datetime_1.isDateTime(vals[0])) { + return vals.map(function (dt) { + // normalize = true as end user won't put 0 = January + return datetime_1.timestamp(dt, true); + }); + } + return vals; +} +exports.values = values; +function type(legend, fieldDef, channel) { + if (legend.type) { + return legend.type; + } + if (channel === channel_1.COLOR && !fieldDef.bin && !fieldDef.timeUnit && util_1.contains([type_1.QUANTITATIVE, type_1.TEMPORAL], fieldDef.type)) { + return 'gradient'; + } + return undefined; +} +exports.type = type; + +},{"../../channel":13,"../../datetime":72,"../../fielddef":75,"../../type":87,"../../util":88}],37:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +exports.area = { + vgMark: 'area', + role: undefined, + encodeEntry: function (model) { + var orient = model.markDef.orient; + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin'), mixins.color(model), mixins.nonPosition('opacity', model), mixins.markDefProperties(model.markDef, ['orient', 'interpolate', 'tension'])); + } +}; + +},{"./mixins":42,"tslib":5}],38:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var log = require("../../log"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.bar = { + vgMark: 'rect', + role: 'bar', + encodeEntry: function (model) { + var stack = model.stack; + return tslib_1.__assign({}, x(model, stack), y(model, stack), mixins.color(model), mixins.nonPosition('opacity', model)); + } +}; +function x(model, stack) { + var config = model.config; + var orient = model.markDef.orient; + var sizeDef = model.encoding.size; + var xDef = model.encoding.x; + var xScaleName = model.scaleName(channel_1.X); + var xScale = model.scale(channel_1.X); + // x, x2, and width -- we must specify two of these in all conditions + if (orient === 'horizontal') { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(xDef)) { + if (!sizeDef && scale_1.isBinScale(xScale.type)) { + return mixins.binnedPosition('x', model, config.bar.binSpacing); + } + else if (xScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('x', model); + } + } + // sized bin, normal point-ordinal axis, quantitative x-axis, or no x + return mixins.centeredBandPosition('x', model, tslib_1.__assign({}, ref.midX(config), { offset: 1 }), // TODO: config.singleBarOffset, + defaultSizeRef(xScaleName, model.scale(channel_1.X), config)); + } +} +function y(model, stack) { + var config = model.config, encoding = model.encoding; + var orient = model.markDef.orient; + var sizeDef = encoding.size; + var yDef = encoding.y; + var yScaleName = model.scaleName(channel_1.Y); + var yScale = model.scale(channel_1.Y); + // y, y2 & height -- we must specify two of these in all conditions + if (orient === 'vertical') { + return tslib_1.__assign({}, mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMin')); + } + else { + if (fielddef_1.isFieldDef(yDef)) { + if (yDef.bin && !sizeDef) { + return mixins.binnedPosition('y', model, config.bar.binSpacing); + } + else if (yScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('y', model); + } + } + return mixins.centeredBandPosition('y', model, ref.midY(config), defaultSizeRef(yScaleName, model.scale(channel_1.Y), config)); + } +} +function defaultSizeRef(scaleName, scale, config) { + if (config.bar.discreteBandSize) { + return { value: config.bar.discreteBandSize }; + } + if (scale) { + if (scale.type === scale_1.ScaleType.POINT) { + if (scale.rangeStep !== null) { + return { value: scale.rangeStep - 1 }; + } + log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL); + } + else if (scale.type === scale_1.ScaleType.BAND) { + return ref.band(scaleName); + } + else { + return { value: config.bar.continuousBandSize }; + } + } + if (config.scale.rangeStep && config.scale.rangeStep !== null) { + return { value: config.scale.rangeStep - 1 }; + } + // TODO: this should depends on cell's width / height? + return { value: 20 }; +} + +},{"../../channel":13,"../../fielddef":75,"../../log":78,"../../scale":80,"./mixins":42,"./valueref":48,"tslib":5}],39:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mark_1 = require("../../mark"); +var encoding_1 = require("../../encoding"); +var log = require("../../log"); +var util_1 = require("../../util"); +var scale_1 = require("../../scale"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var common_1 = require("../common"); +function initMarkDef(mark, encoding, scale, config) { + var markDef = mark_1.isMarkDef(mark) ? mark : { type: mark }; + var specifiedOrient = markDef.orient || common_1.getMarkConfig('orient', markDef.type, config); + markDef.orient = orient(markDef.type, encoding, scale, specifiedOrient); + if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) { + log.warn(log.message.orientOverridden(markDef.orient, specifiedOrient)); + } + return tslib_1.__assign({}, markDef, { + // TODO: filled could be injected to encoding too, but we don't have filled channel yet. + // Thus we inject it here for now. + filled: filled(markDef.type, config) }); +} +exports.initMarkDef = initMarkDef; +/** + * Initialize encoding's value with some special default values + */ +function initEncoding(mark, encoding, stacked, config) { + var opacityConfig = common_1.getMarkConfig('opacity', mark, config); + if (!encoding.opacity && opacityConfig === undefined) { + var opacity = defaultOpacity(mark, encoding, stacked); + if (opacity !== undefined) { + encoding.opacity = { value: opacity }; + } + } + return encoding; +} +exports.initEncoding = initEncoding; +function defaultOpacity(mark, encoding, stacked) { + if (util_1.contains([mark_1.POINT, mark_1.TICK, mark_1.CIRCLE, mark_1.SQUARE], mark)) { + // point-based marks + if (!encoding_1.isAggregate(encoding) || encoding_1.channelHasField(encoding, 'detail')) { + return 0.7; + } + } + if (mark === mark_1.BAR && !stacked) { + if (encoding_1.channelHasField(encoding, 'color') || encoding_1.channelHasField(encoding, 'detail') || encoding_1.channelHasField(encoding, 'size')) { + return 0.7; + } + } + if (mark === mark_1.AREA) { + return 0.7; // inspired by Tableau + } + return undefined; +} +function filled(mark, config) { + var filledConfig = common_1.getMarkConfig('filled', mark, config); + return filledConfig !== undefined ? filledConfig : mark !== mark_1.POINT && mark !== mark_1.LINE && mark !== mark_1.RULE; +} +function orient(mark, encoding, scale, specifiedOrient) { + switch (mark) { + case mark_1.POINT: + case mark_1.CIRCLE: + case mark_1.SQUARE: + case mark_1.TEXT: + case mark_1.RECT: + // orient is meaningless for these marks. + return undefined; + } + var yIsRange = encoding.y && encoding.y2; + var xIsRange = encoding.x && encoding.x2; + switch (mark) { + case mark_1.TICK: + var xScaleType = scale['x'] ? scale['x'].type : null; + var yScaleType = scale['y'] ? scale['y'].type : null; + // Tick is opposite to bar, line, area and never have ranged mark. + if (!scale_1.hasDiscreteDomain(xScaleType) && (!encoding.y || + scale_1.hasDiscreteDomain(yScaleType) || + (fielddef_1.isFieldDef(encoding.y) && encoding.y.bin))) { + return 'vertical'; + } + // y:Q or Ambiguous case, return horizontal + return 'horizontal'; + case mark_1.RULE: + case mark_1.BAR: + case mark_1.AREA: + // If there are range for both x and y, y (vertical) has higher precedence. + if (yIsRange) { + return 'vertical'; + } + else if (xIsRange) { + return 'horizontal'; + } + else if (mark === mark_1.RULE) { + if (encoding.x && !encoding.y) { + return 'vertical'; + } + else if (encoding.y && !encoding.x) { + return 'horizontal'; + } + } + /* tslint:disable */ + case mark_1.LINE: + /* tslint:enable */ + var xIsContinuous = fielddef_1.isFieldDef(encoding.x) && fielddef_1.isContinuous(encoding.x); + var yIsContinuous = fielddef_1.isFieldDef(encoding.y) && fielddef_1.isContinuous(encoding.y); + if (xIsContinuous && !yIsContinuous) { + return 'horizontal'; + } + else if (!xIsContinuous && yIsContinuous) { + return 'vertical'; + } + else if (xIsContinuous && yIsContinuous) { + var xDef = encoding.x; // we can cast here since they are surely fieldDef + var yDef = encoding.y; + var xIsTemporal = xDef.type === type_1.TEMPORAL; + var yIsTemporal = yDef.type === type_1.TEMPORAL; + // temporal without timeUnit is considered continuous, but better serves as dimension + if (xIsTemporal && !yIsTemporal) { + return 'vertical'; + } + else if (!xIsTemporal && yIsTemporal) { + return 'horizontal'; + } + if (!xDef.aggregate && !!yDef.aggregate) { + return 'vertical'; + } + else if (!!xDef.aggregate && !yDef.aggregate) { + return 'horizontal'; + } + if (specifiedOrient) { + // When ambiguous, use user specified one. + return specifiedOrient; + } + if (!(mark === mark_1.LINE && encoding.order)) { + // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots. + log.warn(log.message.unclearOrientContinuous(mark)); + } + return 'vertical'; + } + else { + // For Discrete x Discrete case, return undefined. + log.warn(log.message.unclearOrientDiscreteOrEmpty(mark)); + return undefined; + } + } + return 'vertical'; +} + +},{"../../encoding":73,"../../fielddef":75,"../../log":78,"../../mark":79,"../../scale":80,"../../type":87,"../../util":88,"../common":17,"tslib":5}],40:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +exports.line = { + vgMark: 'line', + role: undefined, + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.color(model), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's line size is strokeWidth + }), mixins.markDefProperties(model.markDef, ['interpolate', 'tension'])); + } +}; + +},{"./mixins":42,"tslib":5}],41:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var mark_1 = require("../../mark"); +var util_1 = require("../../util"); +var area_1 = require("./area"); +var bar_1 = require("./bar"); +var line_1 = require("./line"); +var point_1 = require("./point"); +var rect_1 = require("./rect"); +var rule_1 = require("./rule"); +var text_1 = require("./text"); +var tick_1 = require("./tick"); +var markCompiler = { + area: area_1.area, + bar: bar_1.bar, + line: line_1.line, + point: point_1.point, + text: text_1.text, + tick: tick_1.tick, + rect: rect_1.rect, + rule: rule_1.rule, + circle: point_1.circle, + square: point_1.square +}; +function parseMark(model) { + if (util_1.contains([mark_1.LINE, mark_1.AREA], model.mark())) { + return parsePathMark(model); + } + else { + return parseNonPathMark(model); + } +} +exports.parseMark = parseMark; +// FIXME: maybe this should not be here. Need re-think and refactor, esp. after having all composition in. +function dataFrom(model) { + var parent = model.parent; + if (parent && parent.isFacet()) { + return parent.facetedTable(); + } + if (model.stack) { + return model.dataName('stacked'); + } + return model.dataTable(); +} +var FACETED_PATH_PREFIX = 'faceted-path-'; +function parsePathMark(model) { + var mark = model.mark(); + // FIXME: replace this with more general case for composition + var details = detailFields(model); + var pathMarks = [ + { + name: model.getName('marks'), + type: markCompiler[mark].vgMark, + // If has subfacet for line/area group, need to use faceted data from below. + // FIXME: support sorting path order (in connected scatterplot) + from: { data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + dataFrom(model) }, + encode: { update: markCompiler[mark].encodeEntry(model) } + } + ]; + if (details.length > 0) { + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + return [{ + name: model.getName('pathgroup'), + type: 'group', + from: { + facet: { + name: FACETED_PATH_PREFIX + dataFrom(model), + data: dataFrom(model), + groupby: details, + } + }, + encode: { + update: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } } + } + }, + marks: pathMarks + }]; + } + else { + return pathMarks; + } +} +function parseNonPathMark(model) { + var mark = model.mark(); + var role = markCompiler[mark].role; + var marks = []; // TODO: vgMarks + // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?) + marks.push(tslib_1.__assign({ name: model.getName('marks'), type: markCompiler[mark].vgMark }, (role ? { role: role } : {}), { from: { data: dataFrom(model) }, encode: { update: markCompiler[mark].encodeEntry(model) } })); + return marks; +} +var NONSPATIAL_CHANNELS_EXCEPT_ORDER = util_1.without(channel_1.NONSPATIAL_CHANNELS, ['order']); +/** + * Returns list of detail (group-by) fields + * that the model's spec contains. + */ +function detailFields(model) { + return NONSPATIAL_CHANNELS_EXCEPT_ORDER.reduce(function (details, channel) { + if (model.channelHasField(channel) && !model.fieldDef(channel).aggregate) { + details.push(model.field(channel)); + } + return details; + }, []); +} + +},{"../../channel":13,"../../mark":79,"../../util":88,"./area":37,"./bar":38,"./line":40,"./point":43,"./rect":44,"./rule":45,"./text":46,"./tick":47,"tslib":5}],42:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var util = require("../../util"); +var common_1 = require("../common"); +var ref = require("./valueref"); +var selection_1 = require("../selection/selection"); +function color(model) { + var config = model.config; + var filled = model.markDef.filled; + var e = nonPosition('color', model, { + vgChannel: filled ? 'fill' : 'stroke', + defaultValue: common_1.getMarkConfig('color', model.mark(), config) + }); + // If there is no fill, always fill symbols + // with transparent fills https://github.com/vega/vega-lite/issues/1316 + if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) { + e.fill = { value: 'transparent' }; + } + return e; +} +exports.color = color; +function markDefProperties(mark, props) { + return props.reduce(function (m, prop) { + if (mark[prop]) { + m[prop] = { value: mark[prop] }; + } + return m; + }, {}); +} +exports.markDefProperties = markDefProperties; +function valueIfDefined(prop, value) { + if (value !== undefined) { + return _a = {}, _a[prop] = { value: value }, _a; + } + return undefined; + var _a; +} +exports.valueIfDefined = valueIfDefined; +/** + * Return mixins for non-positional channels with scales. (Text doesn't have scale.) + */ +function nonPosition(channel, model, opt) { + // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + if (opt === void 0) { opt = {}; } + var defaultValue = opt.defaultValue, vgChannel = opt.vgChannel; + var defaultRef = opt.defaultRef || (defaultValue !== undefined ? { value: defaultValue } : undefined); + var channelDef = model.encoding[channel]; + var valueRef = ref.midPoint(channel, channelDef, model.scaleName(channel), model.scale(channel), defaultRef); + return wrapCondition(model, channelDef && channelDef.condition, vgChannel || channel, valueRef); +} +exports.nonPosition = nonPosition; +/** + * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition. + * or a simple mixin if channel def has no condition. + */ +function wrapCondition(model, condition, vgChannel, valueRef) { + if (condition) { + var selection = condition.selection, value = condition.value; + return _a = {}, + _a[vgChannel] = [ + { test: selectionTest(model, selection), value: value } + ].concat((valueRef !== undefined ? [valueRef] : [])), + _a; + } + else { + return valueRef !== undefined ? (_b = {}, _b[vgChannel] = valueRef, _b) : {}; + } + var _a, _b; +} +function selectionTest(model, selectionName) { + var negate = selectionName.charAt(0) === '!', name = negate ? selectionName.slice(1) : selectionName; + return (negate ? '!' : '') + selection_1.predicate(model.component.selection[name]); +} +function text(model) { + var channelDef = model.encoding.text; + return wrapCondition(model, channelDef && channelDef.condition, 'text', ref.text(channelDef, model.config)); +} +exports.text = text; +function bandPosition(channel, model) { + // TODO: band scale doesn't support size yet + var fieldDef = model.encoding[channel]; + var scaleName = model.scaleName(channel); + var sizeChannel = channel === 'x' ? 'width' : 'height'; + return _a = {}, + _a[channel] = ref.fieldRef(fieldDef, scaleName, {}), + _a[sizeChannel] = ref.band(scaleName), + _a; + var _a; +} +exports.bandPosition = bandPosition; +function centeredBandPosition(channel, model, defaultPosRef, defaultSizeRef) { + var centerChannel = channel === 'x' ? 'xc' : 'yc'; + var sizeChannel = channel === 'x' ? 'width' : 'height'; + return tslib_1.__assign({}, pointPosition(channel, model, defaultPosRef, centerChannel), nonPosition('size', model, { defaultRef: defaultSizeRef, vgChannel: sizeChannel })); +} +exports.centeredBandPosition = centeredBandPosition; +function binnedPosition(channel, model, spacing) { + var fieldDef = model.encoding[channel]; + var scaleName = model.scaleName(channel); + if (channel === 'x') { + return { + x2: ref.bin(fieldDef, scaleName, 'start', spacing), + x: ref.bin(fieldDef, scaleName, 'end') + }; + } + else { + return { + y2: ref.bin(fieldDef, scaleName, 'start'), + y: ref.bin(fieldDef, scaleName, 'end', spacing) + }; + } +} +exports.binnedPosition = binnedPosition; +/** + * Return mixins for point (non-band) position channels. + */ +function pointPosition(channel, model, defaultRef, vgChannel) { + // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613 + var encoding = model.encoding, stack = model.stack; + var valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.scale(channel), stack, defaultRef); + return _a = {}, + _a[vgChannel || channel] = valueRef, + _a; + var _a; +} +exports.pointPosition = pointPosition; +/** + * Return mixins for x2, y2. + * If channel is not specified, return one channel based on orientation. + */ +function pointPosition2(model, defaultRef, channel) { + var encoding = model.encoding, markDef = model.markDef, stack = model.stack; + channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2'); + var baseChannel = channel === 'x2' ? 'x' : 'y'; + var valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.scale(baseChannel), stack, defaultRef); + return _a = {}, _a[channel] = valueRef, _a; + var _a; +} +exports.pointPosition2 = pointPosition2; + +},{"../../util":88,"../common":17,"../selection/selection":58,"./valueref":48,"tslib":5}],43:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +var common_1 = require("../common"); +function encodeEntry(model, fixedShape) { + var config = model.config; + return tslib_1.__assign({}, mixins.pointPosition('x', model, ref.midX(config)), mixins.pointPosition('y', model, ref.midY(config)), mixins.color(model), mixins.nonPosition('size', model), shapeMixins(model, config, fixedShape), mixins.nonPosition('opacity', model)); +} +function shapeMixins(model, config, fixedShape) { + if (fixedShape) { + return { shape: { value: fixedShape } }; + } + return mixins.nonPosition('shape', model, { defaultValue: common_1.getMarkConfig('shape', 'point', config) }); +} +exports.shapeMixins = shapeMixins; +exports.point = { + vgMark: 'symbol', + role: 'point', + encodeEntry: function (model) { + return encodeEntry(model); + } +}; +exports.circle = { + vgMark: 'symbol', + role: 'circle', + encodeEntry: function (model) { + return encodeEntry(model, 'circle'); + } +}; +exports.square = { + vgMark: 'symbol', + role: 'square', + encodeEntry: function (model) { + return encodeEntry(model, 'square'); + } +}; + +},{"../common":17,"./mixins":42,"./valueref":48,"tslib":5}],44:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var mark_1 = require("../../mark"); +var log = require("../../log"); +var mixins = require("./mixins"); +exports.rect = { + vgMark: 'rect', + role: undefined, + encodeEntry: function (model) { + return tslib_1.__assign({}, x(model), y(model), mixins.color(model), mixins.nonPosition('opacity', model)); + } +}; +function x(model) { + var xDef = model.encoding.x; + var x2Def = model.encoding.x2; + var xScale = model.scale(channel_1.X); + if (fielddef_1.isFieldDef(xDef) && xDef.bin && !x2Def) { + return mixins.binnedPosition('x', model, 0); + } + else if (xScale && scale_1.hasDiscreteDomain(xScale.type)) { + /* istanbul ignore else */ + if (xScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('x', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(log.message.scaleTypeNotWorkWithMark(mark_1.RECT, xScale.type)); + } + } + else { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'x2')); + } +} +function y(model) { + var yDef = model.encoding.y; + var y2Def = model.encoding.y2; + var yScale = model.scale(channel_1.Y); + if (fielddef_1.isFieldDef(yDef) && yDef.bin && !y2Def) { + return mixins.binnedPosition('y', model, 0); + } + else if (yScale && scale_1.hasDiscreteDomain(yScale.type)) { + /* istanbul ignore else */ + if (yScale.type === scale_1.ScaleType.BAND) { + return mixins.bandPosition('y', model); + } + else { + // We don't support rect mark with point/ordinal scale + throw new Error(log.message.scaleTypeNotWorkWithMark(mark_1.RECT, yScale.type)); + } + } + else { + return tslib_1.__assign({}, mixins.pointPosition('y', model, 'zeroOrMax'), mixins.pointPosition2(model, 'zeroOrMin', 'y2')); + } +} + +},{"../../channel":13,"../../fielddef":75,"../../log":78,"../../mark":79,"../../scale":80,"./mixins":42,"tslib":5}],45:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +exports.rule = { + vgMark: 'rule', + role: undefined, + encodeEntry: function (model) { + return tslib_1.__assign({}, mixins.pointPosition('x', model, 'zeroOrMin'), mixins.pointPosition('y', model, 'zeroOrMin'), mixins.pointPosition2(model, 'zeroOrMax'), mixins.color(model), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'strokeWidth' // VL's rule size is strokeWidth + })); + } +}; + +},{"./mixins":42,"tslib":5}],46:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var channel_1 = require("../../channel"); +var common_1 = require("../common"); +var mixins = require("./mixins"); +var fielddef_1 = require("../../fielddef"); +var type_1 = require("../../type"); +var ref = require("./valueref"); +var encoding_1 = require("../../encoding"); +exports.text = { + vgMark: 'text', + role: undefined, + encodeEntry: function (model) { + var config = model.config, encoding = model.encoding; + var textDef = encoding.text; + return tslib_1.__assign({}, mixins.pointPosition('x', model, xDefault(config, textDef)), mixins.pointPosition('y', model, ref.midY(config)), mixins.text(model), mixins.color(model), mixins.nonPosition('opacity', model), mixins.nonPosition('size', model, { + vgChannel: 'fontSize' // VL's text size is fontSize + }), mixins.valueIfDefined('align', align(encoding, config))); + } +}; +function xDefault(config, textDef) { + if (fielddef_1.isFieldDef(textDef) && textDef.type === type_1.QUANTITATIVE) { + return { field: { group: 'width' }, offset: -5 }; + } + // TODO: allow this to fit (Be consistent with ref.midX()) + return { value: config.scale.textXRangeStep / 2 }; +} +function align(encoding, config) { + var alignConfig = common_1.getMarkConfig('align', 'text', config); + if (alignConfig === undefined) { + return encoding_1.channelHasField(encoding, channel_1.X) ? 'center' : 'right'; + } + // If there is a config, Vega-parser will process this already. + return undefined; +} + +},{"../../channel":13,"../../encoding":73,"../../fielddef":75,"../../type":87,"../common":17,"./mixins":42,"./valueref":48,"tslib":5}],47:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mixins = require("./mixins"); +var ref = require("./valueref"); +exports.tick = { + vgMark: 'rect', + role: 'tick', + encodeEntry: function (model) { + var config = model.config, markDef = model.markDef; + var orient = markDef.orient; + var vgSizeChannel = orient === 'horizontal' ? 'width' : 'height'; + var vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width'; + return tslib_1.__assign({}, mixins.pointPosition('x', model, ref.midX(config), 'xc'), mixins.pointPosition('y', model, ref.midY(config), 'yc'), mixins.nonPosition('size', model, { + defaultValue: defaultSize(model), + vgChannel: vgSizeChannel + }), (_a = {}, _a[vgThicknessChannel] = { value: config.tick.thickness }, _a), mixins.color(model), mixins.nonPosition('opacity', model)); + var _a; + } +}; +function defaultSize(model) { + var config = model.config; + var orient = model.markDef.orient; + var scaleRangeStep = (model.scale(orient === 'horizontal' ? 'x' : 'y') || {}).rangeStep; + if (config.tick.bandSize !== undefined) { + return config.tick.bandSize; + } + else { + var rangeStep = scaleRangeStep !== undefined ? + scaleRangeStep : + config.scale.rangeStep; + if (typeof rangeStep !== 'number') { + // FIXME consolidate this log + throw new Error('Function does not handle non-numeric rangeStep'); + } + return rangeStep / 1.5; + } +} + +},{"./mixins":42,"./valueref":48,"tslib":5}],48:[function(require,module,exports){ +/** + * Utility files for producing Vega ValueRef for marks + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var fielddef_1 = require("../../fielddef"); +var scale_1 = require("../../scale"); +var util_1 = require("../../util"); +var common_1 = require("../common"); +// TODO: we need to find a way to refactor these so that scaleName is a part of scale +// but that's complicated. For now, this is a huge step moving forward. +/** + * @return Vega ValueRef for stackable x or y + */ +function stackable(channel, channelDef, scaleName, scale, stack, defaultRef) { + if (channelDef && stack && channel === stack.fieldChannel) { + // x or y use stack_end so that stacked line's point mark use stack_end too. + return fieldRef(channelDef, scaleName, { suffix: 'end' }); + } + return midPoint(channel, channelDef, scaleName, scale, defaultRef); +} +exports.stackable = stackable; +/** + * @return Vega ValueRef for stackable x2 or y2 + */ +function stackable2(channel, aFieldDef, a2fieldDef, scaleName, scale, stack, defaultRef) { + if (aFieldDef && stack && + // If fieldChannel is X and channel is X2 (or Y and Y2) + channel.charAt(0) === stack.fieldChannel.charAt(0)) { + return fieldRef(aFieldDef, scaleName, { suffix: 'start' }); + } + return midPoint(channel, a2fieldDef, scaleName, scale, defaultRef); +} +exports.stackable2 = stackable2; +/** + * Value Ref for binned fields + */ +function bin(fieldDef, scaleName, side, offset) { + return fieldRef(fieldDef, scaleName, { binSuffix: side }, offset); +} +exports.bin = bin; +function fieldRef(fieldDef, scaleName, opt, offset) { + var ref = { + scale: scaleName, + field: fielddef_1.field(fieldDef, opt), + }; + if (offset) { + ref.offset = offset; + } + return ref; +} +exports.fieldRef = fieldRef; +function band(scaleName, band) { + if (band === void 0) { band = true; } + return { + scale: scaleName, + band: band + }; +} +exports.band = band; +function binMidSignal(fieldDef, scaleName) { + return { + signal: "(" + + ("scale(\"" + scaleName + "\", " + fielddef_1.field(fieldDef, { binSuffix: 'start', datum: true }) + ")") + + " + " + + ("scale(\"" + scaleName + "\", " + fielddef_1.field(fieldDef, { binSuffix: 'end', datum: true }) + ")") + + ")/2" + }; +} +/** + * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels. + */ +function midPoint(channel, channelDef, scaleName, scale, defaultRef) { + // TODO: datum support + if (channelDef) { + /* istanbul ignore else */ + if (fielddef_1.isFieldDef(channelDef)) { + if (scale.type === 'bin-linear') { + return binMidSignal(channelDef, scaleName); + } + else if (scale.type === 'bin-ordinal') { + return fieldRef(channelDef, scaleName, { binSuffix: 'start' }); + } + if (scale_1.hasDiscreteDomain(scale.type)) { + if (scale.type === 'band') { + // For band, to get mid point, need to offset by half of the band + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }, band(scaleName, 0.5)); + } + return fieldRef(channelDef, scaleName, { binSuffix: 'range' }); + } + else { + return fieldRef(channelDef, scaleName, {}); // no need for bin suffix + } + } + else if (channelDef.value) { + return { value: channelDef.value }; + } + else { + throw new Error('FieldDef without field or value.'); // FIXME add this to log.message + } + } + if (defaultRef === 'zeroOrMin') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMinX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMinY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + else if (defaultRef === 'zeroOrMax') { + /* istanbul ignore else */ + if (channel === channel_1.X || channel === channel_1.X2) { + return zeroOrMaxX(scaleName, scale); + } + else if (channel === channel_1.Y || channel === channel_1.Y2) { + return zeroOrMaxY(scaleName, scale); + } + else { + throw new Error("Unsupported channel " + channel + " for base function"); // FIXME add this to log.message + } + } + return defaultRef; +} +exports.midPoint = midPoint; +function text(textDef, config) { + // text + if (textDef) { + if (fielddef_1.isFieldDef(textDef)) { + if (textDef.type === 'quantitative') { + // FIXME: what happens if we have bin? + var format = common_1.numberFormat(textDef, textDef.format, config, 'text'); + return { + signal: "format(" + fielddef_1.field(textDef, { datum: true }) + ", '" + format + "')" + }; + } + else if (textDef.type === 'temporal') { + return { + signal: common_1.timeFormatExpression(fielddef_1.field(textDef, { datum: true }), textDef.timeUnit, textDef.format, config.text.shortTimeLabels, config.timeFormat) + }; + } + else { + return { field: textDef.field }; + } + } + else if (textDef.value) { + return { value: textDef.value }; + } + } + return { value: config.text.text }; +} +exports.text = text; +function midX(config) { + if (typeof config.scale.rangeStep === 'string') { + // TODO: For fit-mode, use middle of the width + throw new Error('midX can not handle string rangeSteps'); + } + return { value: config.scale.rangeStep / 2 }; +} +exports.midX = midX; +function midY(config) { + if (typeof config.scale.rangeStep === 'string') { + // TODO: For fit-mode, use middle of the width + throw new Error('midX can not handle string rangeSteps'); + } + return { value: config.scale.rangeStep / 2 }; +} +exports.midY = midY; +function zeroOrMinX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the x-axis + return { value: 0 }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxX(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + return { field: { group: 'width' } }; +} +function zeroOrMinY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { field: { group: 'height' } }; +} +/** + * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist + */ +function zeroOrMaxY(scaleName, scale) { + if (scaleName) { + // Log / Time / UTC scale do not support zero + if (!util_1.contains([scale_1.ScaleType.LOG, scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scale.type) && + scale.zero !== false) { + return { + scale: scaleName, + value: 0 + }; + } + } + // Put the mark on the y-axis + return { value: 0 }; +} + +},{"../../channel":13,"../../fielddef":75,"../../scale":80,"../../util":88,"../common":17}],49:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../log"); +var channel_1 = require("../channel"); +var data_1 = require("../data"); +var encoding_1 = require("../encoding"); +var fielddef_1 = require("../fielddef"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +var NameMap = (function () { + function NameMap() { + this.nameMap = {}; + } + NameMap.prototype.rename = function (oldName, newName) { + this.nameMap[oldName] = newName; + }; + NameMap.prototype.has = function (name) { + return this.nameMap[name] !== undefined; + }; + NameMap.prototype.get = function (name) { + // If the name appears in the _nameMap, we need to read its new name. + // We have to loop over the dict just in case the new name also gets renamed. + while (this.nameMap[name]) { + name = this.nameMap[name]; + } + return name; + }; + return NameMap; +}()); +exports.NameMap = NameMap; +var Model = (function () { + function Model(spec, parent, parentGivenName) { + this.scales = {}; + this.axes = {}; + this.legends = {}; + this.children = []; + this.parent = parent; + // If name is not provided, always use parent's givenName to avoid name conflicts. + this.name = spec.name || parentGivenName; + // Shared name maps + this.dataNameMap = parent ? parent.dataNameMap : new NameMap(); + this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap(); + this.sizeNameMap = parent ? parent.sizeNameMap : new NameMap(); + this.data = spec.data; + this.description = spec.description; + this.padding = spec.padding; + this.transform = spec.transform; + if (spec.transform) { + if (spec.transform.filterInvalid === undefined && + spec.transform['filterNull'] !== undefined) { + spec.transform.filterInvalid = spec.transform['filterNull']; + log.warn(log.message.DEPRECATED_FILTER_NULL); + } + } + this.component = { data: null, layout: null, mark: null, scales: null, axes: null, axisGroups: null, gridGroups: null, legends: null, selection: null }; + } + Model.prototype.parse = function () { + this.parseData(); + this.parseLayoutData(); + this.parseScale(); // depends on data name + this.parseSelection(); + this.parseAxis(); // depends on scale name + this.parseLegend(); // depends on scale name + this.parseAxisGroup(); // depends on child axis + this.parseGridGroup(); + this.parseMark(); // depends on data name and scale name, axisGroup, gridGroup and children's scale, axis, legend and mark. + }; + Model.prototype.assembleScales = function () { + // FIXME: write assembleScales() in scale.ts that + // help assemble scale domains with scale signature as well + return util_1.flatten(util_1.vals(this.component.scales).map(function (scale) { + var arr = [scale]; + return arr; + })); + }; + Model.prototype.assembleAxes = function () { + return [].concat.apply([], util_1.vals(this.component.axes)); + }; + Model.prototype.assembleLegends = function () { + return util_1.vals(this.component.legends); + }; + Model.prototype.assembleGroup = function () { + var group = {}; + var signals = this.assembleSignals(group.signals || []); + if (signals.length > 0) { + group.signals = signals; + } + // TODO: consider if we want scales to come before marks in the output spec. + group.marks = this.assembleMarks(); + var scales = this.assembleScales(); + if (scales.length > 0) { + group.scales = scales; + } + var axes = this.assembleAxes(); + if (axes.length > 0) { + group.axes = axes; + } + var legends = this.assembleLegends(); + if (legends.length > 0) { + group.legends = legends; + } + return group; + }; + Model.prototype.reduceFieldDef = function (f, init, t) { + return encoding_1.reduce(this.getMapping(), function (acc, cd, c) { + return fielddef_1.isFieldDef(cd) ? f(acc, cd, c) : acc; + }, init, t); + }; + Model.prototype.forEachFieldDef = function (f, t) { + encoding_1.forEach(this.getMapping(), function (cd, c) { + if (fielddef_1.isFieldDef(cd)) { + f(cd, c); + } + }, t); + }; + Model.prototype.hasDescendantWithFieldOnChannel = function (channel) { + for (var _i = 0, _a = this.children; _i < _a.length; _i++) { + var child = _a[_i]; + if (child.isUnit()) { + if (child.channelHasField(channel)) { + return true; + } + } + else { + if (child.hasDescendantWithFieldOnChannel(channel)) { + return true; + } + } + } + return false; + }; + Model.prototype.getName = function (text, delimiter) { + if (delimiter === void 0) { delimiter = '_'; } + if (this.data && text === data_1.SOURCE && data_1.isNamedData(this.data)) { + return this.data.name; + } + return (this.name ? this.name + delimiter : '') + text; + }; + Model.prototype.renameData = function (oldName, newName) { + this.dataNameMap.rename(oldName, newName); + }; + /** + * Return the data source name for the given data source type. + * + * For unit spec, this is always simply the spec.name + '-' + dataSourceType. + * We already use the name map so that marks and scales use the correct data. + */ + Model.prototype.dataName = function (dataSourceType) { + return this.dataNameMap.get(this.getName(String(dataSourceType))); + }; + Model.prototype.renameSize = function (oldName, newName) { + this.sizeNameMap.rename(oldName, newName); + }; + Model.prototype.channelSizeName = function (channel) { + return this.sizeName(channel === channel_1.X || channel === channel_1.COLUMN ? 'width' : 'height'); + }; + Model.prototype.sizeName = function (size) { + return this.sizeNameMap.get(this.getName(size, '_')); + }; + // TRANSFORMS + Model.prototype.calculate = function () { + return this.transform ? this.transform.calculate : undefined; + }; + Model.prototype.filterInvalid = function () { + var transform = this.transform || {}; + if (transform.filterInvalid === undefined) { + return this.parent ? this.parent.filterInvalid() : undefined; + } + return transform.filterInvalid; + }; + Model.prototype.filter = function () { + return this.transform ? this.transform.filter : undefined; + }; + /** Get "field" reference for vega */ + Model.prototype.field = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (fieldDef.bin) { + opt = util_1.extend({ + binSuffix: scale_1.hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start' + }, opt); + } + return fielddef_1.field(fieldDef, opt); + }; + Model.prototype.scale = function (channel) { + return this.scales[channel]; + }; + Model.prototype.hasDiscreteScale = function (channel) { + var scale = this.scale(channel); + return scale && scale_1.hasDiscreteDomain(scale.type); + }; + Model.prototype.renameScale = function (oldName, newName) { + this.scaleNameMap.rename(oldName, newName); + }; + /** + * @return scale name for a given channel after the scale has been parsed and named. + * (DO NOT USE THIS METHOD DURING SCALE PARSING, use model.name() instead) + */ + Model.prototype.scaleName = function (originalScaleName, parse) { + if (parse) { + // During the parse phase always return a value + // No need to refer to rename map because a scale can't be renamed + // before it has the original name. + return this.getName(originalScaleName + ''); + } + // If there is a scale for the channel, it should either + // be in the _scale mapping or exist in the name map + if ( + // in the scale map (the scale is not merged by its parent) + (this.scale && this.scales[originalScaleName]) || + // in the scale name map (the the scale get merged by its parent) + this.scaleNameMap.has(this.getName(originalScaleName + ''))) { + return this.scaleNameMap.get(this.getName(originalScaleName + '')); + } + return undefined; + }; + Model.prototype.sort = function (channel) { + return (this.getMapping()[channel] || {}).sort; + }; + Model.prototype.axis = function (channel) { + return this.axes[channel]; + }; + Model.prototype.legend = function (channel) { + return this.legends[channel]; + }; + /** + * Type checks + */ + Model.prototype.isUnit = function () { + return false; + }; + Model.prototype.isFacet = function () { + return false; + }; + Model.prototype.isLayer = function () { + return false; + }; + return Model; +}()); +exports.Model = Model; + +},{"../channel":13,"../data":71,"../encoding":73,"../fielddef":75,"../log":78,"../scale":80,"../util":88}],50:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var aggregate_1 = require("../../aggregate"); +var data_1 = require("../../data"); +var datetime_1 = require("../../datetime"); +var scale_1 = require("../../scale"); +var sort_1 = require("../../sort"); +var vega_schema_1 = require("../../vega.schema"); +var util = require("../../util"); +function initDomain(domain, fieldDef, scale, scaleConfig) { + if (domain === 'unaggregated') { + var _a = canUseUnaggregatedDomain(fieldDef, scale), valid = _a.valid, reason = _a.reason; + if (!valid) { + log.warn(reason); + return undefined; + } + } + else if (domain === undefined && scaleConfig.useUnaggregatedDomain) { + // Apply config if domain is not specified. + var valid = canUseUnaggregatedDomain(fieldDef, scale).valid; + if (valid) { + return 'unaggregated'; + } + } + return domain; +} +exports.initDomain = initDomain; +function parseDomain(model, channel) { + var scale = model.scale(channel); + // If channel is either X or Y then union them with X2 & Y2 if they exist + if (channel === 'x' && model.channelHasField('x2')) { + if (model.channelHasField('x')) { + return unionDomains(parseSingleChannelDomain(scale, model, 'x'), parseSingleChannelDomain(scale, model, 'x2')); + } + else { + return parseSingleChannelDomain(scale, model, 'x2'); + } + } + else if (channel === 'y' && model.channelHasField('y2')) { + if (model.channelHasField('y')) { + return unionDomains(parseSingleChannelDomain(scale, model, 'y'), parseSingleChannelDomain(scale, model, 'y2')); + } + else { + return parseSingleChannelDomain(scale, model, 'y2'); + } + } + return parseSingleChannelDomain(scale, model, channel); +} +exports.parseDomain = parseDomain; +function parseSingleChannelDomain(scale, model, channel) { + var fieldDef = model.fieldDef(channel); + if (scale.domain && scale.domain !== 'unaggregated') { + if (datetime_1.isDateTime(scale.domain[0])) { + return scale.domain.map(function (dt) { + return datetime_1.timestamp(dt, true); + }); + } + return scale.domain; + } + // special case for temporal scale + if (fieldDef.type === 'temporal') { + return { + data: model.dataTable(), + field: model.field(channel), + sort: { + field: model.field(channel), + op: 'min' + } + }; + } + // For stack, use STACKED data. + var stack = model.stack; + if (stack && channel === stack.fieldChannel) { + if (stack.offset === 'normalize') { + return [0, 1]; + } + return { + data: model.dataName('stacked'), + fields: [ + model.field(channel, { suffix: 'start' }), + model.field(channel, { suffix: 'end' }) + ] + }; + } + var sort = domainSort(model, channel, scale.type); + if (scale.domain === 'unaggregated') { + return { + data: model.dataTable(), + fields: [ + model.field(channel, { aggregate: 'min' }), + model.field(channel, { aggregate: 'max' }) + ] + }; + } + else if (fieldDef.bin) { + if (scale_1.isBinScale(scale.type)) { + var field = model.getName(fieldDef.field + '_bins'); + return { signal: "sequence(" + field + ".start, " + field + ".stop + " + field + ".step, " + field + ".step)" }; + } + if (scale_1.hasDiscreteDomain(scale.type)) { + // ordinal bin scale takes domain from bin_range, ordered by bin_start + // This is useful for both axis-based scale (x, y, column, and row) and legend-based scale (other channels). + return { + data: model.dataTable(), + field: model.field(channel, { binSuffix: 'range' }), + sort: { + field: model.field(channel, { binSuffix: 'start' }), + op: 'min' // min or max doesn't matter since same _range would have the same _start + } + }; + } + else { + if (channel === 'x' || channel === 'y') { + // X/Y position have to include start and end for non-ordinal scale + return { + data: model.dataTable(), + fields: [ + model.field(channel, { binSuffix: 'start' }), + model.field(channel, { binSuffix: 'end' }) + ] + }; + } + else { + // TODO: use bin_mid + return { + data: model.dataTable(), + field: model.field(channel, { binSuffix: 'start' }) + }; + } + } + } + else if (sort) { + return { + // If sort by aggregation of a specified sort field, we need to use SOURCE table, + // so we can aggregate values for the scale independently from the main aggregation. + data: util.isBoolean(sort) ? model.dataTable() : data_1.SOURCE, + field: model.field(channel), + sort: sort + }; + } + else { + return { + data: model.dataTable(), + field: model.field(channel), + }; + } +} +function domainSort(model, channel, scaleType) { + if (!scale_1.hasDiscreteDomain(scaleType)) { + return undefined; + } + var sort = model.sort(channel); + // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale) + if (sort_1.isSortField(sort)) { + return { + op: sort.op, + field: sort.field + }; + } + if (util.contains(['ascending', 'descending', undefined /* default =ascending*/], sort)) { + return true; + } + // sort === 'none' + return undefined; +} +exports.domainSort = domainSort; +/** + * Determine if a scale can use unaggregated domain. + * @return {Boolean} Returns true if all of the following conditons applies: + * 1. `scale.domain` is `unaggregated` + * 2. Aggregation function is not `count` or `sum` + * 3. The scale is quantitative or time scale. + */ +function canUseUnaggregatedDomain(fieldDef, scaleType) { + if (!fieldDef.aggregate) { + return { + valid: false, + reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef) + }; + } + if (aggregate_1.SHARED_DOMAIN_OPS.indexOf(fieldDef.aggregate) === -1) { + return { + valid: false, + reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate) + }; + } + if (fieldDef.type === 'quantitative') { + if (scaleType === 'log') { + return { + valid: false, + reason: log.message.unaggregatedDomainWithLogScale(fieldDef) + }; + } + } + return { valid: true }; +} +exports.canUseUnaggregatedDomain = canUseUnaggregatedDomain; +/** + * Convert the domain to an array of data refs or an array of values. Also, throw + * away sorting information since we always sort the domain when we union two domains. + */ +function normalizeDomain(domain) { + if (util.isArray(domain)) { + return [domain]; + } + else if (vega_schema_1.isDataRefDomain(domain)) { + delete domain.sort; + return [domain]; + } + else if (vega_schema_1.isFieldRefUnionDomain(domain)) { + return domain.fields.map(function (d) { + return { + data: domain.data, + field: d + }; + }); + } + else if (vega_schema_1.isDataRefUnionedDomain(domain)) { + return domain.fields.map(function (d) { + if (util.isArray(d)) { + return d; + } + return { + field: d.field, + data: d.data + }; + }); + } + /* istanbul ignore next: This should never happen. */ + throw new Error(log.message.INVAID_DOMAIN); +} +/** + * Union two data domains. A unioned domain is always sorted. + */ +function unionDomains(domain1, domain2) { + if (vega_schema_1.isSignalRefDomain(domain1) || vega_schema_1.isSignalRefDomain(domain2)) { + if (!vega_schema_1.isSignalRefDomain(domain1) || !vega_schema_1.isSignalRefDomain(domain2) || domain1.signal !== domain2.signal) { + throw new Error(log.message.UNABLE_TO_MERGE_DOMAINS); + } + return domain1; + } + var normalizedDomain1 = normalizeDomain(domain1); + var normalizedDomain2 = normalizeDomain(domain2); + var domains = normalizedDomain1.concat(normalizedDomain2); + domains = util.unique(domains, util.hash); + if (domains.length > 1) { + var allData = domains.map(function (d) { + if (vega_schema_1.isDataRefDomain(d)) { + return d.data; + } + return null; + }); + if (util.unique(allData, function (x) { return x; }).length === 1 && allData[0] !== null) { + return { + data: allData[0], + fields: domains.map(function (d) { return d.field; }) + }; + } + return { fields: domains, sort: true }; + } + else { + return domains[0]; + } +} +exports.unionDomains = unionDomains; + +},{"../../aggregate":10,"../../data":71,"../../datetime":72,"../../log":78,"../../scale":80,"../../sort":82,"../../util":88,"../../vega.schema":90}],51:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var scale_1 = require("../../scale"); +var domain_1 = require("./domain"); +var range_1 = require("./range"); +var rules = require("./rules"); +var type_1 = require("./type"); +var util = require("../../util"); +/** + * All scale properties except type and all range properties. + */ +exports.NON_TYPE_RANGE_SCALE_PROPERTIES = [ + // general properties + 'domain', + 'round', + // quantitative / time + 'clamp', 'nice', + // quantitative + 'exponent', 'zero', + 'interpolate', + // ordinal + 'padding', 'paddingInner', 'paddingOuter' // padding +]; +/** + * Initialize Vega-Lite Scale's properties + * + * Note that we have to apply these rules here because: + * - many other scale and non-scale properties (including layout, mark) depend on scale type + * - layout depends on padding + * - range depends on zero and size (width and height) depends on range + */ +function init(channel, fieldDef, config, mark, topLevelSize, xyRangeSteps) { + var specifiedScale = (fieldDef || {}).scale || {}; + var scale = { + type: type_1.default(specifiedScale.type, channel, fieldDef, mark, topLevelSize !== undefined, specifiedScale.rangeStep, config.scale) + }; + // Use specified value if compatible or determine default values for each property + exports.NON_TYPE_RANGE_SCALE_PROPERTIES.forEach(function (property) { + var specifiedValue = specifiedScale[property]; + var supportedByScaleType = scale_1.scaleTypeSupportProperty(scale.type, property); + var channelIncompatability = scale_1.channelScalePropertyIncompatability(channel, property); + if (specifiedValue !== undefined) { + // If there is a specified value, check if it is compatible with scale type and channel + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scale.type, property, channel)); + } + else if (channelIncompatability) { + log.warn(channelIncompatability); + } + } + if (supportedByScaleType && channelIncompatability === undefined) { + var value = getValue(specifiedValue, property, scale, channel, fieldDef, config.scale); + if (value !== undefined) { + scale[property] = value; + } + } + }); + return util.extend(scale, range_1.default(channel, scale.type, fieldDef.type, specifiedScale, config, scale.zero, mark, topLevelSize, xyRangeSteps)); +} +exports.default = init; +function getValue(specifiedValue, property, scale, channel, fieldDef, scaleConfig) { + // For domain, we might override specified value + if (property === 'domain') { + return domain_1.initDomain(specifiedValue, fieldDef, scale.type, scaleConfig); + } + // Other properties, no overriding default values + if (specifiedValue !== undefined) { + return specifiedValue; + } + return getDefaultValue(property, scale, channel, fieldDef, scaleConfig); +} +function getDefaultValue(property, scale, channel, fieldDef, scaleConfig) { + // If we have default rule-base, determine default value first + switch (property) { + case 'nice': + return rules.nice(scale.type, channel, fieldDef); + case 'padding': + return rules.padding(channel, scale.type, scaleConfig); + case 'paddingInner': + return rules.paddingInner(scale.padding, channel, scaleConfig); + case 'paddingOuter': + return rules.paddingOuter(scale.padding, channel, scale.type, scale.paddingInner, scaleConfig); + case 'round': + return rules.round(channel, scaleConfig); + case 'zero': + return rules.zero(scale, channel, fieldDef); + } + // Otherwise, use scale config + return scaleConfig[property]; +} + +},{"../../log":78,"../../scale":80,"../../util":88,"./domain":50,"./range":53,"./rules":54,"./type":55}],52:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var sort_1 = require("../../sort"); +var domain_1 = require("./domain"); +var range_1 = require("./range"); +/** + * Parse scales for all channels of a model. + */ +function parseScaleComponent(model) { + // TODO: should model.channels() inlcude X2/Y2? + return model.channels().reduce(function (scaleComponentsIndex, channel) { + var scaleComponents = parseScale(model, channel); + if (scaleComponents) { + scaleComponentsIndex[channel] = scaleComponents; + } + return scaleComponentsIndex; + }, {}); +} +exports.default = parseScaleComponent; +exports.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES = [ + 'round', + // quantitative / time + 'clamp', 'nice', + // quantitative + 'exponent', 'interpolate', 'zero', + // ordinal + 'padding', 'paddingInner', 'paddingOuter', +]; +/** + * Parse scales for a single channel of a model. + */ +function parseScale(model, channel) { + if (!model.scale(channel)) { + return null; + } + var scale = model.scale(channel); + var sort = model.sort(channel); + var scaleComponent = { + name: model.scaleName(channel + '', true), + type: scale.type, + domain: domain_1.parseDomain(model, channel), + range: range_1.parseRange(scale) + }; + exports.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES.forEach(function (property) { + scaleComponent[property] = scale[property]; + }); + if (sort && (sort_1.isSortField(sort) ? sort.order : sort) === 'descending') { + scaleComponent.reverse = true; + } + return scaleComponent; +} +exports.parseScale = parseScale; + +},{"../../sort":82,"./domain":50,"./range":53}],53:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var channel_1 = require("../../channel"); +var scale_1 = require("../../scale"); +var util = require("../../util"); +function parseRange(scale) { + if (scale.rangeStep) { + return { step: scale.rangeStep }; + } + else if (scale.scheme) { + var scheme = scale.scheme; + if (scale_1.isExtendedScheme(scheme)) { + var r = { scheme: scheme.name }; + if (scheme.count) { + r.count = scheme.count; + } + if (scheme.extent) { + r.extent = scheme.extent; + } + return r; + } + else { + return { scheme: scheme }; + } + } + return scale.range; +} +exports.parseRange = parseRange; +exports.RANGE_PROPERTIES = ['range', 'rangeStep', 'scheme']; +/** + * Return mixins that includes one of the range properties (range, rangeStep, scheme). + */ +function rangeMixins(channel, scaleType, type, specifiedScale, config, zero, mark, topLevelSize, xyRangeSteps) { + var specifiedRangeStepIsNull = false; + // Check if any of the range properties is specified. + // If so, check if it is compatible and make sure that we only output one of the properties + for (var _i = 0, RANGE_PROPERTIES_1 = exports.RANGE_PROPERTIES; _i < RANGE_PROPERTIES_1.length; _i++) { + var property = RANGE_PROPERTIES_1[_i]; + if (specifiedScale[property] !== undefined) { + var supportedByScaleType = scale_1.scaleTypeSupportProperty(scaleType, property); + var channelIncompatability = scale_1.channelScalePropertyIncompatability(channel, property); + if (!supportedByScaleType) { + log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel)); + } + else if (channelIncompatability) { + log.warn(channelIncompatability); + } + else { + switch (property) { + case 'range': + return { range: specifiedScale[property] }; + case 'scheme': + return { scheme: specifiedScale[property] }; + case 'rangeStep': + if (topLevelSize === undefined) { + var stepSize = specifiedScale[property]; + if (stepSize !== null) { + return { rangeStep: stepSize }; + } + else { + specifiedRangeStepIsNull = true; + } + } + else { + // If top-level size is specified, we ignore specified rangeStep. + log.warn(log.message.rangeStepDropped(channel)); + } + } + } + } + } + switch (channel) { + // TODO: revise row/column when facetSpec has top-level width/height + case channel_1.ROW: + return { range: 'height' }; + case channel_1.COLUMN: + return { range: 'width' }; + case channel_1.X: + case channel_1.Y: + if (topLevelSize === undefined) { + if (util.contains(['point', 'band'], scaleType) && !specifiedRangeStepIsNull) { + if (channel === channel_1.X && mark === 'text') { + if (config.scale.textXRangeStep) { + return { rangeStep: config.scale.textXRangeStep }; + } + } + else { + if (config.scale.rangeStep) { + return { rangeStep: config.scale.rangeStep }; + } + } + } + // If specified range step is null or the range step config is null. + // Use default topLevelSize rule/config + topLevelSize = channel === channel_1.X ? config.cell.width : config.cell.height; + } + return { range: channel === channel_1.X ? [0, topLevelSize] : [topLevelSize, 0] }; + case channel_1.SIZE: + // TODO: support custom rangeMin, rangeMax + var rangeMin = sizeRangeMin(mark, zero, config); + var rangeMax = sizeRangeMax(mark, xyRangeSteps, config); + return { range: [rangeMin, rangeMax] }; + case channel_1.SHAPE: + case channel_1.COLOR: + return { range: defaultRange(channel, scaleType, type, mark) }; + case channel_1.OPACITY: + // TODO: support custom rangeMin, rangeMax + return { range: [config.scale.minOpacity, config.scale.maxOpacity] }; + } + /* istanbul ignore next: should never reach here */ + throw new Error("Scale range undefined for channel " + channel); +} +exports.default = rangeMixins; +function defaultRange(channel, scaleType, type, mark) { + switch (channel) { + case channel_1.SHAPE: + return 'symbol'; + case channel_1.COLOR: + if (scaleType === 'ordinal') { + // Only nominal data uses ordinal scale by default + return type === 'nominal' ? 'category' : 'ordinal'; + } + return mark === 'rect' ? 'heatmap' : 'ramp'; + } +} +function sizeRangeMin(mark, zero, config) { + if (zero) { + return 0; + } + switch (mark) { + case 'bar': + return config.scale.minBandSize !== undefined ? config.scale.minBandSize : config.bar.continuousBandSize; + case 'tick': + return config.scale.minBandSize; + case 'line': + case 'rule': + return config.scale.minStrokeWidth; + case 'text': + return config.scale.minFontSize; + case 'point': + case 'square': + case 'circle': + if (config.scale.minSize) { + return config.scale.minSize; + } + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMin not implemented for the mark + throw new Error(log.message.incompatibleChannel('size', mark)); +} +function sizeRangeMax(mark, xyRangeSteps, config) { + var scaleConfig = config.scale; + // TODO(#1168): make max size scale based on rangeStep / overall plot size + switch (mark) { + case 'bar': + case 'tick': + if (config.scale.maxBandSize !== undefined) { + return config.scale.maxBandSize; + } + return minXYRangeStep(xyRangeSteps, config.scale) - 1; + case 'line': + case 'rule': + return config.scale.maxStrokeWidth; + case 'text': + return config.scale.maxFontSize; + case 'point': + case 'square': + case 'circle': + if (config.scale.maxSize) { + return config.scale.maxSize; + } + // FIXME this case totally should be refactored + var pointStep = minXYRangeStep(xyRangeSteps, scaleConfig); + return (pointStep - 2) * (pointStep - 2); + } + /* istanbul ignore next: should never reach here */ + // sizeRangeMax not implemented for the mark + throw new Error(log.message.incompatibleChannel('size', mark)); +} +/** + * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale. + */ +function minXYRangeStep(xyRangeSteps, scaleConfig) { + if (xyRangeSteps.length > 0) { + return Math.min.apply(null, xyRangeSteps); + } + if (scaleConfig.rangeStep) { + return scaleConfig.rangeStep; + } + return 21; // FIXME: re-evaluate the default value here. +} + +},{"../../channel":13,"../../log":78,"../../scale":80,"../../util":88}],54:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("../../channel"); +var scale_1 = require("../../scale"); +var timeunit_1 = require("../../timeunit"); +var util = require("../../util"); +function nice(scaleType, channel, fieldDef) { + if (util.contains([scale_1.ScaleType.TIME, scale_1.ScaleType.UTC], scaleType)) { + return timeunit_1.smallestUnit(fieldDef.timeUnit); + } + return util.contains([channel_1.X, channel_1.Y], channel); // return true for quantitative X/Y +} +exports.nice = nice; +function padding(channel, scaleType, scaleConfig) { + if (util.contains([channel_1.X, channel_1.Y], channel)) { + if (scaleType === scale_1.ScaleType.POINT) { + return scaleConfig.pointPadding; + } + } + return undefined; +} +exports.padding = padding; +function paddingInner(padding, channel, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingInner. + return undefined; + } + if (util.contains([channel_1.X, channel_1.Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + // paddingOuter would only be called if it's a band scale, just return the default for bandScale. + return scaleConfig.bandPaddingInner; + } + return undefined; +} +exports.paddingInner = paddingInner; +function paddingOuter(padding, channel, scaleType, paddingInner, scaleConfig) { + if (padding !== undefined) { + // If user has already manually specified "padding", no need to add default paddingOuter. + return undefined; + } + if (util.contains([channel_1.X, channel_1.Y], channel)) { + // Padding is only set for X and Y by default. + // Basically it doesn't make sense to add padding for color and size. + if (scaleType === scale_1.ScaleType.BAND) { + if (scaleConfig.bandPaddingOuter !== undefined) { + return scaleConfig.bandPaddingOuter; + } + /* By default, paddingOuter is paddingInner / 2. The reason is that + size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter). + and we want the width/height to be integer by default. + Note that step (by default) and cardinality are integers.) */ + return paddingInner / 2; + } + } + return undefined; +} +exports.paddingOuter = paddingOuter; +function round(channel, scaleConfig) { + if (util.contains(['x', 'y', 'row', 'column'], channel)) { + return scaleConfig.round; + } + return undefined; +} +exports.round = round; +function zero(specifiedScale, channel, fieldDef) { + // By default, return true only for the following cases: + // 1) using quantitative field with size + // While this can be either ratio or interval fields, our assumption is that + // ratio are more common. + if (channel === 'size' && fieldDef.type === 'quantitative') { + return true; + } + // 2) non-binned, quantitative x-scale or y-scale if no custom domain is provided. + // (For binning, we should not include zero by default because binning are calculated without zero. + // Similar, if users explicitly provide a domain range, we should not augment zero as that will be unexpected.) + if (!specifiedScale.domain && !fieldDef.bin && util.contains([channel_1.X, channel_1.Y], channel)) { + return true; + } + return false; +} +exports.zero = zero; + +},{"../../channel":13,"../../scale":80,"../../timeunit":85,"../../util":88}],55:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("../../log"); +var channel_1 = require("../../channel"); +var timeunit_1 = require("../../timeunit"); +var util = require("../../util"); +/** + * Determine if there is a specified scale type and if it is appropriate, + * or determine default type if type is unspecified or inappropriate. + */ +// NOTE: CompassQL uses this method. +function type(specifiedType, channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig) { + var defaultScaleType = defaultType(channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + if (!channel_1.hasScale(channel)) { + // There is no scale for these channels + return null; + } + if (specifiedType !== undefined) { + // for binned fields we don't allow overriding the default scale + if (fieldDef.bin) { + // TODO: generalize this as a method in fieldDef that determines scale type support for a fieldDef (looking at functions and type) + log.warn(log.message.cannotOverrideBinScaleType(channel, defaultScaleType)); + return defaultScaleType; + } + // Check if explicitly specified scale type is supported by the channel + if (channel_1.supportScaleType(channel, specifiedType)) { + return specifiedType; + } + else { + log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType)); + return defaultScaleType; + } + } + return defaultScaleType; +} +exports.default = type; +/** + * Determine appropriate default scale type. + */ +function defaultType(channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig) { + if (util.contains(['row', 'column'], channel)) { + return 'band'; + } + switch (fieldDef.type) { + case 'nominal': + if (channel === 'color' || channel_1.rangeType(channel) === 'discrete') { + return 'ordinal'; + } + return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + case 'ordinal': + if (channel === 'color') { + return 'ordinal'; + } + else if (channel_1.rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal')); + return 'ordinal'; + } + return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + case 'temporal': + if (channel === 'color') { + // Always use `sequential` as the default color scale for continuous data + // since it supports both array range and scheme range. + return 'sequential'; + } + else if (channel_1.rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + if (timeunit_1.isDiscreteByDefault(fieldDef.timeUnit)) { + return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig); + } + return 'time'; + case 'quantitative': + if (channel === 'color') { + if (fieldDef.bin) { + return 'bin-ordinal'; + } + // Use `sequential` as the default color scale for continuous data + // since it supports both array range and scheme range. + return 'sequential'; + } + else if (channel_1.rangeType(channel) === 'discrete') { + log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative')); + // TODO: consider using quantize (equivalent to binning) once we have it + return 'ordinal'; + } + if (fieldDef.bin) { + return 'bin-linear'; + } + return 'linear'; + } + /* istanbul ignore next: should never reach this */ + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +/** + * Determines default scale type for nominal/ordinal field. + * @returns BAND or POINT scale based on channel, mark, and rangeStep + */ +function discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig) { + if (util.contains(['x', 'y'], channel)) { + if (mark === 'rect') { + // The rect mark should fit into a band. + return 'band'; + } + if (mark === 'bar') { + // For bar, use band only if there is no rangeStep since we need to use band for fit mode. + // However, for non-fit mode, point scale provides better center position. + if (haveRangeStep(hasTopLevelSize, specifiedRangeStep, scaleConfig)) { + return 'point'; + } + return 'band'; + } + } + // Otherwise, use ordinal point scale so we can easily get center positions of the marks. + return 'point'; +} +function haveRangeStep(hasTopLevelSize, specifiedRangeStep, scaleConfig) { + if (hasTopLevelSize) { + // if topLevelSize is provided, rangeStep will be dropped. + return false; + } + if (specifiedRangeStep !== undefined) { + return specifiedRangeStep !== null; + } + return !!scaleConfig.rangeStep; +} + +},{"../../channel":13,"../../log":78,"../../timeunit":85,"../../util":88}],56:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./selection"); +var channel_1 = require("../../channel"); +var util_1 = require("../../util"); +var log_1 = require("../../log"); +var scales_1 = require("./transforms/scales"); +exports.BRUSH = '_brush', exports.SIZE = '_size'; +var interval = { + predicate: 'vlInterval', + signals: function (model, selCmpt) { + var signals = [], intervals = [], name = selCmpt.name, size = name + exports.SIZE; + if (selCmpt.translate && !(scales_1.default.has(selCmpt))) { + events(selCmpt, function (_, evt) { + var filters = evt.between[0].filter || (evt.between[0].filter = []); + filters.push('!event.item || (event.item && ' + + ("event.item.mark.name !== " + util_1.stringValue(name + exports.BRUSH) + ")")); + }); + } + selCmpt.project.forEach(function (p) { + if (p.encoding !== channel_1.X && p.encoding !== channel_1.Y) { + log_1.warn('Interval selections only support x and y encoding channels.'); + return; + } + var cs = channelSignal(model, selCmpt, p.encoding); + signals.push(cs); + intervals.push("{field: " + util_1.stringValue(p.field) + ", extent: " + cs.name + "}"); + }); + signals.push({ + name: size, + value: [], + on: events(selCmpt, function (on, evt) { + on.push({ + events: evt.between[0], + update: '{x: x(unit), y: y(unit), width: 0, height: 0}' + }); + on.push({ + events: evt, + update: "{x: " + size + ".x, y: " + size + ".y, " + + ("width: abs(x(unit) - " + size + ".x), height: abs(y(unit) - " + size + ".y)}") + }); + return on; + }) + }, { + name: name, + update: "[" + intervals.join(', ') + "]" + }); + return signals; + }, + tupleExpr: function (model, selCmpt) { + return "intervals: " + selCmpt.name; + }, + modifyExpr: function (model, selCmpt) { + var tpl = selCmpt.name + selection_1.TUPLE; + return tpl + ", {unit: " + tpl + ".unit}"; + }, + marks: function (model, selCmpt, marks) { + var name = selCmpt.name, _a = projections(selCmpt), x = _a.x, y = _a.y; + // Do not add a brush if we're binding to scales. + if (scales_1.default.has(selCmpt)) { + return marks; + } + var update = { + x: util_1.extend({}, x !== null ? + { scale: model.scaleName(channel_1.X), signal: name + "[" + x + "].extent[0]" } : + { value: 0 }), + x2: util_1.extend({}, x !== null ? + { scale: model.scaleName(channel_1.X), signal: name + "[" + x + "].extent[1]" } : + { field: { group: 'width' } }), + y: util_1.extend({}, y !== null ? + { scale: model.scaleName(channel_1.Y), signal: name + "[" + y + "].extent[0]" } : + { value: 0 }), + y2: util_1.extend({}, y !== null ? + { scale: model.scaleName(channel_1.Y), signal: name + "[" + y + "].extent[1]" } : + { field: { group: 'height' } }), + }; + return [{ + name: undefined, + type: 'rect', + encode: { + enter: { fill: { value: '#eee' } }, + update: update + } + }].concat(marks, { + name: name + exports.BRUSH, + type: 'rect', + encode: { + enter: { fill: { value: 'transparent' } }, + update: update + } + }); + } +}; +exports.default = interval; +function projections(selCmpt) { + var x = null, y = null; + selCmpt.project.forEach(function (p, i) { + if (p.encoding === channel_1.X) { + x = i; + } + else if (p.encoding === channel_1.Y) { + y = i; + } + }); + return { x: x, y: y }; +} +exports.projections = projections; +function channelSignal(model, selCmpt, channel) { + var name = selection_1.channelSignalName(selCmpt, channel), size = (channel === channel_1.X ? 'width' : 'height'), coord = channel + "(unit)", invert = selection_1.invert.bind(null, model, selCmpt, channel); + return { + name: name, + value: [], + on: scales_1.default.has(selCmpt) ? [] : events(selCmpt, function (on, evt) { + on.push({ + events: evt.between[0], + update: invert("[" + coord + ", " + coord + "]") + }); + on.push({ + events: evt, + update: "[" + name + "[0], " + invert("clamp(" + coord + ", 0, " + size + ")") + ']' + }); + return on; + }) + }; +} +function events(selCmpt, cb) { + return selCmpt.events.reduce(function (on, evt) { + if (!evt.between) { + log_1.warn(evt + " is not an ordered event stream for interval selections"); + return on; + } + return cb(on, evt); + }, []); +} + +},{"../../channel":13,"../../log":78,"../../util":88,"./selection":58,"./transforms/scales":63}],57:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./selection"); +var util_1 = require("../../util"); +var multi = { + predicate: 'vlPoint', + signals: function (model, selCmpt) { + var proj = selCmpt.project, datum = '(item().isVoronoi ? datum.datum : datum)', fields = proj.map(function (p) { return util_1.stringValue(p.field); }).join(', '), values = proj.map(function (p) { return datum + "[" + util_1.stringValue(p.field) + "]"; }).join(', '); + return [{ + name: selCmpt.name, + value: {}, + on: [{ + events: selCmpt.events, + update: "{fields: [" + fields + "], values: [" + values + "]}" + }] + }]; + }, + tupleExpr: function (model, selCmpt) { + var name = selCmpt.name; + return "fields: " + name + ".fields, values: " + name + ".values"; + }, + modifyExpr: function (model, selCmpt) { + return selCmpt.name + selection_1.TUPLE; + } +}; +exports.default = multi; + +},{"../../util":88,"./selection":58}],58:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../util"); +var transforms_1 = require("./transforms/transforms"); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var single_1 = require("./single"); +var multi_1 = require("./multi"); +var interval_1 = require("./interval"); +exports.STORE = '_store', exports.TUPLE = '_tuple', exports.MODIFY = '_modify'; +function parseUnitSelection(model, selDefs) { + var selCmpts = {}, selectionConfig = model.config.selection; + var _loop_1 = function (name_1) { + if (!selDefs.hasOwnProperty(name_1)) { + return "continue"; + } + var selDef = selDefs[name_1], cfg = selectionConfig[selDef.type]; + // Set default values from config if a property hasn't been specified, + // or if it is true. E.g., "translate": true should use the default + // event handlers for translate. However, true may be a valid value for + // a property (e.g., "nearest": true). + for (var key in cfg) { + // A selection should contain either `encodings` or `fields`, only use + // default values for these two values if neither of them is specified. + if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) { + continue; + } + if (selDef[key] === undefined || selDef[key] === true) { + selDef[key] = cfg[key] || selDef[key]; + } + } + var selCmpt = selCmpts[name_1] = util_1.extend({}, selDef, { + name: model.getName(name_1), + events: util_1.isString(selDef.on) ? event_selector_1.default(selDef.on, 'scope') : selDef.on, + domain: 'data', + resolve: 'union' + }); + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.parse) { + txCompiler.parse(model, selDef, selCmpt); + } + }); + }; + for (var name_1 in selDefs) { + _loop_1(name_1); + } + return selCmpts; +} +exports.parseUnitSelection = parseUnitSelection; +function assembleUnitSignals(model, signals) { + forEachSelection(model, function (selCmpt, selCompiler) { + var name = selCmpt.name, tupleExpr = selCompiler.tupleExpr(model, selCmpt), modifyExpr = selCompiler.modifyExpr(model, selCmpt); + signals.push.apply(signals, selCompiler.signals(model, selCmpt)); + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.signals) { + signals = txCompiler.signals(model, selCmpt, signals); + } + if (txCompiler.modifyExpr) { + modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr); + } + }); + signals.push({ + name: name + exports.TUPLE, + on: [{ + events: { signal: name }, + update: "{unit: unit.datum && unit.datum._id, " + tupleExpr + "}" + }] + }, { + name: name + exports.MODIFY, + on: [{ + events: { signal: name }, + update: "modify(" + util_1.stringValue(name + exports.STORE) + ", " + modifyExpr + ")" + }] + }); + }); + return signals; +} +exports.assembleUnitSignals = assembleUnitSignals; +function assembleTopLevelSignals(model) { + var signals = [{ + name: 'unit', + value: {}, + on: [{ events: 'mousemove', update: 'group()._id ? group() : unit' }] + }]; + forEachSelection(model, function (selCmpt, selCompiler) { + if (selCompiler.topLevelSignals) { + signals.push.apply(signals, selCompiler.topLevelSignals(model, selCmpt)); + } + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + if (txCompiler.topLevelSignals) { + signals = txCompiler.topLevelSignals(model, selCmpt, signals); + } + }); + }); + return signals; +} +exports.assembleTopLevelSignals = assembleTopLevelSignals; +function assembleUnitData(model, data) { + return data + .concat(Object.keys(model.component.selection) + .map(function (k) { + return { name: k + exports.STORE }; + })); +} +exports.assembleUnitData = assembleUnitData; +function assembleUnitMarks(model, marks) { + var clippedGroup = false, selMarks = marks; + forEachSelection(model, function (selCmpt, selCompiler) { + selMarks = selCompiler.marks ? selCompiler.marks(model, selCmpt, selMarks) : selMarks; + transforms_1.forEachTransform(selCmpt, function (txCompiler) { + clippedGroup = clippedGroup || txCompiler.clippedGroup; + if (txCompiler.marks) { + selMarks = txCompiler.marks(model, selCmpt, marks, selMarks); + } + }); + }); + if (clippedGroup) { + selMarks = [{ + type: 'group', + encode: { + enter: { + width: { field: { group: 'width' } }, + height: { field: { group: 'height' } }, + fill: { value: 'transparent' }, + clip: { value: true } + } + }, + marks: selMarks + }]; + } + return selMarks; +} +exports.assembleUnitMarks = assembleUnitMarks; +var PREDICATES_OPS = { + 'single': '"intersect", "all"', + 'independent': '"intersect", "unit"', + 'union': '"union", "all"', + 'union_others': '"union", "others"', + 'intersect': '"intersect", "all"', + 'intersect_others': '"intersect", "others' +}; +function predicate(selCmpt, datum) { + var store = util_1.stringValue(selCmpt.name + exports.STORE), op = PREDICATES_OPS[selCmpt.resolve]; + datum = datum || 'datum'; + return compiler(selCmpt).predicate + ("(" + store + ", parent._id, " + datum + ", " + op + ")"); +} +exports.predicate = predicate; +// Utility functions +function forEachSelection(model, cb) { + var selections = model.component.selection; + for (var name_2 in selections) { + if (selections.hasOwnProperty(name_2)) { + var sel = selections[name_2]; + cb(sel, compiler(sel)); + } + } +} +function compiler(selCmpt) { + switch (selCmpt.type) { + case 'single': + return single_1.default; + case 'multi': + return multi_1.default; + case 'interval': + return interval_1.default; + } + return null; +} +function invert(model, selCmpt, channel, expr) { + var scale = util_1.stringValue(model.scaleName(channel)); + return selCmpt.domain === 'data' ? "invert(" + scale + ", " + expr + ")" : expr; +} +exports.invert = invert; +function channelSignalName(selCmpt, channel) { + return selCmpt.name + '_' + channel; +} +exports.channelSignalName = channelSignalName; + +},{"../../util":88,"./interval":56,"./multi":57,"./single":59,"./transforms/transforms":65,"vega-parser/src/parsers/event-selector":6}],59:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("./selection"); +var multi_1 = require("./multi"); +var util_1 = require("../../util"); +var single = { + predicate: multi_1.default.predicate, + signals: multi_1.default.signals, + topLevelSignals: function (model, selCmpt) { + var name = selCmpt.name; + return [{ + name: name, + update: "data(" + util_1.stringValue(name + selection_1.STORE) + ")[0]" + }]; + }, + tupleExpr: function (model, selCmpt) { + var name = selCmpt.name, values = name + ".values"; + return "fields: " + name + ".fields, values: " + values + ", " + + selCmpt.project.map(function (p, i) { + return p.field + ": " + values + "[" + i + "]"; + }).join(', '); + }, + modifyExpr: function (model, selCmpt) { + return selCmpt.name + selection_1.TUPLE + ', true'; + } +}; +exports.default = single; + +},{"../../util":88,"./multi":57,"./selection":58}],60:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("../../../util"); +var inputBindings = { + has: function (selCmpt) { + return selCmpt.type === 'single' && selCmpt.bind && selCmpt.bind !== 'scales'; + }, + topLevelSignals: function (model, selCmpt, signals) { + var name = selCmpt.name, proj = selCmpt.project, bind = selCmpt.bind, datum = '(item().isVoronoi ? datum.datum : datum)'; + proj.forEach(function (p) { + signals.unshift({ + name: name + id(p.field), + value: '', + on: [{ + events: selCmpt.events, + update: datum + "[" + util_1.stringValue(p.field) + "]" + }], + bind: bind[p.field] || bind[p.encoding] || bind + }); + }); + return signals; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name, proj = selCmpt.project, signal = signals.filter(function (s) { return s.name === name; })[0], fields = proj.map(function (p) { return util_1.stringValue(p.field); }).join(', '), values = proj.map(function (p) { return name + id(p.field); }).join(', '); + signal.update = "{fields: [" + fields + "], values: [" + values + "]}"; + delete signal.value; + delete signal.on; + return signals; + } +}; +exports.default = inputBindings; +function id(str) { + return '_' + str.replace(/\W/g, '_'); +} + +},{"../../../util":88}],61:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var VORONOI = 'voronoi'; +var nearest = { + has: function (selCmpt) { + return selCmpt.nearest !== undefined && selCmpt.nearest !== false; + }, + marks: function (model, selCmpt, marks, selMarks) { + var mark = marks[0], index = selMarks.indexOf(mark), isPathgroup = mark.name === model.getName('pathgroup'), exists = (function (m) { return m.name && m.name.indexOf(VORONOI) >= 0; }), cellDef = { + name: model.getName(VORONOI), + type: 'path', + from: { data: model.getName('marks') }, + encode: { + enter: { + fill: { value: 'transparent' }, + strokeWidth: { value: 0.35 }, + stroke: { value: 'transparent' }, + isVoronoi: { value: true } + } + }, + transform: [{ + type: 'voronoi', + x: 'datum.x', + y: 'datum.y', + size: [{ signal: 'width' }, { signal: 'height' }] + }] + }; + if (isPathgroup && !mark.marks.filter(exists).length) { + mark.marks.push(cellDef); + selMarks.splice(index, 1, mark); + } + else if (!isPathgroup && !selMarks.filter(exists).length) { + selMarks.splice(index + 1, 0, cellDef); + } + return selMarks; + } +}; +exports.default = nearest; + +},{}],62:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var project = { + has: function (selDef) { + return selDef.fields !== undefined || selDef.encodings !== undefined; + }, + parse: function (model, selDef, selCmpt) { + var fields = {}; + // TODO: find a possible channel mapping for these fields. + (selDef.fields || []).forEach(function (f) { return fields[f] = null; }); + (selDef.encodings || []).forEach(function (e) { return fields[model.field(e)] = e; }); + var projection = selCmpt.project || (selCmpt.project = []); + for (var field in fields) { + if (fields.hasOwnProperty(field)) { + projection.push({ field: field, encoding: fields[field] }); + } + } + } +}; +exports.default = project; + +},{}],63:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log_1 = require("../../../log"); +var scale_1 = require("../../../scale"); +var selection_1 = require("../selection"); +var interval_1 = require("../interval"); +var util_1 = require("../../../util"); +var scaleBindings = { + clippedGroup: true, + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.bind && selCmpt.bind === 'scales'; + }, + parse: function (model, selDef, selCmpt) { + var scales = model.component.scales; + var bound = selCmpt.scales = []; + selCmpt.project.forEach(function (p) { + var channel = p.encoding; + var scale = scales[channel]; + if (!scale || !scale_1.hasContinuousDomain(scale.type)) { + log_1.warn('Scale bindings are currently only supported for scales with continuous domains.'); + return; + } + scale.domainRaw = { signal: selection_1.channelSignalName(selCmpt, channel) }; + bound.push(channel); + }); + }, + topLevelSignals: function (model, selCmpt, signals) { + return signals.concat(selCmpt.scales.map(function (channel) { + return { name: selection_1.channelSignalName(selCmpt, channel) }; + })); + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name; + signals = signals.filter(function (s) { + return s.name !== name + interval_1.SIZE && + s.name !== name + selection_1.TUPLE && s.name !== selection_1.MODIFY; + }); + selCmpt.scales.forEach(function (channel) { + var signal = signals.filter(function (s) { return s.name === name + '_' + channel; })[0]; + signal.push = 'outer'; + delete signal.value; + delete signal.update; + }); + return signals; + } +}; +exports.default = scaleBindings; +function domain(model, channel) { + var scale = util_1.stringValue(model.scaleName(channel)); + return "domain(" + scale + ")"; +} +exports.domain = domain; + +},{"../../../log":78,"../../../scale":80,"../../../util":88,"../interval":56,"../selection":58}],64:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var selection_1 = require("../selection"); +var TOGGLE = '_toggle'; +var toggle = { + has: function (selCmpt) { + return selCmpt.toggle !== undefined && selCmpt.toggle !== false; + }, + signals: function (model, selCmpt, signals) { + return signals.concat({ + name: selCmpt.name + TOGGLE, + value: false, + on: [{ events: selCmpt.events, update: selCmpt.toggle }] + }); + }, + modifyExpr: function (model, selCmpt, expr) { + var tpl = selCmpt.name + selection_1.TUPLE, signal = selCmpt.name + TOGGLE; + return signal + " ? null : " + tpl + ", " + + (signal + " ? null : true, ") + + (signal + " ? " + tpl + " : null"); + } +}; +exports.default = toggle; + +},{"../selection":58}],65:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var project_1 = require("./project"); +var toggle_1 = require("./toggle"); +var translate_1 = require("./translate"); +var zoom_1 = require("./zoom"); +var scales_1 = require("./scales"); +var inputs_1 = require("./inputs"); +var nearest_1 = require("./nearest"); +var compilers = { project: project_1.default, toggle: toggle_1.default, scales: scales_1.default, + translate: translate_1.default, zoom: zoom_1.default, inputs: inputs_1.default, nearest: nearest_1.default }; +function forEachTransform(selCmpt, cb) { + for (var t in compilers) { + if (compilers[t].has(selCmpt)) { + cb(compilers[t]); + } + } +} +exports.forEachTransform = forEachTransform; + +},{"./inputs":60,"./nearest":61,"./project":62,"./scales":63,"./toggle":64,"./translate":66,"./zoom":67}],66:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var channel_1 = require("../../../channel"); +var util_1 = require("../../../util"); +var scales_1 = require("./scales"); +var interval_1 = require("../interval"); +var ANCHOR = '_translate_anchor', DELTA = '_translate_delta'; +var translate = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.translate !== undefined && selCmpt.translate !== false; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name, scales = scales_1.default.has(selCmpt), size = scales ? 'unit' : name + interval_1.SIZE, anchor = name + ANCHOR, events = event_selector_1.default(selCmpt.translate, 'scope'), _a = interval_1.projections(selCmpt), x = _a.x, y = _a.y; + if (!scales) { + events = events.map(function (e) { return (e.between[0].markname = name + interval_1.BRUSH, e); }); + } + signals.push({ + name: anchor, + value: {}, + on: [{ + events: events.map(function (e) { return e.between[0]; }), + update: '{x: x(unit), y: y(unit), ' + + ("width: " + size + ".width, height: " + size + ".height, ") + + (x !== null ? 'extent_x: ' + (scales ? scales_1.domain(model, channel_1.X) : + "slice(" + name + "_x)") + ', ' : '') + + (y !== null ? 'extent_y: ' + (scales ? scales_1.domain(model, channel_1.Y) : + "slice(" + name + "_y)") + ', ' : '') + '}' + }] + }, { + name: name + DELTA, + value: {}, + on: [{ + events: events, + update: "{x: x(unit) - " + anchor + ".x, y: y(unit) - " + anchor + ".y}" + }] + }); + if (x !== null) { + onDelta(model, selCmpt, channel_1.X, 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, channel_1.Y, 'height', signals); + } + return signals; + } +}; +exports.default = translate; +function getSign(selCmpt, channel) { + var s = channel === channel_1.X ? '+' : '-'; + if (scales_1.default.has(selCmpt)) { + s = s === '+' ? '-' : '+'; + } + return s; +} +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name, signal = signals.filter(function (s) { return s.name === name + '_' + channel; })[0], anchor = name + ANCHOR, delta = name + DELTA, scale = util_1.stringValue(model.scaleName(channel)), extent = ".extent_" + channel, sign = getSign(selCmpt, channel), offset = sign + " abs(span(" + anchor + extent + ")) * " + + (delta + "." + channel + " / " + anchor + "." + size), range = "[" + anchor + extent + "[0] " + offset + ", " + + ("" + anchor + extent + "[1] " + offset + "]"), lo = "invert(" + scale + (channel === channel_1.X ? ', 0' : ", unit." + size) + ')', hi = "invert(" + scale + (channel === channel_1.X ? ", unit." + size : ', 0') + ')'; + signal.on.push({ + events: { signal: delta }, + update: scales_1.default.has(selCmpt) ? range : "clampRange(" + range + ", " + lo + ", " + hi + ")" + }); +} + +},{"../../../channel":13,"../../../util":88,"../interval":56,"./scales":63,"vega-parser/src/parsers/event-selector":6}],67:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var event_selector_1 = require("vega-parser/src/parsers/event-selector"); +var channel_1 = require("../../../channel"); +var util_1 = require("../../../util"); +var scales_1 = require("./scales"); +var interval_1 = require("../interval"); +var ANCHOR = '_zoom_anchor', DELTA = '_zoom_delta'; +var zoom = { + has: function (selCmpt) { + return selCmpt.type === 'interval' && selCmpt.zoom !== undefined && selCmpt.zoom !== false; + }, + signals: function (model, selCmpt, signals) { + var name = selCmpt.name, delta = name + DELTA, events = event_selector_1.default(selCmpt.zoom, 'scope'), _a = interval_1.projections(selCmpt), x = _a.x, y = _a.y, sx = util_1.stringValue(model.scaleName(channel_1.X)), sy = util_1.stringValue(model.scaleName(channel_1.Y)); + if (!scales_1.default.has(selCmpt)) { + events = events.map(function (e) { return (e.markname = name + interval_1.BRUSH, e); }); + } + signals.push({ + name: name + ANCHOR, + on: [{ + events: events, + update: "{x: invert(" + sx + ", x(unit)), y: invert(" + sy + ", y(unit))}" + }] + }, { + name: delta, + on: [{ + events: events, + force: true, + update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))' + }] + }); + if (x !== null) { + onDelta(model, selCmpt, 'x', 'width', signals); + } + if (y !== null) { + onDelta(model, selCmpt, 'y', 'height', signals); + } + var size = signals.filter(function (s) { return s.name === name + interval_1.SIZE; }); + if (size.length) { + var sname = size[0].name; + size[0].on.push({ + events: { signal: delta }, + update: "{x: " + sname + ".x, y: " + sname + ".y, " + + ("width: " + sname + ".width * " + delta + " , ") + + ("height: " + sname + ".height * " + delta + "}") + }); + } + return signals; + } +}; +exports.default = zoom; +function onDelta(model, selCmpt, channel, size, signals) { + var name = selCmpt.name, signal = signals.filter(function (s) { return s.name === name + '_' + channel; })[0], scales = scales_1.default.has(selCmpt), base = scales ? scales_1.domain(model, channel) : signal.name, anchor = "" + name + ANCHOR + "." + channel, delta = name + DELTA, scale = util_1.stringValue(model.scaleName(channel)), range = "[" + anchor + " + (" + base + "[0] - " + anchor + ") * " + delta + ", " + + (anchor + " + (" + base + "[1] - " + anchor + ") * " + delta + "]"), lo = "invert(" + scale + (channel === channel_1.X ? ', 0' : ", unit." + size) + ')', hi = "invert(" + scale + (channel === channel_1.X ? ", unit." + size : ', 0') + ')'; + signal.on.push({ + events: { signal: delta }, + update: scales ? range : "clampRange(" + range + ", " + lo + ", " + hi + ")" + }); +} + +},{"../../../channel":13,"../../../util":88,"../interval":56,"./scales":63,"vega-parser/src/parsers/event-selector":6}],68:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var axis_1 = require("../axis"); +var channel_1 = require("../channel"); +var config_1 = require("../config"); +var data_1 = require("../data"); +var encoding_1 = require("../encoding"); +var vlEncoding = require("../encoding"); // TODO: remove +var fielddef_1 = require("../fielddef"); +var mark_1 = require("../mark"); +var scale_1 = require("../scale"); +var util_1 = require("../util"); +var parse_1 = require("./axis/parse"); +var common_1 = require("./common"); +var data_2 = require("./data/data"); +var parse_2 = require("./legend/parse"); +var layout_1 = require("./layout"); +var model_1 = require("./model"); +var mark_2 = require("./mark/mark"); +var init_1 = require("./scale/init"); +var parse_3 = require("./scale/parse"); +var stack_1 = require("../stack"); +var selection_1 = require("./selection/selection"); +var init_2 = require("./mark/init"); +/** + * Internal model of Vega-Lite specification for the compiler. + */ +var UnitModel = (function (_super) { + tslib_1.__extends(UnitModel, _super); + function UnitModel(spec, parent, parentGivenName) { + var _this = _super.call(this, spec, parent, parentGivenName) || this; + _this.selection = {}; + _this.scales = {}; + _this.axes = {}; + _this.legends = {}; + _this.children = []; + // use top-level width / height or parent's top-level width / height + // FIXME: once facet supports width/height, this is no longer correct! + var providedWidth = spec.width !== undefined ? spec.width : + parent ? parent['width'] : undefined; // only exists if parent is layer + var providedHeight = spec.height !== undefined ? spec.height : + parent ? parent['height'] : undefined; // only exists if parent is layer + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = _this.encoding = encoding_1.dropInvalidFieldDefs(mark, spec.encoding || {}); + // TODO?: ideally we should use config only inside this constructor + var config = _this.config = _this.initConfig(spec.config, parent); + // calculate stack properties + _this.stack = stack_1.stack(mark, encoding, config.stack); + _this.scales = _this.initScales(mark, encoding, config, providedWidth, providedHeight); + _this.markDef = init_2.initMarkDef(spec.mark, encoding, _this.scales, config); + _this.encoding = init_2.initEncoding(mark, encoding, _this.stack, config); + _this.axes = _this.initAxes(encoding, config); + _this.legends = _this.initLegend(encoding, config); + // Selections will be initialized upon parse. + _this.selection = spec.selection; + // width / height + var _a = _this.initSize(mark, _this.scales, providedWidth, providedHeight, config.cell, config.scale), _b = _a.width, width = _b === void 0 ? _this.width : _b, _c = _a.height, height = _c === void 0 ? _this.height : _c; + _this.width = width; + _this.height = height; + return _this; + } + /** + * Init config by merging config from parent and, if applicable, from facet config + */ + UnitModel.prototype.initConfig = function (specConfig, parent) { + var config = util_1.mergeDeep(util_1.duplicate(config_1.defaultConfig), parent ? parent.config : {}, specConfig); + var hasFacetParent = false; + while (parent !== null) { + if (parent.isFacet()) { + hasFacetParent = true; + break; + } + parent = parent.parent; + } + if (hasFacetParent) { + config.cell = util_1.extend({}, config.cell, config.facet.cell); + } + return config; + }; + UnitModel.prototype.initScales = function (mark, encoding, config, topLevelWidth, topLevelHeight) { + var xyRangeSteps = []; + return channel_1.UNIT_SCALE_CHANNELS.reduce(function (scales, channel) { + if (vlEncoding.channelHasField(encoding, channel) || + (channel === channel_1.X && vlEncoding.channelHasField(encoding, channel_1.X2)) || + (channel === channel_1.Y && vlEncoding.channelHasField(encoding, channel_1.Y2))) { + var scale = scales[channel] = init_1.default(channel, encoding[channel], config, mark, channel === channel_1.X ? topLevelWidth : channel === channel_1.Y ? topLevelHeight : undefined, xyRangeSteps // for determine point / bar size + ); + if (channel === channel_1.X || channel === channel_1.Y) { + if (scale.rangeStep) { + xyRangeSteps.push(scale.rangeStep); + } + } + } + return scales; + }, {}); + }; + // TODO: consolidate this with scale? Current scale range is in parseScale (later), + // but not in initScale because scale range depends on size, + // but size depends on scale type and rangeStep + UnitModel.prototype.initSize = function (mark, scale, width, height, cellConfig, scaleConfig) { + if (width === undefined) { + if (scale[channel_1.X]) { + if (!scale_1.hasDiscreteDomain(scale[channel_1.X].type) || !scale[channel_1.X].rangeStep) { + width = cellConfig.width; + } // else: Do nothing, use dynamic width. + } + else { + if (mark === mark_1.TEXT) { + // for text table without x/y scale we need wider rangeStep + width = scaleConfig.textXRangeStep; + } + else { + if (typeof scaleConfig.rangeStep === 'string') { + throw new Error('_initSize does not handle string rangeSteps'); + } + width = scaleConfig.rangeStep; + } + } + } + if (height === undefined) { + if (scale[channel_1.Y]) { + if (!scale_1.hasDiscreteDomain(scale[channel_1.Y].type) || !scale[channel_1.Y].rangeStep) { + height = cellConfig.height; + } // else: Do nothing, use dynamic height . + } + else { + if (typeof scaleConfig.rangeStep === 'string') { + throw new Error('_initSize does not handle string rangeSteps'); + } + height = scaleConfig.rangeStep; + } + } + return { width: width, height: height }; + }; + UnitModel.prototype.initAxes = function (encoding, config) { + return [channel_1.X, channel_1.Y].reduce(function (_axis, channel) { + // Position Axis + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef) || + (channel === channel_1.X && fielddef_1.isFieldDef(encoding.x2)) || + (channel === channel_1.Y && fielddef_1.isFieldDef(encoding.y2))) { + var axisSpec = fielddef_1.isFieldDef(channelDef) ? channelDef.axis : null; + // We no longer support false in the schema, but we keep false here for backward compatability. + if (axisSpec !== null && axisSpec !== false) { + var vlOnlyAxisProperties_1 = {}; + axis_1.VL_ONLY_AXIS_PROPERTIES.forEach(function (property) { + if (config.axis[property] !== undefined) { + vlOnlyAxisProperties_1[property] = config.axis[property]; + } + }); + _axis[channel] = tslib_1.__assign({}, vlOnlyAxisProperties_1, axisSpec); + } + } + return _axis; + }, {}); + }; + UnitModel.prototype.initLegend = function (encoding, config) { + return channel_1.NONSPATIAL_SCALE_CHANNELS.reduce(function (_legend, channel) { + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef)) { + var legendSpec = channelDef.legend; + if (legendSpec !== null && legendSpec !== false) { + _legend[channel] = tslib_1.__assign({}, legendSpec); + } + } + return _legend; + }, {}); + }; + UnitModel.prototype.parseData = function () { + this.component.data = data_2.parseUnitData(this); + }; + UnitModel.prototype.parseSelection = function () { + this.component.selection = selection_1.parseUnitSelection(this, this.selection); + }; + UnitModel.prototype.parseLayoutData = function () { + this.component.layout = layout_1.parseUnitLayout(this); + }; + UnitModel.prototype.parseScale = function () { + this.component.scales = parse_3.default(this); + }; + UnitModel.prototype.parseMark = function () { + this.component.mark = mark_2.parseMark(this); + }; + UnitModel.prototype.parseAxis = function () { + this.component.axes = parse_1.parseAxisComponent(this, [channel_1.X, channel_1.Y]); + }; + UnitModel.prototype.parseAxisGroup = function () { + return null; + }; + UnitModel.prototype.parseGridGroup = function () { + return null; + }; + UnitModel.prototype.parseLegend = function () { + this.component.legends = parse_2.parseLegendComponent(this); + }; + UnitModel.prototype.assembleSignals = function (signals) { + return selection_1.assembleUnitSignals(this, signals); + }; + UnitModel.prototype.assembleSelectionData = function (data) { + return selection_1.assembleUnitData(this, data); + }; + UnitModel.prototype.assembleData = function (data) { + return data_2.assembleData(this, data); + }; + UnitModel.prototype.assembleLayout = function (layoutData) { + return layout_1.assembleLayout(this, layoutData); + }; + UnitModel.prototype.assembleMarks = function () { + return selection_1.assembleUnitMarks(this, this.component.mark); + }; + UnitModel.prototype.assembleParentGroupProperties = function (cellConfig) { + return common_1.applyConfig({}, cellConfig, mark_1.FILL_STROKE_CONFIG.concat(['clip'])); + }; + UnitModel.prototype.channels = function () { + return channel_1.UNIT_CHANNELS; + }; + UnitModel.prototype.getMapping = function () { + return this.encoding; + }; + UnitModel.prototype.toSpec = function (excludeConfig, excludeData) { + var encoding = util_1.duplicate(this.encoding); + var spec; + spec = { + mark: this.markDef, + encoding: encoding + }; + if (!excludeConfig) { + spec.config = util_1.duplicate(this.config); + } + if (!excludeData) { + spec.data = util_1.duplicate(this.data); + } + // remove defaults + return spec; + }; + UnitModel.prototype.mark = function () { + return this.markDef.type; + }; + UnitModel.prototype.channelHasField = function (channel) { + return vlEncoding.channelHasField(this.encoding, channel); + }; + UnitModel.prototype.fieldDef = function (channel) { + // TODO: remove this || {} + // Currently we have it to prevent null pointer exception. + return this.encoding[channel] || {}; + }; + /** Get "field" reference for vega */ + UnitModel.prototype.field = function (channel, opt) { + if (opt === void 0) { opt = {}; } + var fieldDef = this.fieldDef(channel); + if (fieldDef.bin) { + opt = util_1.extend({ + binSuffix: scale_1.hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start' + }, opt); + } + return fielddef_1.field(fieldDef, opt); + }; + UnitModel.prototype.dataTable = function () { + return this.dataName(vlEncoding.isAggregate(this.encoding) ? data_1.SUMMARY : data_1.SOURCE); + }; + UnitModel.prototype.isUnit = function () { + return true; + }; + return UnitModel; +}(model_1.Model)); +exports.UnitModel = UnitModel; + +},{"../axis":11,"../channel":13,"../config":70,"../data":71,"../encoding":73,"../fielddef":75,"../mark":79,"../scale":80,"../stack":84,"../util":88,"./axis/parse":15,"./common":17,"./data/data":20,"./layout":33,"./legend/parse":35,"./mark/init":39,"./mark/mark":41,"./model":49,"./scale/init":51,"./scale/parse":52,"./selection/selection":58,"tslib":5}],69:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var mark_1 = require("./mark"); +exports.ERRORBAR = 'error-bar'; +/** + * Registry index for all composite mark's normalizer + */ +var normalizerRegistry = {}; +function add(mark, normalizer) { + normalizerRegistry[mark] = normalizer; +} +exports.add = add; +function remove(mark) { + delete normalizerRegistry[mark]; +} +exports.remove = remove; +/** + * Transform a unit spec with composite mark into a normal layer spec. + */ +function normalize( + // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels. + spec) { + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var normalizer = normalizerRegistry[mark]; + if (normalizer) { + return normalizer(spec); + } + throw new Error("Unregistered composite mark " + mark); +} +exports.normalize = normalize; +add(exports.ERRORBAR, function (spec) { + var _m = spec.mark, encoding = spec.encoding, outerSpec = tslib_1.__rest(spec, ["mark", "encoding"]); + var _s = encoding.size, encodingWithoutSize = tslib_1.__rest(encoding, ["size"]); + var _x2 = encoding.x2, _y2 = encoding.y2, encodingWithoutX2Y2 = tslib_1.__rest(encoding, ["x2", "y2"]); + return tslib_1.__assign({}, outerSpec, { layer: [ + { + mark: 'rule', + encoding: encodingWithoutSize + }, { + mark: 'tick', + encoding: encodingWithoutX2Y2 + }, { + mark: 'tick', + encoding: tslib_1.__assign({}, encodingWithoutX2Y2, (encoding.x2 ? { x: encoding.x2 } : {}), (encoding.y2 ? { y: encoding.y2 } : {})) + } + ] }); +}); + +},{"./mark":79,"tslib":5}],70:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var axis_1 = require("./axis"); +var legend_1 = require("./legend"); +var mark = require("./mark"); +var scale_1 = require("./scale"); +var selection_1 = require("./selection"); +exports.defaultCellConfig = { + width: 200, + height: 200, + fill: 'transparent' +}; +exports.defaultFacetCellConfig = { + stroke: '#ccc', + strokeWidth: 1 +}; +var defaultFacetGridConfig = { + color: '#000000', + opacity: 0.4, + offset: 0 +}; +exports.defaultFacetConfig = { + axis: {}, + grid: defaultFacetGridConfig, + cell: exports.defaultFacetCellConfig +}; +exports.defaultOverlayConfig = { + line: false, + pointStyle: { filled: true }, + lineStyle: {} +}; +exports.defaultConfig = { + padding: 5, + numberFormat: 's', + timeFormat: '%b %d, %Y', + countTitle: 'Number of Records', + cell: exports.defaultCellConfig, + mark: mark.defaultMarkConfig, + area: {}, + bar: mark.defaultBarConfig, + circle: {}, + line: {}, + point: {}, + rect: {}, + rule: {}, + square: {}, + text: mark.defaultTextConfig, + tick: mark.defaultTickConfig, + overlay: exports.defaultOverlayConfig, + scale: scale_1.defaultScaleConfig, + axis: axis_1.defaultAxisConfig, + legend: legend_1.defaultLegendConfig, + facet: exports.defaultFacetConfig, + selection: selection_1.defaultConfig +}; + +},{"./axis":11,"./legend":77,"./mark":79,"./scale":80,"./selection":81}],71:[function(require,module,exports){ +/* + * Constants and utilities for data. + */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isUrlData(data) { + return !!data['url']; +} +exports.isUrlData = isUrlData; +function isInlineData(data) { + return !!data['values']; +} +exports.isInlineData = isInlineData; +function isNamedData(data) { + return !!data['name']; +} +exports.isNamedData = isNamedData; +exports.SUMMARY = 'summary'; +exports.SOURCE = 'source'; +exports.STACKED = 'stacked'; +exports.LAYOUT = 'layout'; + +},{}],72:[function(require,module,exports){ +// DateTime definition object +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var log = require("./log"); +/* + * A designated year that starts on Sunday. + */ +var SUNDAY_YEAR = 2006; +function isDateTime(o) { + return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day || + !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds); +} +exports.isDateTime = isDateTime; +exports.MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; +exports.SHORT_MONTHS = exports.MONTHS.map(function (m) { return m.substr(0, 3); }); +exports.DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday']; +exports.SHORT_DAYS = exports.DAYS.map(function (d) { return d.substr(0, 3); }); +function normalizeQuarter(q) { + if (util_1.isNumber(q)) { + if (q > 4) { + log.warn(log.message.invalidTimeUnit('quarter', q)); + } + // We accept 1-based quarter, so need to readjust to 0-based quarter + return (q - 1) + ''; + } + else { + // Invalid quarter + throw new Error(log.message.invalidTimeUnit('quarter', q)); + } +} +function normalizeMonth(m) { + if (util_1.isNumber(m)) { + // We accept 1-based month, so need to readjust to 0-based month + return (m - 1) + ''; + } + else { + var lowerM = m.toLowerCase(); + var monthIndex = exports.MONTHS.indexOf(lowerM); + if (monthIndex !== -1) { + return monthIndex + ''; // 0 for january, ... + } + var shortM = lowerM.substr(0, 3); + var shortMonthIndex = exports.SHORT_MONTHS.indexOf(shortM); + if (shortMonthIndex !== -1) { + return shortMonthIndex + ''; + } + // Invalid month + throw new Error(log.message.invalidTimeUnit('month', m)); + } +} +function normalizeDay(d) { + if (util_1.isNumber(d)) { + // mod so that this can be both 0-based where 0 = sunday + // and 1-based where 7=sunday + return (d % 7) + ''; + } + else { + var lowerD = d.toLowerCase(); + var dayIndex = exports.DAYS.indexOf(lowerD); + if (dayIndex !== -1) { + return dayIndex + ''; // 0 for january, ... + } + var shortD = lowerD.substr(0, 3); + var shortDayIndex = exports.SHORT_DAYS.indexOf(shortD); + if (shortDayIndex !== -1) { + return shortDayIndex + ''; + } + // Invalid day + throw new Error(log.message.invalidTimeUnit('day', d)); + } +} +function timestamp(d, normalize) { + var date = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date + // FIXME support UTC + if (d.day !== undefined) { + if (util_1.keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = util_1.duplicate(d); + delete d.day; + } + else { + // Use a year that has 1/1 as Sunday so we can setDate below + date.setFullYear(SUNDAY_YEAR); + var day = normalize ? normalizeDay(d.day) : d.day; + date.setDate(+day + 1); // +1 since date start at 1 in JS + } + } + if (d.year !== undefined) { + date.setFullYear(d.year); + } + if (d.quarter !== undefined) { + var quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + date.setMonth(+quarter * 3); + } + if (d.month !== undefined) { + var month = normalize ? normalizeMonth(d.month) : d.month; + date.setMonth(+month); + } + if (d.date !== undefined) { + date.setDate(d.date); + } + if (d.hours !== undefined) { + date.setHours(d.hours); + } + if (d.minutes !== undefined) { + date.setMinutes(d.minutes); + } + if (d.seconds !== undefined) { + date.setSeconds(d.seconds); + } + if (d.milliseconds !== undefined) { + date.setMilliseconds(d.milliseconds); + } + return date.getTime(); +} +exports.timestamp = timestamp; +/** + * Return Vega Expression for a particular date time. + * @param d + * @param normalize whether to normalize quarter, month, day. + */ +function dateTimeExpr(d, normalize) { + if (normalize === void 0) { normalize = false; } + var units = []; + if (normalize && d.day !== undefined) { + if (util_1.keys(d).length > 1) { + log.warn(log.message.droppedDay(d)); + d = util_1.duplicate(d); + delete d.day; + } + } + if (d.year !== undefined) { + units.push(d.year); + } + else if (d.day !== undefined) { + // Set year to 2006 for working with day since January 1 2006 is a Sunday + units.push(SUNDAY_YEAR); + } + else { + units.push(0); + } + if (d.month !== undefined) { + var month = normalize ? normalizeMonth(d.month) : d.month; + units.push(month); + } + else if (d.quarter !== undefined) { + var quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter; + units.push(quarter + '*3'); + } + else { + units.push(0); // months start at zero in JS + } + if (d.date !== undefined) { + units.push(d.date); + } + else if (d.day !== undefined) { + // HACK: Day only works as a standalone unit + // This is only correct because we always set year to 2006 for day + var day = normalize ? normalizeDay(d.day) : d.day; + units.push(day + '+1'); + } + else { + units.push(1); // Date starts at 1 in JS + } + // Note: can't use TimeUnit enum here as importing it will create + // circular dependency problem! + for (var _i = 0, _a = ['hours', 'minutes', 'seconds', 'milliseconds']; _i < _a.length; _i++) { + var timeUnit = _a[_i]; + if (d[timeUnit] !== undefined) { + units.push(d[timeUnit]); + } + else { + units.push(0); + } + } + return 'datetime(' + units.join(', ') + ')'; +} +exports.dateTimeExpr = dateTimeExpr; + +},{"./log":78,"./util":88}],73:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// utility for encoding mapping +var fielddef_1 = require("./fielddef"); +var channel_1 = require("./channel"); +var util_1 = require("./util"); +var log = require("./log"); +function channelHasField(encoding, channel) { + var channelDef = encoding && encoding[channel]; + if (channelDef) { + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.field; }); + } + else { + return fielddef_1.isFieldDef(channelDef); + } + } + return false; +} +exports.channelHasField = channelHasField; +function isAggregate(encoding) { + return util_1.some(channel_1.CHANNELS, function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + if (util_1.isArray(channelDef)) { + return util_1.some(channelDef, function (fieldDef) { return !!fieldDef.aggregate; }); + } + else { + return fielddef_1.isFieldDef(channelDef) && !!channelDef.aggregate; + } + } + return false; + }); +} +exports.isAggregate = isAggregate; +function dropInvalidFieldDefs(mark, encoding) { + // clone to prevent side effect to the original spec + encoding = util_1.duplicate(encoding); + Object.keys(encoding).forEach(function (channel) { + if (!channel_1.supportMark(channel, mark)) { + // Drop unsupported channel + log.warn(log.message.incompatibleChannel(channel, mark)); + delete encoding[channel]; + return; + } + // Drop line's size if the field is aggregated. + if (channel === 'size' && mark === 'line') { + var channelDef = encoding[channel]; + if (fielddef_1.isFieldDef(channelDef) && channelDef.aggregate) { + log.warn(log.message.incompatibleChannel(channel, mark, 'when the field is aggregated.')); + delete encoding[channel]; + } + return; + } + if (util_1.isArray(encoding[channel])) { + // Array of fieldDefs for detail channel (or production rule) + encoding[channel] = encoding[channel].reduce(function (channelDefs, channelDef) { + if (!fielddef_1.isFieldDef(channelDef) && !fielddef_1.isValueDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + } + else { + channelDefs.push(fielddef_1.normalize(channelDef, channel)); + } + return channelDefs; + }, []); + } + else { + var channelDef = encoding[channel]; + if (!fielddef_1.isFieldDef(channelDef) && !fielddef_1.isValueDef(channelDef)) { + log.warn(log.message.emptyFieldDef(channelDef, channel)); + delete encoding[channel]; + return; + } + fielddef_1.normalize(channelDef, channel); + } + }); + return encoding; +} +exports.dropInvalidFieldDefs = dropInvalidFieldDefs; +function isRanged(encoding) { + return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2)); +} +exports.isRanged = isRanged; +function fieldDefs(encoding) { + var arr = []; + channel_1.CHANNELS.forEach(function (channel) { + if (channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + arr.push(fieldDef); + }); + } + }); + return arr; +} +exports.fieldDefs = fieldDefs; +; +function forEach(mapping, f, thisArg) { + if (!mapping) { + return; + } + Object.keys(mapping).forEach(function (c) { + var channel = c; + if (util_1.isArray(mapping[channel])) { + mapping[channel].forEach(function (channelDef) { + f.call(thisArg, channelDef, channel); + }); + } + else { + f.call(thisArg, mapping[channel], channel); + } + }); +} +exports.forEach = forEach; +function reduce(mapping, f, init, thisArg) { + if (!mapping) { + return init; + } + return Object.keys(mapping).reduce(function (r, c) { + var channel = c; + if (util_1.isArray(mapping[channel])) { + return mapping[channel].reduce(function (r1, channelDef) { + return f.call(thisArg, r1, channelDef, channel); + }, r); + } + else { + return f.call(thisArg, r, mapping[channel], channel); + } + }, init); +} +exports.reduce = reduce; + +},{"./channel":13,"./fielddef":75,"./log":78,"./util":88}],74:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +},{}],75:[function(require,module,exports){ +// utility for a field definition object +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var channel_1 = require("./channel"); +var log = require("./log"); +var timeunit_1 = require("./timeunit"); +var type_1 = require("./type"); +; +function isFieldDef(channelDef) { + return channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count'); +} +exports.isFieldDef = isFieldDef; +function isValueDef(channelDef) { + return channelDef && 'value' in channelDef && channelDef['value'] !== undefined; +} +exports.isValueDef = isValueDef; +function field(fieldDef, opt) { + if (opt === void 0) { opt = {}; } + var field = fieldDef.field; + var prefix = opt.prefix; + var suffix = opt.suffix; + if (isCount(fieldDef)) { + field = 'count_*'; + } + else { + var fn = undefined; + if (!opt.nofn) { + if (fieldDef.bin) { + fn = 'bin'; + suffix = opt.binSuffix; + } + else if (fieldDef.aggregate) { + fn = String(opt.aggregate || fieldDef.aggregate); + } + else if (fieldDef.timeUnit) { + fn = String(fieldDef.timeUnit); + } + } + if (!!fn) { + field = fn + "_" + field; + } + } + if (!!suffix) { + field = field + "_" + suffix; + } + if (!!prefix) { + field = prefix + "_" + field; + } + if (opt.datum) { + field = "datum[\"" + field + "\"]"; + } + return field; +} +exports.field = field; +function isDiscrete(fieldDef) { + switch (fieldDef.type) { + case 'nominal': + case 'ordinal': + return true; + case 'quantitative': + return !!fieldDef.bin; + case 'temporal': + // TODO: deal with custom scale type case. + return timeunit_1.isDiscreteByDefault(fieldDef.timeUnit); + } + throw new Error(log.message.invalidFieldType(fieldDef.type)); +} +exports.isDiscrete = isDiscrete; +function isContinuous(fieldDef) { + return !isDiscrete(fieldDef); +} +exports.isContinuous = isContinuous; +function isCount(fieldDef) { + return fieldDef.aggregate === 'count'; +} +exports.isCount = isCount; +function title(fieldDef, config) { + if (fieldDef.title != null) { + return fieldDef.title; + } + if (isCount(fieldDef)) { + return config.countTitle; + } + var fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin'); + if (fn) { + return fn.toString().toUpperCase() + '(' + fieldDef.field + ')'; + } + else { + return fieldDef.field; + } +} +exports.title = title; +function defaultType(fieldDef, channel) { + if (!!fieldDef.timeUnit) { + return 'temporal'; + } + if (!!fieldDef.bin) { + return 'quantitative'; + } + switch (channel_1.rangeType(channel)) { + case 'continuous': + return 'quantitative'; + case 'discrete': + return 'nominal'; + case 'flexible': + return 'nominal'; + default: + return 'quantitative'; + } +} +exports.defaultType = defaultType; +/** + * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing. + */ +function normalize(fieldDef, channel) { + // If a fieldDef contains a field, we need type. + if (isFieldDef(fieldDef)) { + // convert short type to full type + var fullType = type_1.getFullName(fieldDef.type); + if (fullType) { + fieldDef.type = fullType; + } + else { + // If type is empty / invalid, then augment with default type + var newType = defaultType(fieldDef, channel); + log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType)); + fieldDef.type = newType; + } + var _a = channelCompatibility(fieldDef, channel), compatible = _a.compatible, warning = _a.warning; + if (!compatible) { + log.warn(warning); + } + } + return fieldDef; +} +exports.normalize = normalize; +var COMPATIBLE = { compatible: true }; +function channelCompatibility(fieldDef, channel) { + switch (channel) { + case 'row': + case 'column': + if (isContinuous(fieldDef) && !fieldDef.timeUnit) { + // TODO:(https://github.com/vega/vega-lite/issues/2011): + // with timeUnit it's not always strictly continuous + return { + compatible: false, + warning: log.message.facetChannelShouldBeDiscrete(channel) + }; + } + return COMPATIBLE; + case 'x': + case 'y': + case 'color': + case 'text': + case 'detail': + return COMPATIBLE; + case 'opacity': + case 'size': + case 'x2': + case 'y2': + if (isDiscrete(fieldDef) && !fieldDef.bin) { + return { + compatible: false, + warning: "Channel " + channel + " should not be used with discrete field." + }; + } + return COMPATIBLE; + case 'shape': + if (fieldDef.type !== 'nominal') { + return { + compatible: false, + warning: 'Shape channel should be used with nominal data only' + }; + } + else { + return COMPATIBLE; + } + case 'order': + if (fieldDef.type === 'nominal') { + return { + compatible: false, + warning: "Channel order is inappropriate for nominal field, which has no inherent order." + }; + } + return COMPATIBLE; + } + throw new Error('channelCompatability not implemented for channel ' + channel); +} +exports.channelCompatibility = channelCompatibility; + +},{"./channel":13,"./log":78,"./timeunit":85,"./type":87}],76:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("./datetime"); +var fielddef_1 = require("./fielddef"); +var timeunit_1 = require("./timeunit"); +var util_1 = require("./util"); +function isEqualFilter(filter) { + return filter && !!filter.field && filter.equal !== undefined; +} +exports.isEqualFilter = isEqualFilter; +function isRangeFilter(filter) { + if (filter && !!filter.field) { + if (util_1.isArray(filter.range) && filter.range.length === 2) { + return true; + } + } + return false; +} +exports.isRangeFilter = isRangeFilter; +function isOneOfFilter(filter) { + return filter && !!filter.field && (util_1.isArray(filter.oneOf) || + util_1.isArray(filter.in) // backward compatibility + ); +} +exports.isOneOfFilter = isOneOfFilter; +function expression(filter) { + if (util_1.isString(filter)) { + return filter; + } + else { + var fieldExpr = filter.timeUnit ? + // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly. + // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline + // TODO: support utc + ('time(' + timeunit_1.fieldExpr(filter.timeUnit, filter.field) + ')') : + fielddef_1.field(filter, { datum: true }); + if (isEqualFilter(filter)) { + return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit); + } + else if (isOneOfFilter(filter)) { + // "oneOf" was formerly "in" -- so we need to add backward compatibility + var oneOf = filter.oneOf || filter['in']; + return 'indexof([' + + oneOf.map(function (v) { return valueExpr(v, filter.timeUnit); }).join(',') + + '], ' + fieldExpr + ') !== -1'; + } + else if (isRangeFilter(filter)) { + var lower = filter.range[0]; + var upper = filter.range[1]; + if (lower !== null && upper !== null) { + return 'inrange(' + fieldExpr + ', ' + + valueExpr(lower, filter.timeUnit) + ', ' + + valueExpr(upper, filter.timeUnit) + ')'; + } + else if (lower !== null) { + return fieldExpr + ' >= ' + lower; + } + else if (upper !== null) { + return fieldExpr + ' <= ' + upper; + } + } + } + return undefined; +} +exports.expression = expression; +function valueExpr(v, timeUnit) { + if (datetime_1.isDateTime(v)) { + var expr = datetime_1.dateTimeExpr(v, true); + return 'time(' + expr + ')'; + } + if (timeunit_1.isSingleTimeUnit(timeUnit)) { + var datetime = {}; + datetime[timeUnit] = v; + var expr = datetime_1.dateTimeExpr(datetime, true); + return 'time(' + expr + ')'; + } + return JSON.stringify(v); +} + +},{"./datetime":72,"./fielddef":75,"./timeunit":85,"./util":88}],77:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultLegendConfig = { + orient: undefined, +}; +exports.LEGEND_PROPERTIES = ['entryPadding', 'format', 'offset', 'orient', 'tickCount', 'title', 'type', 'values', 'zindex']; + +},{}],78:[function(require,module,exports){ +/// +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Vega-Lite's singleton logger utility. + */ +var vega_util_1 = require("vega-util"); +/** + * Main (default) Vega Logger instance for Vega-Lite + */ +var main = vega_util_1.logger(vega_util_1.Warn); +var current = main; +/** + * Logger tool for checking if the code throws correct warning + */ +var LocalLogger = (function () { + function LocalLogger() { + this.warns = []; + this.infos = []; + this.debugs = []; + } + LocalLogger.prototype.level = function () { + return this; + }; + LocalLogger.prototype.warn = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.warns).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.info = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.infos).push.apply(_a, args); + return this; + var _a; + }; + LocalLogger.prototype.debug = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + (_a = this.debugs).push.apply(_a, args); + return this; + var _a; + }; + return LocalLogger; +}()); +exports.LocalLogger = LocalLogger; +function runLocalLogger(f) { + var localLogger = current = new LocalLogger(); + f(localLogger); + reset(); +} +exports.runLocalLogger = runLocalLogger; +function wrap(f) { + return function () { + var logger = current = new LocalLogger(); + f(logger); + reset(); + }; +} +exports.wrap = wrap; +/** + * Set the singleton logger to be a custom logger + */ +function set(logger) { + current = logger; + return current; +} +exports.set = set; +/** + * Reset the main logger to use the default Vega Logger + */ +function reset() { + current = main; + return current; +} +exports.reset = reset; +function warn() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.warn.apply(current, arguments); +} +exports.warn = warn; +function info() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.info.apply(current, arguments); +} +exports.info = info; +function debug() { + var _ = []; + for (var _i = 0; _i < arguments.length; _i++) { + _[_i] = arguments[_i]; + } + current.debug.apply(current, arguments); +} +exports.debug = debug; +/** + * Collection of all Vega-Lite Error Messages + */ +var message; +(function (message) { + message.INVALID_SPEC = 'Invalid spec'; + // DATA + message.DEPRECATED_FILTER_NULL = 'filterNull is deprecated. Please use filterInvalid instead.'; + // ENCODING & FACET + function invalidFieldType(type) { + return "Invalid field type \"" + type + "\""; + } + message.invalidFieldType = invalidFieldType; + function emptyOrInvalidFieldType(type, channel, newType) { + return "Invalid field type (" + type + ") for channel " + channel + ", using " + newType + " instead."; + } + message.emptyOrInvalidFieldType = emptyOrInvalidFieldType; + function emptyFieldDef(fieldDef, channel) { + return "Dropping " + JSON.stringify(fieldDef) + " from channel " + channel + " since it does not contain data field or value."; + } + message.emptyFieldDef = emptyFieldDef; + function incompatibleChannel(channel, markOrFacet, when) { + return channel + " dropped as it is incompatible with " + markOrFacet + + when ? "when " + when : ''; + } + message.incompatibleChannel = incompatibleChannel; + function facetChannelShouldBeDiscrete(channel) { + return channel + " encoding should be discrete (ordinal / nominal / binned)."; + } + message.facetChannelShouldBeDiscrete = facetChannelShouldBeDiscrete; + function discreteChannelCannotEncode(channel, type) { + return "Using discrete channel " + channel + " to encode " + type + " field can be misleading as it does not encode " + (type === 'ordinal' ? 'order' : 'magnitude') + "."; + } + message.discreteChannelCannotEncode = discreteChannelCannotEncode; + // Mark + message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.'; + function unclearOrientContinuous(mark) { + return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode continous fields. In this case, we use vertical by default'; + } + message.unclearOrientContinuous = unclearOrientContinuous; + function unclearOrientDiscreteOrEmpty(mark) { + return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode discrete or empty fields.'; + } + message.unclearOrientDiscreteOrEmpty = unclearOrientDiscreteOrEmpty; + function orientOverridden(original, actual) { + return "Specified orient " + original + " overridden with " + actual; + } + message.orientOverridden = orientOverridden; + // SCALE + message.CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain'; + function cannotUseScalePropertyWithNonColor(prop) { + return "Cannot use " + prop + " with non-color channel."; + } + message.cannotUseScalePropertyWithNonColor = cannotUseScalePropertyWithNonColor; + function unaggregateDomainHasNoEffectForRawField(fieldDef) { + return "Using unaggregated domain with raw field has no effect (" + JSON.stringify(fieldDef) + ")."; + } + message.unaggregateDomainHasNoEffectForRawField = unaggregateDomainHasNoEffectForRawField; + function unaggregateDomainWithNonSharedDomainOp(aggregate) { + return "Unaggregated domain not applicable for " + aggregate + " since it produces values outside the origin domain of the source data."; + } + message.unaggregateDomainWithNonSharedDomainOp = unaggregateDomainWithNonSharedDomainOp; + function unaggregatedDomainWithLogScale(fieldDef) { + return "Unaggregated domain is currently unsupported for log scale (" + JSON.stringify(fieldDef) + ")."; + } + message.unaggregatedDomainWithLogScale = unaggregatedDomainWithLogScale; + message.CANNOT_USE_RANGE_WITH_POSITION = 'Cannot use custom range with x or y channel. Please customize width, height, padding, or rangeStep instead.'; + message.CANNOT_USE_PADDING_WITH_FACET = 'Cannot use padding with facet\'s scale. Please use spacing instead.'; + function cannotUseRangePropertyWithFacet(propName) { + return "Cannot use custom " + propName + " with row or column channel. Please use width, height, or spacing instead."; + } + message.cannotUseRangePropertyWithFacet = cannotUseRangePropertyWithFacet; + function rangeStepDropped(channel) { + return "rangeStep for " + channel + " is dropped as top-level " + (channel === 'x' ? 'width' : 'height') + " is provided."; + } + message.rangeStepDropped = rangeStepDropped; + function cannotOverrideBinScaleType(channel, defaultScaleType) { + return "Cannot override scale type for binned channel " + channel + ". We are using " + defaultScaleType + " scale instead."; + } + message.cannotOverrideBinScaleType = cannotOverrideBinScaleType; + function scaleTypeNotWorkWithChannel(channel, scaleType, defaultScaleType) { + return "Channel " + channel + " does not work with " + scaleType + " scale. We are using " + defaultScaleType + " scale instead."; + } + message.scaleTypeNotWorkWithChannel = scaleTypeNotWorkWithChannel; + function scalePropertyNotWorkWithScaleType(scaleType, propName, channel) { + return channel + "-scale's \"" + propName + "\" is dropped as it does not work with " + scaleType + " scale."; + } + message.scalePropertyNotWorkWithScaleType = scalePropertyNotWorkWithScaleType; + function scaleTypeNotWorkWithMark(mark, scaleType) { + return "Scale type \"" + scaleType + "\" does not work with mark " + mark + "."; + } + message.scaleTypeNotWorkWithMark = scaleTypeNotWorkWithMark; + message.INVAID_DOMAIN = 'Invalid scale domain'; + message.UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains'; + // AXIS + message.INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.'; + // STACK + function cannotStackRangedMark(channel) { + return "Cannot stack " + channel + " if there is already " + channel + "2"; + } + message.cannotStackRangedMark = cannotStackRangedMark; + function cannotStackNonLinearScale(scaleType) { + return "Cannot stack non-linear scale (" + scaleType + ")"; + } + message.cannotStackNonLinearScale = cannotStackNonLinearScale; + function cannotStackNonSummativeAggregate(aggregate) { + return "Cannot stack when the aggregate function is non-summative (" + aggregate + ")"; + } + message.cannotStackNonSummativeAggregate = cannotStackNonSummativeAggregate; + // TIMEUNIT + function invalidTimeUnit(unitName, value) { + return "Invalid " + unitName + ": " + value; + } + message.invalidTimeUnit = invalidTimeUnit; + function dayReplacedWithDate(fullTimeUnit) { + return "Time unit \"" + fullTimeUnit + "\" is not supported. We are replacing it with " + + (fullTimeUnit + '').replace('day', 'date') + '.'; + } + message.dayReplacedWithDate = dayReplacedWithDate; + function droppedDay(d) { + return 'Dropping day from datetime ' + JSON.stringify(d) + + ' as day cannot be combined with other units.'; + } + message.droppedDay = droppedDay; +})(message = exports.message || (exports.message = {})); + +},{"vega-util":8}],79:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +var Mark; +(function (Mark) { + Mark.AREA = 'area'; + Mark.BAR = 'bar'; + Mark.LINE = 'line'; + Mark.POINT = 'point'; + Mark.RECT = 'rect'; + Mark.RULE = 'rule'; + Mark.TEXT = 'text'; + Mark.TICK = 'tick'; + Mark.CIRCLE = 'circle'; + Mark.SQUARE = 'square'; +})(Mark = exports.Mark || (exports.Mark = {})); +exports.AREA = Mark.AREA; +exports.BAR = Mark.BAR; +exports.LINE = Mark.LINE; +exports.POINT = Mark.POINT; +exports.TEXT = Mark.TEXT; +exports.TICK = Mark.TICK; +exports.RECT = Mark.RECT; +exports.RULE = Mark.RULE; +exports.CIRCLE = Mark.CIRCLE; +exports.SQUARE = Mark.SQUARE; +exports.PRIMITIVE_MARKS = [exports.AREA, exports.BAR, exports.LINE, exports.POINT, exports.TEXT, exports.TICK, exports.RECT, exports.RULE, exports.CIRCLE, exports.SQUARE]; +function isMarkDef(mark) { + return mark['type']; +} +exports.isMarkDef = isMarkDef; +var PRIMITIVE_MARK_INDEX = util_1.toSet(exports.PRIMITIVE_MARKS); +function isPrimitiveMark(mark) { + var markType = isMarkDef(mark) ? mark.type : mark; + return markType in PRIMITIVE_MARK_INDEX; +} +exports.isPrimitiveMark = isPrimitiveMark; +exports.STROKE_CONFIG = ['stroke', 'strokeWidth', + 'strokeDash', 'strokeDashOffset', 'strokeOpacity']; +exports.FILL_CONFIG = ['fill', 'fillOpacity']; +exports.FILL_STROKE_CONFIG = [].concat(exports.STROKE_CONFIG, exports.FILL_CONFIG); +exports.defaultMarkConfig = { + color: '#4c78a8', +}; +exports.defaultBarConfig = { + binSpacing: 1, + continuousBandSize: 2 +}; +exports.defaultTextConfig = { + baseline: 'middle', +}; +exports.defaultTickConfig = { + thickness: 1 +}; + +},{"./util":88}],80:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("./log"); +var util_1 = require("./util"); +var ScaleType; +(function (ScaleType) { + // Continuous - Quantitative + ScaleType.LINEAR = 'linear'; + ScaleType.BIN_LINEAR = 'bin-linear'; + ScaleType.LOG = 'log'; + ScaleType.POW = 'pow'; + ScaleType.SQRT = 'sqrt'; + // Continuous - Time + ScaleType.TIME = 'time'; + ScaleType.UTC = 'utc'; + // sequential + ScaleType.SEQUENTIAL = 'sequential'; + // Quantile, Quantize, threshold + ScaleType.QUANTILE = 'quantile'; + ScaleType.QUANTIZE = 'quantize'; + ScaleType.THRESHOLD = 'threshold'; + ScaleType.ORDINAL = 'ordinal'; + ScaleType.BIN_ORDINAL = 'bin-ordinal'; + ScaleType.POINT = 'point'; + ScaleType.BAND = 'band'; +})(ScaleType = exports.ScaleType || (exports.ScaleType = {})); +exports.SCALE_TYPES = [ + // Continuous - Quantitative + 'linear', 'bin-linear', 'log', 'pow', 'sqrt', + // Continuous - Time + 'time', 'utc', + // Sequential + 'sequential', + // Discrete + 'ordinal', 'bin-ordinal', 'point', 'band', +]; +exports.CONTINUOUS_TO_CONTINUOUS_SCALES = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc']; +var CONTINUOUS_TO_CONTINUOUS_INDEX = util_1.toSet(exports.CONTINUOUS_TO_CONTINUOUS_SCALES); +exports.CONTINUOUS_DOMAIN_SCALES = exports.CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]); +var CONTINUOUS_DOMAIN_INDEX = util_1.toSet(exports.CONTINUOUS_DOMAIN_SCALES); +exports.DISCRETE_DOMAIN_SCALES = ['ordinal', 'bin-ordinal', 'point', 'band']; +var DISCRETE_DOMAIN_INDEX = util_1.toSet(exports.DISCRETE_DOMAIN_SCALES); +var BIN_SCALES_INDEX = util_1.toSet(['bin-linear', 'bin-ordinal']); +exports.TIME_SCALE_TYPES = ['time', 'utc']; +function hasDiscreteDomain(type) { + return type in DISCRETE_DOMAIN_INDEX; +} +exports.hasDiscreteDomain = hasDiscreteDomain; +function isBinScale(type) { + return type in BIN_SCALES_INDEX; +} +exports.isBinScale = isBinScale; +function hasContinuousDomain(type) { + return type in CONTINUOUS_DOMAIN_INDEX; +} +exports.hasContinuousDomain = hasContinuousDomain; +function isContinuousToContinuous(type) { + return type in CONTINUOUS_TO_CONTINUOUS_INDEX; +} +exports.isContinuousToContinuous = isContinuousToContinuous; +exports.defaultScaleConfig = { + round: true, + textXRangeStep: 90, + rangeStep: 21, + pointPadding: 0.5, + bandPaddingInner: 0.1, + facetSpacing: 16, + minFontSize: 8, + maxFontSize: 40, + minOpacity: 0.3, + maxOpacity: 0.8, + // FIXME: revise if these *can* become ratios of rangeStep + minSize: 9, + minStrokeWidth: 1, + maxStrokeWidth: 4, + shapes: ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down'] +}; +function isExtendedScheme(scheme) { + return scheme && !!scheme['name']; +} +exports.isExtendedScheme = isExtendedScheme; +exports.SCALE_PROPERTIES = [ + 'type', 'domain', 'range', 'round', 'rangeStep', 'scheme', 'padding', 'paddingInner', 'paddingOuter', 'clamp', 'nice', + 'exponent', 'zero', 'interpolate' +]; +function scaleTypeSupportProperty(scaleType, propName) { + switch (propName) { + case 'type': + case 'domain': + case 'range': + case 'scheme': + return true; + case 'interpolate': + return scaleType === 'linear' || scaleType === 'bin-linear'; + case 'round': + return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point'; + case 'rangeStep': + case 'padding': + case 'paddingOuter': + return util_1.contains(['point', 'band'], scaleType); + case 'paddingInner': + return scaleType === 'band'; + case 'clamp': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential'; + case 'nice': + return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType === 'quantize'; + case 'exponent': + return scaleType === 'pow' || scaleType === 'log'; + case 'zero': + // TODO: what about quantize, threshold? + return scaleType === 'bin-ordinal' || (!hasDiscreteDomain(scaleType) && !util_1.contains(['log', 'time', 'utc'], scaleType)); + } + /* istanbul ignore next: should never reach here*/ + throw new Error("Invalid scale property " + propName + "."); +} +exports.scaleTypeSupportProperty = scaleTypeSupportProperty; +/** + * Returns undefined if the input channel supports the input scale property name + */ +function channelScalePropertyIncompatability(channel, propName) { + switch (propName) { + case 'range': + // User should not customize range for position and facet channel directly. + if (channel === 'x' || channel === 'y') { + return log.message.CANNOT_USE_RANGE_WITH_POSITION; + } + if (channel === 'row' || channel === 'column') { + return log.message.cannotUseRangePropertyWithFacet('range'); + } + return undefined; // GOOD! + // band / point + case 'rangeStep': + if (channel === 'row' || channel === 'column') { + return log.message.cannotUseRangePropertyWithFacet('rangeStep'); + } + return undefined; // GOOD! + case 'padding': + case 'paddingInner': + case 'paddingOuter': + if (channel === 'row' || channel === 'column') { + /* + * We do not use d3 scale's padding for row/column because padding there + * is a ratio ([0, 1]) and it causes the padding to be decimals. + * Therefore, we manually calculate "spacing" in the layout by ourselves. + */ + return log.message.CANNOT_USE_PADDING_WITH_FACET; + } + return undefined; // GOOD! + case 'interpolate': + case 'scheme': + if (channel !== 'color') { + return log.message.cannotUseScalePropertyWithNonColor(channel); + } + return undefined; + case 'type': + case 'domain': + case 'round': + case 'clamp': + case 'exponent': + case 'nice': + case 'zero': + // These channel do not have strict requirement + return undefined; // GOOD! + } + /* istanbul ignore next: it should never reach here */ + throw new Error('Invalid scale property "${propName}".'); +} +exports.channelScalePropertyIncompatability = channelScalePropertyIncompatability; + +},{"./log":78,"./util":88}],81:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultConfig = { + single: { on: 'click', fields: ['_id'] }, + multi: { on: 'click', fields: ['_id'], toggle: 'event.shiftKey' }, + interval: { + on: '[mousedown, window:mouseup] > window:mousemove!', + encodings: ['x', 'y'], + translate: '[mousedown, window:mouseup] > window:mousemove!', + zoom: 'wheel' + } +}; + +},{}],82:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isSortField(sort) { + return !!sort && !!sort['field'] && !!sort['op']; +} +exports.isSortField = isSortField; + +},{}],83:[function(require,module,exports){ +/* Package of defining Vega-lite Specification's json schema at its utility functions */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var config_1 = require("./config"); +var compositeMark = require("./compositemark"); +var encoding_1 = require("./encoding"); +var log = require("./log"); +var mark_1 = require("./mark"); +var stack_1 = require("./stack"); +var channel_1 = require("./channel"); +var vlEncoding = require("./encoding"); +var util_1 = require("./util"); +/* Custom type guards */ +function isFacetSpec(spec) { + return spec['facet'] !== undefined; +} +exports.isFacetSpec = isFacetSpec; +function isFacetedUnitSpec(spec) { + if (isUnitSpec(spec)) { + var hasRow = encoding_1.channelHasField(spec.encoding, channel_1.ROW); + var hasColumn = encoding_1.channelHasField(spec.encoding, channel_1.COLUMN); + return hasRow || hasColumn; + } + return false; +} +exports.isFacetedUnitSpec = isFacetedUnitSpec; +function isUnitSpec(spec) { + return !!spec['mark']; +} +exports.isUnitSpec = isUnitSpec; +function isLayerSpec(spec) { + return spec['layer'] !== undefined; +} +exports.isLayerSpec = isLayerSpec; +/** + * Decompose extended unit specs into composition of pure unit specs. + */ +// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize +function normalize(spec) { + if (isFacetSpec(spec)) { + return normalizeFacet(spec); + } + if (isLayerSpec(spec)) { + return normalizeLayer(spec); + } + if (isFacetedUnitSpec(spec)) { + return normalizeFacetedUnit(spec); + } + if (isUnitSpec(spec)) { + return normalizeNonFacetUnit(spec); + } + throw new Error(log.message.INVALID_SPEC); +} +exports.normalize = normalize; +function normalizeNonFacet(spec) { + if (isLayerSpec(spec)) { + return normalizeLayer(spec); + } + return normalizeNonFacetUnit(spec); +} +function normalizeFacet(spec) { + var subspec = spec.spec, rest = tslib_1.__rest(spec, ["spec"]); + return tslib_1.__assign({}, rest, { spec: normalizeNonFacet(subspec) }); +} +function normalizeLayer(spec) { + var layer = spec.layer, rest = tslib_1.__rest(spec, ["layer"]); + return tslib_1.__assign({}, rest, { layer: layer.map(normalizeNonFacet) }); +} +function normalizeFacetedUnit(spec) { + // New encoding in the inside spec should not contain row / column + // as row/column should be moved to facet + var _a = spec.encoding, row = _a.row, column = _a.column, encoding = tslib_1.__rest(_a, ["row", "column"]); + // Mark and encoding should be moved into the inner spec + var mark = spec.mark, _ = spec.encoding, outerSpec = tslib_1.__rest(spec, ["mark", "encoding"]); + return tslib_1.__assign({}, outerSpec, { facet: tslib_1.__assign({}, (row ? { row: row } : {}), (column ? { column: column } : {})), spec: normalizeNonFacetUnit({ + mark: mark, + encoding: encoding + }) }); +} +function isNonFacetUnitSpecWithPrimitiveMark(spec) { + return mark_1.isPrimitiveMark(spec.mark); +} +function normalizeNonFacetUnit(spec) { + var config = spec.config; + var overlayConfig = config && config.overlay; + var overlayWithLine = overlayConfig && spec.mark === mark_1.AREA && + util_1.contains(['linepoint', 'line'], overlayConfig.area); + var overlayWithPoint = overlayConfig && ((overlayConfig.line && spec.mark === mark_1.LINE) || + (overlayConfig.area === 'linepoint' && spec.mark === mark_1.AREA)); + if (isNonFacetUnitSpecWithPrimitiveMark(spec)) { + // TODO: thoroughly test + if (encoding_1.isRanged(spec.encoding)) { + return normalizeRangedUnit(spec); + } + // TODO: consider moving this to become another case of compositeMark + if (overlayWithPoint || overlayWithLine) { + return normalizeOverlay(spec, overlayWithPoint, overlayWithLine); + } + return spec; // Nothing to normalize + } + else { + return compositeMark.normalize(spec); + } +} +function normalizeRangedUnit(spec) { + var hasX = encoding_1.channelHasField(spec.encoding, channel_1.X); + var hasY = encoding_1.channelHasField(spec.encoding, channel_1.Y); + var hasX2 = encoding_1.channelHasField(spec.encoding, channel_1.X2); + var hasY2 = encoding_1.channelHasField(spec.encoding, channel_1.Y2); + if ((hasX2 && !hasX) || (hasY2 && !hasY)) { + var normalizedSpec = util_1.duplicate(spec); + if (hasX2 && !hasX) { + normalizedSpec.encoding.x = normalizedSpec.encoding.x2; + delete normalizedSpec.encoding.x2; + } + if (hasY2 && !hasY) { + normalizedSpec.encoding.y = normalizedSpec.encoding.y2; + delete normalizedSpec.encoding.y2; + } + return normalizedSpec; + } + return spec; +} +// FIXME(#1804): rewrite this +function normalizeOverlay(spec, overlayWithPoint, overlayWithLine) { + var outerProps = ['name', 'description', 'data', 'transform']; + var baseSpec = util_1.omit(spec, outerProps.concat('config')); + var baseConfig = util_1.duplicate(spec.config); + delete baseConfig.overlay; + // TODO: remove shape, size + // Need to copy stack config to overlayed layer + var stacked = stack_1.stack(spec.mark, spec.encoding, spec.config ? spec.config.stack : undefined); + var layerSpec = tslib_1.__assign({}, util_1.pick(spec, outerProps), { layer: [baseSpec] }, (util_1.keys(baseConfig).length > 0 ? { config: baseConfig } : {})); + if (overlayWithLine) { + // TODO: add name with suffix + var lineSpec = util_1.duplicate(baseSpec); + lineSpec.mark = mark_1.LINE; + // TODO: remove shape, size + var markConfig = util_1.extend({}, config_1.defaultOverlayConfig.lineStyle, spec.config.overlay.lineStyle, stacked ? { stacked: stacked.offset } : null); + if (util_1.keys(markConfig).length > 0) { + lineSpec.config = { mark: markConfig }; + } + layerSpec.layer.push(lineSpec); + } + if (overlayWithPoint) { + // TODO: add name with suffix + var pointSpec = util_1.duplicate(baseSpec); + pointSpec.mark = mark_1.POINT; + var markConfig = util_1.extend({}, config_1.defaultOverlayConfig.pointStyle, spec.config.overlay.pointStyle, stacked ? { stacked: stacked.offset } : null); + if (util_1.keys(markConfig).length > 0) { + pointSpec.config = { mark: markConfig }; + } + layerSpec.layer.push(pointSpec); + } + return layerSpec; +} +// TODO: add vl.spec.validate & move stuff from vl.validate to here +/* Accumulate non-duplicate fieldDefs in a dictionary */ +function accumulate(dict, fieldDefs) { + fieldDefs.forEach(function (fieldDef) { + // Consider only pure fieldDef properties (ignoring scale, axis, legend) + var pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce(function (f, key) { + if (fieldDef[key] !== undefined) { + f[key] = fieldDef[key]; + } + return f; + }, {}); + var key = util_1.hash(pureFieldDef); + dict[key] = dict[key] || fieldDef; + }); + return dict; +} +/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */ +function fieldDefIndex(spec, dict) { + if (dict === void 0) { dict = {}; } + // TODO: Support repeat and concat + if (isLayerSpec(spec)) { + spec.layer.forEach(function (layer) { + if (isUnitSpec(layer)) { + accumulate(dict, vlEncoding.fieldDefs(layer.encoding)); + } + else { + fieldDefIndex(layer, dict); + } + }); + } + else if (isFacetSpec(spec)) { + accumulate(dict, vlEncoding.fieldDefs(spec.facet)); + fieldDefIndex(spec.spec, dict); + } + else { + accumulate(dict, vlEncoding.fieldDefs(spec.encoding)); + } + return dict; +} +/* Returns all non-duplicate fieldDefs in a spec in a flat array */ +function fieldDefs(spec) { + return util_1.vals(fieldDefIndex(spec)); +} +exports.fieldDefs = fieldDefs; +; +function isStacked(spec) { + if (mark_1.isPrimitiveMark(spec.mark)) { + return stack_1.stack(spec.mark, spec.encoding, spec.config ? spec.config.stack : undefined) !== null; + } + return false; +} +exports.isStacked = isStacked; + +},{"./channel":13,"./compositemark":69,"./config":70,"./encoding":73,"./log":78,"./mark":79,"./stack":84,"./util":88,"tslib":5}],84:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var log = require("./log"); +var aggregate_1 = require("./aggregate"); +var channel_1 = require("./channel"); +var encoding_1 = require("./encoding"); +var fielddef_1 = require("./fielddef"); +var mark_1 = require("./mark"); +var scale_1 = require("./scale"); +var util_1 = require("./util"); +exports.STACKABLE_MARKS = [mark_1.BAR, mark_1.AREA, mark_1.RULE, mark_1.POINT, mark_1.CIRCLE, mark_1.SQUARE, mark_1.LINE, mark_1.TEXT, mark_1.TICK]; +exports.STACK_BY_DEFAULT_MARKS = [mark_1.BAR, mark_1.AREA]; +// Note: CompassQL uses this method and only pass in required properties of each argument object. +// If required properties change, make sure to update CompassQL. +function stack(m, encoding, stackConfig) { + var mark = mark_1.isMarkDef(m) ? m.type : m; + // Should have stackable mark + if (!util_1.contains(exports.STACKABLE_MARKS, mark)) { + return null; + } + // Should be aggregate plot + if (!encoding_1.isAggregate(encoding)) { + return null; + } + // Should have grouping level of detail + var stackBy = channel_1.STACK_GROUP_CHANNELS.reduce(function (sc, channel) { + if (encoding_1.channelHasField(encoding, channel)) { + var channelDef = encoding[channel]; + (util_1.isArray(channelDef) ? channelDef : [channelDef]).forEach(function (fieldDef) { + if (fielddef_1.isFieldDef(fieldDef) && !fieldDef.aggregate) { + sc.push({ + channel: channel, + fieldDef: fieldDef + }); + } + }); + } + return sc; + }, []); + if (stackBy.length === 0) { + return null; + } + // Has only one aggregate axis + var hasXField = fielddef_1.isFieldDef(encoding.x); + var hasYField = fielddef_1.isFieldDef(encoding.y); + var xIsAggregate = fielddef_1.isFieldDef(encoding.x) && !!encoding.x.aggregate; + var yIsAggregate = fielddef_1.isFieldDef(encoding.y) && !!encoding.y.aggregate; + if (xIsAggregate !== yIsAggregate) { + var fieldChannel = xIsAggregate ? channel_1.X : channel_1.Y; + var fieldDef = encoding[fieldChannel]; + var fieldChannelAggregate = fieldDef.aggregate; + var fieldChannelScale = fieldDef.scale; + var stackOffset = null; + if (fieldDef.stack !== undefined) { + stackOffset = fieldDef.stack; + } + else if (util_1.contains(exports.STACK_BY_DEFAULT_MARKS, mark)) { + // Bar and Area with sum ops are automatically stacked by default + stackOffset = stackConfig === undefined ? 'zero' : stackConfig; + } + else { + stackOffset = stackConfig; + } + if (!stackOffset || stackOffset === 'none') { + return null; + } + // If stacked, check if it qualifies for stacking (and log warning if not qualified.) + if (fieldChannelScale && fieldChannelScale.type && fieldChannelScale.type !== scale_1.ScaleType.LINEAR) { + log.warn(log.message.cannotStackNonLinearScale(fieldChannelScale.type)); + return null; + } + if (encoding_1.channelHasField(encoding, fieldChannel === channel_1.X ? channel_1.X2 : channel_1.Y2)) { + log.warn(log.message.cannotStackRangedMark(fieldChannel)); + return null; + } + if (!util_1.contains(aggregate_1.SUM_OPS, fieldChannelAggregate)) { + log.warn(log.message.cannotStackNonSummativeAggregate(fieldChannelAggregate)); + return null; + } + return { + groupbyChannel: xIsAggregate ? (hasYField ? channel_1.Y : null) : (hasXField ? channel_1.X : null), + fieldChannel: fieldChannel, + stackBy: stackBy, + offset: stackOffset + }; + } + return null; +} +exports.stack = stack; + +},{"./aggregate":10,"./channel":13,"./encoding":73,"./fielddef":75,"./log":78,"./mark":79,"./scale":80,"./util":88}],85:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var datetime_1 = require("./datetime"); +var util_1 = require("./util"); +var log = require("./log"); +var TimeUnit; +(function (TimeUnit) { + TimeUnit.YEAR = 'year'; + TimeUnit.MONTH = 'month'; + TimeUnit.DAY = 'day'; + TimeUnit.DATE = 'date'; + TimeUnit.HOURS = 'hours'; + TimeUnit.MINUTES = 'minutes'; + TimeUnit.SECONDS = 'seconds'; + TimeUnit.MILLISECONDS = 'milliseconds'; + TimeUnit.YEARMONTH = 'yearmonth'; + TimeUnit.YEARMONTHDATE = 'yearmonthdate'; + TimeUnit.YEARMONTHDATEHOURS = 'yearmonthdatehours'; + TimeUnit.YEARMONTHDATEHOURSMINUTES = 'yearmonthdatehoursminutes'; + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS = 'yearmonthdatehoursminutesseconds'; + // MONTHDATE always include 29 February since we use year 0th (which is a leap year); + TimeUnit.MONTHDATE = 'monthdate'; + TimeUnit.HOURSMINUTES = 'hoursminutes'; + TimeUnit.HOURSMINUTESSECONDS = 'hoursminutesseconds'; + TimeUnit.MINUTESSECONDS = 'minutesseconds'; + TimeUnit.SECONDSMILLISECONDS = 'secondsmilliseconds'; + TimeUnit.QUARTER = 'quarter'; + TimeUnit.YEARQUARTER = 'yearquarter'; + TimeUnit.QUARTERMONTH = 'quartermonth'; + TimeUnit.YEARQUARTERMONTH = 'yearquartermonth'; +})(TimeUnit = exports.TimeUnit || (exports.TimeUnit = {})); +/** Time Unit that only corresponds to only one part of Date objects. */ +exports.SINGLE_TIMEUNITS = [ + TimeUnit.YEAR, + TimeUnit.QUARTER, + TimeUnit.MONTH, + TimeUnit.DAY, + TimeUnit.DATE, + TimeUnit.HOURS, + TimeUnit.MINUTES, + TimeUnit.SECONDS, + TimeUnit.MILLISECONDS, +]; +var SINGLE_TIMEUNIT_INDEX = exports.SINGLE_TIMEUNITS.reduce(function (d, timeUnit) { + d[timeUnit] = true; + return d; +}, {}); +function isSingleTimeUnit(timeUnit) { + return !!SINGLE_TIMEUNIT_INDEX[timeUnit]; +} +exports.isSingleTimeUnit = isSingleTimeUnit; +/** + * Converts a date to only have the measurements relevant to the specified unit + * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00' + * Note: the base date is Jan 01 1900 00:00:00 + */ +function convert(unit, date) { + var result = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date + exports.SINGLE_TIMEUNITS.forEach(function (singleUnit) { + if (containsTimeUnit(unit, singleUnit)) { + switch (singleUnit) { + case TimeUnit.DAY: + throw new Error('Cannot convert to TimeUnits containing \'day\''); + case TimeUnit.YEAR: + result.setFullYear(date.getFullYear()); + break; + case TimeUnit.QUARTER: + // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3) + result.setMonth((Math.floor(date.getMonth() / 3)) * 3); + break; + case TimeUnit.MONTH: + result.setMonth(date.getMonth()); + break; + case TimeUnit.DATE: + result.setDate(date.getDate()); + break; + case TimeUnit.HOURS: + result.setHours(date.getHours()); + break; + case TimeUnit.MINUTES: + result.setMinutes(date.getMinutes()); + break; + case TimeUnit.SECONDS: + result.setSeconds(date.getSeconds()); + break; + case TimeUnit.MILLISECONDS: + result.setMilliseconds(date.getMilliseconds()); + break; + } + } + }); + return result; +} +exports.convert = convert; +exports.MULTI_TIMEUNITS = [ + TimeUnit.YEARQUARTER, + TimeUnit.YEARQUARTERMONTH, + TimeUnit.YEARMONTH, + TimeUnit.YEARMONTHDATE, + TimeUnit.YEARMONTHDATEHOURS, + TimeUnit.YEARMONTHDATEHOURSMINUTES, + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, + TimeUnit.QUARTERMONTH, + TimeUnit.HOURSMINUTES, + TimeUnit.HOURSMINUTESSECONDS, + TimeUnit.MINUTESSECONDS, + TimeUnit.SECONDSMILLISECONDS, +]; +var MULTI_TIMEUNIT_INDEX = exports.MULTI_TIMEUNITS.reduce(function (d, timeUnit) { + d[timeUnit] = true; + return d; +}, {}); +function isMultiTimeUnit(timeUnit) { + return !!MULTI_TIMEUNIT_INDEX[timeUnit]; +} +exports.isMultiTimeUnit = isMultiTimeUnit; +exports.TIMEUNITS = [ + TimeUnit.YEAR, + TimeUnit.QUARTER, + TimeUnit.MONTH, + TimeUnit.DAY, + TimeUnit.DATE, + TimeUnit.HOURS, + TimeUnit.MINUTES, + TimeUnit.SECONDS, + TimeUnit.MILLISECONDS, + TimeUnit.YEARQUARTER, + TimeUnit.YEARQUARTERMONTH, + TimeUnit.YEARMONTH, + TimeUnit.YEARMONTHDATE, + TimeUnit.YEARMONTHDATEHOURS, + TimeUnit.YEARMONTHDATEHOURSMINUTES, + TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS, + TimeUnit.QUARTERMONTH, + TimeUnit.HOURSMINUTES, + TimeUnit.HOURSMINUTESSECONDS, + TimeUnit.MINUTESSECONDS, + TimeUnit.SECONDSMILLISECONDS +]; +/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */ +function containsTimeUnit(fullTimeUnit, timeUnit) { + var fullTimeUnitStr = fullTimeUnit.toString(); + var timeUnitStr = timeUnit.toString(); + var index = fullTimeUnitStr.indexOf(timeUnitStr); + return index > -1 && + (timeUnit !== TimeUnit.SECONDS || + index === 0 || + fullTimeUnitStr.charAt(index - 1) !== 'i' // exclude milliseconds + ); +} +exports.containsTimeUnit = containsTimeUnit; +/** + * Returns Vega expresssion for a given timeUnit and fieldRef + */ +function fieldExpr(fullTimeUnit, field) { + var fieldRef = "datum[\"" + field + "\"]"; + function func(timeUnit) { + if (timeUnit === TimeUnit.QUARTER) { + // quarter starting at 0 (0,3,6,9). + return "(quarter(" + fieldRef + ")-1)"; + } + else { + return timeUnit + "(" + fieldRef + ")"; + } + } + var d = exports.SINGLE_TIMEUNITS.reduce(function (_d, tu) { + if (containsTimeUnit(fullTimeUnit, tu)) { + _d[tu] = func(tu); + } + return _d; + }, {}); + if (d.day && util_1.keys(d).length > 1) { + log.warn(log.message.dayReplacedWithDate(fullTimeUnit)); + delete d.day; + d.date = func(TimeUnit.DATE); + } + return datetime_1.dateTimeExpr(d); +} +exports.fieldExpr = fieldExpr; +/** returns the smallest nice unit for scale.nice */ +function smallestUnit(timeUnit) { + if (!timeUnit) { + return undefined; + } + if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) { + return 'second'; + } + if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) { + return 'minute'; + } + if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) { + return 'hour'; + } + if (containsTimeUnit(timeUnit, TimeUnit.DAY) || + containsTimeUnit(timeUnit, TimeUnit.DATE)) { + return 'day'; + } + if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) { + return 'month'; + } + if (containsTimeUnit(timeUnit, TimeUnit.YEAR)) { + return 'year'; + } + return undefined; +} +exports.smallestUnit = smallestUnit; +/** returns the signal expression used for axis labels for a time unit */ +function formatExpression(timeUnit, field, shortTimeLabels) { + if (!timeUnit) { + return undefined; + } + var dateComponents = []; + var expression = ''; + var hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR); + if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) { + // special expression for quarter as prefix + expression = "'Q' + quarter(" + field + ")"; + } + if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) { + // By default use short month name + dateComponents.push(shortTimeLabels !== false ? '%b' : '%B'); + } + if (containsTimeUnit(timeUnit, TimeUnit.DAY)) { + dateComponents.push(shortTimeLabels ? '%a' : '%A'); + } + else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) { + dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year + } + if (hasYear) { + dateComponents.push(shortTimeLabels ? '%y' : '%Y'); + } + var timeComponents = []; + if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) { + timeComponents.push('%H'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) { + timeComponents.push('%M'); + } + if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) { + timeComponents.push('%S'); + } + if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) { + timeComponents.push('%L'); + } + var dateTimeComponents = []; + if (dateComponents.length > 0) { + dateTimeComponents.push(dateComponents.join(' ')); + } + if (timeComponents.length > 0) { + dateTimeComponents.push(timeComponents.join(':')); + } + if (dateTimeComponents.length > 0) { + if (expression) { + // Add space between quarter and main time format + expression += " + ' ' + "; + } + expression += "timeFormat(" + field + ", '" + dateTimeComponents.join(' ') + "')"; + } + // If expression is still an empty string, return undefined instead. + return expression || undefined; +} +exports.formatExpression = formatExpression; +function isDiscreteByDefault(timeUnit) { + switch (timeUnit) { + // These time unit use discrete scale by default + case 'hours': + case 'day': + case 'month': + case 'quarter': + return true; + } + return false; +} +exports.isDiscreteByDefault = isDiscreteByDefault; + +},{"./datetime":72,"./log":78,"./util":88}],86:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +},{}],87:[function(require,module,exports){ +/** Constants and utilities for data type */ +/** Data type based on level of measurement */ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var Type; +(function (Type) { + Type.QUANTITATIVE = 'quantitative'; + Type.ORDINAL = 'ordinal'; + Type.TEMPORAL = 'temporal'; + Type.NOMINAL = 'nominal'; +})(Type = exports.Type || (exports.Type = {})); +exports.QUANTITATIVE = Type.QUANTITATIVE; +exports.ORDINAL = Type.ORDINAL; +exports.TEMPORAL = Type.TEMPORAL; +exports.NOMINAL = Type.NOMINAL; +/** + * Get full, lowercase type name for a given type. + * @param type + * @return Full type name. + */ +function getFullName(type) { + if (type) { + type = type.toLowerCase(); + switch (type) { + case 'q': + case exports.QUANTITATIVE: + return 'quantitative'; + case 't': + case exports.TEMPORAL: + return 'temporal'; + case 'o': + case exports.ORDINAL: + return 'ordinal'; + case 'n': + case exports.NOMINAL: + return 'nominal'; + } + } + // If we get invalid input, return undefined type. + return undefined; +} +exports.getFullName = getFullName; + +},{}],88:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var stringify = require("json-stable-stringify"); +var vega_util_1 = require("vega-util"); +exports.extend = vega_util_1.extend; +exports.isArray = vega_util_1.isArray; +exports.isObject = vega_util_1.isObject; +exports.isNumber = vega_util_1.isNumber; +exports.isString = vega_util_1.isString; +exports.truncate = vega_util_1.truncate; +exports.toSet = vega_util_1.toSet; +exports.stringValue = vega_util_1.stringValue; +var vega_util_2 = require("vega-util"); +/** + * Creates an object composed of the picked object properties. + * + * Example: (from lodash) + * + * var object = {'a': 1, 'b': '2', 'c': 3}; + * pick(object, ['a', 'c']); + * // → {'a': 1, 'c': 3} + * + */ +function pick(obj, props) { + var copy = {}; + props.forEach(function (prop) { + if (obj.hasOwnProperty(prop)) { + copy[prop] = obj[prop]; + } + }); + return copy; +} +exports.pick = pick; +/** + * The opposite of _.pick; this method creates an object composed of the own + * and inherited enumerable string keyed properties of object that are not omitted. + */ +function omit(obj, props) { + var copy = duplicate(obj); + props.forEach(function (prop) { + delete copy[prop]; + }); + return copy; +} +exports.omit = omit; +function hash(a) { + if (vega_util_2.isString(a) || vega_util_2.isNumber(a) || isBoolean(a)) { + return String(a); + } + return stringify(a); +} +exports.hash = hash; +function contains(array, item) { + return array.indexOf(item) > -1; +} +exports.contains = contains; +/** Returns the array without the elements in item */ +function without(array, excludedItems) { + return array.filter(function (item) { return !contains(excludedItems, item); }); +} +exports.without = without; +function union(array, other) { + return array.concat(without(other, array)); +} +exports.union = union; +function reduce(obj, f, init, thisArg) { + if (obj.reduce) { + return obj.reduce.call(thisArg, f, init); + } + else { + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + init = f.call(thisArg, init, obj[k], k, obj); + } + } + return init; + } +} +exports.reduce = reduce; +/** + * Returns true if any item returns true. + */ +function some(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (f(arr[k], k, i++)) { + return true; + } + } + return false; +} +exports.some = some; +/** + * Returns true if all items return true. + */ +function every(arr, f) { + var i = 0; + for (var k = 0; k < arr.length; k++) { + if (!f(arr[k], k, i++)) { + return false; + } + } + return true; +} +exports.every = every; +function flatten(arrays) { + return [].concat.apply([], arrays); +} +exports.flatten = flatten; +/** + * recursively merges src into dest + */ +function mergeDeep(dest) { + var src = []; + for (var _i = 1; _i < arguments.length; _i++) { + src[_i - 1] = arguments[_i]; + } + for (var _a = 0, src_1 = src; _a < src_1.length; _a++) { + var s = src_1[_a]; + dest = deepMerge_(dest, s); + } + return dest; +} +exports.mergeDeep = mergeDeep; +; +// recursively merges src into dest +function deepMerge_(dest, src) { + if (typeof src !== 'object' || src === null) { + return dest; + } + for (var p in src) { + if (!src.hasOwnProperty(p)) { + continue; + } + if (src[p] === undefined) { + continue; + } + if (typeof src[p] !== 'object' || vega_util_2.isArray(src[p]) || src[p] === null) { + dest[p] = src[p]; + } + else if (typeof dest[p] !== 'object' || dest[p] === null) { + dest[p] = mergeDeep(src[p].constructor === Array ? [] : {}, src[p]); + } + else { + mergeDeep(dest[p], src[p]); + } + } + return dest; +} +function unique(values, f) { + var results = []; + var u = {}; + var v; + for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { + var val = values_1[_i]; + v = f(val); + if (v in u) { + continue; + } + u[v] = 1; + results.push(val); + } + return results; +} +exports.unique = unique; +; +/** + * Returns true if the two dictionaries disagree. Applies only to defined values. + */ +function differ(dict, other) { + for (var key in dict) { + if (dict.hasOwnProperty(key)) { + if (other[key] && dict[key] && other[key] !== dict[key]) { + return true; + } + } + } + return false; +} +exports.differ = differ; +exports.keys = Object.keys; +function vals(x) { + var _vals = []; + for (var k in x) { + if (x.hasOwnProperty(k)) { + _vals.push(x[k]); + } + } + return _vals; +} +exports.vals = vals; +; +function duplicate(obj) { + return JSON.parse(JSON.stringify(obj)); +} +exports.duplicate = duplicate; +; +function isBoolean(b) { + return b === true || b === false; +} +exports.isBoolean = isBoolean; + +},{"json-stable-stringify":1,"vega-util":8}],89:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var mark_1 = require("./mark"); +// TODO: move to vl.spec.validator? +var util_1 = require("./util"); +var mark_2 = require("./mark"); +/** + * Required Encoding Channels for each mark type + * @type {Object} + */ +exports.DEFAULT_REQUIRED_CHANNEL_MAP = { + text: ['text'], + line: ['x', 'y'], + area: ['x', 'y'] +}; +/** + * Supported Encoding Channel for each mark type + */ +exports.DEFAULT_SUPPORTED_CHANNEL_TYPE = { + bar: util_1.toSet(['row', 'column', 'x', 'y', 'size', 'color', 'detail']), + line: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + area: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + tick: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'detail']), + circle: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + square: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']), + point: util_1.toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']), + text: util_1.toSet(['row', 'column', 'size', 'color', 'text']) // TODO(#724) revise +}; +// TODO: consider if we should add validate method and +// requires ZSchema in the main vega-lite repo +/** + * Further check if encoding mapping of a spec is invalid and + * return error if it is invalid. + * + * This checks if + * (1) all the required encoding channels for the mark type are specified + * (2) all the specified encoding channels are supported by the mark type + * @param {[type]} spec [description] + * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap + * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap + * @return {String} Return one reason why the encoding is invalid, + * or null if the encoding is valid. + */ +function getEncodingMappingError(spec, requiredChannelMap, supportedChannelMap) { + if (requiredChannelMap === void 0) { requiredChannelMap = exports.DEFAULT_REQUIRED_CHANNEL_MAP; } + if (supportedChannelMap === void 0) { supportedChannelMap = exports.DEFAULT_SUPPORTED_CHANNEL_TYPE; } + var mark = mark_1.isMarkDef(spec.mark) ? spec.mark.type : spec.mark; + var encoding = spec.encoding; + var requiredChannels = requiredChannelMap[mark]; + var supportedChannels = supportedChannelMap[mark]; + for (var i in requiredChannels) { + if (!(requiredChannels[i] in encoding)) { + return 'Missing encoding channel \"' + requiredChannels[i] + + '\" for mark \"' + mark + '\"'; + } + } + for (var channel in encoding) { + if (!supportedChannels[channel]) { + return 'Encoding channel \"' + channel + + '\" is not supported by mark type \"' + mark + '\"'; + } + } + if (mark === mark_2.BAR && !encoding.x && !encoding.y) { + return 'Missing both x and y for bar'; + } + return null; +} +exports.getEncodingMappingError = getEncodingMappingError; + +},{"./mark":79,"./util":88}],90:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var util_1 = require("./util"); +function isDataRefUnionedDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && !('data' in domain); + } + return false; +} +exports.isDataRefUnionedDomain = isDataRefUnionedDomain; +function isFieldRefUnionDomain(domain) { + if (!util_1.isArray(domain)) { + return 'fields' in domain && 'data' in domain; + } + return false; +} +exports.isFieldRefUnionDomain = isFieldRefUnionDomain; +function isDataRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'field' in domain && 'data' in domain; + } + return false; +} +exports.isDataRefDomain = isDataRefDomain; +function isSignalRefDomain(domain) { + if (!util_1.isArray(domain)) { + return 'signal' in domain; + } + return false; +} +exports.isSignalRefDomain = isSignalRefDomain; +; + +},{"./util":88}],91:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.axis = require("./axis"); +exports.aggregate = require("./aggregate"); +exports.bin = require("./bin"); +exports.channel = require("./channel"); +exports.compositeMark = require("./compositemark"); +var compile_1 = require("./compile/compile"); +exports.compile = compile_1.compile; +exports.config = require("./config"); +exports.data = require("./data"); +exports.datetime = require("./datetime"); +exports.encoding = require("./encoding"); +exports.facet = require("./facet"); +exports.fieldDef = require("./fielddef"); +exports.legend = require("./legend"); +exports.mark = require("./mark"); +exports.scale = require("./scale"); +exports.sort = require("./sort"); +exports.spec = require("./spec"); +exports.stack = require("./stack"); +exports.timeUnit = require("./timeunit"); +exports.transform = require("./transform"); +exports.type = require("./type"); +exports.util = require("./util"); +exports.validate = require("./validate"); +exports.version = require('../package.json').version; + +},{"../package.json":9,"./aggregate":10,"./axis":11,"./bin":12,"./channel":13,"./compile/compile":18,"./compositemark":69,"./config":70,"./data":71,"./datetime":72,"./encoding":73,"./facet":74,"./fielddef":75,"./legend":77,"./mark":79,"./scale":80,"./sort":82,"./spec":83,"./stack":84,"./timeunit":85,"./transform":86,"./type":87,"./util":88,"./validate":89}]},{},[91])(91) +}); +//# sourceMappingURL=vega-lite.js.map diff --git a/build/vega-lite.js.map b/build/vega-lite.js.map new file mode 100644 index 0000000000..b7a2d13a9e --- /dev/null +++ b/build/vega-lite.js.map @@ -0,0 +1,191 @@ +{ + "version": 3, + "sources": [ + "node_modules/browser-pack/_prelude.js", + "node_modules/json-stable-stringify/index.js", + "node_modules/jsonify/index.js", + "node_modules/jsonify/lib/parse.js", + "node_modules/jsonify/lib/stringify.js", + "node_modules/tslib/tslib.js", + "node_modules/vega-parser/src/parsers/event-selector.js", + "node_modules/vega-parser/src/parsers/marks/marktypes.js", + "node_modules/vega-util/build/vega-util.js", + "package.json", + "src/aggregate.ts", + "src/axis.ts", + "src/bin.ts", + "src/channel.ts", + "src/compile/axis/encode.ts", + "src/compile/axis/parse.ts", + "src/compile/axis/rules.ts", + "src/compile/common.ts", + "src/compile/compile.ts", + "src/compile/data/bin.ts", + "src/compile/data/data.ts", + "src/compile/data/filter.ts", + "src/compile/data/formatparse.ts", + "src/compile/data/formula.ts", + "src/compile/data/nonpositivefilter.ts", + "src/compile/data/nullfilter.ts", + "src/compile/data/pathorder.ts", + "src/compile/data/source.ts", + "src/compile/data/stack.ts", + "src/compile/data/summary.ts", + "src/compile/data/timeunit.ts", + "src/compile/facet.ts", + "src/compile/layer.ts", + "src/compile/layout.ts", + "src/compile/legend/encode.ts", + "src/compile/legend/parse.ts", + "src/compile/legend/rules.ts", + "src/compile/mark/area.ts", + "src/compile/mark/bar.ts", + "src/compile/mark/init.ts", + "src/compile/mark/line.ts", + "src/compile/mark/mark.ts", + "src/compile/mark/mixins.ts", + "src/compile/mark/point.ts", + "src/compile/mark/rect.ts", + "src/compile/mark/rule.ts", + "src/compile/mark/text.ts", + "src/compile/mark/tick.ts", + "src/compile/mark/valueref.ts", + "src/compile/model.ts", + "src/compile/scale/domain.ts", + "src/compile/scale/init.ts", + "src/compile/scale/parse.ts", + "src/compile/scale/range.ts", + "src/compile/scale/rules.ts", + "src/compile/scale/type.ts", + "src/compile/selection/interval.ts", + "src/compile/selection/multi.ts", + "src/compile/selection/selection.ts", + "src/compile/selection/single.ts", + "src/compile/selection/transforms/inputs.ts", + "src/compile/selection/transforms/nearest.ts", + "src/compile/selection/transforms/project.ts", + "src/compile/selection/transforms/scales.ts", + "src/compile/selection/transforms/toggle.ts", + "src/compile/selection/transforms/transforms.ts", + "src/compile/selection/transforms/translate.ts", + "src/compile/selection/transforms/zoom.ts", + "src/compile/unit.ts", + "src/compositemark.ts", + "src/config.ts", + "src/data.ts", + "src/datetime.ts", + "src/encoding.ts", + "src/fielddef.ts", + "src/filter.ts", + "src/legend.ts", + "src/log.ts", + "src/mark.ts", + "src/scale.ts", + "src/selection.ts", + "src/sort.ts", + "src/spec.ts", + "src/stack.ts", + "src/timeunit.ts", + "src/type.ts", + "src/util.ts", + "src/validate.ts", + "src/vega.schema.ts", + "src/vl.ts" + ], + "names": [], + "mappings": "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", + "file": "generated.js", + "sourceRoot": "", + "sourcesContent": [ + "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o= '0' && ch <= '9') {\n string += ch;\n next();\n }\n if (ch === '.') {\n string += '.';\n while (next() && ch >= '0' && ch <= '9') {\n string += ch;\n }\n }\n if (ch === 'e' || ch === 'E') {\n string += ch;\n next();\n if (ch === '-' || ch === '+') {\n string += ch;\n next();\n }\n while (ch >= '0' && ch <= '9') {\n string += ch;\n next();\n }\n }\n number = +string;\n if (!isFinite(number)) {\n error(\"Bad number\");\n } else {\n return number;\n }\n },\n \n string = function () {\n // Parse a string value.\n var hex,\n i,\n string = '',\n uffff;\n \n // When parsing for string values, we must look for \" and \\ characters.\n if (ch === '\"') {\n while (next()) {\n if (ch === '\"') {\n next();\n return string;\n } else if (ch === '\\\\') {\n next();\n if (ch === 'u') {\n uffff = 0;\n for (i = 0; i < 4; i += 1) {\n hex = parseInt(next(), 16);\n if (!isFinite(hex)) {\n break;\n }\n uffff = uffff * 16 + hex;\n }\n string += String.fromCharCode(uffff);\n } else if (typeof escapee[ch] === 'string') {\n string += escapee[ch];\n } else {\n break;\n }\n } else {\n string += ch;\n }\n }\n }\n error(\"Bad string\");\n },\n\n white = function () {\n\n// Skip whitespace.\n\n while (ch && ch <= ' ') {\n next();\n }\n },\n\n word = function () {\n\n// true, false, or null.\n\n switch (ch) {\n case 't':\n next('t');\n next('r');\n next('u');\n next('e');\n return true;\n case 'f':\n next('f');\n next('a');\n next('l');\n next('s');\n next('e');\n return false;\n case 'n':\n next('n');\n next('u');\n next('l');\n next('l');\n return null;\n }\n error(\"Unexpected '\" + ch + \"'\");\n },\n\n value, // Place holder for the value function.\n\n array = function () {\n\n// Parse an array value.\n\n var array = [];\n\n if (ch === '[') {\n next('[');\n white();\n if (ch === ']') {\n next(']');\n return array; // empty array\n }\n while (ch) {\n array.push(value());\n white();\n if (ch === ']') {\n next(']');\n return array;\n }\n next(',');\n white();\n }\n }\n error(\"Bad array\");\n },\n\n object = function () {\n\n// Parse an object value.\n\n var key,\n object = {};\n\n if (ch === '{') {\n next('{');\n white();\n if (ch === '}') {\n next('}');\n return object; // empty object\n }\n while (ch) {\n key = string();\n white();\n next(':');\n if (Object.hasOwnProperty.call(object, key)) {\n error('Duplicate key \"' + key + '\"');\n }\n object[key] = value();\n white();\n if (ch === '}') {\n next('}');\n return object;\n }\n next(',');\n white();\n }\n }\n error(\"Bad object\");\n };\n\nvalue = function () {\n\n// Parse a JSON value. It could be an object, an array, a string, a number,\n// or a word.\n\n white();\n switch (ch) {\n case '{':\n return object();\n case '[':\n return array();\n case '\"':\n return string();\n case '-':\n return number();\n default:\n return ch >= '0' && ch <= '9' ? number() : word();\n }\n};\n\n// Return the json_parse function. It will have access to all of the above\n// functions and variables.\n\nmodule.exports = function (source, reviver) {\n var result;\n \n text = source;\n at = 0;\n ch = ' ';\n result = value();\n white();\n if (ch) {\n error(\"Syntax error\");\n }\n\n // If there is a reviver function, we recursively walk the new structure,\n // passing each name/value pair to the reviver function for possible\n // transformation, starting with a temporary root object that holds the result\n // in an empty key. If there is not a reviver function, we simply return the\n // result.\n\n return typeof reviver === 'function' ? (function walk(holder, key) {\n var k, v, value = holder[key];\n if (value && typeof value === 'object') {\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = walk(value, k);\n if (v !== undefined) {\n value[k] = v;\n } else {\n delete value[k];\n }\n }\n }\n }\n return reviver.call(holder, key, value);\n }({'': result}, '')) : result;\n};\n", + "var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n gap,\n indent,\n meta = { // table of character substitutions\n '\\b': '\\\\b',\n '\\t': '\\\\t',\n '\\n': '\\\\n',\n '\\f': '\\\\f',\n '\\r': '\\\\r',\n '\"' : '\\\\\"',\n '\\\\': '\\\\\\\\'\n },\n rep;\n\nfunction quote(string) {\n // If the string contains no control characters, no quote characters, and no\n // backslash characters, then we can safely slap some quotes around it.\n // Otherwise we must also replace the offending characters with safe escape\n // sequences.\n \n escapable.lastIndex = 0;\n return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n var c = meta[a];\n return typeof c === 'string' ? c :\n '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n }) + '\"' : '\"' + string + '\"';\n}\n\nfunction str(key, holder) {\n // Produce a string from holder[key].\n var i, // The loop counter.\n k, // The member key.\n v, // The member value.\n length,\n mind = gap,\n partial,\n value = holder[key];\n \n // If the value has a toJSON method, call it to obtain a replacement value.\n if (value && typeof value === 'object' &&\n typeof value.toJSON === 'function') {\n value = value.toJSON(key);\n }\n \n // If we were called with a replacer function, then call the replacer to\n // obtain a replacement value.\n if (typeof rep === 'function') {\n value = rep.call(holder, key, value);\n }\n \n // What happens next depends on the value's type.\n switch (typeof value) {\n case 'string':\n return quote(value);\n \n case 'number':\n // JSON numbers must be finite. Encode non-finite numbers as null.\n return isFinite(value) ? String(value) : 'null';\n \n case 'boolean':\n case 'null':\n // If the value is a boolean or null, convert it to a string. Note:\n // typeof null does not produce 'null'. The case is included here in\n // the remote chance that this gets fixed someday.\n return String(value);\n \n case 'object':\n if (!value) return 'null';\n gap += indent;\n partial = [];\n \n // Array.isArray\n if (Object.prototype.toString.apply(value) === '[object Array]') {\n length = value.length;\n for (i = 0; i < length; i += 1) {\n partial[i] = str(i, value) || 'null';\n }\n \n // Join all of the elements together, separated with commas, and\n // wrap them in brackets.\n v = partial.length === 0 ? '[]' : gap ?\n '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n '[' + partial.join(',') + ']';\n gap = mind;\n return v;\n }\n \n // If the replacer is an array, use it to select the members to be\n // stringified.\n if (rep && typeof rep === 'object') {\n length = rep.length;\n for (i = 0; i < length; i += 1) {\n k = rep[i];\n if (typeof k === 'string') {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n else {\n // Otherwise, iterate through all of the keys in the object.\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n \n // Join all of the member texts together, separated with commas,\n // and wrap them in braces.\n\n v = partial.length === 0 ? '{}' : gap ?\n '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n '{' + partial.join(',') + '}';\n gap = mind;\n return v;\n }\n}\n\nmodule.exports = function (value, replacer, space) {\n var i;\n gap = '';\n indent = '';\n \n // If the space parameter is a number, make an indent string containing that\n // many spaces.\n if (typeof space === 'number') {\n for (i = 0; i < space; i += 1) {\n indent += ' ';\n }\n }\n // If the space parameter is a string, it will be used as the indent string.\n else if (typeof space === 'string') {\n indent = space;\n }\n\n // If there is a replacer, it must be a function or an array.\n // Otherwise, throw an error.\n rep = replacer;\n if (replacer && typeof replacer !== 'function'\n && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {\n throw new Error('JSON.stringify');\n }\n \n // Make a fake root object containing our value under the key of ''.\n // Return the result of stringifying the value.\n return str('', {'': value});\n};\n", + "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [0, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function (m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n };\r\n\r\n __values = function (o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), q = [], c, i;\r\n return i = { next: verb(\"next\"), \"throw\": verb(\"throw\"), \"return\": verb(\"return\") }, i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }\r\n function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }\r\n function step(r) { r.done ? settle(c[2], r) : r.value[0] === \"yield\" ? settle(c[2], { value: r.value[1], done: false }) : Promise.resolve(r.value[1]).then(r.value[0] === \"delegate\" ? delegate : fulfill, reject); }\r\n function delegate(r) { step(r.done ? r : { value: [\"yield\", r.value], done: false }); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { c = void 0, f(v), next(); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i = { next: verb(\"next\"), \"throw\": verb(\"throw\", function (e) { throw e; }), \"return\": verb(\"return\", function (v) { return { value: v, done: true }; }) };\r\n return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { return function (v) { return { value: [\"delegate\", (o[n] || f).call(o, v)], done: false }; }; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator];\r\n return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n});", + "import {isMarkType} from './marks/marktypes';\n\n/**\n * Parse an event selector string.\n * Returns an array of event stream definitions.\n */\nexport default function(selector, source) {\n DEFAULT_SOURCE = source || VIEW;\n return parseMerge(selector.trim()).map(parseSelector);\n}\n\nvar VIEW = 'view',\n LBRACK = '[',\n RBRACK = ']',\n LBRACE = '{',\n RBRACE = '}',\n COLON = ':',\n COMMA = ',',\n NAME = '@',\n GT = '>';\n\nvar ILLEGAL = /[\\[\\]\\{\\}]/,\n DEFAULT_SOURCE;\n\nfunction find(s, i, endChar, pushChar, popChar) {\n var count = 0,\n n = s.length,\n c;\n for (; i= 0) --count;\n else if (pushChar && pushChar.indexOf(c) >= 0) ++count;\n }\n return i;\n}\n\nfunction parseMerge(s) {\n var output = [],\n start = 0,\n n = s.length,\n i = 0;\n\n while (i < n) {\n i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE);\n output.push(s.substring(start, i).trim());\n start = ++i;\n }\n\n if (output.length === 0) {\n throw 'Empty event selector: ' + s;\n }\n return output;\n}\n\nfunction parseSelector(s) {\n return s[0] === '['\n ? parseBetween(s)\n : parseStream(s);\n}\n\nfunction parseBetween(s) {\n var start = 1,\n n = s.length,\n i = 1,\n b, stream;\n\n i = find(s, i, RBRACK, LBRACK, RBRACK);\n if (i === n) {\n throw 'Empty between selector: ' + s;\n }\n\n b = parseMerge(s.substring(start, i));\n if (b.length !== 2) {\n throw 'Between selector must have two elements: ' + s;\n }\n\n s = s.slice(i + 1).trim();\n if (s[0] !== GT) {\n throw 'Expected \\'>\\' after between selector: ' + s;\n }\n\n b = b.map(parseSelector);\n\n stream = parseSelector(s.slice(1).trim());\n if (stream.between) {\n return {\n between: b,\n stream: stream\n };\n } else {\n stream.between = b;\n }\n\n return stream;\n}\n\nfunction parseStream(s) {\n var stream = {source: DEFAULT_SOURCE},\n source = [],\n throttle = [0, 0],\n markname = 0,\n start = 0,\n n = s.length,\n i = 0, j,\n filter;\n\n // extract throttle from end\n if (s[n-1] === RBRACE) {\n i = s.lastIndexOf(LBRACE);\n if (i >= 0) {\n try {\n throttle = parseThrottle(s.substring(i+1, n-1));\n } catch (e) {\n throw 'Invalid throttle specification: ' + s;\n }\n s = s.slice(0, i).trim();\n n = s.length;\n } else throw 'Unmatched right brace: ' + s;\n i = 0;\n }\n\n if (!n) throw s;\n\n // set name flag based on first char\n if (s[0] === NAME) markname = ++i;\n\n // extract first part of multi-part stream selector\n j = find(s, i, COLON);\n if (j < n) {\n source.push(s.substring(start, j).trim());\n start = i = ++j;\n }\n\n // extract remaining part of stream selector\n i = find(s, i, LBRACK);\n if (i === n) {\n source.push(s.substring(start, n).trim());\n } else {\n source.push(s.substring(start, i).trim());\n filter = [];\n start = ++i;\n if (start === n) throw 'Unmatched left bracket: ' + s;\n }\n\n // extract filters\n while (i < n) {\n i = find(s, i, RBRACK);\n if (i === n) throw 'Unmatched left bracket: ' + s;\n filter.push(s.substring(start, i).trim());\n if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s;\n start = ++i;\n }\n\n // marshall event stream specification\n if (!(n = source.length) || ILLEGAL.test(source[n-1])) {\n throw 'Invalid event selector: ' + s;\n }\n\n if (n > 1) {\n stream.type = source[1];\n if (markname) {\n stream.markname = source[0].slice(1);\n } else if (isMarkType(source[0])) {\n stream.marktype = source[0];\n } else {\n stream.source = source[0];\n }\n } else {\n stream.type = source[0];\n }\n if (stream.type.slice(-1) === '!') {\n stream.consume = true;\n stream.type = stream.type.slice(0, -1)\n }\n if (filter != null) stream.filter = filter;\n if (throttle[0]) stream.throttle = throttle[0];\n if (throttle[1]) stream.debounce = throttle[1];\n\n return stream;\n}\n\nfunction parseThrottle(s) {\n var a = s.split(COMMA);\n if (!s.length || a.length > 2) throw s;\n return a.map(function(_) {\n var x = +_;\n if (x !== x) throw s;\n return x;\n });\n}\n", + "import {toSet} from 'vega-util';\n\nexport var ArcMark = 'arc';\nexport var AreaMark = 'area';\nexport var GroupMark = 'group';\nexport var ImageMark = 'image';\nexport var LineMark = 'line';\nexport var PathMark = 'path';\nexport var RectMark = 'rect';\nexport var RuleMark = 'rule';\nexport var ShapeMark = 'shape';\nexport var SymbolMark = 'symbol';\nexport var TextMark = 'text';\n\nexport var marktypes = toSet([\n '*',\n 'arc',\n 'area',\n 'group',\n 'image',\n 'line',\n 'path',\n 'rect',\n 'rule',\n 'shape',\n 'symbol',\n 'text'\n]);\n\nexport function isMarkType(type) {\n return marktypes.hasOwnProperty(type);\n}\n", + "(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (factory((global.vega = global.vega || {})));\n}(this, (function (exports) { 'use strict';\n\nvar accessor = function(fn, fields, name) {\n return (\n fn.fields = fields || [],\n fn.fname = name,\n fn\n );\n}\n\nfunction accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nfunction accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n\nvar error = function(message) {\n throw Error(message);\n}\n\nvar splitAccessPath = function(p) {\n var path = [],\n q = null,\n b = 0,\n n = p.length,\n s = '',\n i, j, c;\n\n p = p + '';\n\n function push() {\n path.push(s + p.substring(i, j));\n s = '';\n i = j + 1;\n }\n\n for (i=j=0; j i) ? push() : (i = j + 1);\n else if (c === '[') {\n if (j > i) push();\n b = i = j + 1;\n }\n else if (c === ']') {\n if (!b) error('Access path missing open bracket: ' + p);\n if (b > 0) push();\n b = 0;\n i = j + 1;\n }\n }\n\n if (b) error('Access path missing closing bracket: ' + p);\n if (q) error('Access path missing closing quote: ' + p);\n if (j > i) ++j, push();\n return path;\n}\n\nvar isArray = Array.isArray;\n\nvar isObject = function(_) {\n return _ === Object(_);\n}\n\nvar isString = function(_) {\n return typeof _ === 'string';\n}\n\nfunction $(x) {\n return isArray(x) ? '[' + x.map($) + ']'\n : isObject(x) || isString(x) ?\n // Output valid JSON and JS source strings.\n // See http://timelessrepo.com/json-isnt-a-javascript-subset\n JSON.stringify(x).replace('\\u2028','\\\\u2028').replace('\\u2029', '\\\\u2029')\n : x;\n}\n\nvar field = function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map($).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n}\n\nvar empty = [];\n\nvar id = field('id');\n\nvar identity = accessor(function(_) { return _; }, empty, 'identity');\n\nvar zero = accessor(function() { return 0; }, empty, 'zero');\n\nvar one = accessor(function() { return 1; }, empty, 'one');\n\nvar truthy = accessor(function() { return true; }, empty, 'true');\n\nvar falsy = accessor(function() { return false; }, empty, 'false');\n\nfunction log(method, level, input) {\n var args = [level].concat([].slice.call(input));\n console[method].apply(console, args); // eslint-disable-line no-console\n}\n\nvar None = 0;\nvar Warn = 1;\nvar Info = 2;\nvar Debug = 3;\n\nvar logger = function(_) {\n var level = _ || None;\n return {\n level: function(_) {\n return arguments.length ? (level = +_, this) : level;\n },\n warn: function() {\n if (level >= Warn) log('warn', 'WARN', arguments);\n return this;\n },\n info: function() {\n if (level >= Info) log('log', 'INFO', arguments);\n return this;\n },\n debug: function() {\n if (level >= Debug) log('log', 'DEBUG', arguments);\n return this;\n }\n }\n}\n\nvar array = function(_) {\n return _ != null ? (isArray(_) ? _ : [_]) : [];\n}\n\nvar compare = function(fields, orders) {\n var idx = [],\n cmp = (fields = array(fields)).map(function(f, i) {\n return f == null ? null\n : (idx.push(i), splitAccessPath(f).map($).join(']['));\n }),\n n = idx.length - 1,\n ord = array(orders),\n code = 'var u,v;return ',\n i, j, f, u, v, d, lt, gt;\n\n if (n < 0) return null;\n\n for (j=0; j<=n; ++j) {\n i = idx[j];\n f = cmp[i];\n u = '(u=a['+f+'])';\n v = '(v=b['+f+'])';\n d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))';\n lt = ord[i] !== 'descending' ? (gt=1, -1) : (gt=-1, 1);\n code += '(' + u+'<'+v+'||u==null)&&v!=null?' + lt\n + ':(u>v||v==null)&&u!=null?' + gt\n + ':'+d+'!==u&&v===v?' + lt\n + ':v!==v&&u===u?' + gt\n + (i < n ? ':' : ':0');\n }\n\n return accessor(\n Function('a', 'b', code + ';'),\n fields.filter(function(_) { return _ != null; })\n );\n}\n\nvar isFunction = function(_) {\n return typeof _ === 'function';\n}\n\nvar constant = function(_) {\n return isFunction(_) ? _ : function() { return _; };\n}\n\nvar extend = function(_) {\n for (var x, k, i=1, len=arguments.length; i= b) { a = c = b; break; }\n u = v = i;\n while (++i < n) if ((b = array[i]) != null) {\n if (a > b) a = b, u = i;\n if (c < b) c = b, v = i;\n }\n } else {\n while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; }\n u = v = i;\n while (++i < n) if ((b = f(array[i], i, array)) != null) {\n if (a > b) a = b, u = i;\n if (c < b) c = b, v = i;\n }\n }\n\n return [u, v];\n}\n\nvar NULL = {};\n\nvar fastmap = function(input) {\n var obj = {},\n map,\n test;\n\n function has(key) {\n return obj.hasOwnProperty(key) && obj[key] !== NULL;\n }\n\n map = {\n size: 0,\n empty: 0,\n object: obj,\n has: has,\n get: function(key) {\n return has(key) ? obj[key] : undefined;\n },\n set: function(key, value) {\n if (!has(key)) {\n ++map.size;\n if (obj[key] === NULL) --map.empty;\n }\n obj[key] = value;\n return this;\n },\n delete: function(key) {\n if (has(key)) {\n --map.size;\n ++map.empty;\n obj[key] = NULL;\n }\n return this;\n },\n clear: function() {\n map.size = map.empty = 0;\n map.object = obj = {};\n },\n test: function(_) {\n return arguments.length ? (test = _, map) : test;\n },\n clean: function() {\n var next = {},\n size = 0,\n key, value;\n for (key in obj) {\n value = obj[key];\n if (value !== NULL && (!test || !test(value))) {\n next[key] = value;\n ++size;\n }\n }\n map.size = size;\n map.empty = 0;\n map.object = (obj = next);\n }\n };\n\n if (input) Object.keys(input).forEach(function(key) {\n map.set(key, input[key]);\n });\n\n return map;\n}\n\nvar inherits = function(child, parent) {\n var proto = (child.prototype = Object.create(parent.prototype));\n proto.constructor = child;\n return proto;\n}\n\nvar isNumber = function(_) {\n return typeof _ === 'number';\n}\n\nvar key = function(fields) {\n fields = fields ? array(fields) : fields;\n var fn = !(fields && fields.length)\n ? function() { return ''; }\n : Function('_', 'return \\'\\'+' +\n fields.map(function(f) {\n return '_[' + splitAccessPath(f).map($).join('][') + ']';\n }).join('+\\'|\\'+') + ';');\n return accessor(fn, fields, 'key');\n}\n\nvar merge = function(compare, array0, array1, output) {\n var n0 = array0.length,\n n1 = array1.length;\n\n if (!n1) return array0;\n if (!n0) return array1;\n\n var merged = output || new array0.constructor(n0 + n1),\n i0 = 0, i1 = 0, i = 0;\n\n for (; i0 0\n ? array1[i1++]\n : array0[i0++];\n }\n\n for (; i0= 0) s += str;\n return s;\n}\n\nvar pad = function(str, length, padchar, align) {\n var c = padchar || ' ',\n s = str + '',\n n = length - s.length;\n\n return n <= 0 ? s\n : align === 'left' ? repeat(c, n) + s\n : align === 'center' ? repeat(c, ~~(n/2)) + s + repeat(c, Math.ceil(n/2))\n : s + repeat(c, n);\n}\n\nvar peek = function(array) {\n return array[array.length - 1];\n}\n\nvar toSet = function(_) {\n for (var s={}, i=0, n=_.length; i (http://kanitw.yellowpigz.com)\",\n \"Dominik Moritz (https://www.domoritz.de)\",\n \"Jeffrey Heer (http://jheer.org)\"\n ],\n \"homepage\": \"https://vega.github.io/vega-lite/\",\n \"description\": \"Vega-lite provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.\",\n \"main\": \"build/src/vl.js\",\n \"types\": \"build/src/vl.d.ts\",\n \"bin\": {\n \"vl2png\": \"./bin/vl2png\",\n \"vl2svg\": \"./bin/vl2svg\",\n \"vl2vg\": \"./bin/vl2vg\"\n },\n \"directories\": {\n \"test\": \"test\"\n },\n \"scripts\": {\n \"prebuild\": \"mkdir -p build/site build/examples/images build/test-gallery\",\n \"build\": \"tsc && cp package.json build && browserify src/vl.ts -p tsify -g [ babelify ] -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js\",\n \"postbuild\": \"uglifyjs build/vega-lite.js -cm --in-source-map build/vega-lite.js.map --source-map build/vega-lite.min.js.map > build/vega-lite.min.js && npm run schema\",\n \"build:images\": \"npm run data && scripts/generate-images.sh\",\n \"build:toc\": \"bundle exec jekyll build -q && scripts/generate-toc\",\n \"build:site\": \"browserify site/static/main.ts -p [tsify -p site] -d > build/site/main.js\",\n \"build:versions\": \"scripts/update-version.sh\",\n \"build:test-gallery\": \"browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js\",\n \"checkschema\": \"scripts/check-schema.sh\",\n \"clean\": \"rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\\\.(js|js.map|d.ts)' -delete & rm -rf examples/_diff examples/_original examples/_output examples/images && rm -rf data\",\n \"data\": \"rsync -r node_modules/vega-datasets/data/* data\",\n\n \"deploy\": \"scripts/deploy.sh\",\n \"deploy:gh\": \"scripts/deploy-gh.sh\",\n \"deploy:schema\": \"scripts/deploy-schema.sh\",\n\n \"prestart\": \"npm run data && npm run build && scripts/index-examples\",\n \"start\": \"nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'\",\n \"poststart\": \"rm examples/all-examples.json\",\n\n \"preschema\": \"npm run prebuild\",\n \"schema\": \"typescript-json-schema --required true --noExtraProps true src/spec.ts ExtendedSpec > build/vega-lite-schema.json\",\n\n \"presite\": \"npm run build && npm run data && npm run build:site && npm run build:toc && npm run build:versions\",\n \"site\": \"bundle exec jekyll serve\",\n\n \"lint\": \"tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'\",\n\n \"test\": \"tsc && npm run schema && npm run data && npm run test:nocompile\",\n \"test:nocompile\": \"npm run test:only && npm run lint && npm run mocha:examples\",\n \"test:only\": \"nyc --reporter=html --reporter=text-summary npm run mocha:test\",\n \"test:debug\": \"tsc && npm run schema && npm run data && mocha --recursive --require ./test/babel.ts --debug-brk build/test build/examples\",\n \"mocha:test\": \"mocha --reporter dot --recursive build/test\",\n \"mocha:examples\": \"mocha --require ./test/babel.ts --reporter dot --recursive build/examples\",\n\n \"codecov\": \"nyc report --reporter=json && codecov -f coverage/*.json\",\n \"watch:build\": \"watchify src/vl.ts -p tsify -g [ babelify ] -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'\",\n \"watch:test\": \"nodemon -x 'npm test'\",\n \"watch\": \"nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build\",\n \"x-compile\": \"./scripts/examples-compile.sh\",\n \"x-diff\": \"./scripts/examples-diff.sh\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/vega/vega-lite.git\"\n },\n \"license\": \"BSD-3-Clause\",\n \"bugs\": {\n \"url\": \"https://github.com/vega/vega-lite/issues\"\n },\n \"devDependencies\": {\n \"@types/chai\": \"^3.4.35\",\n \"@types/highlight.js\": \"^9.1.9\",\n \"@types/d3\": \"^4.5.0\",\n \"@types/json-stable-stringify\": \"^1.0.30\",\n \"@types/mocha\": \"^2.2.39\",\n \"@types/node\": \"^7.0.5\",\n \"ajv\": \"5.0.1-beta.1\",\n \"babel-preset-es2015\": \"^6.22.0\",\n \"babelify\": \"^7.3.0\",\n \"browser-sync\": \"~2.18.8\",\n \"browserify\": \"~14.1.0\",\n \"browserify-shim\": \"^3.8.13\",\n \"chai\": \"~3.5.0\",\n \"cheerio\": \"~0.22.0\",\n \"codecov\": \"~1.0.1\",\n \"d3\": \"^4.7.0\",\n \"exorcist\": \"~0.4.0\",\n \"highlight.js\": \"^9.9.0\",\n \"mocha\": \"~3.2.0\",\n \"nodemon\": \"~1.11.0\",\n \"nyc\": \"~10.1.2\",\n \"source-map-support\": \"~0.4.11\",\n \"tsify\": \"~3.0.1\",\n \"tslint\": \"~4.5.1\",\n \"tslint-eslint-rules\": \"^3.4.0\",\n \"typescript\": \"^2.2.1\",\n \"typescript-json-schema\": \"^0.10.0\",\n \"uglify-js\": \"~2.8.4\",\n \"vega\": \"3.0.0-beta.25\",\n \"vega-datasets\": \"vega/vega-datasets#gh-pages\",\n \"vega-embed\": \"3.0.0-beta.5\",\n \"vega-parser\": \"^1.0.0-beta.38\",\n \"watchify\": \"~3.9.0\",\n \"yaml-front-matter\": \"~3.4.0\"\n },\n \"dependencies\": {\n \"json-stable-stringify\": \"~1.0.1\",\n \"tslib\": \"^1.6.0\",\n \"vega-util\": \"~1.1.4\",\n \"yargs\": \"~6.6.0\"\n }\n}\n", + "\nexport type AggregateOp = 'argmax' | 'argmin' | 'average' | 'count'\n | 'distinct' | 'max' | 'mean' | 'median' | 'min' | 'missing' | 'modeskew'\n | 'q1' | 'q3' | 'stdev' | 'stdevp' | 'sum' | 'valid' | 'values' | 'variance'\n | 'variancep';\n\nexport const AGGREGATE_OPS: AggregateOp[] = [\n 'values',\n 'count',\n 'valid',\n 'missing',\n 'distinct',\n 'sum',\n 'mean',\n 'average',\n 'variance',\n 'variancep',\n 'stdev',\n 'stdevp',\n 'median',\n 'q1',\n 'q3',\n 'modeskew',\n 'min',\n 'max',\n 'argmin',\n 'argmax',\n];\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = [\n 'count',\n 'sum',\n 'distinct',\n 'valid',\n 'missing'\n];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = [\n 'mean',\n 'average',\n 'median',\n 'q1',\n 'q3',\n 'min',\n 'max',\n];\n", + "import {DateTime} from './datetime';\nimport {VgAxisEncode, VgAxisBase, VgAxisConfig} from './vega.schema';\n\nexport type AxisOrient = 'top' | 'right' | 'left' | 'bottom';\n\nexport interface AxisConfig extends VgAxisConfig, VlOnlyAxisBase {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport const defaultAxisConfig: AxisConfig = {\n labelMaxLength: 25,\n};\n\nexport interface Axis extends VgAxisBase, VlOnlyAxisBase {\n /**\n * The padding, in pixels, between axis and text labels.\n */\n labelPadding?: number;\n\n /**\n * The formatting pattern for axis labels.\n */\n format?: string; // default value determined by config.format anyway\n\n /**\n * The orientation of the axis. One of top, bottom, left or right. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart).\n */\n orient?: AxisOrient;\n\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n * @TJS-type integer\n */\n tickCount?: number;\n\n /**\n * A title for the axis. Shows field name and its function by default.\n */\n title?: string;\n\n values?: number[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Optional mark definitions for custom axis encoding.\n */\n encode?: VgAxisEncode;\n}\n\n\n/**\n * Base object for properties that are shared between Axis and Axis Config.\n * These properties are not in Vega Axis and Axis Config.\n */\nexport interface VlOnlyAxisBase {\n /**\n * Truncate labels that are too long.\n * @minimum 1\n * @TJS-type integer\n */\n labelMaxLength?: number;\n}\n\nexport const AXIS_PROPERTIES:(keyof Axis)[] = [\n 'domain', 'format', 'grid', 'labelPadding', 'labels', 'maxExtent', 'minExtent', 'offset', 'orient', 'position', 'tickCount', 'ticks', 'tickSize', 'title', 'titlePadding', 'values', 'zindex'\n];\n\nexport const VL_ONLY_AXIS_PROPERTIES:(keyof VlOnlyAxisBase)[] = ['labelMaxLength'];\n", + "import {Channel, ROW, COLUMN, SHAPE, SIZE} from './channel';\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface Bin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[];\n\n /**\n * The number base to use for automatic bin determination (default is base 10).\n */\n base?: number;\n /**\n * An exact step size to use between bins. If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n * @minimum 2\n */\n maxbins?: number;\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n", + "/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {Encoding} from './encoding';\nimport {Facet} from './facet';\nimport {Mark} from './mark';\nimport {RangeType} from './compile/scale/type';\nimport {ScaleType, SCALE_TYPES} from './scale';\nimport {contains, toSet, without} from './util';\n\nexport namespace Channel {\n // Facet\n export const ROW: 'row' = 'row';\n export const COLUMN: 'column' = 'column';\n\n // Position\n export const X: 'x' = 'x';\n export const Y: 'y' = 'y';\n export const X2: 'x2' = 'x2';\n export const Y2: 'y2' = 'y2';\n\n // Mark property with scale\n export const COLOR: 'color' = 'color';\n export const SHAPE: 'shape' = 'shape';\n export const SIZE: 'size' = 'size';\n export const OPACITY: 'opacity' = 'opacity';\n\n // Non-scale channel\n export const TEXT: 'text' = 'text';\n export const ORDER: 'order' = 'order';\n export const DETAIL: 'detail' = 'detail';\n}\n\nexport type Channel = keyof Encoding | keyof Facet;\n\nexport const X = Channel.X;\nexport const Y = Channel.Y;\nexport const X2 = Channel.X2;\nexport const Y2 = Channel.Y2;\nexport const ROW = Channel.ROW;\nexport const COLUMN = Channel.COLUMN;\nexport const SHAPE = Channel.SHAPE;\nexport const SIZE = Channel.SIZE;\nexport const COLOR = Channel.COLOR;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\n\n\nexport const CHANNELS = [X, Y, X2, Y2, ROW, COLUMN, SIZE, SHAPE, COLOR, ORDER, OPACITY, TEXT, DETAIL];\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = [X, Y, X2, Y2, SIZE, SHAPE, COLOR, ORDER, OPACITY, TEXT, DETAIL];\n\n// UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT\nexport const UNIT_SCALE_CHANNELS = [X, Y, SIZE, SHAPE, COLOR, OPACITY];\n\n// UNIT_SCALE_CHANNELS with ROW, COLUMN\nexport const SCALE_CHANNELS = [X, Y, SIZE, SHAPE, COLOR, OPACITY, ROW, COLUMN];\n\n// UNIT_CHANNELS without X, Y, X2, Y2;\nexport const NONSPATIAL_CHANNELS = [SIZE, SHAPE, COLOR, ORDER, OPACITY, TEXT, DETAIL];\n\n// UNIT_SCALE_CHANNELS without X, Y;\nexport const NONSPATIAL_SCALE_CHANNELS = [SIZE, SHAPE, COLOR, OPACITY];\n\n/** Channels that can serve as groupings for stacked charts. */\nexport const STACK_GROUP_CHANNELS = [COLOR, DETAIL, ORDER, OPACITY, SIZE];\n\nexport interface SupportedMark {\n point?: boolean;\n tick?: boolean;\n rule?: boolean;\n circle?: boolean;\n square?: boolean;\n bar?: boolean;\n rect?: boolean;\n line?: boolean;\n area?: boolean;\n text?: boolean;\n};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return mark in getSupportedMark(channel);\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to boolean values.\n */\nexport function getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case X:\n case Y:\n case COLOR:\n case DETAIL:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case ROW:\n case COLUMN:\n return { // all marks\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, area: true, text: true\n };\n case X2:\n case Y2:\n return {\n rule: true, bar: true, rect: true, area: true\n };\n case SIZE:\n return {\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, text: true, line: true\n };\n case SHAPE:\n return {point: true};\n case TEXT:\n return {text: true};\n }\n return {};\n}\n\nexport function hasScale(channel: Channel) {\n return !contains([DETAIL, TEXT, ORDER], channel);\n}\n\n// Position does not work with ordinal (lookup) scale and sequential (which is only for color)\nconst POSITION_SCALE_TYPE_INDEX = toSet(without(SCALE_TYPES, ['ordinal', 'sequential'] as ScaleType[]));\n\nexport function supportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case ROW:\n case COLUMN:\n return scaleType === 'band'; // row / column currently supports band only\n case X:\n case Y:\n case SIZE: // TODO: size and opacity can support ordinal with more modification\n case OPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return scaleType in POSITION_SCALE_TYPE_INDEX;\n case COLOR:\n return scaleType !== 'band'; // band does not make sense with color\n case SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case OPACITY:\n return 'continuous';\n\n case ROW:\n case COLUMN:\n case SHAPE:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n return 'flexible';\n\n // No scale, no range type.\n case X2:\n case Y2:\n case DETAIL:\n case TEXT:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('getSupportedRole not implemented for ' + channel);\n}\n", + "import {COLUMN, X, Channel} from '../../channel';\nimport {NOMINAL, ORDINAL, TEMPORAL} from '../../type';\nimport {contains, keys, extend} from '../../util';\nimport {VgAxis} from '../../vega.schema';\n\nimport {timeFormatExpression} from '../common';\nimport {Model} from '../model';\n\nexport function labels(model: Model, channel: Channel, labelsSpec: any, def: VgAxis) {\n const fieldDef = model.fieldDef(channel);\n const axis = model.axis(channel);\n const config = model.config;\n\n // Text\n if (contains([NOMINAL, ORDINAL], fieldDef.type) && axis.labelMaxLength) {\n // TODO replace this with Vega's labelMaxLength once it is introduced\n labelsSpec = extend({\n text: {\n signal: `truncate(datum.value, ${axis.labelMaxLength})`\n }\n }, labelsSpec || {});\n } else if (fieldDef.type === TEMPORAL) {\n labelsSpec = extend({\n text: {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat)\n }\n }, labelsSpec);\n }\n\n // Label Angle\n if (axis.labelAngle !== undefined) {\n labelsSpec.angle = {value: axis.labelAngle};\n } else {\n // auto rotate for X\n if (channel === X && (contains([NOMINAL, ORDINAL], fieldDef.type) || !!fieldDef.bin || fieldDef.type === TEMPORAL)) {\n labelsSpec.angle = {value: 270};\n }\n }\n\n // Auto set align if rotated\n // TODO: consider other value besides 270, 90\n if (labelsSpec.angle) {\n if (labelsSpec.angle.value === 270) {\n labelsSpec.align = {\n value: def.orient === 'top' ? 'left':\n (channel === X || channel === COLUMN) ? 'right' :\n 'center'\n };\n } else if (labelsSpec.angle.value === 90) {\n labelsSpec.align = {value: 'center'};\n }\n }\n\n if (labelsSpec.angle) {\n // Auto set baseline if rotated\n // TODO: consider other value besides 270, 90\n if (labelsSpec.angle.value === 270) {\n labelsSpec.baseline = {value: (channel === X || channel === COLUMN) ? 'middle' : 'bottom'};\n } else if (labelsSpec.angle.value === 90) {\n labelsSpec.baseline = {value: 'bottom'};\n }\n }\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\n}\n", + "import {Axis, AXIS_PROPERTIES} from '../../axis';\nimport {Channel} from '../../channel';\nimport {VgAxis} from '../../vega.schema';\n\nimport * as encode from './encode';\nimport * as rules from './rules';\n\nimport {Model} from '../model';\nimport {Dict, keys, some} from '../../util';\n\ntype AxisPart = 'domain' | 'grid' | 'labels' | 'ticks' | 'title';\nconst AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\nexport function parseAxisComponent(model: Model, axisChannels: Channel[]): Dict {\n return axisChannels.reduce(function(axis, channel) {\n const vgAxes: VgAxis[] = [];\n if (model.axis(channel)) {\n const main = parseMainAxis(channel, model);\n if (main && isVisibleAxis(main)) {\n vgAxes.push(main);\n }\n\n const grid = parseGridAxis(channel, model);\n if (grid && isVisibleAxis(grid)) {\n vgAxes.push(grid);\n }\n\n if (vgAxes.length > 0) {\n axis[channel] = vgAxes;\n }\n }\n return axis;\n }, {});\n}\n\nfunction isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\n/**\n * Return if an axis is visible (shows at least one part of the axis).\n */\nfunction isVisibleAxis(axis: VgAxis) {\n return some(AXIS_PARTS, (part) => hasAxisPart(axis, part));\n}\n\nfunction hasAxisPart(axis: VgAxis, part: AxisPart) {\n // FIXME this method can be wrong if users use a Vega theme.\n // (Not sure how to correctly handle that yet.).\n\n if (part === 'grid' || part === 'title') {\n return !!axis[part];\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(axis[part]);\n}\n\n/**\n * Make an inner axis for showing grid for shared axis.\n */\nexport function parseGridAxis(channel: Channel, model: Model): VgAxis {\n // FIXME: support adding ticks for grid axis that are inner axes of faceted plots.\n return parseAxis(channel, model, true);\n}\n\nexport function parseMainAxis(channel: Channel, model: Model) {\n return parseAxis(channel, model, false);\n}\n\nfunction parseAxis(channel: Channel, model: Model, isGridAxis: boolean): VgAxis {\n const axis = model.axis(channel);\n\n let vgAxis: VgAxis = {\n scale: model.scaleName(channel)\n };\n\n // 1.2. Add properties\n AXIS_PROPERTIES.forEach(function(property) {\n const value = getSpecifiedOrDefaultValue(property, axis, channel, model, isGridAxis);\n if (value !== undefined) {\n vgAxis[property] = value;\n }\n });\n\n // Special case for gridScale since gridScale is not a Vega-Lite Axis property.\n const gridScale = getSpecifiedOrDefaultValue('gridScale', axis, channel, model, isGridAxis);\n if (gridScale !== undefined) {\n vgAxis.gridScale = gridScale;\n }\n\n // 2) Add guide encode definition groups\n\n const encodeSpec = axis.encode || {};\n AXIS_PARTS.forEach(function(part) {\n if (!hasAxisPart(vgAxis, part)) {\n // No need to create encode for a disabled part.\n return;\n }\n // TODO(@yuhanlu): instead of calling encode[part], break this line based on part type\n // as different require different parameters.\n let value;\n if (part === 'labels') {\n value = encode.labels(model, channel, encodeSpec.labels || {}, vgAxis);\n } else {\n value = encodeSpec[part] || {};\n }\n\n if (value !== undefined && keys(value).length > 0) {\n vgAxis.encode = vgAxis.encode || {};\n vgAxis.encode[part] = {update: value};\n }\n });\n\n return vgAxis;\n}\n\nfunction getSpecifiedOrDefaultValue(property: keyof VgAxis, specifiedAxis: Axis, channel: Channel, model: Model, isGridAxis: boolean) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'labels':\n return isGridAxis ? false : specifiedAxis[property];\n case 'domain':\n return rules.domain(property, specifiedAxis, isGridAxis, channel);\n case 'ticks':\n return rules.ticks(property, specifiedAxis, isGridAxis, channel);\n case 'format':\n return rules.format(specifiedAxis, channel, fieldDef, model.config);\n case 'grid':\n return rules.grid(model, channel, isGridAxis); // FIXME: refactor this\n case 'gridScale':\n return rules.gridScale(model, channel, isGridAxis);\n case 'orient':\n return rules.orient(specifiedAxis, channel);\n case 'tickCount':\n return rules.tickCount(specifiedAxis, channel, fieldDef); // TODO: scaleType\n case 'title':\n return rules.title(specifiedAxis, fieldDef, model.config, isGridAxis);\n case 'values':\n return rules.values(specifiedAxis);\n case 'zindex':\n return rules.zindex(specifiedAxis, isGridAxis);\n }\n // Otherwise, return specified property.\n return specifiedAxis[property];\n}\n", + "import * as log from '../../log';\n\nimport {Axis} from '../../axis';\nimport {VgAxis} from '../../vega.schema';\nimport {COLUMN, ROW, X, Y, Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {DateTime, isDateTime, timestamp} from '../../datetime';\nimport {title as fieldDefTitle, FieldDef} from '../../fielddef';\nimport {truncate} from '../../util';\n\nimport {numberFormat} from '../common';\nimport {Model} from '../model';\n\nexport function format(specifiedAxis: Axis, channel: Channel, fieldDef: FieldDef, config: Config) {\n return numberFormat(fieldDef, specifiedAxis.format, config, channel);\n}\n\n// TODO: we need to refactor this method after we take care of config refactoring\n/**\n * Default rules for whether to show a grid should be shown for a channel.\n * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned\n */\nexport function gridShow(model: Model, channel: Channel) {\n const grid = model.axis(channel).grid;\n if (grid !== undefined) {\n return grid;\n }\n\n return !model.hasDiscreteScale(channel) && !model.fieldDef(channel).bin;\n}\n\nexport function grid(model: Model, channel: Channel, isGridAxis: boolean) {\n if (channel === ROW || channel === COLUMN) {\n // never apply grid for ROW and COLUMN since we manually create rule-group for them\n return false;\n }\n\n if (!isGridAxis) {\n return undefined;\n }\n\n return gridShow(model, channel);\n}\n\nexport function gridScale(model: Model, channel: Channel, isGridAxis: boolean) {\n if (isGridAxis) {\n const gridChannel: Channel = channel === 'x' ? 'y' : 'x';\n if (model.scale(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n }\n return undefined;\n}\n\nexport function orient(specifiedAxis: Axis, channel: Channel) {\n const orient = specifiedAxis.orient;\n if (orient) {\n return orient;\n }\n\n switch (channel) {\n case COLUMN:\n // FIXME test and decide\n return 'top';\n case X:\n return 'bottom';\n case ROW:\n case Y:\n return 'left';\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS);\n}\n\nexport function tickCount(specifiedAxis: Axis, channel: Channel, fieldDef: FieldDef) {\n const count = specifiedAxis.tickCount;\n if (count !== undefined) {\n return count;\n }\n\n // FIXME depends on scale type too\n if (channel === X && !fieldDef.bin) {\n // Vega's default tickCount often lead to a lot of label occlusion on X without 90 degree rotation\n return 5;\n }\n\n return undefined;\n}\n\nexport function title(specifiedAxis: Axis, fieldDef: FieldDef, config: Config, isGridAxis: boolean) {\n if (isGridAxis) {\n return undefined;\n }\n if (specifiedAxis.title !== undefined) {\n return specifiedAxis.title;\n }\n\n // if not defined, automatically determine axis title from field def\n const fieldTitle = fieldDefTitle(fieldDef, config);\n\n let maxLength: number = specifiedAxis.titleMaxLength;\n return maxLength ? truncate(fieldTitle, maxLength) : fieldTitle;\n}\n\nexport function values(specifiedAxis: Axis) {\n const vals = specifiedAxis.values;\n if (specifiedAxis.values && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return timestamp(dt, true);\n });\n }\n return vals;\n}\n\nexport function zindex(specifiedAxis: Axis, isGridAxis: boolean) {\n const z = specifiedAxis.zindex;\n if (z !== undefined) {\n return z;\n }\n if (isGridAxis) {\n // if grid is true, need to put layer on the back so that grid is behind marks\n return 0;\n }\n return 1; // otherwise return undefined and use Vega's default.\n};\n\nexport function domainAndTicks(property: keyof VgAxis, specifiedAxis: Axis, isGridAxis: boolean, channel: Channel) {\n if (isGridAxis || channel === ROW || channel === COLUMN) {\n return false;\n }\n return specifiedAxis[property];\n}\n\nexport const domain = domainAndTicks;\nexport const ticks = domainAndTicks;\n", + "import * as log from '../log';\n\nimport {TEXT, Channel} from '../channel';\nimport {Config, CellConfig} from '../config';\nimport {FieldDef, OrderFieldDef, field} from '../fielddef';\nimport {Mark, MarkConfig, TextConfig} from '../mark';\nimport {TimeUnit} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {isArray} from '../util';\n\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {formatExpression} from '../timeunit';\nimport {UnitModel} from './unit';\nimport {Spec, isUnitSpec, isFacetSpec, isLayerSpec} from '../spec';\nimport {VgEncodeEntry, VgSort} from '../vega.schema';\n\nexport function buildModel(spec: Spec, parent: Model, parentGivenName: string): Model {\n if (isFacetSpec(spec)) {\n return new FacetModel(spec, parent, parentGivenName);\n }\n\n if (isLayerSpec(spec)) {\n return new LayerModel(spec, parent, parentGivenName);\n }\n\n if (isUnitSpec(spec)) {\n return new UnitModel(spec, parent, parentGivenName);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n}\n\nexport function applyConfig(e: VgEncodeEntry,\n config: CellConfig | MarkConfig | TextConfig, // TODO(#1842): consolidate MarkConfig | TextConfig?\n propsList: string[]) {\n propsList.forEach((property) => {\n const value = config[property];\n if (value !== undefined) {\n e[property] = {value: value};\n }\n });\n return e;\n}\n\nexport function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]) {\n propsList.forEach((property) => {\n const value = getMarkConfig(property, model.mark(), model.config);\n if (value !== undefined) {\n e[property] = {value: value};\n }\n });\n return e;\n}\n\n/**\n * Return value mark specific config property if exists.\n * Otherwise, return general mark specific config.\n */\nexport function getMarkConfig

(prop: P, mark: Mark, config: Config): MarkConfig[P] {\n const markSpecificConfig = config[mark];\n if (markSpecificConfig[prop] !== undefined) {\n return markSpecificConfig[prop];\n }\n return config.mark[prop];\n}\n\n/**\n * Returns number format for a fieldDef\n *\n * @param format explicitly specified format\n */\nexport function numberFormat(fieldDef: FieldDef, format: string, config: Config, channel: Channel) {\n if (fieldDef.type === QUANTITATIVE) {\n // add number format for quantitative type only\n\n if (format) {\n return format;\n } else if (fieldDef.aggregate === 'count' && channel === TEXT) {\n // FIXME: need a more holistic way to deal with this.\n return 'd';\n }\n // TODO: need to make this work correctly for numeric ordinal / nominal type\n return config.numberFormat;\n }\n return undefined;\n}\n\n/**\n * Returns the time expression used for axis/legend labels or text mark for a temporal field\n */\nexport function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n const _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n return `timeFormat(${field}, '${_format}')`;\n } else {\n return formatExpression(timeUnit, field, shortTimeLabels);\n }\n}\n\n/**\n * Return Vega sort parameters (tuple of field and order).\n */\nexport function sortParams(orderDef: OrderFieldDef | OrderFieldDef[]): VgSort {\n return (isArray(orderDef) ? orderDef : [orderDef]).reduce((s, orderChannelDef) => {\n s.field.push(field(orderChannelDef, {binSuffix: 'start'}));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n", + "/**\n * Module for compiling Vega-lite spec into Vega spec.\n */\n\nimport {LAYOUT} from '../data';\nimport * as log from '../log';\nimport {Model} from './model';\nimport {normalize, ExtendedSpec} from '../spec';\nimport {extend} from '../util';\nimport {assembleTopLevelSignals} from './selection/selection';\nimport {buildModel} from './common';\n\nexport function compile(inputSpec: ExtendedSpec, logger?: log.LoggerInterface) {\n if (logger) {\n // set the singleton logger to the provided logger\n log.set(logger);\n }\n\n try {\n // 1. Convert input spec into a normal form\n // (Decompose all extended unit specs into composition of unit spec.)\n const spec = normalize(inputSpec);\n\n // 2. Instantiate the model with default properties\n const model = buildModel(spec, null, '');\n\n // 3. Parse each part of the model to produce components that will be assembled later\n // We traverse the whole tree to parse once for each type of components\n // (e.g., data, layout, mark, scale).\n // Please see inside model.parse() for order for compilation.\n model.parse();\n\n // 4. Assemble a Vega Spec from the parsed components in 3.\n return assemble(model);\n } finally {\n // Reset the singleton logger if a logger is provided\n if (logger) {\n log.reset();\n }\n }\n}\n\nfunction assemble(model: Model) {\n // TODO: change type to become VgSpec\n const output = extend(\n {\n $schema: 'http://vega.github.io/schema/vega/v3.0.json',\n },\n topLevelBasicProperties(model),\n {\n // Map calculated layout width and height to width and height signals.\n signals: [\n {\n name: 'width',\n update: \"data('layout')[0].width\"\n },\n {\n name: 'height',\n update: \"data('layout')[0].height\"\n }\n ].concat(assembleTopLevelSignals(model))\n },{\n data: [].concat(\n model.assembleData([]),\n model.assembleLayout([]),\n model.assembleSelectionData([])\n ),\n marks: [assembleRootGroup(model)]\n });\n\n return {\n spec: output\n // TODO: add warning / errors here\n };\n}\n\nexport function topLevelBasicProperties(model: Model) {\n const config = model.config;\n return extend(\n // TODO: Add other top-level basic properties (#1778)\n {padding: model.padding || config.padding},\n {autosize: 'pad'},\n config.viewport ? {viewport: config.viewport} : {},\n config.background ? {background: config.background} : {}\n );\n}\n\nexport function assembleRootGroup(model: Model) {\n let rootGroup:any = extend(\n {\n name: model.getName('main'),\n type: 'group',\n },\n model.description ? {description: model.description} : {},\n {\n from: {data: model.getName(LAYOUT +'')},\n encode: {\n update: extend(\n {\n width: {field: model.getName('width')},\n height: {field: model.getName('height')}\n },\n model.assembleParentGroupProperties(model.config.cell)\n )\n }\n });\n\n return extend(rootGroup, model.assembleGroup());\n}\n", + "import {DataComponentCompiler} from './base';\n\nimport {autoMaxBins} from '../../bin';\nimport {Channel} from '../../channel';\nimport {field, FieldDef} from '../../fielddef';\nimport {extend, vals, flatten, hash, Dict} from '../../util';\nimport {VgTransform} from '../../vega.schema';\nimport {hasDiscreteDomain} from '../../scale';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\n\nfunction numberFormatExpr(expr: string, format: string) {\n return `format(${expr}, '${format}')`;\n}\n\nfunction parse(model: Model): Dict {\n return model.reduceFieldDef(function(binComponent: Dict, fieldDef: FieldDef, channel: Channel) {\n const bin = model.fieldDef(channel).bin;\n if (bin) {\n\n let binTrans: VgTransform = extend({\n type: 'bin',\n field: fieldDef.field,\n as: [field(fieldDef, {binSuffix: 'start'}), field(fieldDef, {binSuffix: 'end'})],\n signal: model.getName(fieldDef.field + '_bins')\n },\n // if bin is an object, load parameter here!\n typeof bin === 'boolean' ? {} : bin\n );\n\n const transform: VgTransform[] = [];\n if (!binTrans.extent) {\n const extentSignal = model.getName(fieldDef.field + '_extent');\n transform.push({\n type: 'extent',\n field: fieldDef.field,\n signal: extentSignal\n });\n\n binTrans.extent = {signal: extentSignal};\n }\n\n if (!binTrans.maxbins && !binTrans.step) {\n // if both maxbins and step are not specified, need to automatically determine bin\n binTrans.maxbins = autoMaxBins(channel);\n }\n\n transform.push(binTrans);\n\n const discreteDomain = hasDiscreteDomain(model.scale(channel).type);\n if (discreteDomain) {\n // read format from axis or legend, if there is no format then use config.numberFormat\n const format = (model.axis(channel) || model.legend(channel) || {}).format ||\n model.config.numberFormat;\n\n const startField = field(fieldDef, {datum: true, binSuffix: 'start'});\n const endField = field(fieldDef, {datum: true, binSuffix: 'end'});\n\n transform.push({\n type: 'formula',\n as: field(fieldDef, {binSuffix: 'range'}),\n expr: `${numberFormatExpr(startField, format)} + ' - ' + ${numberFormatExpr(endField, format)}`\n });\n }\n // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color\n const key = hash(bin) + '_' + fieldDef.field + 'oc:' + discreteDomain;\n binComponent[key] = transform;\n }\n return binComponent;\n }, {});\n}\n\nexport const bin: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n let binComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color\n extend(binComponent, childDataComponent.bin);\n delete childDataComponent.bin;\n }\n return binComponent;\n },\n\n parseLayer: function (model: LayerModel) {\n let binComponent = parse(model);\n\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(binComponent, childDataComponent.bin);\n delete childDataComponent.bin;\n }\n });\n\n return binComponent;\n },\n\n assemble: function (component: Dict) {\n return flatten(vals(component));\n }\n};\n", + "import {SOURCE} from '../../data';\nimport {FieldDef} from '../../fielddef';\nimport {Formula} from '../../transform';\nimport {Dict, StringSet} from '../../util';\nimport {VgData, VgSort, VgTransform} from '../../vega.schema';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\nimport {UnitModel} from './../unit';\n\nimport {source} from './source';\nimport {formatParse} from './formatparse';\nimport {nullFilter} from './nullfilter';\nimport {filter} from './filter';\nimport {bin} from './bin';\nimport {formula} from './formula';\nimport {pathOrder} from './pathorder';\nimport {nonPositiveFilter} from './nonpositivefilter';\nimport {summary} from './summary';\nimport {stack, StackComponent} from './stack';\nimport {timeUnit} from './timeunit';\n\n/**\n * Composable component instance of a model's data.\n */\nexport interface DataComponent {\n source: VgData;\n\n /** Mapping from field name to primitive data type. */\n formatParse: Dict;\n\n /** String set of fields for null filtering */\n nullFilter: Dict;\n\n /** Hashset of a formula object */\n calculate: Dict;\n\n /** Filter test expression */\n filter: string;\n\n /** Dictionary mapping a bin parameter hash to transforms of the binned field */\n bin: Dict;\n\n /** Dictionary mapping an output field name (hash) to the time unit transform */\n timeUnit: Dict;\n\n /** String set of fields to be filtered */\n nonPositiveFilter: Dict;\n\n /** Sort order to apply at the end */\n pathOrder: VgSort;\n\n /**\n * Stack transforms to be applied.\n */\n stack: StackComponent;\n\n /** Array of summary component object for producing summary (aggregate) data source */\n summary: SummaryComponent[];\n}\n\n/**\n * Composable component for a model's summary data\n */\nexport interface SummaryComponent {\n /** Name of the summary data source */\n name: string;\n\n /** String set for all dimension fields */\n dimensions: StringSet;\n\n /** dictionary mapping field name to string set of aggregate ops */\n measures: Dict;\n}\n\n// TODO: split this file into multiple files and remove this linter flag\n/* tslint:disable:no-use-before-declare */\n\nexport function parseUnitData(model: UnitModel): DataComponent {\n return {\n formatParse: formatParse.parseUnit(model),\n nullFilter: nullFilter.parseUnit(model),\n filter: filter.parseUnit(model),\n nonPositiveFilter: nonPositiveFilter.parseUnit(model),\n pathOrder: pathOrder.parseUnit(model),\n\n source: source.parseUnit(model),\n bin: bin.parseUnit(model),\n calculate: formula.parseUnit(model),\n timeUnit: timeUnit.parseUnit(model),\n summary: summary.parseUnit(model),\n stack: stack.parseUnit(model)\n };\n}\n\nexport function parseFacetData(model: FacetModel): DataComponent {\n return {\n formatParse: formatParse.parseFacet(model),\n nullFilter: nullFilter.parseFacet(model),\n filter: filter.parseFacet(model),\n nonPositiveFilter: nonPositiveFilter.parseFacet(model),\n pathOrder: pathOrder.parseFacet(model),\n\n source: source.parseFacet(model),\n bin: bin.parseFacet(model),\n calculate: formula.parseFacet(model),\n timeUnit: timeUnit.parseFacet(model),\n summary: summary.parseFacet(model),\n stack: stack.parseFacet(model)\n };\n}\n\nexport function parseLayerData(model: LayerModel): DataComponent {\n return {\n // filter and formatParse could cause us to not be able to merge into parent\n // so let's parse them first\n filter: filter.parseLayer(model),\n formatParse: formatParse.parseLayer(model),\n nullFilter: nullFilter.parseLayer(model),\n nonPositiveFilter: nonPositiveFilter.parseLayer(model),\n pathOrder: pathOrder.parseLayer(model),\n\n // everything after here does not affect whether we can merge child data into parent or not\n source: source.parseLayer(model),\n bin: bin.parseLayer(model),\n calculate: formula.parseLayer(model),\n timeUnit: timeUnit.parseLayer(model),\n summary: summary.parseLayer(model),\n stack: stack.parseLayer(model)\n };\n}\n\n/* tslint:enable:no-use-before-declare */\n\n/**\n * Creates Vega Data array from a given compiled model and append all of them to the given array\n *\n * @param model\n * @param data array\n * @return modified data array\n */\nexport function assembleData(model: Model, data: VgData[]) {\n const dataComponent = model.component.data;\n\n const sourceData = source.assemble(dataComponent);\n if (sourceData) {\n data.push(sourceData);\n }\n\n summary.assemble(dataComponent.summary || [], model.dataName(SOURCE)).forEach(function(summaryData) {\n data.push(summaryData);\n });\n\n // nonPositiveFilter\n const nonPositiveFilterTransform = nonPositiveFilter.assemble(dataComponent.nonPositiveFilter);\n if (nonPositiveFilterTransform.length > 0) {\n if (data.length > 0) {\n const dataTable = data[data.length - 1];\n dataTable.transform = (dataTable.transform || []).concat(nonPositiveFilterTransform);\n } else { /* istanbul ignore else: should never reach here */\n throw new Error('Invalid nonPositiveFilter not merged');\n }\n }\n\n // stack\n const stackData = stack.assemble(dataComponent.stack);\n if (stackData) {\n data.push(stackData);\n }\n\n // Path Order\n const pathOrderCollectTransform = pathOrder.assemble(dataComponent.pathOrder);\n if (pathOrderCollectTransform) {\n const dataTable = data[data.length - 1];\n if (data.length > 0) {\n dataTable.transform = (dataTable.transform || []).concat([pathOrderCollectTransform]);\n } else { /* istanbul ignore else: should never reach here */\n throw new Error('Invalid path order collect transform not added');\n }\n }\n\n return data;\n}\n", + "import {DataComponentCompiler} from './base';\n\nimport {expression} from '../../filter';\nimport {isArray} from '../../util';\n\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {Model} from '../model';\n\n/**\n * @param v value to be converted into Vega Expression\n * @param timeUnit\n * @return Vega Expression of the value v. This could be one of:\n * - a timestamp value of datetime object\n * - a timestamp value of casted single time unit value\n * - stringified value\n */\n\nfunction parse(model: Model): string {\n const filter = model.filter();\n if (isArray(filter)) {\n return '(' +\n filter.map((f) => expression(f))\n .filter((f) => f !==undefined)\n .join(') && (') +\n ')';\n } else if (filter) {\n return expression(filter);\n }\n return undefined;\n}\n\nexport const filter: DataComponentCompiler = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n let filterComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source but has filter, then merge\n if (!childDataComponent.source && childDataComponent.filter) {\n // merge by adding &&\n filterComponent =\n (filterComponent ? filterComponent + ' && ' : '') +\n childDataComponent.filter;\n delete childDataComponent.filter;\n }\n return filterComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n // Note that this `filter.parseLayer` method is called before `source.parseLayer`\n let filterComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && childDataComponent.filter && childDataComponent.filter === filterComponent) {\n // same filter in child so we can just delete it\n delete childDataComponent.filter;\n }\n });\n return filterComponent;\n },\n\n assemble: function(filterComponent: string) {\n return filterComponent ? [{\n type: 'filter',\n expr: filterComponent\n }] : [];\n }\n};\n", + "import {DataComponentCompiler} from './base';\n\nimport {isDateTime, DateTime} from '../../datetime';\nimport {isUrlData} from '../../data';\nimport {FieldDef, isCount} from '../../fielddef';\nimport {isOneOfFilter, isEqualFilter, isRangeFilter} from '../../filter';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {extend, differ, keys, isArray, isNumber, isString, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nfunction parse(model: Model): Dict {\n const calcFieldMap = (model.calculate() || []).reduce(function(fieldMap, formula) {\n fieldMap[formula.as] = true;\n return fieldMap;\n }, {});\n\n let parseComponent: Dict = {};\n\n // Parse filter fields\n let filter = model.filter();\n if (!isArray(filter)) {\n filter = [filter];\n }\n filter.forEach(f => {\n let val: string | number | boolean | DateTime = null;\n // For EqualFilter, just use the equal property.\n // For RangeFilter and OneOfFilter, all array members should have\n // the same type, so we only use the first one.\n if (isEqualFilter(f)) {\n val = f.equal;\n } else if (isRangeFilter(f)) {\n val = f.range[0];\n } else if (isOneOfFilter(f)) {\n val = (f.oneOf || f['in'])[0];\n } // else -- for filter expression, we can't infer anything\n\n if (!!val) {\n if (isDateTime(val)) {\n parseComponent[f['field']] = 'date';\n } else if (isNumber(val)) {\n parseComponent[f['field']] = 'number';\n } else if (isString(val)) {\n parseComponent[f['field']] = 'string';\n }\n }\n });\n\n // Parse encoded fields\n model.forEachFieldDef(function(fieldDef: FieldDef) {\n if (fieldDef.type === TEMPORAL) {\n parseComponent[fieldDef.field] = 'date';\n } else if (fieldDef.type === QUANTITATIVE) {\n if (isCount(fieldDef) || calcFieldMap[fieldDef.field]) {\n return;\n }\n parseComponent[fieldDef.field] = 'number';\n }\n });\n\n // Custom parse should override inferred parse\n const data = model.data;\n if (data && isUrlData(data) && data.format && data.format.parse) {\n const parse = data.format.parse;\n keys(parse).forEach((field) => {\n parseComponent[field] = parse[field];\n });\n }\n\n return parseComponent;\n}\n\nexport const formatParse: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n let parseComponent = parse(model);\n\n // If child doesn't have its own data source, but has its own parse, then merge\n const childDataComponent = model.child.component.data;\n if (!childDataComponent.source && childDataComponent.formatParse) {\n extend(parseComponent, childDataComponent.formatParse);\n delete childDataComponent.formatParse;\n }\n return parseComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n let parseComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && !differ(childDataComponent.formatParse, parseComponent)) {\n // merge parse up if the child does not have an incompatible parse\n extend(parseComponent, childDataComponent.formatParse);\n delete childDataComponent.formatParse;\n }\n });\n return parseComponent;\n },\n\n // identity function\n assemble: function (x) {return x;}\n};\n", + "import {DataComponentCompiler} from './base';\n\nimport {Formula} from '../../transform';\nimport {extend, vals, hash, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nfunction parse(model: Model): Dict {\n return (model.calculate() || []).reduce(function(formulaComponent, formula) {\n formulaComponent[hash(formula)] = formula;\n return formulaComponent;\n }, {});\n}\n\nexport const formula: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel): Dict {\n let formulaComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(formulaComponent, childDataComponent.calculate);\n delete childDataComponent.calculate;\n }\n return formulaComponent;\n },\n\n parseLayer: function(model: LayerModel): Dict {\n let formulaComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (!childDataComponent.source && childDataComponent.calculate) {\n extend(formulaComponent || {}, childDataComponent.calculate);\n delete childDataComponent.calculate;\n }\n });\n return formulaComponent;\n },\n\n assemble: function(component: Dict) {\n return vals(component).reduce(function(transform: any, f: any) {\n transform.push(extend({type: 'formula'}, f));\n return transform;\n }, []);\n }\n};\n", + "import {DataComponentCompiler} from './base';\n\nimport {ScaleType} from '../../scale';\nimport {extend, keys, differ, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\n\nexport const nonPositiveFilter: DataComponentCompiler> = {\n parseUnit: function(model: Model): Dict {\n return model.channels().reduce(function(nonPositiveComponent, channel) {\n const scale = model.scale(channel);\n if (!model.field(channel) || !scale) {\n // don't set anything\n return nonPositiveComponent;\n }\n nonPositiveComponent[model.field(channel)] = scale.type === ScaleType.LOG;\n return nonPositiveComponent;\n }, {});\n },\n\n parseFacet: function(model: FacetModel) {\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then consider merging\n if (!childDataComponent.source) {\n // For now, let's assume it always has union scale\n const nonPositiveFilterComponent = childDataComponent.nonPositiveFilter;\n delete childDataComponent.nonPositiveFilter;\n return nonPositiveFilterComponent;\n }\n return {};\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n let nonPositiveFilterComponent = {};\n\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && !differ(childDataComponent.nonPositiveFilter, nonPositiveFilterComponent)) {\n extend(nonPositiveFilterComponent, childDataComponent.nonPositiveFilter);\n delete childDataComponent.nonPositiveFilter;\n }\n });\n\n return nonPositiveFilterComponent;\n },\n\n assemble: function(nonPositiveFilterComponent: Dict) {\n if (nonPositiveFilterComponent) {\n return keys(nonPositiveFilterComponent).filter((field) => {\n // Only filter fields (keys) with value = true\n return nonPositiveFilterComponent[field];\n }).map(function(field) {\n return {\n type: 'filter',\n expr: 'datum[\"' + field + '\"] > 0'\n };\n });\n }\n return [];\n }\n};\n", + "import {DataComponentCompiler} from './base';\n\nimport {FieldDef} from '../../fielddef';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {contains, extend, keys, differ, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nconst DEFAULT_NULL_FILTERS = {\n nominal: false,\n ordinal: false,\n quantitative: true,\n temporal: true\n};\n\n/** Return Hashset of fields for null filtering (key=field, value = true). */\nfunction parse(model: Model): Dict {\n const filterInvalid = model.filterInvalid();\n\n return model.reduceFieldDef(function(aggregator: Dict, fieldDef: FieldDef) {\n if (fieldDef.field !== '*') { // Ignore * for count(*) fields.\n if (filterInvalid ||\n (filterInvalid === undefined && fieldDef.field && DEFAULT_NULL_FILTERS[fieldDef.type])) {\n aggregator[fieldDef.field] = fieldDef;\n } else {\n // define this so we know that we don't filter nulls for this field\n // this makes it easier to merge into parents\n aggregator[fieldDef.field] = null;\n }\n }\n return aggregator;\n }, {});\n}\n\nexport const nullFilter: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n const nullFilterComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(nullFilterComponent, childDataComponent.nullFilter);\n delete childDataComponent.nullFilter;\n }\n return nullFilterComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n\n // FIXME: null filters are not properly propagated right now\n let nullFilterComponent = parse(model);\n\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && !differ(childDataComponent.nullFilter, nullFilterComponent)) {\n extend(nullFilterComponent, childDataComponent.nullFilter);\n delete childDataComponent.nullFilter;\n }\n });\n\n return nullFilterComponent;\n },\n\n assemble: function(component: Dict) {\n const filters = keys(component).reduce((_filters, field) => {\n const fieldDef = component[field];\n if (fieldDef !== null) {\n _filters.push('datum[\"' + fieldDef.field + '\"] !== null');\n if (contains([QUANTITATIVE, TEMPORAL], fieldDef.type)) {\n // TODO(https://github.com/vega/vega-lite/issues/1436):\n // We can be even smarter and add NaN filter for N,O that are numbers\n // based on the `parse` property once we have it.\n _filters.push('!isNaN(datum[\"'+ fieldDef.field + '\"])');\n }\n }\n return _filters;\n }, []);\n\n return filters.length > 0 ?\n [{\n type: 'filter',\n expr: filters.join(' && ')\n }] : [];\n }\n};\n", + "import * as stringify from 'json-stable-stringify';\n\nimport {DataComponentCompiler} from './base';\n\nimport {isAggregate} from '../../encoding';\nimport {field} from '../../fielddef';\nimport {isSortField} from '../../sort';\nimport {VgSort} from '../../vega.schema';\nimport {contains} from '../../util';\n\nimport {sortParams} from '../common';\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {UnitModel} from '../unit';\n\nexport const pathOrder: DataComponentCompiler = {\n parseUnit: function(model: UnitModel): VgSort {\n if (contains(['line', 'area'], model.mark())) {\n if (model.mark() === 'line' && model.channelHasField('order')) {\n // For only line, sort by the order field if it is specified.\n return sortParams(model.encoding.order);\n } else {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannel: 'x' | 'y' = model.markDef.orient === 'horizontal' ? 'y' : 'x';\n const sort = model.sort(dimensionChannel);\n const sortField = isSortField(sort) ?\n field({\n // FIXME: this op might not already exist?\n // FIXME: what if dimensionChannel (x or y) contains custom domain?\n aggregate: isAggregate(model.encoding) ? sort.op : undefined,\n field: sort.field\n }) :\n model.field(dimensionChannel, {binSuffix: 'start'});\n\n return {\n field: sortField,\n order: 'descending'\n };\n }\n\n }\n return null;\n },\n\n parseFacet: function(model: FacetModel) {\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then consider merging\n if (!childDataComponent.source) {\n // For now, let's assume it always has union scale\n const pathOrderComponent = childDataComponent.pathOrder;\n delete childDataComponent.pathOrder;\n return pathOrderComponent;\n }\n return null;\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n let pathOrderComponent: VgSort = null;\n let stringifiedPathOrder: string = null;\n\n for (let child of model.children) {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && childDataComponent.pathOrder !== null) {\n if (pathOrderComponent === null) {\n pathOrderComponent = childDataComponent.pathOrder;\n stringifiedPathOrder = stringify(pathOrderComponent);\n } else if (stringifiedPathOrder !== stringify(childDataComponent.pathOrder)) {\n pathOrderComponent = null;\n break;\n }\n }\n }\n\n if (pathOrderComponent !== null) {\n // If we merge pathOrderComponent, remove them from children.\n for (let child of model.children) {\n delete child.component.data.pathOrder;\n }\n }\n\n return pathOrderComponent;\n },\n\n assemble: function(pathOrderComponent: VgSort) {\n if (pathOrderComponent) {\n return {\n type: 'collect',\n sort: pathOrderComponent\n };\n }\n return null;\n }\n};\n", + "import {DataFormat, isNamedData, isInlineData, isUrlData, SOURCE} from '../../data';\nimport {contains, extend} from '../../util';\nimport {VgData} from '../../vega.schema';\n\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {Model} from './../model';\n\nimport {DataComponent} from './data';\nimport {nullFilter} from './nullfilter';\nimport {filter} from './filter';\nimport {bin} from './bin';\nimport {formula} from './formula';\nimport {timeUnit} from './timeunit';\n\nexport namespace source {\n function parse(model: Model): VgData {\n let data = model.data;\n\n if (data) {\n // If data is explicitly provided\n\n let sourceData: VgData = {name: model.dataName(SOURCE)};\n if (isInlineData(data)) {\n sourceData.values = data.values;\n sourceData.format = {type: 'json'};\n } else if (isUrlData(data)) {\n sourceData.url = data.url;\n\n // Extract extension from URL using snippet from\n // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript\n let defaultExtension = /(?:\\.([^.]+))?$/.exec(sourceData.url)[1];\n if (!contains(['json', 'csv', 'tsv', 'topojson'], defaultExtension)) {\n defaultExtension = 'json';\n }\n const dataFormat: DataFormat = data.format || {};\n\n // For backward compatibility for former `data.formatType` property\n const formatType: DataFormat = dataFormat.type || data['formatType'];\n sourceData.format =\n extend(\n {type: formatType ? formatType : defaultExtension},\n dataFormat.property ? {property: dataFormat.property} : {},\n // Feature and mesh are two mutually exclusive properties\n dataFormat.feature ?\n {feature : dataFormat.feature} :\n dataFormat.mesh ?\n {mesh : dataFormat.mesh} :\n {}\n );\n } else if (isNamedData(data)) {\n return {name: data.name};\n }\n\n return sourceData;\n } else if (!model.parent) {\n // If data is not explicitly provided but the model is a root,\n // need to produce a source as well\n return {name: model.dataName(SOURCE)};\n }\n return undefined;\n }\n\n export const parseUnit: (model: Model) => VgData = parse;\n\n export function parseFacet(model: FacetModel) {\n let sourceData = parse(model);\n if (!model.child.component.data.source) {\n // If the child does not have its own source, have to rename its source.\n model.child.renameData(model.child.dataName(SOURCE), model.dataName(SOURCE));\n }\n\n return sourceData;\n }\n\n export function parseLayer(model: LayerModel) {\n let sourceData = parse(model);\n model.children.forEach((child) => {\n const childData = child.component.data;\n\n if (model.compatibleSource(child)) {\n // we cannot merge if the child has filters defined even after we tried to move them up\n const canMerge = !childData.filter && !childData.formatParse && !childData.nullFilter;\n if (canMerge) {\n // rename source because we can just remove it\n child.renameData(child.dataName(SOURCE), model.dataName(SOURCE));\n delete childData.source;\n } else {\n // child does not have data defined or the same source so just use the parents source\n childData.source = {\n name: child.dataName(SOURCE),\n source: model.dataName(SOURCE)\n };\n }\n }\n });\n return sourceData;\n }\n\n export function assemble(component: DataComponent) {\n if (component.source) {\n let sourceData: VgData = component.source;\n\n if (component.formatParse) {\n component.source.format = component.source.format || {};\n component.source.format.parse = component.formatParse;\n }\n\n sourceData.transform = [].concat(\n formula.assemble(component.calculate),\n nullFilter.assemble(component.nullFilter),\n filter.assemble(component.filter),\n bin.assemble(component.bin),\n timeUnit.assemble(component.timeUnit)\n );\n\n return sourceData;\n }\n return null;\n }\n}\n", + "import {DataComponentCompiler} from './base';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {UnitModel} from './../unit';\n\nimport {sortParams} from '../common';\nimport {STACKED, SUMMARY} from '../../data';\nimport {FieldDef, field} from '../../fielddef';\nimport {hasDiscreteDomain} from '../../scale';\nimport {StackOffset} from '../../stack';\nimport {contains} from '../../util';\nimport {VgData, VgSort, VgStackTransform, VgImputeTransform} from '../../vega.schema';\n\nexport interface StackComponent {\n /**\n * Name of the output stacked data source\n */\n name: string;\n\n /**\n * Name of the input source data for stacked data source\n */\n source: string;\n\n /**\n * Grouping fields for stacked charts. This includes one of x- or 'y-field and may include faceted field.\n */\n groupby: string[];\n\n /**\n * Stack measure's field\n */\n field: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n */\n stackby: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n */\n sort: VgSort;\n\n /** Mode for stacking marks. */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking.\n */\n impute: boolean;\n}\n\n\nfunction getStackByFields(model: UnitModel) {\n return model.stack.stackBy.reduce((fields, by) => {\n const channel = by.channel;\n const fieldDef = by.fieldDef;\n\n const scale = model.scale(channel);\n const _field = field(fieldDef, {\n binSuffix: scale && hasDiscreteDomain(scale.type) ? 'range' : 'start'\n });\n if (!!_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\n/**\n * Stack data compiler\n */\nexport const stack: DataComponentCompiler = {\n\n parseUnit: function(model: UnitModel): StackComponent {\n const stackProperties = model.stack;\n if (!stackProperties) {\n return undefined;\n }\n\n const groupby = [];\n if (stackProperties.groupbyChannel) {\n const groupbyFieldDef = model.fieldDef(stackProperties.groupbyChannel);\n if (groupbyFieldDef.bin) {\n // For Bin, we need to add both start and end to ensure that both get imputed\n // and included in the stack output (https://github.com/vega/vega-lite/issues/1805).\n groupby.push(model.field(stackProperties.groupbyChannel, {binSuffix: 'start'}));\n groupby.push(model.field(stackProperties.groupbyChannel, {binSuffix: 'end'}));\n } else {\n groupby.push(model.field(stackProperties.groupbyChannel));\n }\n }\n\n const stackby = getStackByFields(model);\n const orderDef = model.encoding.order;\n\n let sort: VgSort;\n if (orderDef) {\n sort = sortParams(orderDef);\n } else {\n // default = descending by stackFields\n // FIXME is the default here correct for binned fields?\n sort = stackby.reduce((s, field) => {\n s.field.push(field);\n s.order.push('descending');\n return s;\n }, {field:[], order: []});\n }\n\n return {\n name: model.dataName(STACKED),\n source: model.dataName(SUMMARY),\n groupby: groupby,\n field: model.field(stackProperties.fieldChannel),\n stackby: stackby,\n sort: sort,\n offset: stackProperties.offset,\n impute: contains(['area', 'line'], model.mark())\n };\n },\n\n parseLayer: function(model: LayerModel): StackComponent {\n // FIXME: merge if identical\n // FIXME: Correctly support facet of layer of stack.\n return undefined;\n },\n\n parseFacet: function(model: FacetModel): StackComponent {\n const child = model.child;\n const childDataComponent = child.component.data;\n // FIXME: Correctly support facet of layer of stack.\n if (childDataComponent.stack) {\n let stackComponent = childDataComponent.stack;\n\n const newName = model.dataName(STACKED);\n child.renameData(stackComponent.name, newName);\n stackComponent.name = newName;\n\n // Refer to facet's summary instead (always summary because stacked only works with aggregation)\n stackComponent.source = model.dataName(SUMMARY);\n\n // Add faceted field to groupby\n stackComponent.groupby = model.reduceFieldDef((groupby: string[], fieldDef: FieldDef) => {\n const facetedField = field(fieldDef, {binSuffix: 'start'});\n if (!contains(groupby, facetedField)) {\n groupby.push(facetedField);\n }\n return groupby;\n }, stackComponent.groupby);\n\n delete childDataComponent.stack;\n return stackComponent;\n }\n return undefined;\n },\n assemble: (stackComponent: StackComponent): VgData => {\n if (!stackComponent) {\n return undefined;\n }\n\n let transform: (VgStackTransform|VgImputeTransform)[] = [];\n // Impute\n if (stackComponent.impute) {\n transform.push({\n type: 'impute',\n field: stackComponent.field,\n groupby: stackComponent.stackby,\n orderby: stackComponent.groupby,\n method: 'value',\n value: 0\n });\n }\n\n // Stack\n transform.push({\n type: 'stack',\n groupby: stackComponent.groupby,\n field: stackComponent.field,\n sort: stackComponent.sort,\n as: [\n stackComponent.field + '_start',\n stackComponent.field + '_end'\n ],\n offset: stackComponent.offset\n });\n\n return {\n name: stackComponent.name,\n source: stackComponent.source,\n transform: transform\n };\n }\n};\n", + "import {SUMMARY} from '../../data';\nimport {field, FieldDef} from '../../fielddef';\nimport {keys, vals, reduce, hash, Dict, StringSet} from '../../util';\nimport {VgData} from '../../vega.schema';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nimport {SummaryComponent} from './data';\n\n\nexport namespace summary {\n function addDimension(dims: {[field: string]: boolean}, fieldDef: FieldDef) {\n if (fieldDef.bin) {\n dims[field(fieldDef, {binSuffix: 'start'})] = true;\n dims[field(fieldDef, {binSuffix: 'end'})] = true;\n\n // const scale = model.scale(channel);\n // if (scaleType(scale, fieldDef, channel, model.mark()) === ScaleType.ORDINAL) {\n // also produce bin_range if the binned field use ordinal scale\n dims[field(fieldDef, {binSuffix: 'range'})] = true;\n // }\n } else {\n dims[field(fieldDef)] = true;\n }\n return dims;\n }\n\n export function parseUnit(model: Model): SummaryComponent[] {\n /* string set for dimensions */\n const dims: StringSet = {};\n\n /* dictionary mapping field name => dict set of aggregation functions */\n const meas: Dict = {};\n\n model.forEachFieldDef(function(fieldDef, channel) {\n if (fieldDef.aggregate) {\n if (fieldDef.aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n /* tslint:disable:no-string-literal */\n meas['*']['count'] = true;\n /* tslint:enable:no-string-literal */\n } else {\n meas[fieldDef.field] = meas[fieldDef.field] || {};\n meas[fieldDef.field][fieldDef.aggregate] = true;\n\n // add min/max so we can use their union as unaggregated domain\n const scale = model.scale(channel);\n if (scale && scale.domain === 'unaggregated') {\n meas[fieldDef.field]['min'] = true;\n meas[fieldDef.field]['max'] = true;\n }\n }\n } else {\n addDimension(dims, fieldDef);\n };\n });\n\n return [{\n name: model.dataName(SUMMARY),\n dimensions: dims,\n measures: meas\n }];\n }\n\n export function parseFacet(model: FacetModel): SummaryComponent[] {\n const childDataComponent = model.child.component.data;\n\n // FIXME: this could be incorrect for faceted layer charts.\n\n // If child doesn't have its own data source but has a summary data source, merge\n if (!childDataComponent.source && childDataComponent.summary) {\n let summaryComponents = childDataComponent.summary.map(function(summaryComponent) {\n // add facet fields as dimensions\n summaryComponent.dimensions = model.reduceFieldDef(addDimension, summaryComponent.dimensions);\n\n const summaryNameWithoutPrefix = summaryComponent.name.substr(model.child.getName('').length);\n model.child.renameData(summaryComponent.name, summaryNameWithoutPrefix);\n summaryComponent.name = summaryNameWithoutPrefix;\n return summaryComponent;\n });\n\n delete childDataComponent.summary;\n return summaryComponents;\n }\n return [];\n }\n\n function mergeMeasures(parentMeasures: Dict>, childMeasures: Dict>) {\n for (const field in childMeasures) {\n if (childMeasures.hasOwnProperty(field)) {\n // when we merge a measure, we either have to add an aggregation operator or even a new field\n const ops = childMeasures[field];\n for (const op in ops) {\n if (ops.hasOwnProperty(op)) {\n if (field in parentMeasures) {\n // add operator to existing measure field\n parentMeasures[field][op] = true;\n } else {\n parentMeasures[field] = {op: true};\n }\n }\n }\n }\n }\n }\n\n export function parseLayer(model: LayerModel): SummaryComponent[] {\n // Index by the fields we are grouping by\n let summaries = {};\n\n // Combine summaries for children that don't have a distinct source\n // (either having its own data source, or its own tranformation of the same data source).\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (!childDataComponent.source && childDataComponent.summary) {\n // Merge the summaries if we can\n childDataComponent.summary.forEach((childSummary) => {\n // The key is a hash based on the dimensions;\n // we use it to find out whether we have a summary that uses the same group by fields.\n const key = hash(childSummary.dimensions);\n if (key in summaries) {\n // yes, there is a summary hat we need to merge into\n // we know that the dimensions are the same so we only need to merge the measures\n mergeMeasures(summaries[key].measures, childSummary.measures);\n } else {\n // give the summary a new name\n childSummary.name = model.dataName(SUMMARY) + '_' + keys(summaries).length;\n summaries[key] = childSummary;\n }\n\n // remove summary from child\n child.renameData(child.dataName(SUMMARY), summaries[key].name);\n delete childDataComponent.summary;\n });\n }\n });\n\n return vals(summaries);\n }\n\n /**\n * Assemble the summary. Needs a rename function because we cannot guarantee that the\n * parent data before the children data.\n */\n export function assemble(component: SummaryComponent[], sourceName: string): VgData[] {\n return component.reduce(function(summaryData, summaryComponent) {\n const dims = summaryComponent.dimensions;\n const meas = summaryComponent.measures;\n\n if (keys(meas).length > 0) { // has aggregate\n const groupby = keys(dims);\n const transform = reduce(meas, function(t, fnDictSet, field) {\n const ops = keys(fnDictSet);\n for (const op of ops) {\n t.fields.push(field);\n t.ops.push(op);\n }\n return t;\n }, {\n type: 'aggregate',\n groupby: groupby,\n fields: [],\n ops: []\n });\n\n summaryData.push({\n name: summaryComponent.name,\n source: sourceName,\n transform: [transform]\n });\n }\n return summaryData;\n }, []);\n }\n}\n", + "import {DataComponentCompiler} from './base';\n\nimport {field, FieldDef} from '../../fielddef';\nimport {fieldExpr} from '../../timeunit';\nimport {TEMPORAL} from '../../type';\nimport {extend, vals, Dict} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\n\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {Model} from '../model';\n\nfunction parse(model: Model): Dict {\n return model.reduceFieldDef(function(timeUnitComponent: Dict, fieldDef: FieldDef) {\n if (fieldDef.type === TEMPORAL && fieldDef.timeUnit) {\n\n const f = field(fieldDef);\n timeUnitComponent[f] = {\n type: 'formula',\n as: f,\n expr: fieldExpr(fieldDef.timeUnit, fieldDef.field)\n };\n }\n return timeUnitComponent;\n }, {});\n}\n\nexport const timeUnit: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function (model: FacetModel) {\n let timeUnitComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(timeUnitComponent, childDataComponent.timeUnit);\n delete childDataComponent.timeUnit;\n }\n return timeUnitComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n let timeUnitComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (!childDataComponent.source) {\n extend(timeUnitComponent, childDataComponent.timeUnit);\n delete childDataComponent.timeUnit;\n }\n });\n return timeUnitComponent;\n },\n assemble: function(component: Dict) {\n // just join the values, which are already transforms\n return vals(component);\n }\n};\n", + "import * as log from '../log';\n\nimport {Axis, VlOnlyAxisBase, VL_ONLY_AXIS_PROPERTIES} from '../axis';\nimport {COLUMN, ROW, X, Y, Channel} from '../channel';\nimport {defaultConfig, Config} from '../config';\nimport {Facet} from '../facet';\nimport {forEach} from '../encoding';\nimport {FieldDef, normalize} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Scale} from '../scale';\nimport {FacetSpec} from '../spec';\nimport {contains, extend, keys, vals, flatten, duplicate, mergeDeep, Dict} from '../util';\nimport {VgData, VgEncodeEntry} from '../vega.schema';\nimport {StackProperties} from '../stack';\n\nimport {parseMainAxis, parseGridAxis, parseAxisComponent} from './axis/parse';\nimport {gridShow} from './axis/rules';\nimport {buildModel} from './common';\nimport {assembleData, parseFacetData} from './data/data';\nimport {assembleLayout, parseFacetLayout} from './layout';\nimport {Model} from './model';\n\nimport initScale from './scale/init';\nimport parseScaleComponent from './scale/parse';\n\n/**\n * Prefix for special data sources for driving column's axis group.\n */\n\nexport const COLUMN_AXES_DATA_PREFIX = 'column-';\n\n/**\n * Prefix for special data sources for driving row's axis group.\n */\nexport const ROW_AXES_DATA_PREFIX = 'row-';\n\nexport class FacetModel extends Model {\n public readonly facet: Facet;\n\n public readonly child: Model;\n\n public readonly children: Model[];\n protected readonly scales: Dict = {};\n\n protected readonly axes: Dict = {};\n\n protected readonly legends: Dict = {};\n\n public readonly config: Config;\n\n public readonly stack: StackProperties = null;\n\n private readonly _spacing: {\n row?: number;\n column?: number;\n } = {};\n\n constructor(spec: FacetSpec, parent: Model, parentGivenName: string) {\n super(spec, parent, parentGivenName);\n\n // Config must be initialized before child as it gets cascaded to the child\n const config = this.config = this.initConfig(spec.config, parent);\n\n const child = this.child = buildModel(spec.spec, this, this.getName('child'));\n this.children = [child];\n\n const facet = this.facet = this.initFacet(spec.facet);\n this.scales = this.initScalesAndSpacing(facet, config);\n this.axes = this.initAxis(facet, config, child);\n this.legends = {};\n }\n\n private initConfig(specConfig: Config, parent: Model) {\n return mergeDeep(duplicate(defaultConfig), parent ? parent.config : {}, specConfig);\n }\n\n private initFacet(facet: Facet) {\n // clone to prevent side effect to the original spec\n facet = duplicate(facet);\n\n forEach(facet, function(fieldDef: FieldDef, channel: Channel) {\n if (!contains([ROW, COLUMN], channel)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, 'facet'));\n delete facet[channel];\n return;\n }\n\n // TODO: array of row / column ?\n if (fieldDef.field === undefined) { // TODO: datum\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n delete facet[channel];\n return;\n }\n\n // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n normalize(fieldDef, channel);\n });\n return facet;\n }\n\n private initScalesAndSpacing(facet: Facet, config: Config): Dict {\n const model = this;\n return [ROW, COLUMN].reduce(function(_scale, channel) {\n if (facet[channel]) {\n _scale[channel] = initScale(\n channel, facet[channel], config,\n undefined, // Facet doesn't have one single mark\n undefined, // TODO(#1647): support width / height here\n [] // There is no xyRangeSteps here and there is no need to input\n );\n\n model._spacing[channel] = spacing(facet[channel].scale || {}, model, config);\n }\n return _scale;\n }, {});\n }\n\n private initAxis(facet: Facet, config: Config, child: Model): Dict {\n const model = this;\n return [ROW, COLUMN].reduce(function(_axis, channel) {\n if (facet[channel]) {\n const axisSpec = facet[channel].axis;\n if (axisSpec !== false) {\n let vlOnlyAxisProperties: VlOnlyAxisBase = {};\n VL_ONLY_AXIS_PROPERTIES.forEach(function(property) {\n if (config.facet.axis[property] !== undefined) {\n vlOnlyAxisProperties[property] = config.facet.axis[property];\n }\n });\n\n const modelAxis = _axis[channel] = {\n ...vlOnlyAxisProperties,\n ...axisSpec\n };\n\n if (channel === ROW) {\n const yAxis: any = child.axis(Y);\n if (yAxis && yAxis.orient !== 'right' && !modelAxis.orient) {\n modelAxis.orient = 'right';\n }\n if (model.hasDescendantWithFieldOnChannel(X) && !modelAxis.labelAngle) {\n modelAxis.labelAngle = modelAxis.orient === 'right' ? 90 : 270;\n }\n }\n }\n }\n return _axis;\n }, {});\n }\n\n public channelHasField(channel: Channel): boolean {\n return !!this.facet[channel];\n }\n\n private hasSummary() {\n const summary = this.component.data.summary;\n for (const s of summary) {\n if (keys(s.measures).length > 0) {\n return true;\n }\n }\n return false;\n }\n\n public facetedTable(): string {\n // FIXME: revise if the suffix should be 'data'\n return 'faceted-' + this.getName('data');\n }\n\n public dataTable(): string {\n // FIXME: shouldn't we apply data renaming here?\n if (this.component.data.stack) {\n return 'stacked';\n }\n if (this.hasSummary()) {\n return 'summary';\n }\n return 'source';\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return this.facet[channel];\n }\n\n public parseData() {\n this.child.parseData();\n this.component.data = parseFacetData(this);\n }\n\n public parseSelection() {\n // TODO: @arvind can write this\n // We might need to split this into compileSelectionData and compileSelectionSignals?\n }\n\n public parseLayoutData() {\n this.child.parseLayoutData();\n this.component.layout = parseFacetLayout(this);\n }\n\n public parseScale() {\n const child = this.child;\n const model = this;\n\n child.parseScale();\n\n // TODO: support scales for field reference of parent data (e.g., for SPLOM)\n\n // First, add scale for row and column.\n let scaleComponent = this.component.scales = parseScaleComponent(this);\n\n // Then, move shared/union from its child spec.\n keys(child.component.scales).forEach(function(channel) {\n // TODO: correctly implement independent scale\n if (true) { // if shared/union scale\n const scale = scaleComponent[channel] = child.component.scales[channel];\n\n const scaleNameWithoutPrefix = scale.name.substr(child.getName('').length);\n const newName = model.scaleName(scaleNameWithoutPrefix, true);\n child.renameScale(scale.name, newName);\n\n // Once put in parent, just remove the child's scale.\n delete child.component.scales[channel];\n }\n });\n }\n\n public parseMark() {\n this.child.parseMark();\n\n this.component.mark = extend(\n {\n name: this.getName('cell'),\n type: 'group',\n from: extend(\n {\n facet: {\n name: this.facetedTable(),\n data: this.dataTable(),\n groupby: [].concat(\n this.channelHasField(ROW) ? [this.field(ROW)] : [],\n this.channelHasField(COLUMN) ? [this.field(COLUMN)] : []\n )\n }\n }\n ),\n encode: {\n update: getFacetGroupProperties(this)\n }\n },\n // FIXME: move this call to assembleMarks()\n // Call child's assembleGroup to add marks, scales, axes, and legends.\n // Note that we can call child's assembleGroup() here because parseMark()\n // is the last method in compile() and thus the child is completely compiled\n // at this point.\n this.child.assembleGroup()\n );\n }\n\n public parseAxis() {\n this.child.parseAxis();\n this.component.axes = parseAxisComponent(this, [ROW, COLUMN]);\n }\n\n public parseAxisGroup() {\n // TODO: with nesting, we might need to consider calling child\n // this.child.parseAxisGroup();\n\n const xAxisGroup = parseAxisGroups(this, X);\n const yAxisGroup = parseAxisGroups(this, Y);\n\n this.component.axisGroups = extend(\n xAxisGroup ? {x: xAxisGroup} : {},\n yAxisGroup ? {y: yAxisGroup} : {}\n );\n }\n\n public parseGridGroup() {\n // TODO: with nesting, we might need to consider calling child\n // this.child.parseGridGroup();\n\n const child = this.child;\n\n this.component.gridGroups = extend(\n !child.channelHasField(X) && this.channelHasField(COLUMN) ? {column: getColumnGridGroups(this)} : {},\n !child.channelHasField(Y) && this.channelHasField(ROW) ? {row: getRowGridGroups(this)} : {}\n );\n }\n\n public parseLegend() {\n this.child.parseLegend();\n\n // TODO: support legend for independent non-position scale across facets\n // TODO: support legend for field reference of parent data (e.g., for SPLOM)\n\n // For now, assuming that non-positional scales are always shared across facets\n // Thus, just move all legends from its child\n this.component.legends = this.child.component.legends;\n this.child.component.legends = {};\n }\n\n public assembleParentGroupProperties(): any {\n return null;\n }\n\n public assembleSignals(signals: any): any[] {\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return [];\n }\n\n public assembleData(data: VgData[]): VgData[] {\n // Prefix traversal – parent data might be referred by children data\n assembleData(this, data);\n this.child.assembleData(data);\n assembleAxesGroupData(this, data);\n\n return data;\n }\n\n\n public assembleLayout(layoutData: VgData[]): VgData[] {\n // Postfix traversal – layout is assembled bottom-up\n this.child.assembleLayout(layoutData);\n return assembleLayout(this, layoutData);\n }\n\n public assembleMarks(): any[] {\n return [].concat(\n // axisGroup is a mapping to VgMarkGroup\n vals(this.component.axisGroups),\n flatten(vals(this.component.gridGroups)),\n this.component.mark\n );\n }\n\n public channels() {\n return [ROW, COLUMN];\n }\n\n protected getMapping() {\n return this.facet;\n }\n\n public spacing(channel: Channel) {\n return this._spacing[channel];\n }\n\n public isFacet() {\n return true;\n }\n}\n\nexport function hasSubPlotWithXy(model: FacetModel) {\n return model.hasDescendantWithFieldOnChannel('x') ||\n model.hasDescendantWithFieldOnChannel('y');\n}\n\nexport function spacing(scale: Scale, model: FacetModel, config: Config) {\n if (scale.spacing !== undefined) {\n return scale.spacing;\n }\n\n if (!hasSubPlotWithXy(model)) {\n // If there is no subplot with x/y, it's a simple table so there should be no spacing.\n return 0;\n }\n return config.scale.facetSpacing;\n}\n\nfunction getFacetGroupProperties(model: FacetModel) {\n const child = model.child;\n const mergedCellConfig = extend({}, child.config.cell, child.config.facet.cell);\n\n return extend({\n x: model.channelHasField(COLUMN) ? {\n scale: model.scaleName(COLUMN),\n field: model.field(COLUMN),\n // offset by the spacing / 2\n offset: model.spacing(COLUMN) / 2\n } : {value: model.config.scale.facetSpacing / 2},\n\n y: model.channelHasField(ROW) ? {\n scale: model.scaleName(ROW),\n field: model.field(ROW),\n // offset by the spacing / 2\n offset: model.spacing(ROW) / 2\n } : {value: model.config.scale.facetSpacing / 2},\n\n width: {field: {parent: model.child.sizeName('width')}},\n height: {field: {parent: model.child.sizeName('height')}}\n },\n hasSubPlotWithXy(model) ? child.assembleParentGroupProperties(mergedCellConfig) : {}\n );\n}\n\n// TODO: move the rest of the file src/compile/facet/*.ts\n\n/**\n * Add data for driving row/column axes when there are both row and column\n * Note that we don't have to deal with these in the parse step at all\n * because these items never get merged with any other items.\n */\nexport function assembleAxesGroupData(model: FacetModel, data: VgData[]) {\n if (model.facet.column) {\n data.push({\n name: COLUMN_AXES_DATA_PREFIX + model.dataTable(),\n source: model.dataTable(),\n transform: [{\n type: 'aggregate',\n groupby: [model.field(COLUMN)]\n }]\n });\n }\n\n if (model.facet.row) {\n data.push({\n name: ROW_AXES_DATA_PREFIX + model.dataTable(),\n source: model.dataTable(),\n transform: [{\n type: 'aggregate',\n groupby: [model.field(ROW)]\n }]\n });\n }\n return data;\n}\n\nfunction parseAxisGroups(model: FacetModel, channel: 'x' | 'y') {\n // TODO: add a case where inner spec is not a unit (facet/layer/concat)\n let axisGroup: any = null;\n\n const child = model.child;\n if (child.channelHasField(channel)) {\n if (child.axis(channel)) {\n if (true) { // the channel has shared axes\n\n // add a group for the shared axes\n axisGroup = getSharedAxisGroup(model, channel);\n\n if (child.axis(channel) && gridShow(child, channel)) { // show inner grid\n // add inner axis (aka axis that shows only grid to )\n child.component.axes[channel] = [parseGridAxis(channel, child)];\n } else {\n // Delete existing child axes\n delete child.component.axes[channel];\n }\n } else {\n // TODO: implement independent axes support\n }\n }\n }\n return axisGroup;\n}\n\n\nexport function getSharedAxisGroup(model: FacetModel, channel: 'x' | 'y'): VgEncodeEntry {\n const isX = channel === 'x' ;\n const facetChannel = isX ? 'column' : 'row';\n const hasFacet = !!model.facet[facetChannel];\n const dataPrefix = isX ? COLUMN_AXES_DATA_PREFIX : ROW_AXES_DATA_PREFIX;\n\n let axesGroup: VgEncodeEntry = {\n name: model.getName(channel + '-axes'),\n type: 'group'\n };\n\n if (hasFacet) {\n // Need to drive this with special data source that has one item for each column/row value.\n\n // TODO: We might only need to drive this with special data source if there are both row and column\n // However, it might be slightly difficult as we have to merge this with the main group.\n axesGroup.from = {data: dataPrefix + model.dataTable()};\n }\n\n if (isX) {\n axesGroup.encode = {\n update: {\n width: {field: {parent: model.child.sizeName('width')}},\n height: {field: {group: 'height'}},\n x: hasFacet ? {\n scale: model.scaleName(COLUMN),\n field: model.field(COLUMN),\n // offset by the spacing\n offset: model.spacing(COLUMN) / 2\n } : {\n // TODO: support custom spacing here\n // offset by the spacing\n value: model.config.scale.facetSpacing / 2\n }\n }\n };\n } else {\n axesGroup.encode = {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {parent: model.child.sizeName('height')}},\n y: hasFacet ? {\n scale: model.scaleName(ROW),\n field: model.field(ROW),\n // offset by the spacing\n offset: model.spacing(ROW) / 2\n } : {\n // offset by the spacing\n value: model.config.scale.facetSpacing / 2\n }\n }\n };\n }\n\n axesGroup.axes = [parseMainAxis(channel, model.child)];\n return axesGroup;\n}\n\n\nfunction getRowGridGroups(model: Model): any[] { // TODO: VgMarks\n const facetGridConfig = model.config.facet.grid;\n\n const rowGrid = {\n name: model.getName('row-grid'),\n type: 'rule',\n from: {\n data: ROW_AXES_DATA_PREFIX + model.dataTable()\n },\n encode: {\n update: {\n y: {\n scale: model.scaleName(ROW),\n field: model.field(ROW)\n },\n x: {value: 0, offset: -facetGridConfig.offset},\n x2: {field: {group: 'width'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n };\n\n return [rowGrid, {\n name: model.getName('row-grid-end'),\n type: 'rule',\n encode: {\n update: {\n y: {field: {group: 'height'}},\n x: {value: 0, offset: -facetGridConfig.offset},\n x2: {field: {group: 'width'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n }];\n}\n\nfunction getColumnGridGroups(model: Model): any { // TODO: VgMarks\n const facetGridConfig = model.config.facet.grid;\n\n const columnGrid = {\n name: model.getName('column-grid'),\n type: 'rule',\n from: {\n data: COLUMN_AXES_DATA_PREFIX + model.dataTable()\n },\n encode: {\n update: {\n x: {\n scale: model.scaleName(COLUMN),\n field: model.field(COLUMN)\n },\n y: {value: 0, offset: -facetGridConfig.offset},\n y2: {field: {group: 'height'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n };\n\n return [columnGrid, {\n name: model.getName('column-grid-end'),\n type: 'rule',\n encode: {\n update: {\n x: {field: {group: 'width'}},\n y: {value: 0, offset: -facetGridConfig.offset},\n y2: {field: {group: 'height'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n }];\n}\n", + "import {Channel} from '../channel';\nimport {defaultConfig, CellConfig, Config} from '../config';\nimport {FieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Scale} from '../scale';\nimport {Axis} from '../axis';\nimport {LayerSpec} from '../spec';\nimport {StackProperties} from '../stack';\nimport {FILL_STROKE_CONFIG} from '../mark';\nimport {keys, duplicate, mergeDeep, flatten, Dict} from '../util';\nimport {VgData, VgEncodeEntry, isSignalRefDomain, VgScale} from '../vega.schema';\nimport {isUrlData} from '../data';\n\nimport {assembleData, parseLayerData} from './data/data';\nimport {applyConfig, buildModel} from './common';\nimport {assembleLayout, parseLayerLayout} from './layout';\nimport {Model} from './model';\nimport {UnitModel} from './unit';\n\nimport {unionDomains} from './scale/domain';\n\n\nexport class LayerModel extends Model {\n public readonly children: UnitModel[];\n\n protected readonly scales: Dict = {};\n\n protected readonly axes: Dict = {};\n\n protected readonly legends: Dict = {};\n\n public readonly config: Config;\n\n public readonly stack: StackProperties = null;\n\n /**\n * Fixed width for the unit visualization.\n * If undefined (e.g., for ordinal scale), the width of the\n * visualization will be calculated dynamically.\n */\n public readonly width: number;\n\n /**\n * Fixed height for the unit visualization.\n * If undefined (e.g., for ordinal scale), the height of the\n * visualization will be calculated dynamically.\n */\n public readonly height: number;\n\n constructor(spec: LayerSpec, parent: Model, parentGivenName: string) {\n super(spec, parent, parentGivenName);\n\n this.width = spec.width;\n this.height = spec.height;\n\n this.config = this.initConfig(spec.config, parent);\n this.children = spec.layer.map((layer, i) => {\n // we know that the model has to be a unit model because we pass in a unit spec\n return buildModel(layer, this, this.getName('layer_' + i)) as UnitModel;\n });\n }\n\n private initConfig(specConfig: Config, parent: Model) {\n return mergeDeep(duplicate(defaultConfig), specConfig, parent ? parent.config : {});\n }\n\n public channelHasField(channel: Channel): boolean {\n // layer does not have any channels\n return false;\n }\n\n public hasDiscreteScale(channel: Channel) {\n // since we assume shared scales we can just ask the first child\n return this.children[0].hasDiscreteScale(channel);\n }\n\n public dataTable() {\n // FIXME: don't just use the first child\n return this.children[0].dataTable();\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return null; // layer does not have field defs\n }\n\n public parseData() {\n this.children.forEach((child) => {\n child.parseData();\n });\n this.component.data = parseLayerData(this);\n }\n\n public parseSelection() {\n // TODO: @arvind can write this\n // We might need to split this into compileSelectionData and compileSelectionSignals?\n }\n\n public parseLayoutData() {\n // TODO: correctly union ordinal scales rather than just using the layout of the first child\n this.children.forEach(child => {\n child.parseLayoutData();\n });\n this.component.layout = parseLayerLayout(this);\n }\n\n public parseScale(this: LayerModel) {\n const model = this;\n\n const scaleComponent: Dict = this.component.scales = {};\n\n this.children.forEach(function(child) {\n child.parseScale();\n\n // FIXME(#1602): correctly implement independent scale\n // Also need to check whether the scales are actually compatible, e.g. use the same sort or throw error\n if (true) { // if shared/union scale\n keys(child.component.scales).forEach(function(channel) {\n let childScale = child.component.scales[channel];\n const modelScale = scaleComponent[channel];\n\n if (!childScale || isSignalRefDomain(childScale.domain) || (modelScale && isSignalRefDomain(modelScale.domain))) {\n // TODO: merge signal ref domains\n return;\n }\n\n if (modelScale) {\n modelScale.domain = unionDomains(modelScale.domain, childScale.domain);\n } else {\n scaleComponent[channel] = childScale;\n }\n\n // rename child scale to parent scales\n const scaleNameWithoutPrefix = childScale.name.substr(child.getName('').length);\n const newName = model.scaleName(scaleNameWithoutPrefix, true);\n child.renameScale(childScale.name, newName);\n\n // remove merged scales from children\n delete child.component.scales[channel];\n });\n }\n });\n }\n\n public parseMark() {\n this.children.forEach(function(child) {\n child.parseMark();\n });\n }\n\n public parseAxis() {\n let axisComponent = this.component.axes = {};\n\n this.children.forEach(function(child) {\n child.parseAxis();\n\n // TODO: correctly implement independent axes\n if (true) { // if shared/union scale\n keys(child.component.axes).forEach(function(channel) {\n // TODO: support multiple axes for shared scale\n\n // just use the first axis definition for each channel\n if (!axisComponent[channel]) {\n axisComponent[channel] = child.component.axes[channel];\n }\n });\n }\n });\n }\n\n public parseAxisGroup(): void {\n return null;\n }\n\n public parseGridGroup(): void {\n return null;\n }\n\n public parseLegend() {\n let legendComponent = this.component.legends = {};\n\n this.children.forEach(function(child) {\n child.parseLegend();\n\n // TODO: correctly implement independent axes\n if (true) { // if shared/union scale\n keys(child.component.legends).forEach(function(channel) {\n // just use the first legend definition for each channel\n if (!legendComponent[channel]) {\n legendComponent[channel] = child.component.legends[channel];\n }\n });\n }\n });\n }\n\n public assembleParentGroupProperties(cellConfig: CellConfig): VgEncodeEntry {\n return applyConfig({}, cellConfig, FILL_STROKE_CONFIG.concat(['clip']));\n }\n\n public assembleSignals(signals: any[]): any[] {\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return [];\n }\n\n public assembleScales(): VgScale[] {\n // combine with scales from children\n return this.children.reduce((scales, c) => {\n return scales.concat(c.assembleScales());\n }, super.assembleScales());\n }\n\n public assembleData(data: VgData[]): VgData[] {\n // Prefix traversal – parent data might be referred to by children data\n assembleData(this, data);\n this.children.forEach((child) => {\n child.assembleData(data);\n });\n return data;\n }\n\n public assembleLayout(layoutData: VgData[]): VgData[] {\n // Postfix traversal – layout is assembled bottom-up\n this.children.forEach((child) => {\n child.assembleLayout(layoutData);\n });\n return assembleLayout(this, layoutData);\n }\n\n public assembleMarks(): any[] {\n // only children have marks\n return flatten(this.children.map((child) => {\n return child.assembleMarks();\n }));\n }\n\n public channels(): Channel[] {\n return [];\n }\n\n protected getMapping(): any {\n return null;\n }\n\n public isLayer() {\n return true;\n }\n\n /**\n * Returns true if the child either has no source defined or uses the same url.\n * This is useful if you want to know whether it is possible to move a filter up.\n *\n * This function can only be called once th child has been parsed.\n */\n public compatibleSource(child: UnitModel) {\n const data = this.data;\n const childData = child.component.data;\n const compatible = !childData.source || (data && isUrlData(data) && data.url === childData.source.url);\n return compatible;\n }\n}\n", + "\nimport {Channel, X, Y, ROW, COLUMN} from '../channel';\nimport {LAYOUT} from '../data';\nimport {hasDiscreteDomain} from '../scale';\nimport {Formula} from '../transform';\nimport {extend, keys, StringSet} from '../util';\nimport {VgData} from '../vega.schema';\n\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {UnitModel} from './unit';\n\n// FIXME: for nesting x and y, we need to declare x,y layout separately before joining later\n// For now, let's always assume shared scale\nexport interface LayoutComponent {\n width: SizeComponent;\n height: SizeComponent;\n}\n\nexport interface SizeComponent {\n /** Field that we need to calculate distinct */\n distinct: StringSet;\n\n /** Array of formulas */\n formula: Formula[];\n}\n\nexport function assembleLayout(model: Model, layoutData: VgData[]): VgData[] {\n const layoutComponent = model.component.layout;\n if (!layoutComponent.width && !layoutComponent.height) {\n return layoutData; // Do nothing\n }\n\n if (true) { // if both are shared scale, we can simply merge data source for width and for height\n const distinctFields = keys(extend(layoutComponent.width.distinct, layoutComponent.height.distinct));\n const formula = layoutComponent.width.formula.concat(layoutComponent.height.formula)\n .map(f => extend({type: 'formula'}, f));\n\n return [\n distinctFields.length > 0 ? {\n name: model.dataName(LAYOUT),\n source: model.dataTable(),\n transform: [{\n type: 'aggregate',\n fields: distinctFields,\n ops: distinctFields.map(() => 'distinct')\n } as any].concat(formula)\n } : {\n name: model.dataName(LAYOUT),\n values: [{}],\n transform: formula\n }\n ];\n }\n // FIXME: implement\n // otherwise, we need to join width and height (cross)\n}\n\n// FIXME: for nesting x and y, we need to declare x,y layout separately before joining later\n// For now, let's always assume shared scale\nexport function parseUnitLayout(model: UnitModel): LayoutComponent {\n return {\n width: parseUnitSizeLayout(model, X),\n height: parseUnitSizeLayout(model, Y)\n };\n}\n\nfunction parseUnitSizeLayout(model: UnitModel, channel: Channel): SizeComponent {\n return {\n distinct: getDistinct(model, channel),\n formula: [{\n as: model.channelSizeName(channel),\n expr: unitSizeExpr(model, channel)\n }]\n };\n}\n\nexport function unitSizeExpr(model: UnitModel, channel: Channel): string {\n const scale = model.scale(channel);\n if (scale) {\n\n if (hasDiscreteDomain(scale.type) && scale.rangeStep) {\n // If the spec has top level size or specified rangeStep = fit, it will be undefined here.\n\n const cardinality = cardinalityExpr(model, channel);\n const paddingOuter = scale.paddingOuter !== undefined ? scale.paddingOuter : scale.padding;\n const paddingInner = scale.type === 'band' ?\n // only band has real paddingInner\n (scale.paddingInner !== undefined ? scale.paddingInner : scale.padding) :\n // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128,\n // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points.\n 1;\n\n let space = cardinality +\n (paddingInner ? ` - ${paddingInner}` : '') +\n (paddingOuter ? ` + 2*${paddingOuter}` : '');\n\n // This formula is equivalent to\n // space = count - inner + outer * 2\n // range = rangeStep * (space > 0 ? space : 0)\n // in https://github.com/vega/vega-encode/blob/master/src/Scale.js#L112\n return `max(${space}, 0) * ${scale.rangeStep}`;\n }\n }\n return (channel === X ? model.width : model.height) + '';\n}\n\nexport function parseFacetLayout(model: FacetModel): LayoutComponent {\n return {\n width: parseFacetSizeLayout(model, COLUMN),\n height: parseFacetSizeLayout(model, ROW)\n };\n}\n\nfunction parseFacetSizeLayout(model: FacetModel, channel: Channel): SizeComponent {\n const childLayoutComponent = model.child.component.layout;\n const sizeType = channel === ROW ? 'height' : 'width';\n const childSizeComponent: SizeComponent = childLayoutComponent[sizeType];\n\n if (true) { // assume shared scale\n // For shared scale, we can simply merge the layout into one data source\n\n const distinct = extend(getDistinct(model, channel), childSizeComponent.distinct);\n const formula = childSizeComponent.formula.concat([{\n as: model.channelSizeName(channel),\n expr: facetSizeFormula(model, channel, model.child.channelSizeName(channel))\n }]);\n\n delete childLayoutComponent[sizeType];\n return {\n distinct: distinct,\n formula: formula\n };\n }\n // FIXME implement independent scale as well\n // TODO: - also consider when children have different data source\n}\n\nfunction facetSizeFormula(model: FacetModel, channel: Channel, innerSize: string) {\n if (model.channelHasField(channel)) {\n return '(datum[\"' + innerSize + '\"] + ' + model.spacing(channel) + ')' + ' * ' + cardinalityExpr(model, channel);\n } else {\n return 'datum[\"' + innerSize + '\"] + ' + model.config.scale.facetSpacing; // need to add outer padding for facet\n }\n}\n\nexport function parseLayerLayout(model: LayerModel): LayoutComponent {\n return {\n width: parseLayerSizeLayout(model, X),\n height: parseLayerSizeLayout(model, Y)\n };\n}\n\nfunction parseLayerSizeLayout(model: LayerModel, channel: Channel): SizeComponent {\n if (true) {\n // For shared scale, we can simply merge the layout into one data source\n // TODO: don't just take the layout from the first child\n\n const childLayoutComponent = model.children[0].component.layout;\n const sizeType = channel === Y ? 'height' : 'width';\n const childSizeComponent: SizeComponent = childLayoutComponent[sizeType];\n\n const distinct = childSizeComponent.distinct;\n const formula: Formula[] = [{\n as: model.channelSizeName(channel),\n expr: childSizeComponent.formula[0].expr\n }];\n\n model.children.forEach((child) => {\n delete child.component.layout[sizeType];\n });\n\n return {\n distinct: distinct,\n formula: formula\n };\n }\n}\n\nfunction getDistinct(model: Model, channel: Channel): StringSet {\n if (model.channelHasField(channel) && model.hasDiscreteScale(channel)) {\n const scale = model.scale(channel);\n if (hasDiscreteDomain(scale.type) && !(scale.domain instanceof Array)) {\n // if explicit domain is declared, use array length\n const distinctField = model.field(channel);\n let distinct: StringSet = {};\n distinct[distinctField] = true;\n return distinct;\n }\n }\n return {};\n}\n\nexport function cardinalityExpr(model: Model, channel: Channel):string {\n const scale = model.scale(channel);\n if (scale.domain instanceof Array) {\n return scale.domain.length + '';\n }\n\n return model.field(channel, {datum: true, prefix: 'distinct'});\n}\n", + "import {COLOR, SHAPE, Channel} from '../../channel';\nimport {FieldDef, isValueDef} from '../../fielddef';\nimport {AREA, BAR, TICK, TEXT, LINE, POINT, CIRCLE, SQUARE, FILL_STROKE_CONFIG} from '../../mark';\nimport {TEMPORAL} from '../../type';\nimport {extend, keys, without} from '../../util';\n\nimport {VgValueRef} from '../../vega.schema';\n\nimport {applyMarkConfig, timeFormatExpression} from '../common';\nimport {UnitModel} from '../unit';\n\nexport function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel) {\n let symbols:any = {};\n const mark = model.mark();\n\n switch (mark) {\n case BAR:\n case TICK:\n case TEXT:\n symbols.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n symbols.shape = {value: mark};\n break;\n case POINT:\n case LINE:\n case AREA:\n // use default circle\n break;\n }\n\n const cfg = model.config;\n const filled = model.markDef.filled;\n\n let config = channel === COLOR ?\n /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */\n without(FILL_STROKE_CONFIG, [ filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) :\n /* For other legend, no need to omit. */\n FILL_STROKE_CONFIG;\n\n config = without(config, ['strokeDash', 'strokeDashOffset']);\n\n applyMarkConfig(symbols, model, config);\n\n if (filled) {\n symbols.strokeWidth = {value: 0};\n }\n\n let value: VgValueRef;\n const colorDef = model.encoding.color;\n if (isValueDef(colorDef)) {\n value = {value: colorDef.value};\n }\n\n if (value !== undefined) {\n // apply the value\n if (filled) {\n symbols.fill = value;\n } else {\n symbols.stroke = value;\n }\n } else if (channel !== COLOR) {\n // For non-color legend, apply color config if there is no fill / stroke config.\n // (For color, do not override scale specified!)\n symbols[filled ? 'fill' : 'stroke'] = symbols[filled ? 'fill' : 'stroke'] ||\n {value: cfg.mark.color};\n }\n\n if (symbols.fill === undefined) {\n // fall back to mark config colors for legend fill\n if (cfg.mark.fill !== undefined) {\n symbols.fill = {value: cfg.mark.fill};\n } else if (cfg.mark.stroke !== undefined) {\n symbols.stroke = {value: cfg.mark.stroke};\n }\n }\n\n const shapeDef = model.encoding.shape;\n if (channel !== SHAPE) {\n if (isValueDef(shapeDef)) {\n symbols.shape = {value: shapeDef.value};\n }\n }\n\n symbols = extend(symbols, symbolsSpec || {});\n\n return keys(symbols).length > 0 ? symbols : undefined;\n}\n\nexport function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: Channel) {\n const legend = model.legend(channel);\n const config = model.config;\n\n let labels:any = {};\n\n if (fieldDef.type === TEMPORAL) {\n labelsSpec = extend({\n text: {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat)\n }\n }, labelsSpec || {});\n }\n\n labels = extend(labels, labelsSpec || {});\n\n return keys(labels).length > 0 ? labels : undefined;\n}\n\n", + "import {COLOR, SIZE, SHAPE, OPACITY, Channel} from '../../channel';\nimport {keys, Dict} from '../../util';\nimport {VgLegend} from '../../vega.schema';\nimport {Legend, LEGEND_PROPERTIES} from '../../legend';\n\nimport {Model} from '../model';\nimport {numberFormat} from '../common';\nimport {UnitModel} from '../unit';\n\nimport * as encode from './encode';\nimport * as rules from './rules';\n\nexport function parseLegendComponent(model: UnitModel): Dict {\n return [COLOR, SIZE, SHAPE, OPACITY].reduce(function(legendComponent, channel) {\n if (model.legend(channel)) {\n legendComponent[channel] = parseLegend(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: Channel): VgLegend {\n // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels\n switch (channel) {\n case COLOR:\n const scale = model.scaleName(COLOR);\n return model.markDef.filled ? {fill: scale} : {stroke: scale};\n case SIZE:\n return {size: model.scaleName(SIZE)};\n case SHAPE:\n return {shape: model.scaleName(SHAPE)};\n case OPACITY:\n return {opacity: model.scaleName(OPACITY)};\n }\n return null;\n}\n\nexport function parseLegend(model: UnitModel, channel: Channel): VgLegend {\n const fieldDef = model.fieldDef(channel);\n const legend = model.legend(channel);\n\n let def: VgLegend = getLegendDefWithScale(model, channel);\n\n LEGEND_PROPERTIES.forEach(function(property) {\n const value = getSpecifiedOrDefaultValue(property, legend, channel, model);\n if (value !== undefined) {\n def[property] = value;\n }\n });\n\n // 2) Add mark property definition groups\n const encodeSpec = legend.encode || {};\n ['labels', 'legend', 'title', 'symbols'].forEach(function(part) {\n let value = encode[part] ?\n encode[part](fieldDef, encodeSpec[part], model, channel) : // apply rule\n encodeSpec[part]; // no rule -- just default values\n if (value !== undefined && keys(value).length > 0) {\n def.encode = def.encode || {};\n def.encode[part] = {update: value};\n }\n });\n\n return def;\n}\n\nfunction getSpecifiedOrDefaultValue(property: keyof VgLegend, specifiedLegend: Legend, channel: Channel, model: Model) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'format':\n return numberFormat(fieldDef, specifiedLegend.format, model.config, channel);\n case 'title':\n return rules.title(specifiedLegend, fieldDef, model.config);\n case 'values':\n return rules.values(specifiedLegend);\n case 'type':\n rules.type(specifiedLegend, fieldDef, channel);\n }\n\n // Otherwise, return specified property.\n return specifiedLegend[property];\n}\n\n", + "import {COLOR, Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {DateTime, isDateTime, timestamp} from '../../datetime';\nimport {FieldDef} from '../../fielddef';\nimport {Legend} from '../../legend';\nimport {title as fieldTitle} from '../../fielddef';\nimport {TEMPORAL, QUANTITATIVE} from '../../type';\nimport {contains} from '../../util';\n\nexport function title(legend: Legend, fieldDef: FieldDef, config: Config) {\n if (legend.title !== undefined) {\n return legend.title;\n }\n\n return fieldTitle(fieldDef, config);\n}\n\nexport function values(legend: Legend) {\n const vals = legend.values;\n if (vals && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return timestamp(dt, true);\n });\n }\n return vals;\n}\n\nexport function type(legend: Legend, fieldDef: FieldDef, channel: Channel) {\n if (legend.type) {\n return legend.type;\n }\n\n if (channel === COLOR && !fieldDef.bin && !fieldDef.timeUnit && contains([QUANTITATIVE, TEMPORAL], fieldDef.type)) {\n return 'gradient';\n }\n return undefined;\n}\n", + "import * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\n\nexport const area: MarkCompiler = {\n vgMark: 'area',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n const orient = model.markDef.orient;\n\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.markDefProperties(model.markDef, ['orient', 'interpolate', 'tension']),\n };\n }\n};\n", + "import {X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {isFieldDef} from '../../fielddef';\nimport {Scale, ScaleType, isBinScale} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport * as log from '../../log';\nimport {VgEncodeEntry} from '../../vega.schema';\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\nimport {VgValueRef} from '../../vega.schema';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\n\nexport const bar: MarkCompiler = {\n vgMark: 'rect',\n role: 'bar',\n encodeEntry: (model: UnitModel) => {\n const stack = model.stack;\n return {\n ...x(model, stack),\n ...y(model, stack),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model)\n };\n }\n};\n\nfunction x(model: UnitModel, stack: StackProperties): VgEncodeEntry {\n const {config} = model;\n const orient = model.markDef.orient;\n const sizeDef = model.encoding.size;\n\n const xDef = model.encoding.x;\n const xScaleName = model.scaleName(X);\n const xScale = model.scale(X);\n // x, x2, and width -- we must specify two of these in all conditions\n if (orient === 'horizontal') {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n };\n } else { // vertical\n if (isFieldDef(xDef)) {\n if (!sizeDef && isBinScale(xScale.type)) {\n return mixins.binnedPosition('x', model, config.bar.binSpacing);\n } else if (xScale.type === ScaleType.BAND) {\n return mixins.bandPosition('x', model);\n }\n }\n // sized bin, normal point-ordinal axis, quantitative x-axis, or no x\n\n return mixins.centeredBandPosition('x', model,\n {...ref.midX(config), offset: 1}, // TODO: config.singleBarOffset,\n defaultSizeRef(xScaleName, model.scale(X), config)\n );\n }\n}\n\nfunction y(model: UnitModel, stack: StackProperties) {\n const {config, encoding} = model;\n const orient = model.markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const yScaleName = model.scaleName(Y);\n const yScale = model.scale(Y);\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical') {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n };\n } else {\n if (isFieldDef(yDef)) {\n if (yDef.bin && !sizeDef) {\n return mixins.binnedPosition('y', model, config.bar.binSpacing);\n } else if (yScale.type === ScaleType.BAND) {\n return mixins.bandPosition('y', model);\n }\n }\n return mixins.centeredBandPosition('y', model, ref.midY(config), defaultSizeRef(yScaleName, model.scale(Y), config));\n }\n}\n\nfunction defaultSizeRef(scaleName: string, scale: Scale, config: Config): VgValueRef {\n if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n }\n\n if (scale) {\n if (scale.type === ScaleType.POINT) {\n if (scale.rangeStep !== null) {\n return {value: scale.rangeStep - 1};\n }\n log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL);\n } else if (scale.type === ScaleType.BAND) {\n return ref.band(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n }\n if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n // TODO: this should depends on cell's width / height?\n return {value: 20};\n}\n\n", + "import {Mark, MarkDef, isMarkDef, BAR, AREA, POINT, LINE, TICK, CIRCLE, SQUARE, RECT, RULE, TEXT, Orient} from '../../mark';\nimport {Encoding, isAggregate, channelHasField} from '../../encoding';\nimport * as log from '../../log';\nimport {Dict, contains} from '../../util';\nimport {Scale, hasDiscreteDomain} from '../../scale';\nimport {isFieldDef, FieldDef, isContinuous} from '../../fielddef';\nimport {TEMPORAL} from '../../type';\nimport {Config} from '../../config';\nimport {getMarkConfig} from '../common';\nimport {StackProperties} from '../../stack';\n\nexport function initMarkDef(mark: Mark | MarkDef, encoding: Encoding, scale: Dict, config: Config): MarkDef & {filled: boolean} {\n const markDef = isMarkDef(mark) ? mark : {type: mark};\n\n const specifiedOrient = markDef.orient || getMarkConfig('orient', markDef.type, config);\n markDef.orient = orient(markDef.type, encoding, scale, specifiedOrient);\n if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) {\n log.warn(log.message.orientOverridden(markDef.orient,specifiedOrient));\n }\n\n return {\n ...markDef,\n\n // TODO: filled could be injected to encoding too, but we don't have filled channel yet.\n // Thus we inject it here for now.\n filled: filled(markDef.type, config)\n };\n}\n\n/**\n * Initialize encoding's value with some special default values\n */\nexport function initEncoding(mark: Mark, encoding: Encoding, stacked: StackProperties, config: Config): Encoding {\n const opacityConfig = getMarkConfig('opacity', mark, config);\n if (!encoding.opacity && opacityConfig === undefined) {\n const opacity = defaultOpacity(mark, encoding, stacked);\n if (opacity !== undefined) {\n encoding.opacity = {value: opacity};\n }\n }\n return encoding;\n}\n\n\nfunction defaultOpacity(mark: Mark, encoding: Encoding, stacked: StackProperties) {\n if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) {\n // point-based marks\n if (!isAggregate(encoding) || channelHasField(encoding, 'detail')) {\n return 0.7;\n }\n }\n if (mark === BAR && !stacked) {\n if (channelHasField(encoding, 'color') || channelHasField(encoding, 'detail') || channelHasField(encoding, 'size')) {\n return 0.7;\n }\n }\n if (mark === AREA) {\n return 0.7; // inspired by Tableau\n }\n return undefined;\n}\n\nfunction filled(mark: Mark, config: Config) {\n const filledConfig = getMarkConfig('filled', mark, config);\n return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE;\n}\n\nfunction orient(mark: Mark, encoding: Encoding, scale: Dict, specifiedOrient: Orient): Orient {\n switch (mark) {\n case POINT:\n case CIRCLE:\n case SQUARE:\n case TEXT:\n case RECT:\n // orient is meaningless for these marks.\n return undefined;\n }\n\n const yIsRange = encoding.y && encoding.y2;\n const xIsRange = encoding.x && encoding.x2;\n\n switch (mark) {\n case TICK:\n const xScaleType = scale['x'] ? scale['x'].type : null;\n const yScaleType = scale['y'] ? scale['y'].type : null;\n\n // Tick is opposite to bar, line, area and never have ranged mark.\n if (!hasDiscreteDomain(xScaleType) && (\n !encoding.y ||\n hasDiscreteDomain(yScaleType) ||\n (isFieldDef(encoding.y) && encoding.y.bin)\n )) {\n return 'vertical';\n }\n // y:Q or Ambiguous case, return horizontal\n return 'horizontal';\n\n case RULE:\n case BAR:\n case AREA:\n // If there are range for both x and y, y (vertical) has higher precedence.\n if (yIsRange) {\n return 'vertical';\n } else if (xIsRange) {\n return 'horizontal';\n } else if (mark === RULE) {\n if (encoding.x && !encoding.y) {\n return 'vertical';\n } else if (encoding.y && !encoding.x) {\n return 'horizontal';\n }\n }\n\n /* tslint:disable */\n case LINE: // intentional fall through\n /* tslint:enable */\n const xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x);\n const yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y);\n if (xIsContinuous && !yIsContinuous) {\n return 'horizontal';\n } else if (!xIsContinuous && yIsContinuous) {\n return 'vertical';\n } else if (xIsContinuous && yIsContinuous) {\n const xDef = encoding.x as FieldDef; // we can cast here since they are surely fieldDef\n const yDef = encoding.y as FieldDef;\n\n const xIsTemporal = xDef.type === TEMPORAL;\n const yIsTemporal = yDef.type === TEMPORAL;\n\n // temporal without timeUnit is considered continuous, but better serves as dimension\n if (xIsTemporal && !yIsTemporal) {\n return 'vertical';\n } else if (!xIsTemporal && yIsTemporal) {\n return 'horizontal';\n }\n\n if (!xDef.aggregate && !!yDef.aggregate) {\n return 'vertical';\n } else if (!!xDef.aggregate && !yDef.aggregate) {\n return 'horizontal';\n }\n\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n if (!(mark === LINE && encoding.order)) {\n // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots.\n log.warn(log.message.unclearOrientContinuous(mark));\n }\n return 'vertical';\n } else {\n // For Discrete x Discrete case, return undefined.\n log.warn(log.message.unclearOrientDiscreteOrEmpty(mark));\n return undefined;\n }\n }\n return 'vertical';\n}\n", + "import * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n }),\n ...mixins.markDefProperties(model.markDef, ['interpolate', 'tension'])\n };\n }\n};\n", + "import {NONSPATIAL_CHANNELS, Channel} from '../../channel';\nimport {AREA, LINE} from '../../mark';\nimport {contains, without} from '../../util';\n\nimport {MarkCompiler} from './base';\nimport {area} from './area';\nimport {bar} from './bar';\nimport {line} from './line';\nimport {point, circle, square} from './point';\nimport {rect} from './rect';\nimport {rule} from './rule';\nimport {text} from './text';\nimport {tick} from './tick';\n\nimport {FacetModel} from '../facet';\nimport {UnitModel} from '../unit';\n\nconst markCompiler: {[type: string]: MarkCompiler} = {\n area: area,\n bar: bar,\n line: line,\n point: point,\n text: text,\n tick: tick,\n rect: rect,\n rule: rule,\n circle: circle,\n square: square\n};\n\nexport function parseMark(model: UnitModel): any[] {\n if (contains([LINE, AREA], model.mark())) {\n return parsePathMark(model);\n } else {\n return parseNonPathMark(model);\n }\n}\n\n// FIXME: maybe this should not be here. Need re-think and refactor, esp. after having all composition in.\nfunction dataFrom(model: UnitModel): string {\n const parent = model.parent;\n if (parent && parent.isFacet()) {\n return (parent as FacetModel).facetedTable();\n }\n if (model.stack) {\n return model.dataName('stacked');\n }\n return model.dataTable();\n}\n\nconst FACETED_PATH_PREFIX = 'faceted-path-';\n\nfunction parsePathMark(model: UnitModel) {\n const mark = model.mark();\n // FIXME: replace this with more general case for composition\n const details = detailFields(model);\n\n let pathMarks: any = [\n {\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n // If has subfacet for line/area group, need to use faceted data from below.\n // FIXME: support sorting path order (in connected scatterplot)\n from: {data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + dataFrom(model)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n }\n ];\n\n if (details.length > 0) { // have level of details - need to facet line into subgroups\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n return [{\n name: model.getName('pathgroup'),\n type: 'group',\n from: {\n facet: {\n name: FACETED_PATH_PREFIX + dataFrom(model),\n data: dataFrom(model),\n groupby: details,\n }\n },\n encode: {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}}\n }\n },\n marks: pathMarks\n }];\n } else {\n return pathMarks;\n }\n}\n\nfunction parseNonPathMark(model: UnitModel) {\n const mark = model.mark();\n\n const role = markCompiler[mark].role;\n\n let marks: any[] = []; // TODO: vgMarks\n\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n marks.push({\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(role? {role} : {}),\n from: {data: dataFrom(model)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n });\n\n return marks;\n}\n\nconst NONSPATIAL_CHANNELS_EXCEPT_ORDER = without(NONSPATIAL_CHANNELS, ['order'] as Channel[]);\n\n/**\n * Returns list of detail (group-by) fields\n * that the model's spec contains.\n */\nfunction detailFields(model: UnitModel): string[] {\n return NONSPATIAL_CHANNELS_EXCEPT_ORDER.reduce(function(details, channel) {\n if (model.channelHasField(channel) && !model.fieldDef(channel).aggregate) {\n details.push(model.field(channel));\n }\n return details;\n }, []);\n}\n", + "import {MarkDef} from '../../mark';\nimport * as util from '../../util';\nimport {VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\n\nimport * as ref from './valueref';\n\nimport {NONSPATIAL_SCALE_CHANNELS} from '../../channel';\nimport {Condition} from '../../fielddef';\nimport {predicate} from '../selection/selection';\n\nexport function color(model: UnitModel) {\n const config = model.config;\n const filled = model.markDef.filled;\n\n let e = nonPosition('color', model, {\n vgChannel: filled ? 'fill' : 'stroke',\n defaultValue: getMarkConfig('color', model.mark(), config) as string\n });\n\n // If there is no fill, always fill symbols\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) {\n e.fill = {value: 'transparent'};\n }\n return e;\n}\n\nexport function markDefProperties(mark: MarkDef, props: (keyof MarkDef)[]) {\n return props.reduce((m, prop) => {\n if (mark[prop]) {\n m[prop] = {value: mark[prop]};\n }\n return m;\n }, {});\n}\n\nexport function valueIfDefined(prop: string, value: VgValueRef): VgEncodeEntry {\n if (value !== undefined) {\n return {[prop]: {value: value}};\n }\n return undefined;\n}\n\n/**\n * Return mixins for non-positional channels with scales. (Text doesn't have scale.)\n */\nexport function nonPosition(channel: typeof NONSPATIAL_SCALE_CHANNELS[0], model: UnitModel, opt: {defaultValue?: number | string | boolean, vgChannel?: string, defaultRef?: VgValueRef} = {}): VgEncodeEntry {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {defaultValue, vgChannel} = opt;\n const defaultRef = opt.defaultRef || (defaultValue !== undefined ? {value: defaultValue} : undefined);\n\n const channelDef = model.encoding[channel];\n const valueRef = ref.midPoint(channel, channelDef, model.scaleName(channel), model.scale(channel), defaultRef);\n\n return wrapCondition(model, channelDef && channelDef.condition, vgChannel || channel, valueRef);\n}\n\n/**\n * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition.\n * or a simple mixin if channel def has no condition.\n */\nfunction wrapCondition(model: UnitModel, condition: Condition, vgChannel: string, valueRef: VgValueRef): VgEncodeEntry {\n if (condition) {\n const {selection, value} = condition;\n return {\n [vgChannel]: [\n {test: selectionTest(model, selection), value},\n ...(valueRef !== undefined ? [valueRef] : [])\n ]\n };\n } else {\n return valueRef !== undefined ? {[vgChannel]: valueRef} : {};\n }\n}\n\nfunction selectionTest(model: UnitModel, selectionName: string) {\n const negate = selectionName.charAt(0) === '!',\n name = negate ? selectionName.slice(1) : selectionName;\n return (negate ? '!' : '') + predicate(model.component.selection[name]);\n}\n\nexport function text(model: UnitModel) {\n const channelDef = model.encoding.text;\n return wrapCondition(model, channelDef && channelDef.condition, 'text', ref.text(channelDef, model.config));\n}\n\nexport function bandPosition(channel: 'x'|'y', model: UnitModel) {\n // TODO: band scale doesn't support size yet\n const fieldDef = model.encoding[channel];\n const scaleName = model.scaleName(channel);\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n [channel]: ref.fieldRef(fieldDef, scaleName, {}),\n [sizeChannel]: ref.band(scaleName)\n };\n}\n\nexport function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef) {\n const centerChannel: 'xc' | 'yc' = channel === 'x' ? 'xc' : 'yc';\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n ...pointPosition(channel, model, defaultPosRef, centerChannel),\n ...nonPosition('size', model, {defaultRef: defaultSizeRef, vgChannel: sizeChannel})\n };\n}\n\nexport function binnedPosition(channel: 'x'|'y', model: UnitModel, spacing: number) {\n const fieldDef = model.encoding[channel];\n const scaleName = model.scaleName(channel);\n if (channel === 'x') {\n return {\n x2: ref.bin(fieldDef, scaleName, 'start', spacing),\n x: ref.bin(fieldDef, scaleName, 'end')\n };\n } else {\n return {\n y2: ref.bin(fieldDef, scaleName, 'start'),\n y: ref.bin(fieldDef, scaleName, 'end', spacing)\n };\n }\n}\n\n/**\n * Return mixins for point (non-band) position channels.\n */\nexport function pointPosition(channel: 'x'|'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x'|'y'|'xc'|'yc') {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {encoding, stack} = model;\n const valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.scale(channel), stack, defaultRef);\n\n return {\n [vgChannel || channel]: valueRef\n };\n}\n\n/**\n * Return mixins for x2, y2.\n * If channel is not specified, return one channel based on orientation.\n */\nexport function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel?: 'x2' | 'y2') {\n const {encoding, markDef, stack} = model;\n channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2');\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n\n const valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.scale(baseChannel), stack, defaultRef);\n return {[channel]: valueRef};\n}\n", + "\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\nimport {getMarkConfig} from '../common';\nimport {Config} from '../../config';\n\nfunction encodeEntry(model: UnitModel, fixedShape?: 'circle' | 'square') {\n const {config} = model;\n\n return {\n ...mixins.pointPosition('x', model, ref.midX(config)),\n ...mixins.pointPosition('y', model, ref.midY(config)),\n\n ...mixins.color(model),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n ...mixins.nonPosition('opacity', model)\n };\n}\n\nexport function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square') {\n if (fixedShape) {\n return {shape: {value: fixedShape}};\n }\n return mixins.nonPosition('shape', model, {defaultValue: getMarkConfig('shape', 'point', config) as string});\n}\n\nexport const point: MarkCompiler = {\n vgMark: 'symbol',\n role: 'point',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model);\n }\n};\n\nexport const circle: MarkCompiler = {\n vgMark: 'symbol',\n role: 'circle',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'circle');\n }\n};\n\nexport const square: MarkCompiler = {\n vgMark: 'symbol',\n role: 'square',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'square');\n }\n};\n", + "import {X, Y} from '../../channel';\nimport {isFieldDef} from '../../fielddef';\nimport {ScaleType, hasDiscreteDomain} from '../../scale';\nimport {RECT} from '../../mark';\nimport * as log from '../../log';\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n return {\n ...x(model),\n ...y(model),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction x(model: UnitModel) {\n const xDef = model.encoding.x;\n const x2Def = model.encoding.x2;\n const xScale = model.scale(X);\n\n if (isFieldDef(xDef) && xDef.bin && !x2Def) {\n return mixins.binnedPosition('x', model, 0);\n } else if (xScale && hasDiscreteDomain(xScale.type)) {\n /* istanbul ignore else */\n if (xScale.type === ScaleType.BAND) {\n return mixins.bandPosition('x', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, xScale.type));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2')\n };\n }\n}\n\nfunction y(model: UnitModel) {\n const yDef = model.encoding.y;\n const y2Def = model.encoding.y2;\n const yScale = model.scale(Y);\n\n if (isFieldDef(yDef) && yDef.bin && !y2Def) {\n return mixins.binnedPosition('y', model, 0);\n } else if (yScale && hasDiscreteDomain(yScale.type)) {\n /* istanbul ignore else */\n if (yScale.type === ScaleType.BAND) {\n return mixins.bandPosition('y', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, yScale.type));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2')\n };\n }\n}\n", + "import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\nexport const rule: MarkCompiler = {\n vgMark: 'rule',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMax'),\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's rule size is strokeWidth\n })\n };\n }\n};\n", + "import {X} from '../../channel';\nimport {getMarkConfig} from '../common';\n\nimport * as mixins from './mixins';\nimport {Config} from '../../config';\nimport {ChannelDef, isFieldDef} from '../../fielddef';\nimport {QUANTITATIVE} from '../../type';\nimport {UnitModel} from '../unit';\nimport {VgValueRef} from '../../vega.schema';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\nimport {Encoding, channelHasField} from '../../encoding';\n\nexport const text: MarkCompiler = {\n vgMark: 'text',\n role: undefined,\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding} = model;\n const textDef = encoding.text;\n\n return {\n ...mixins.pointPosition('x', model, xDefault(config, textDef)),\n ...mixins.pointPosition('y', model, ref.midY(config)),\n ...mixins.text(model),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(encoding, config))\n };\n }\n};\n\nfunction xDefault(config: Config, textDef: ChannelDef): VgValueRef {\n if (isFieldDef(textDef) && textDef.type === QUANTITATIVE) {\n return {field: {group: 'width'}, offset: -5};\n }\n // TODO: allow this to fit (Be consistent with ref.midX())\n return {value: config.scale.textXRangeStep / 2};\n}\n\nfunction align(encoding: Encoding, config: Config) {\n const alignConfig = getMarkConfig('align', 'text', config);\n if (alignConfig === undefined) {\n return channelHasField(encoding, X) ? 'center' : 'right';\n }\n // If there is a config, Vega-parser will process this already.\n return undefined;\n}\n", + "\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\n\nexport const tick: MarkCompiler = {\n vgMark: 'rect',\n role: 'tick',\n\n encodeEntry: (model: UnitModel) => {\n const {config, markDef} = model;\n const orient = markDef.orient;\n\n const vgSizeChannel = orient === 'horizontal' ? 'width' : 'height';\n const vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width';\n\n return {\n ...mixins.pointPosition('x', model, ref.midX(config), 'xc'),\n ...mixins.pointPosition('y', model, ref.midY(config), 'yc'),\n\n // size / thickness => width / height\n ...mixins.nonPosition('size', model, {\n defaultValue: defaultSize(model),\n vgChannel: vgSizeChannel\n }),\n [vgThicknessChannel]: {value: config.tick.thickness},\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config} = model;\n const orient = model.markDef.orient;\n\n const scaleRangeStep: number | null = (model.scale(orient === 'horizontal' ? 'x' : 'y') || {}).rangeStep;\n\n if (config.tick.bandSize !== undefined) {\n return config.tick.bandSize;\n } else {\n const rangeStep = scaleRangeStep !== undefined ?\n scaleRangeStep :\n config.scale.rangeStep;\n if (typeof rangeStep !== 'number') {\n // FIXME consolidate this log\n throw new Error('Function does not handle non-numeric rangeStep');\n }\n return rangeStep / 1.5;\n }\n}\n", + "/**\n * Utility files for producing Vega ValueRef for marks\n */\n\nimport {Channel, X, X2, Y, Y2} from '../../channel';\nimport {Config} from '../../config';\nimport {ChannelDef, FieldDef, FieldRefOption, field, isFieldDef, TextFieldDef, ValueDef} from '../../fielddef';\nimport {Scale, ScaleType, hasDiscreteDomain} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {contains} from '../../util';\nimport {VgValueRef} from '../../vega.schema';\nimport {numberFormat, timeFormatExpression} from '../common';\n\n// TODO: we need to find a way to refactor these so that scaleName is a part of scale\n// but that's complicated. For now, this is a huge step moving forward.\n\n/**\n * @return Vega ValueRef for stackable x or y\n */\nexport function stackable(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: Scale,\n stack: StackProperties, defaultRef: VgValueRef): VgValueRef {\n if (channelDef && stack && channel === stack.fieldChannel) {\n // x or y use stack_end so that stacked line's point mark use stack_end too.\n return fieldRef(channelDef, scaleName, {suffix: 'end'});\n }\n return midPoint(channel, channelDef, scaleName, scale, defaultRef);\n}\n\n/**\n * @return Vega ValueRef for stackable x2 or y2\n */\nexport function stackable2(channel: 'x2' | 'y2', aFieldDef: FieldDef, a2fieldDef: FieldDef, scaleName: string, scale: Scale,\n stack: StackProperties, defaultRef: VgValueRef): VgValueRef {\n if (aFieldDef && stack &&\n // If fieldChannel is X and channel is X2 (or Y and Y2)\n channel.charAt(0) === stack.fieldChannel.charAt(0)\n ) {\n return fieldRef(aFieldDef, scaleName, {suffix: 'start'});\n }\n return midPoint(channel, a2fieldDef, scaleName, scale, defaultRef);\n}\n\n/**\n * Value Ref for binned fields\n */\nexport function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number) {\n return fieldRef(fieldDef, scaleName, {binSuffix: side}, offset);\n}\n\nexport function fieldRef(fieldDef: FieldDef, scaleName: string, opt: FieldRefOption, offset?: number | VgValueRef): VgValueRef {\n let ref: VgValueRef = {\n scale: scaleName,\n field: field(fieldDef, opt),\n };\n if (offset) {\n ref.offset = offset;\n }\n return ref;\n}\n\nexport function band(scaleName: string, band: number|boolean = true): VgValueRef {\n return {\n scale: scaleName,\n band: band\n };\n}\n\nfunction binMidSignal(fieldDef: FieldDef, scaleName: string) {\n return {\n signal: `(` +\n `scale(\"${scaleName}\", ${field(fieldDef, {binSuffix: 'start', datum: true})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${field(fieldDef, {binSuffix: 'end', datum: true})})`+\n `)/2`\n };\n}\n\n/**\n * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels.\n */\nexport function midPoint(channel: Channel, channelDef: ChannelDef, scaleName: string, scale: Scale,\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): VgValueRef {\n // TODO: datum support\n\n if (channelDef) {\n /* istanbul ignore else */\n if (isFieldDef(channelDef)) {\n if (scale.type === 'bin-linear') {\n return binMidSignal(channelDef, scaleName);\n } else if (scale.type === 'bin-ordinal') {\n return fieldRef(channelDef, scaleName, {binSuffix: 'start'});\n }\n\n if (hasDiscreteDomain(scale.type)) {\n if (scale.type === 'band') {\n // For band, to get mid point, need to offset by half of the band\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'}, band(scaleName, 0.5));\n }\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'});\n } else {\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n }\n } else if (channelDef.value) {\n return {value: channelDef.value};\n } else {\n throw new Error('FieldDef without field or value.'); // FIXME add this to log.message\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMinX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMinY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n } else if (defaultRef === 'zeroOrMax') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMaxX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMaxY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n }\n return defaultRef;\n}\n\nexport function text(textDef: TextFieldDef | ValueDef, config: Config): VgValueRef {\n // text\n if (textDef) {\n if (isFieldDef(textDef)) {\n if (textDef.type === 'quantitative') {\n // FIXME: what happens if we have bin?\n const format = numberFormat(textDef, textDef.format, config, 'text');\n return {\n signal: `format(${field(textDef, {datum: true})}, '${format}')`\n };\n } else if (textDef.type === 'temporal') {\n return {\n signal: timeFormatExpression(field(textDef, {datum: true}), textDef.timeUnit, textDef.format, config.text.shortTimeLabels, config.timeFormat)\n };\n } else {\n return {field: textDef.field};\n }\n } else if (textDef.value) {\n return {value: textDef.value};\n }\n }\n return {value: config.text.text};\n}\n\nexport function midX(config: Config): VgValueRef {\n\n if (typeof config.scale.rangeStep === 'string') {\n // TODO: For fit-mode, use middle of the width\n throw new Error('midX can not handle string rangeSteps');\n }\n return {value: config.scale.rangeStep / 2};\n}\n\nexport function midY(config: Config): VgValueRef {\n if (typeof config.scale.rangeStep === 'string') {\n // TODO: For fit-mode, use middle of the width\n throw new Error('midX can not handle string rangeSteps');\n }\n return {value: config.scale.rangeStep / 2};\n}\n\nfunction zeroOrMinX(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the x-axis\n return {value: 0};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxX(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n return {field: {group: 'width'}};\n}\n\nfunction zeroOrMinY(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {field: {group: 'height'}};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxY(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {value: 0};\n}\n", + "import * as log from '../log';\n\nimport {Axis} from '../axis';\nimport {Channel, X, COLUMN} from '../channel';\nimport {Config, CellConfig} from '../config';\nimport {Data, DataSourceType, isNamedData, SOURCE} from '../data';\nimport {reduce, forEach} from '../encoding';\nimport {FieldDef, FieldRefOption, field, isFieldDef, ChannelDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Scale, hasDiscreteDomain} from '../scale';\nimport {SortField, SortOrder} from '../sort';\nimport {BaseSpec, Padding} from '../spec';\nimport {Transform} from '../transform';\nimport {extend, flatten, vals, Dict} from '../util';\nimport {VgData, VgEncodeEntry, VgScale, VgAxis, VgLegend} from '../vega.schema';\nimport {Formula} from '../transform';\nimport {OneOfFilter, EqualFilter, RangeFilter} from '../filter';\n\nimport {DataComponent} from './data/data';\nimport {LayoutComponent} from './layout';\nimport {StackProperties} from '../stack';\n\nimport {SelectionComponent} from './selection/selection';\n\n/**\n * Composable Components that are intermediate results of the parsing phase of the\n * compilations. These composable components will be assembled in the last\n * compilation step.\n */\nexport interface Component {\n data: DataComponent;\n layout: LayoutComponent;\n scales: Dict;\n selection: Dict;\n\n /** Dictionary mapping channel to VgAxis definition */\n axes: Dict;\n\n /** Dictionary mapping channel to VgLegend definition */\n legends: Dict;\n\n /** Dictionary mapping channel to axis mark group for facet and concat */\n axisGroups: Dict;\n\n /** Dictionary mapping channel to grid mark group for facet (and concat?) */\n gridGroups: Dict;\n\n mark: VgEncodeEntry[];\n}\n\nexport class NameMap implements NameMapInterface {\n private nameMap: Dict;\n\n constructor() {\n this.nameMap = {};\n }\n\n public rename(oldName: string, newName: string) {\n this.nameMap[oldName] = newName;\n }\n\n\n public has(name: string): boolean {\n return this.nameMap[name] !== undefined;\n }\n\n public get(name: string): string {\n // If the name appears in the _nameMap, we need to read its new name.\n // We have to loop over the dict just in case the new name also gets renamed.\n while (this.nameMap[name]) {\n name = this.nameMap[name];\n }\n\n return name;\n }\n}\n\nexport interface NameMapInterface {\n rename(oldname: string, newName: string): void;\n has(name: string): boolean;\n get(name: string): string;\n}\n\nexport abstract class Model {\n public readonly parent: Model;\n protected readonly name: string;\n public readonly description: string;\n public readonly padding: Padding;\n\n public readonly data: Data;\n\n /** Name map for data sources, which can be renamed by a model's parent. */\n protected dataNameMap: NameMapInterface;\n\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected sizeNameMap: NameMapInterface;\n\n protected readonly transform: Transform;\n protected abstract readonly scales: Dict = {};\n\n protected abstract readonly axes: Dict = {};\n\n protected abstract readonly legends: Dict = {};\n\n public abstract readonly config: Config;\n\n public component: Component;\n\n public abstract readonly children: Model[] = [];\n\n public abstract stack: StackProperties;\n\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string) {\n this.parent = parent;\n\n // If name is not provided, always use parent's givenName to avoid name conflicts.\n this.name = spec.name || parentGivenName;\n\n // Shared name maps\n this.dataNameMap = parent ? parent.dataNameMap : new NameMap();\n this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap();\n this.sizeNameMap = parent ? parent.sizeNameMap : new NameMap();\n\n this.data = spec.data;\n\n this.description = spec.description;\n this.padding = spec.padding;\n this.transform = spec.transform;\n\n if (spec.transform) {\n if (spec.transform.filterInvalid === undefined &&\n spec.transform['filterNull'] !== undefined) {\n spec.transform.filterInvalid = spec.transform['filterNull'];\n log.warn(log.message.DEPRECATED_FILTER_NULL);\n }\n }\n\n this.component = {data: null, layout: null, mark: null, scales: null, axes: null, axisGroups: null, gridGroups: null, legends: null, selection: null};\n }\n\n\n public parse() {\n this.parseData();\n this.parseLayoutData();\n this.parseScale(); // depends on data name\n this.parseSelection();\n this.parseAxis(); // depends on scale name\n this.parseLegend(); // depends on scale name\n this.parseAxisGroup(); // depends on child axis\n this.parseGridGroup();\n this.parseMark(); // depends on data name and scale name, axisGroup, gridGroup and children's scale, axis, legend and mark.\n }\n\n public abstract parseData(): void;\n\n public abstract parseSelection(): void;\n\n public abstract parseLayoutData(): void;\n\n public abstract parseScale(): void;\n\n public abstract parseMark(): void;\n\n public abstract parseAxis(): void;\n\n public abstract parseLegend(): void;\n\n // TODO: revise if these two methods make sense for shared scale concat\n public abstract parseAxisGroup(): void;\n public abstract parseGridGroup(): void;\n\n public abstract assembleSignals(signals: any[]): any[];\n\n public abstract assembleSelectionData(data: VgData[]): VgData[];\n public abstract assembleData(data: VgData[]): VgData[];\n\n public abstract assembleLayout(layoutData: VgData[]): VgData[];\n\n public assembleScales(): VgScale[] {\n // FIXME: write assembleScales() in scale.ts that\n // help assemble scale domains with scale signature as well\n return flatten(vals(this.component.scales).map((scale: VgScale) => {\n let arr = [scale];\n return arr;\n }));\n }\n\n public abstract assembleMarks(): any[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return [].concat.apply([], vals(this.component.axes));\n }\n\n public assembleLegends(): any[] { // TODO: VgLegend[]\n return vals(this.component.legends);\n }\n\n public assembleGroup() {\n let group: VgEncodeEntry = {};\n\n const signals = this.assembleSignals(group.signals || []);\n if (signals.length > 0) {\n group.signals = signals;\n }\n\n // TODO: consider if we want scales to come before marks in the output spec.\n group.marks = this.assembleMarks();\n const scales = this.assembleScales();\n if (scales.length > 0) {\n group.scales = scales;\n }\n\n const axes = this.assembleAxes();\n if (axes.length > 0) {\n group.axes = axes;\n }\n\n const legends = this.assembleLegends();\n if (legends.length > 0) {\n group.legends = legends;\n }\n\n return group;\n }\n\n public abstract assembleParentGroupProperties(cellConfig: CellConfig): VgEncodeEntry;\n\n public abstract channels(): Channel[];\n\n protected abstract getMapping(): {[key: string]: any};\n\n public reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any) {\n return reduce(this.getMapping(), (acc:U , cd: ChannelDef, c: Channel) => {\n return isFieldDef(cd) ? f(acc, cd, c) : acc;\n }, init, t);\n }\n\n public forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any) {\n forEach(this.getMapping(), (cd: ChannelDef, c: Channel) => {\n if (isFieldDef(cd)) {\n f(cd, c);\n }\n }, t);\n }\n\n public hasDescendantWithFieldOnChannel(channel: Channel) {\n for (let child of this.children) {\n if (child.isUnit()) {\n if (child.channelHasField(channel)) {\n return true;\n }\n } else {\n if (child.hasDescendantWithFieldOnChannel(channel)) {\n return true;\n }\n }\n }\n return false;\n }\n\n public abstract channelHasField(channel: Channel): boolean;\n\n public getName(text: string, delimiter: string = '_') {\n if (this.data && text === SOURCE && isNamedData(this.data)) {\n return this.data.name;\n }\n return (this.name ? this.name + delimiter : '') + text;\n }\n\n public renameData(oldName: string, newName: string) {\n this.dataNameMap.rename(oldName, newName);\n }\n\n /**\n * Return the data source name for the given data source type.\n *\n * For unit spec, this is always simply the spec.name + '-' + dataSourceType.\n * We already use the name map so that marks and scales use the correct data.\n */\n public dataName(dataSourceType: DataSourceType): string {\n return this.dataNameMap.get(this.getName(String(dataSourceType)));\n }\n\n public renameSize(oldName: string, newName: string) {\n this.sizeNameMap.rename(oldName, newName);\n }\n\n public channelSizeName(channel: Channel): string {\n return this.sizeName(channel === X || channel === COLUMN ? 'width' : 'height');\n }\n\n public sizeName(size: string): string {\n return this.sizeNameMap.get(this.getName(size, '_'));\n }\n\n public abstract dataTable(): string;\n\n // TRANSFORMS\n public calculate(): Formula[] {\n return this.transform ? this.transform.calculate : undefined;\n }\n\n public filterInvalid(): boolean {\n const transform = this.transform || {};\n if (transform.filterInvalid === undefined) {\n return this.parent ? this.parent.filterInvalid() : undefined;\n }\n return transform.filterInvalid;\n }\n\n public filter(): string | OneOfFilter | EqualFilter| RangeFilter | (string | OneOfFilter | EqualFilter| RangeFilter)[] {\n return this.transform ? this.transform.filter : undefined;\n }\n\n /** Get \"field\" reference for vega */\n public field(channel: Channel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (fieldDef.bin) { // bin has default suffix that depends on scaleType\n opt = extend({\n binSuffix: hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start'\n }, opt);\n }\n\n return field(fieldDef, opt);\n }\n\n public abstract fieldDef(channel: Channel): FieldDef;\n\n public scale(channel: Channel): Scale {\n return this.scales[channel];\n }\n\n public hasDiscreteScale(channel: Channel) {\n const scale = this.scale(channel);\n return scale && hasDiscreteDomain(scale.type);\n }\n\n public renameScale(oldName: string, newName: string) {\n this.scaleNameMap.rename(oldName, newName);\n }\n\n\n /**\n * @return scale name for a given channel after the scale has been parsed and named.\n * (DO NOT USE THIS METHOD DURING SCALE PARSING, use model.name() instead)\n */\n public scaleName(this: Model, originalScaleName: Channel|string, parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a scale can't be renamed\n // before it has the original name.\n return this.getName(originalScaleName + '');\n }\n\n // If there is a scale for the channel, it should either\n // be in the _scale mapping or exist in the name map\n if (\n // in the scale map (the scale is not merged by its parent)\n (this.scale && this.scales[originalScaleName]) ||\n // in the scale name map (the the scale get merged by its parent)\n this.scaleNameMap.has(this.getName(originalScaleName + ''))\n ) {\n return this.scaleNameMap.get(this.getName(originalScaleName + ''));\n }\n return undefined;\n }\n\n public sort(channel: Channel): SortField | SortOrder {\n return (this.getMapping()[channel] || {}).sort;\n }\n\n public axis(channel: Channel): Axis {\n return this.axes[channel];\n }\n\n public legend(channel: Channel): Legend {\n return this.legends[channel];\n }\n\n /**\n * Type checks\n */\n public isUnit() {\n return false;\n }\n public isFacet() {\n return false;\n }\n public isLayer() {\n return false;\n }\n}\n", + "import * as log from '../../log';\n\nimport {SHARED_DOMAIN_OPS} from '../../aggregate';\nimport {Channel} from '../../channel';\nimport {SOURCE} from '../../data';\nimport {DateTime, isDateTime, timestamp} from '../../datetime';\nimport {Domain, hasDiscreteDomain, isBinScale, Scale, ScaleConfig, ScaleType} from '../../scale';\nimport {isSortField} from '../../sort';\nimport {\n FieldRefUnionDomain,\n DataRefUnionDomain,\n isDataRefDomain,\n isDataRefUnionedDomain,\n isFieldRefUnionDomain,\n isSignalRefDomain,\n VgDataRef,\n VgDomain,\n VgSortField\n} from '../../vega.schema';\n\nimport * as util from '../../util';\n\nimport {Model} from '../model';\nimport {FieldDef} from '../../fielddef';\n\nexport function initDomain(domain: Domain, fieldDef: FieldDef, scale: ScaleType, scaleConfig: ScaleConfig) {\n if (domain === 'unaggregated') {\n const {valid, reason} = canUseUnaggregatedDomain(fieldDef, scale);\n if(!valid) {\n log.warn(reason);\n return undefined;\n }\n } else if (domain === undefined && scaleConfig.useUnaggregatedDomain) {\n // Apply config if domain is not specified.\n const {valid} = canUseUnaggregatedDomain(fieldDef, scale);\n if (valid) {\n return 'unaggregated';\n }\n }\n\n return domain;\n}\n\n\nexport function parseDomain(model: Model, channel: Channel): VgDomain {\n const scale = model.scale(channel);\n\n // If channel is either X or Y then union them with X2 & Y2 if they exist\n if (channel === 'x' && model.channelHasField('x2')) {\n if (model.channelHasField('x')) {\n return unionDomains(parseSingleChannelDomain(scale, model, 'x'), parseSingleChannelDomain(scale, model, 'x2'));\n } else {\n return parseSingleChannelDomain(scale, model, 'x2');\n }\n } else if (channel === 'y' && model.channelHasField('y2')) {\n if (model.channelHasField('y')) {\n return unionDomains(parseSingleChannelDomain(scale, model, 'y'), parseSingleChannelDomain(scale, model, 'y2'));\n } else {\n return parseSingleChannelDomain(scale, model, 'y2');\n }\n }\n return parseSingleChannelDomain(scale, model, channel);\n}\n\nfunction parseSingleChannelDomain(scale: Scale, model: Model, channel:Channel): VgDomain {\n const fieldDef = model.fieldDef(channel);\n\n if (scale.domain && scale.domain !== 'unaggregated') { // explicit value\n if (isDateTime(scale.domain[0])) {\n return (scale.domain as DateTime[]).map((dt) => {\n return timestamp(dt, true);\n });\n }\n return scale.domain;\n }\n\n // special case for temporal scale\n if (fieldDef.type === 'temporal') {\n return {\n data: model.dataTable(),\n field: model.field(channel),\n sort: {\n field: model.field(channel),\n op: 'min'\n }\n };\n }\n\n // For stack, use STACKED data.\n const stack = model.stack;\n if (stack && channel === stack.fieldChannel) {\n if(stack.offset === 'normalize') {\n return [0, 1];\n }\n return {\n data: model.dataName('stacked'),\n fields: [\n model.field(channel, {suffix: 'start'}),\n model.field(channel, {suffix: 'end'})\n ]\n };\n }\n\n const sort = domainSort(model, channel, scale.type);\n\n if (scale.domain === 'unaggregated') {\n return {\n data: model.dataTable(),\n fields: [\n model.field(channel, {aggregate: 'min'}),\n model.field(channel, {aggregate: 'max'})\n ]\n };\n } else if (fieldDef.bin) { // bin\n if (isBinScale(scale.type)) {\n const field = model.getName(fieldDef.field + '_bins');\n return {signal: `sequence(${field}.start, ${field}.stop + ${field}.step, ${field}.step)`};\n }\n\n if (hasDiscreteDomain(scale.type)) {\n // ordinal bin scale takes domain from bin_range, ordered by bin_start\n // This is useful for both axis-based scale (x, y, column, and row) and legend-based scale (other channels).\n return {\n data: model.dataTable(),\n field: model.field(channel, {binSuffix: 'range'}),\n sort: {\n field: model.field(channel, {binSuffix: 'start'}),\n op: 'min' // min or max doesn't matter since same _range would have the same _start\n }\n };\n } else { // continuous scales\n if (channel === 'x' || channel === 'y') {\n // X/Y position have to include start and end for non-ordinal scale\n return {\n data: model.dataTable(),\n fields: [\n model.field(channel, {binSuffix: 'start'}),\n model.field(channel, {binSuffix: 'end'})\n ]\n };\n } else {\n // TODO: use bin_mid\n return {\n data: model.dataTable(),\n field: model.field(channel, {binSuffix: 'start'})\n };\n }\n }\n } else if (sort) { // have sort -- only for ordinal\n return {\n // If sort by aggregation of a specified sort field, we need to use SOURCE table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.dataTable(): SOURCE,\n field: model.field(channel),\n sort: sort\n };\n } else {\n return {\n data: model.dataTable(),\n field: model.field(channel),\n };\n }\n}\n\nexport function domainSort(model: Model, channel: Channel, scaleType: ScaleType): VgSortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const sort = model.sort(channel);\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n return {\n op: sort.op,\n field: sort.field\n };\n }\n\n if (util.contains(['ascending', 'descending', undefined /* default =ascending*/], sort)) {\n return true;\n }\n\n // sort === 'none'\n return undefined;\n}\n\n\n\n/**\n * Determine if a scale can use unaggregated domain.\n * @return {Boolean} Returns true if all of the following conditons applies:\n * 1. `scale.domain` is `unaggregated`\n * 2. Aggregation function is not `count` or `sum`\n * 3. The scale is quantitative or time scale.\n */\nexport function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): {valid: boolean, reason?: string} {\n if (!fieldDef.aggregate) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)\n };\n }\n\n if (SHARED_DOMAIN_OPS.indexOf(fieldDef.aggregate) === -1) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate)\n };\n }\n\n if (fieldDef.type === 'quantitative') {\n if (scaleType === 'log') {\n return {\n valid: false,\n reason: log.message.unaggregatedDomainWithLogScale(fieldDef)\n };\n }\n }\n\n return {valid: true};\n}\n\n/**\n * Scale domains that we can union. We cannot union signal domains we use for\n * binned data because they have to be exactly the same. Otherwise it doesn't\n * make any sense to union.\n */\ntype UnionableDomain = any[] | VgDataRef | DataRefUnionDomain | FieldRefUnionDomain;\n\n/**\n * Convert the domain to an array of data refs or an array of values. Also, throw\n * away sorting information since we always sort the domain when we union two domains.\n */\nfunction normalizeDomain(domain: UnionableDomain): (any[] | VgDataRef)[] {\n if (util.isArray(domain)) {\n return [domain];\n } else if (isDataRefDomain(domain)) {\n delete domain.sort;\n return [domain];\n } else if(isFieldRefUnionDomain(domain)) {\n return domain.fields.map(d => {\n return {\n data: domain.data,\n field: d\n };\n });\n } else if (isDataRefUnionedDomain(domain)) {\n return domain.fields.map(d => {\n if (util.isArray(d)) {\n return d;\n }\n return {\n field: d.field,\n data: d.data\n };\n });\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVAID_DOMAIN);\n}\n\n/**\n * Union two data domains. A unioned domain is always sorted.\n */\nexport function unionDomains(domain1: VgDomain, domain2: VgDomain): VgDomain {\n if (isSignalRefDomain(domain1) || isSignalRefDomain(domain2)) {\n if (!isSignalRefDomain(domain1) || !isSignalRefDomain(domain2) || domain1.signal !== domain2.signal) {\n throw new Error(log.message.UNABLE_TO_MERGE_DOMAINS);\n }\n return domain1;\n }\n\n const normalizedDomain1 = normalizeDomain(domain1);\n const normalizedDomain2 = normalizeDomain(domain2);\n\n let domains = normalizedDomain1.concat(normalizedDomain2);\n domains = util.unique(domains, util.hash);\n\n if (domains.length > 1) {\n const allData = domains.map(d => {\n if (isDataRefDomain(d)) {\n return d.data;\n }\n return null;\n });\n\n if (util.unique(allData, x => x).length === 1 && allData[0] !== null) {\n return {\n data: allData[0],\n fields: domains.map(d => (d as VgDataRef).field)\n };\n }\n\n return {fields: domains, sort: true};\n } else {\n return domains[0];\n }\n}\n", + "import * as log from '../../log';\n\nimport {Config} from '../../config';\nimport {Channel} from '../../channel';\nimport {ScaleFieldDef, FieldDef} from '../../fielddef';\nimport {Mark} from '../../mark';\nimport {Scale, ScaleConfig, scaleTypeSupportProperty, channelScalePropertyIncompatability} from '../../scale';\n\nimport {initDomain} from './domain';\nimport rangeMixins from './range';\nimport * as rules from './rules';\nimport scaleType from './type';\nimport * as util from '../../util';\n\n/**\n * All scale properties except type and all range properties.\n */\nexport const NON_TYPE_RANGE_SCALE_PROPERTIES: (keyof Scale)[] = [\n // general properties\n 'domain', // For domain, we only copy specified value here. Default value is determined during parsing phase.\n 'round',\n // quantitative / time\n 'clamp', 'nice',\n // quantitative\n 'exponent', 'zero', // zero depends on domain\n 'interpolate',\n // ordinal\n 'padding', 'paddingInner', 'paddingOuter' // padding\n];\n\n/**\n * Initialize Vega-Lite Scale's properties\n *\n * Note that we have to apply these rules here because:\n * - many other scale and non-scale properties (including layout, mark) depend on scale type\n * - layout depends on padding\n * - range depends on zero and size (width and height) depends on range\n */\nexport default function init(\n channel: Channel, fieldDef: ScaleFieldDef, config: Config,\n mark: Mark | undefined, topLevelSize: number | undefined, xyRangeSteps: number[]): Scale {\n const specifiedScale = (fieldDef || {}).scale || {};\n\n const scale: Scale = {\n type: scaleType(\n specifiedScale.type, channel, fieldDef, mark, topLevelSize !== undefined,\n specifiedScale.rangeStep, config.scale\n )\n };\n\n // Use specified value if compatible or determine default values for each property\n NON_TYPE_RANGE_SCALE_PROPERTIES.forEach(function(property) {\n const specifiedValue = specifiedScale[property];\n\n const supportedByScaleType = scaleTypeSupportProperty(scale.type, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n\n if (specifiedValue !== undefined) {\n // If there is a specified value, check if it is compatible with scale type and channel\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scale.type, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n }\n }\n if (supportedByScaleType && channelIncompatability === undefined) {\n const value = getValue(specifiedValue, property, scale, channel, fieldDef, config.scale);\n if (value !== undefined) { // use the default value\n scale[property] = value;\n }\n }\n });\n\n return util.extend(\n scale,\n rangeMixins(\n channel, scale.type, fieldDef.type, specifiedScale, config,\n scale.zero, mark, topLevelSize, xyRangeSteps\n )\n );\n}\n\nfunction getValue(specifiedValue: any, property: keyof Scale, scale: Scale, channel: Channel, fieldDef: FieldDef, scaleConfig: ScaleConfig) {\n // For domain, we might override specified value\n if (property === 'domain') {\n return initDomain(specifiedValue, fieldDef, scale.type, scaleConfig);\n }\n\n // Other properties, no overriding default values\n if (specifiedValue !== undefined) {\n return specifiedValue;\n }\n return getDefaultValue(property, scale, channel, fieldDef, scaleConfig);\n}\n\nfunction getDefaultValue(property: keyof Scale, scale: Scale, channel: Channel, fieldDef: FieldDef, scaleConfig: ScaleConfig) {\n\n // If we have default rule-base, determine default value first\n switch (property) {\n case 'nice':\n return rules.nice(scale.type, channel, fieldDef);\n case 'padding':\n return rules.padding(channel, scale.type, scaleConfig);\n case 'paddingInner':\n return rules.paddingInner(scale.padding, channel, scaleConfig);\n case 'paddingOuter':\n return rules.paddingOuter(scale.padding, channel, scale.type, scale.paddingInner, scaleConfig);\n case 'round':\n return rules.round(channel, scaleConfig);\n case 'zero':\n return rules.zero(scale, channel, fieldDef);\n }\n // Otherwise, use scale config\n return scaleConfig[property];\n}\n", + "import {Channel} from '../../channel';\nimport {Scale} from '../../scale';\nimport {isSortField} from '../../sort';\nimport {Dict} from '../../util';\n\nimport {Model} from '../model';\n\nimport {parseDomain} from './domain';\nimport {parseRange} from './range';\nimport {VgScale} from '../../vega.schema';\n\n/**\n * Parse scales for all channels of a model.\n */\nexport default function parseScaleComponent(model: Model): Dict {\n // TODO: should model.channels() inlcude X2/Y2?\n return model.channels().reduce(function(scaleComponentsIndex: Dict, channel: Channel) {\n const scaleComponents = parseScale(model, channel);\n if (scaleComponents) {\n scaleComponentsIndex[channel] = scaleComponents;\n }\n return scaleComponentsIndex;\n }, {});\n}\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES: (keyof Scale)[] = [\n 'round',\n // quantitative / time\n 'clamp', 'nice',\n // quantitative\n 'exponent', 'interpolate', 'zero', // zero depends on domain\n // ordinal\n 'padding', 'paddingInner', 'paddingOuter', // padding\n];\n\n/**\n * Parse scales for a single channel of a model.\n */\nexport function parseScale(model: Model, channel: Channel) {\n if (!model.scale(channel)) {\n return null;\n }\n\n const scale = model.scale(channel);\n const sort = model.sort(channel);\n\n let scaleComponent: VgScale = {\n name: model.scaleName(channel + '', true),\n type: scale.type,\n domain: parseDomain(model, channel),\n range: parseRange(scale)\n };\n\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES.forEach((property) => {\n scaleComponent[property] = scale[property];\n });\n\n if (sort && (isSortField(sort) ? sort.order : sort) === 'descending') {\n scaleComponent.reverse = true;\n }\n return scaleComponent;\n}\n", + "import * as log from '../../log';\n\nimport {COLUMN, ROW, X, Y, SHAPE, SIZE, COLOR, OPACITY, Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {Mark} from '../../mark';\nimport {Scale, ScaleConfig, ScaleType, scaleTypeSupportProperty, Scheme, Range, isExtendedScheme, channelScalePropertyIncompatability} from '../../scale';\nimport {Type} from '../../type';\nimport {VgRange, VgRangeScheme} from '../../vega.schema';\nimport * as util from '../../util';\n\nexport type RangeMixins = {range: Range} | {rangeStep: number} | {scheme: Scheme};\n\nexport function parseRange(scale: Scale): VgRange {\n if (scale.rangeStep) {\n return {step: scale.rangeStep};\n } else if (scale.scheme) {\n const scheme = scale.scheme;\n if (isExtendedScheme(scheme)) {\n let r: VgRangeScheme = {scheme: scheme.name};\n if (scheme.count) {\n r.count = scheme.count;\n }\n if (scheme.extent) {\n r.extent = scheme.extent;\n }\n return r;\n } else {\n return {scheme};\n }\n }\n return scale.range;\n}\n\nexport const RANGE_PROPERTIES: (keyof Scale)[] = ['range', 'rangeStep', 'scheme'];\n\n/**\n * Return mixins that includes one of the range properties (range, rangeStep, scheme).\n */\nexport default function rangeMixins(\n channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config,\n zero: boolean, mark: Mark, topLevelSize: number | undefined, xyRangeSteps: number[]): RangeMixins {\n\n let specifiedRangeStepIsNull = false;\n\n // Check if any of the range properties is specified.\n // If so, check if it is compatible and make sure that we only output one of the properties\n for (let property of RANGE_PROPERTIES) {\n if (specifiedScale[property] !== undefined) {\n let supportedByScaleType = scaleTypeSupportProperty(scaleType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n } else {\n switch (property) {\n case 'range':\n return {range: specifiedScale[property]};\n case 'scheme':\n return {scheme: specifiedScale[property]};\n case 'rangeStep':\n if (topLevelSize === undefined) {\n const stepSize = specifiedScale[property];\n if (stepSize !== null) {\n return {rangeStep: stepSize};\n } else {\n specifiedRangeStepIsNull = true;\n }\n } else {\n // If top-level size is specified, we ignore specified rangeStep.\n log.warn(log.message.rangeStepDropped(channel));\n }\n }\n }\n }\n }\n\n switch (channel) {\n // TODO: revise row/column when facetSpec has top-level width/height\n case ROW:\n return {range: 'height'};\n case COLUMN:\n return {range: 'width'};\n case X:\n case Y:\n if (topLevelSize === undefined) {\n if (util.contains(['point', 'band'], scaleType) && !specifiedRangeStepIsNull) { // FIXME isDiscrete blah blah\n if (channel === X && mark === 'text') {\n if (config.scale.textXRangeStep) {\n return {rangeStep: config.scale.textXRangeStep};\n }\n } else {\n if (config.scale.rangeStep) {\n return {rangeStep: config.scale.rangeStep};\n }\n }\n }\n // If specified range step is null or the range step config is null.\n // Use default topLevelSize rule/config\n topLevelSize = channel === X ? config.cell.width : config.cell.height;\n }\n return {range: channel === X ? [0, topLevelSize] : [topLevelSize, 0]};\n\n case SIZE:\n // TODO: support custom rangeMin, rangeMax\n const rangeMin = sizeRangeMin(mark, zero, config);\n const rangeMax = sizeRangeMax(mark, xyRangeSteps, config);\n return {range: [rangeMin, rangeMax]};\n case SHAPE:\n case COLOR:\n return {range: defaultRange(channel, scaleType, type, mark)};\n\n\n case OPACITY:\n // TODO: support custom rangeMin, rangeMax\n return {range: [config.scale.minOpacity, config.scale.maxOpacity]};\n }\n /* istanbul ignore next: should never reach here */\n throw new Error(`Scale range undefined for channel ${channel}`);\n}\n\nfunction defaultRange(channel: 'shape' | 'color', scaleType: ScaleType, type: Type, mark: Mark) {\n switch (channel) {\n case SHAPE:\n return 'symbol';\n case COLOR:\n if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' ? 'heatmap' : 'ramp';\n }\n}\n\nfunction sizeRangeMin(mark: Mark, zero: boolean, config: Config) {\n if (zero) {\n return 0;\n }\n switch (mark) {\n case 'bar':\n return config.scale.minBandSize !== undefined ? config.scale.minBandSize : config.bar.continuousBandSize;\n case 'tick':\n return config.scale.minBandSize;\n case 'line':\n case 'rule':\n return config.scale.minStrokeWidth;\n case 'text':\n return config.scale.minFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.minSize) {\n return config.scale.minSize;\n }\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMin not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\nfunction sizeRangeMax(mark: Mark, xyRangeSteps: number[], config: Config) {\n const scaleConfig = config.scale;\n // TODO(#1168): make max size scale based on rangeStep / overall plot size\n switch (mark) {\n case 'bar':\n case 'tick':\n if (config.scale.maxBandSize !== undefined) {\n return config.scale.maxBandSize;\n }\n return minXYRangeStep(xyRangeSteps, config.scale) - 1;\n case 'line':\n case 'rule':\n return config.scale.maxStrokeWidth;\n case 'text':\n return config.scale.maxFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.maxSize) {\n return config.scale.maxSize;\n }\n\n // FIXME this case totally should be refactored\n const pointStep = minXYRangeStep(xyRangeSteps, scaleConfig);\n return (pointStep - 2) * (pointStep - 2);\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMax not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\n/**\n * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale.\n */\nfunction minXYRangeStep(xyRangeSteps: number[], scaleConfig: ScaleConfig): number {\n if (xyRangeSteps.length > 0) {\n return Math.min.apply(null, xyRangeSteps);\n }\n if (scaleConfig.rangeStep) {\n return scaleConfig.rangeStep;\n }\n return 21; // FIXME: re-evaluate the default value here.\n}\n", + "\nimport {X, Y, Channel} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport {Scale, ScaleConfig, ScaleType, NiceTime} from '../../scale';\nimport {smallestUnit} from '../../timeunit';\nimport * as util from '../../util';\n\nexport function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime {\n if (util.contains([ScaleType.TIME, ScaleType.UTC], scaleType)) {\n return smallestUnit(fieldDef.timeUnit) as any;\n }\n return util.contains([X, Y], channel); // return true for quantitative X/Y\n}\n\nexport function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig) {\n if (util.contains([X, Y], channel)) {\n if (scaleType === ScaleType.POINT) {\n return scaleConfig.pointPadding;\n }\n }\n return undefined;\n}\n\nexport function paddingInner(padding: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (padding !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingInner.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n\n // paddingOuter would only be called if it's a band scale, just return the default for bandScale.\n return scaleConfig.bandPaddingInner;\n }\n return undefined;\n}\n\nexport function paddingOuter(padding: number, channel: Channel, scaleType: ScaleType, paddingInner: number, scaleConfig: ScaleConfig) {\n if (padding !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingOuter.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n if (scaleType === ScaleType.BAND) {\n if (scaleConfig.bandPaddingOuter !== undefined) {\n return scaleConfig.bandPaddingOuter;\n }\n /* By default, paddingOuter is paddingInner / 2. The reason is that\n size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter).\n and we want the width/height to be integer by default.\n Note that step (by default) and cardinality are integers.) */\n return paddingInner / 2;\n }\n }\n return undefined;\n}\n\nexport function round(channel: Channel, scaleConfig: ScaleConfig) {\n if (util.contains(['x', 'y', 'row', 'column'], channel)) {\n return scaleConfig.round;\n }\n return undefined;\n}\n\nexport function zero(specifiedScale: Scale, channel: Channel, fieldDef: FieldDef) {\n // By default, return true only for the following cases:\n\n // 1) using quantitative field with size\n // While this can be either ratio or interval fields, our assumption is that\n // ratio are more common.\n if (channel === 'size' && fieldDef.type === 'quantitative') {\n return true;\n }\n\n // 2) non-binned, quantitative x-scale or y-scale if no custom domain is provided.\n // (For binning, we should not include zero by default because binning are calculated without zero.\n // Similar, if users explicitly provide a domain range, we should not augment zero as that will be unexpected.)\n if (!specifiedScale.domain && !fieldDef.bin && util.contains([X, Y], channel)) {\n return true;\n }\n return false;\n}\n", + "import * as log from '../../log';\n\nimport {hasScale, supportScaleType, rangeType, Channel} from '../../channel';\nimport {Mark} from '../../mark';\nimport {ScaleType, ScaleConfig} from '../../scale';\nimport {isDiscreteByDefault} from '../../timeunit';\n\nimport * as util from '../../util';\nimport {FieldDef} from '../../fielddef';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport default function type(\n specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef, mark: Mark,\n hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType {\n\n const defaultScaleType = defaultType(channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n\n if (!hasScale(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (specifiedType !== undefined) {\n // for binned fields we don't allow overriding the default scale\n if (fieldDef.bin) {\n // TODO: generalize this as a method in fieldDef that determines scale type support for a fieldDef (looking at functions and type)\n log.warn(log.message.cannotOverrideBinScaleType(channel, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the channel\n if (supportScaleType(channel, specifiedType)) {\n return specifiedType;\n } else {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\nfunction defaultType(channel: Channel, fieldDef: FieldDef, mark: Mark,\n hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType {\n\n if (util.contains(['row', 'column'], channel)) {\n return 'band';\n }\n\n switch (fieldDef.type) {\n case 'nominal':\n if (channel === 'color' || rangeType(channel) === 'discrete') {\n return 'ordinal';\n }\n return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n\n case 'ordinal':\n if (channel === 'color') {\n return 'ordinal';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n return 'ordinal';\n }\n return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n\n case 'temporal':\n if (channel === 'color') {\n // Always use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n if (isDiscreteByDefault(fieldDef.timeUnit)) {\n return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n }\n return 'time';\n\n case 'quantitative':\n if (channel === 'color') {\n if (fieldDef.bin) {\n return 'bin-ordinal';\n }\n // Use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n if (fieldDef.bin) {\n return 'bin-linear';\n }\n return 'linear';\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\n/**\n * Determines default scale type for nominal/ordinal field.\n * @returns BAND or POINT scale based on channel, mark, and rangeStep\n */\nfunction discreteToContinuousType(\n channel: Channel, mark: Mark, hasTopLevelSize: boolean,\n specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType {\n\n if (util.contains(['x', 'y'], channel)) {\n if (mark === 'rect') {\n // The rect mark should fit into a band.\n return 'band';\n }\n if (mark === 'bar') {\n // For bar, use band only if there is no rangeStep since we need to use band for fit mode.\n // However, for non-fit mode, point scale provides better center position.\n if (haveRangeStep(hasTopLevelSize, specifiedRangeStep, scaleConfig)) {\n return 'point';\n }\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n}\n\nfunction haveRangeStep(hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig) {\n if (hasTopLevelSize) {\n // if topLevelSize is provided, rangeStep will be dropped.\n return false;\n }\n if (specifiedRangeStep !== undefined) {\n return specifiedRangeStep !== null;\n }\n return !!scaleConfig.rangeStep;\n}\n", + "import {SelectionComponent, SelectionCompiler, TUPLE, invert as invertFn, channelSignalName} from './selection';\nimport {X, Y, Channel} from '../../channel';\nimport {UnitModel} from '../unit';\nimport {stringValue, extend} from '../../util';\nimport {warn} from '../../log';\nimport scales from './transforms/scales';\n\nexport const BRUSH = '_brush',\n SIZE = '_size';\n\nconst interval:SelectionCompiler = {\n predicate: 'vlInterval',\n\n signals: function(model, selCmpt) {\n let signals: any[] = [],\n intervals:any[] = [],\n name = selCmpt.name,\n size = name + SIZE;\n\n if (selCmpt.translate && !(scales.has(selCmpt))) {\n events(selCmpt, function(_: any[], evt: any) {\n let filters = evt.between[0].filter || (evt.between[0].filter = []);\n filters.push('!event.item || (event.item && ' +\n `event.item.mark.name !== ${stringValue(name + BRUSH)})`);\n });\n }\n\n selCmpt.project.forEach(function(p) {\n if (p.encoding !== X && p.encoding !== Y) {\n warn('Interval selections only support x and y encoding channels.');\n return;\n }\n\n let cs = channelSignal(model, selCmpt, p.encoding);\n signals.push(cs);\n intervals.push(`{field: ${stringValue(p.field)}, extent: ${cs.name}}`);\n });\n\n signals.push({\n name: size,\n value: [],\n on: events(selCmpt, function(on: any[], evt: any) {\n on.push({\n events: evt.between[0],\n update: '{x: x(unit), y: y(unit), width: 0, height: 0}'\n });\n\n on.push({\n events: evt,\n update: `{x: ${size}.x, y: ${size}.y, ` +\n `width: abs(x(unit) - ${size}.x), height: abs(y(unit) - ${size}.y)}`\n });\n\n return on;\n })\n }, {\n name: name,\n update: `[${intervals.join(', ')}]`\n });\n\n return signals;\n },\n\n tupleExpr: function(model, selCmpt) {\n return `intervals: ${selCmpt.name}`;\n },\n\n modifyExpr: function(model, selCmpt) {\n let tpl = selCmpt.name + TUPLE;\n return `${tpl}, {unit: ${tpl}.unit}`;\n },\n\n marks: function(model, selCmpt, marks) {\n let name = selCmpt.name,\n {x, y} = projections(selCmpt);\n\n // Do not add a brush if we're binding to scales.\n if (scales.has(selCmpt)) {\n return marks;\n }\n\n let update = {\n x: extend({}, x !== null ?\n {scale: model.scaleName(X), signal: `${name}[${x}].extent[0]`} :\n {value: 0}),\n\n x2: extend({}, x !== null ?\n {scale: model.scaleName(X), signal: `${name}[${x}].extent[1]`} :\n {field: {group: 'width'}}),\n\n y: extend({}, y !== null ?\n {scale: model.scaleName(Y), signal: `${name}[${y}].extent[0]`} :\n {value: 0}),\n\n y2: extend({}, y !== null ?\n {scale: model.scaleName(Y), signal: `${name}[${y}].extent[1]`} :\n {field: {group: 'height'}}),\n };\n\n return [{\n name: undefined,\n type: 'rect',\n encode: {\n enter: {fill: {value: '#eee'}},\n update: update\n }\n }].concat(marks, {\n name: name + BRUSH,\n type: 'rect',\n encode: {\n enter: {fill: {value: 'transparent'}},\n update: update\n }\n });\n }\n};\nexport {interval as default};\n\nexport function projections(selCmpt: SelectionComponent) {\n let x:number = null, y:number = null;\n selCmpt.project.forEach(function(p, i) {\n if (p.encoding === X) {\n x = i;\n } else if (p.encoding === Y) {\n y = i;\n }\n });\n return {x: x, y: y};\n}\n\nfunction channelSignal(model: UnitModel, selCmpt: SelectionComponent, channel: Channel): any {\n let name = channelSignalName(selCmpt, channel),\n size = (channel === X ? 'width' : 'height'),\n coord = `${channel}(unit)`,\n invert = invertFn.bind(null, model, selCmpt, channel);\n\n return {\n name: name,\n value: [],\n on: scales.has(selCmpt) ? [] : events(selCmpt, function(on: any[], evt: any) {\n on.push({\n events: evt.between[0],\n update: invert(`[${coord}, ${coord}]`)\n });\n\n on.push({\n events: evt,\n update: `[${name}[0], ` + invert(`clamp(${coord}, 0, ${size})`) + ']'\n });\n\n return on;\n })\n };\n}\n\nfunction events(selCmpt: SelectionComponent, cb: Function) {\n return selCmpt.events.reduce(function(on: any[], evt: any) {\n if (!evt.between) {\n warn(`${evt} is not an ordered event stream for interval selections`);\n return on;\n }\n return cb(on, evt);\n }, []);\n}\n", + "import {TUPLE, SelectionCompiler} from './selection';\nimport {stringValue} from '../../util';\n\nconst multi:SelectionCompiler = {\n predicate: 'vlPoint',\n\n signals: function(model, selCmpt) {\n let proj = selCmpt.project,\n datum = '(item().isVoronoi ? datum.datum : datum)',\n fields = proj.map((p) => stringValue(p.field)).join(', '),\n values = proj.map((p) => `${datum}[${stringValue(p.field)}]`).join(', ');\n return [{\n name: selCmpt.name,\n value: {},\n on: [{\n events: selCmpt.events,\n update: `{fields: [${fields}], values: [${values}]}`\n }]\n }];\n },\n\n tupleExpr: function(model, selCmpt) {\n let name = selCmpt.name;\n return `fields: ${name}.fields, values: ${name}.values`;\n },\n\n modifyExpr: function(model, selCmpt) {\n return selCmpt.name + TUPLE;\n }\n};\n\nexport {multi as default};\n", + "import {SelectionDef, SelectionDomain, SelectionResolutions, SelectionTypes} from '../../selection';\nimport {SelectionComponent} from './selection';\nimport {Model} from '../model';\nimport {UnitModel} from '../unit';\nimport {Channel} from '../../channel';\nimport {Dict, extend, stringValue, isString} from '../../util';\nimport {forEachTransform} from './transforms/transforms';\nimport parseSelector from 'vega-parser/src/parsers/event-selector';\nimport {VgData, VgBinding} from '../../vega.schema';\nimport singleCompiler from './single';\nimport multiCompiler from './multi';\nimport intervalCompiler from './interval';\n\nexport const STORE = '_store',\n TUPLE = '_tuple',\n MODIFY = '_modify';\n\nexport interface SelectionComponent {\n name: string;\n type: SelectionTypes;\n domain: SelectionDomain;\n events: any;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n resolve: SelectionResolutions;\n\n // Transforms\n project?: ProjectComponent[];\n scales?: Channel[];\n toggle?: any;\n translate?: any;\n zoom?: any;\n nearest?: any;\n}\n\nexport interface ProjectComponent {\n field?: string;\n encoding?: Channel;\n}\n\nexport interface SelectionCompiler {\n signals: (model: UnitModel, selCmpt: SelectionComponent) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent) => any[];\n tupleExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n predicate: string; // Vega expr string to determine inclusion in selection.\n}\n\nexport function parseUnitSelection(model: UnitModel, selDefs: Dict) {\n let selCmpts: Dict = {},\n selectionConfig = model.config.selection;\n\n for (let name in selDefs) {\n if (!selDefs.hasOwnProperty(name)) {\n continue;\n }\n\n let selDef = selDefs[name],\n cfg = selectionConfig[selDef.type];\n\n // Set default values from config if a property hasn't been specified,\n // or if it is true. E.g., \"translate\": true should use the default\n // event handlers for translate. However, true may be a valid value for\n // a property (e.g., \"nearest\": true).\n for (let key in cfg) {\n // A selection should contain either `encodings` or `fields`, only use\n // default values for these two values if neither of them is specified.\n if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) {\n continue;\n }\n\n if (selDef[key] === undefined || selDef[key] === true) {\n selDef[key] = cfg[key] || selDef[key];\n }\n }\n\n let selCmpt = selCmpts[name] = extend({}, selDef, {\n name: model.getName(name),\n events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on,\n domain: 'data' as SelectionDomain, // TODO: Support def.domain\n resolve: 'union' as SelectionResolutions\n }) as SelectionComponent;\n\n forEachTransform(selCmpt, function(txCompiler) {\n if (txCompiler.parse) {\n txCompiler.parse(model, selDef, selCmpt);\n }\n });\n }\n\n return selCmpts;\n}\n\nexport function assembleUnitSignals(model: UnitModel, signals: any[]) {\n forEachSelection(model, function(selCmpt, selCompiler) {\n let name = selCmpt.name,\n tupleExpr = selCompiler.tupleExpr(model, selCmpt),\n modifyExpr = selCompiler.modifyExpr(model, selCmpt);\n\n signals.push.apply(signals, selCompiler.signals(model, selCmpt));\n\n forEachTransform(selCmpt, function(txCompiler) {\n if (txCompiler.signals) {\n signals = txCompiler.signals(model, selCmpt, signals);\n }\n if (txCompiler.modifyExpr) {\n modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr);\n }\n });\n\n signals.push({\n name: name + TUPLE,\n on: [{\n events: {signal: name},\n update: `{unit: unit.datum && unit.datum._id, ${tupleExpr}}`\n }]\n }, {\n name: name + MODIFY,\n on: [{\n events: {signal: name},\n update: `modify(${stringValue(name + STORE)}, ${modifyExpr})`\n }]\n });\n });\n\n return signals;\n}\n\nexport function assembleTopLevelSignals(model: Model) {\n let signals:any[] = [{\n name: 'unit',\n value: {},\n on: [{events: 'mousemove', update: 'group()._id ? group() : unit'}]\n }];\n\n forEachSelection(model, function(selCmpt, selCompiler) {\n if (selCompiler.topLevelSignals) {\n signals.push.apply(signals, selCompiler.topLevelSignals(model, selCmpt));\n }\n\n forEachTransform(selCmpt, function(txCompiler) {\n if (txCompiler.topLevelSignals) {\n signals = txCompiler.topLevelSignals(model, selCmpt, signals);\n }\n });\n });\n\n return signals;\n}\n\nexport function assembleUnitData(model: UnitModel, data: VgData[]): VgData[] {\n return data\n .concat(Object.keys(model.component.selection)\n .map(function(k: string) {\n return {name: k + STORE};\n }));\n}\n\nexport function assembleUnitMarks(model: UnitModel, marks: any[]): any[] {\n let clippedGroup = false,\n selMarks = marks;\n forEachSelection(model, function(selCmpt, selCompiler) {\n selMarks = selCompiler.marks ? selCompiler.marks(model, selCmpt, selMarks) : selMarks;\n forEachTransform(selCmpt, function(txCompiler) {\n clippedGroup = clippedGroup || txCompiler.clippedGroup;\n if (txCompiler.marks) {\n selMarks = txCompiler.marks(model, selCmpt, marks, selMarks);\n }\n });\n });\n\n if (clippedGroup) {\n selMarks = [{\n type: 'group',\n encode: {\n enter: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}},\n fill: {value: 'transparent'},\n clip: {value: true}\n }\n },\n marks: selMarks\n }];\n }\n\n return selMarks;\n}\n\nlet PREDICATES_OPS = {\n 'single': '\"intersect\", \"all\"',\n 'independent': '\"intersect\", \"unit\"',\n 'union': '\"union\", \"all\"',\n 'union_others': '\"union\", \"others\"',\n 'intersect': '\"intersect\", \"all\"',\n 'intersect_others': '\"intersect\", \"others'\n};\n\nexport function predicate(selCmpt: SelectionComponent, datum?: string): string {\n const store = stringValue(selCmpt.name + STORE),\n op = PREDICATES_OPS[selCmpt.resolve];\n datum = datum || 'datum';\n return compiler(selCmpt).predicate + `(${store}, parent._id, ${datum}, ${op})`;\n}\n\n// Utility functions\n\nfunction forEachSelection(model: Model, cb: (selCmpt: SelectionComponent, selCompiler: SelectionCompiler) => void) {\n let selections = model.component.selection;\n for (let name in selections) {\n if (selections.hasOwnProperty(name)) {\n let sel = selections[name];\n cb(sel, compiler(sel));\n }\n }\n}\n\nfunction compiler(selCmpt: SelectionComponent): SelectionCompiler {\n switch (selCmpt.type) {\n case 'single':\n return singleCompiler;\n case 'multi':\n return multiCompiler;\n case 'interval':\n return intervalCompiler;\n }\n return null;\n}\n\nexport function invert(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, expr: string) {\n let scale = stringValue(model.scaleName(channel));\n return selCmpt.domain === 'data' ? `invert(${scale}, ${expr})` : expr;\n}\n\nexport function channelSignalName(selCmpt: SelectionComponent, channel: Channel) {\n return selCmpt.name + '_' + channel;\n}\n", + "import {TUPLE, STORE, SelectionCompiler} from './selection';\nimport multi from './multi';\nimport {stringValue} from '../../util';\n\nconst single:SelectionCompiler = {\n predicate: multi.predicate,\n\n signals: multi.signals,\n\n topLevelSignals: function(model, selCmpt) {\n let name = selCmpt.name;\n return [{\n name: name,\n update: `data(${stringValue(name + STORE)})[0]`\n }];\n },\n\n tupleExpr: function(model, selCmpt) {\n let name = selCmpt.name, values = `${name}.values`;\n return `fields: ${name}.fields, values: ${values}, ` +\n selCmpt.project.map(function(p, i) {\n return `${p.field}: ${values}[${i}]`;\n }).join(', ');\n },\n\n modifyExpr: function(model, selCmpt) {\n return selCmpt.name + TUPLE + ', true';\n }\n};\n\nexport {single as default};\n", + "import {TransformCompiler} from './transforms';\nimport {stringValue} from '../../../util';\n\nconst inputBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'single' && selCmpt.bind && selCmpt.bind !== 'scales';\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n let name = selCmpt.name,\n proj = selCmpt.project,\n bind = selCmpt.bind,\n datum = '(item().isVoronoi ? datum.datum : datum)';\n\n proj.forEach(function(p) {\n signals.unshift({\n name: name + id(p.field),\n value: '',\n on: [{\n events: selCmpt.events,\n update: `${datum}[${stringValue(p.field)}]`\n }],\n bind: bind[p.field] || bind[p.encoding] || bind\n });\n });\n\n return signals;\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name, proj = selCmpt.project,\n signal = signals.filter((s) => s.name === name)[0],\n fields = proj.map((p) => stringValue(p.field)).join(', '),\n values = proj.map((p) => name + id(p.field)).join(', ');\n\n signal.update = `{fields: [${fields}], values: [${values}]}`;\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport {inputBindings as default};\n\nfunction id(str: string) {\n return '_' + str.replace(/\\W/g, '_');\n}\n", + "import {TransformCompiler} from './transforms';\n\nconst VORONOI = 'voronoi';\n\nconst nearest:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.nearest !== undefined && selCmpt.nearest !== false;\n },\n\n marks: function(model, selCmpt, marks, selMarks) {\n let mark = marks[0],\n index = selMarks.indexOf(mark),\n isPathgroup = mark.name === model.getName('pathgroup'),\n exists = ((m: any) => m.name && m.name.indexOf(VORONOI) >= 0),\n cellDef = {\n name: model.getName(VORONOI),\n type: 'path',\n from: {data: model.getName('marks')},\n encode: {\n enter: {\n fill: {value: 'transparent'},\n strokeWidth: {value: 0.35},\n stroke: {value: 'transparent'},\n isVoronoi: {value: true}\n }\n },\n transform: [{\n type: 'voronoi',\n x: 'datum.x',\n y: 'datum.y',\n size: [{signal: 'width'}, {signal: 'height'}]\n }]\n };\n\n if (isPathgroup && !mark.marks.filter(exists).length) {\n mark.marks.push(cellDef);\n selMarks.splice(index, 1, mark);\n } else if (!isPathgroup && !selMarks.filter(exists).length) {\n selMarks.splice(index + 1, 0, cellDef);\n }\n\n return selMarks;\n }\n};\n\nexport {nearest as default};\n", + "import {Channel} from '../../../channel';\nimport {SelectionDef} from '../../../selection';\nimport {TransformCompiler} from './transforms';\n\nconst project:TransformCompiler = {\n has: function(selDef: SelectionDef) {\n return selDef.fields !== undefined || selDef.encodings !== undefined;\n },\n\n parse: function(model, selDef, selCmpt) {\n let fields = {};\n // TODO: find a possible channel mapping for these fields.\n (selDef.fields || []).forEach((f) => fields[f] = null);\n (selDef.encodings || []).forEach((e: Channel) => fields[model.field(e)] = e);\n\n let projection = selCmpt.project || (selCmpt.project = []);\n for (let field in fields) {\n if (fields.hasOwnProperty(field)) {\n projection.push({field: field, encoding: fields[field]});\n }\n }\n }\n};\n\nexport {project as default};\n", + "import {TransformCompiler} from './transforms';\nimport {warn} from '../../../log';\nimport {hasContinuousDomain} from '../../../scale';\nimport {Channel} from '../../../channel';\nimport {TUPLE, MODIFY, channelSignalName} from '../selection';\nimport {UnitModel} from '../../unit';\nimport {SIZE as INTERVAL_SIZE} from '../interval';\nimport {stringValue} from '../../../util';\n\nconst scaleBindings:TransformCompiler = {\n clippedGroup: true,\n\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.bind && selCmpt.bind === 'scales';\n },\n\n parse: function(model, selDef, selCmpt) {\n const scales = model.component.scales;\n const bound:Channel[] = selCmpt.scales = [];\n\n selCmpt.project.forEach(function(p) {\n const channel = p.encoding;\n const scale = scales[channel];\n\n if (!scale || !hasContinuousDomain(scale.type)) {\n warn('Scale bindings are currently only supported for scales with continuous domains.');\n return;\n }\n\n scale.domainRaw = {signal: channelSignalName(selCmpt, channel)};\n bound.push(channel);\n });\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n return signals.concat(selCmpt.scales.map((channel) => {\n return {name: channelSignalName(selCmpt, channel)};\n }));\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name;\n signals = signals.filter(function(s) {\n return s.name !== name + INTERVAL_SIZE &&\n s.name !== name + TUPLE && s.name !== MODIFY;\n });\n\n selCmpt.scales.forEach(function(channel) {\n let signal = signals.filter((s) => s.name === name + '_' + channel)[0];\n signal.push = 'outer';\n delete signal.value;\n delete signal.update;\n });\n\n return signals;\n }\n};\n\nexport {scaleBindings as default};\n\nexport function domain(model: UnitModel, channel: Channel) {\n let scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\n", + "import {TransformCompiler} from './transforms';\nimport {TUPLE} from '../selection';\n\nconst TOGGLE = '_toggle';\n\nconst toggle:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.toggle !== undefined && selCmpt.toggle !== false;\n },\n\n signals: function(model, selCmpt, signals) {\n return signals.concat({\n name: selCmpt.name + TOGGLE,\n value: false,\n on: [{events: selCmpt.events, update: selCmpt.toggle}]\n });\n },\n\n modifyExpr: function(model, selCmpt, expr) {\n let tpl = selCmpt.name + TUPLE,\n signal = selCmpt.name + TOGGLE;\n\n return `${signal} ? null : ${tpl}, ` +\n `${signal} ? null : true, ` +\n `${signal} ? ${tpl} : null`;\n }\n};\n\nexport {toggle as default};\n", + "import {Model} from '../../model';\nimport {UnitModel} from '../../unit';\nimport {SelectionDef} from '../../../selection';\nimport {SelectionComponent} from '../selection';\nimport {Dict} from '../../../util';\n\nexport interface TransformCompiler {\n has: (selCmpt: SelectionComponent | SelectionDef) => boolean;\n parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void;\n signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: any[]) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[];\n // tupleExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[], selMarks: any[]) => any[];\n clippedGroup?: boolean;\n}\n\nimport project from './project';\nimport toggle from './toggle';\nimport translate from './translate';\nimport zoom from './zoom';\nimport scales from './scales';\nimport inputs from './inputs';\nimport nearest from './nearest';\nconst compilers: Dict = {project, toggle, scales,\n translate, zoom, inputs, nearest};\n\nexport function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void) {\n for (let t in compilers) {\n if (compilers[t].has(selCmpt)) {\n cb(compilers[t]);\n }\n }\n}\n", + "import parseSelector from 'vega-parser/src/parsers/event-selector';\nimport {UnitModel} from './../../unit';\nimport {SelectionComponent} from '../selection';\nimport {X, Y, Channel} from '../../../channel';\nimport {stringValue} from '../../../util';\nimport {TransformCompiler} from './transforms';\nimport {default as scalesCompiler, domain} from './scales';\nimport {projections as intervalProjections, SIZE as INTERVAL_SIZE, BRUSH as INTERVAL_BRUSH} from '../interval';\n\nconst ANCHOR = '_translate_anchor',\n DELTA = '_translate_delta';\n\nconst translate:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.translate !== undefined && selCmpt.translate !== false;\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name,\n scales = scalesCompiler.has(selCmpt),\n size = scales ? 'unit' : name + INTERVAL_SIZE,\n anchor = name + ANCHOR,\n events = parseSelector(selCmpt.translate, 'scope'),\n {x, y} = intervalProjections(selCmpt);\n\n if (!scales) {\n events = events.map((e) => (e.between[0].markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: anchor,\n value: {},\n on: [{\n events: events.map((e) => e.between[0]),\n update: '{x: x(unit), y: y(unit), ' +\n `width: ${size}.width, height: ${size}.height, ` +\n\n (x !== null ? 'extent_x: ' + (scales ? domain(model, X) :\n `slice(${name}_x)`) + ', ' : '') +\n\n (y !== null ? 'extent_y: ' + (scales ? domain(model, Y) :\n `slice(${name}_y)`) + ', ' : '') + '}'\n }]\n }, {\n name: name + DELTA,\n value: {},\n on: [{\n events: events,\n update: `{x: x(unit) - ${anchor}.x, y: y(unit) - ${anchor}.y}`\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, X, 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, Y, 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport {translate as default};\n\nfunction getSign(selCmpt: SelectionComponent, channel: Channel) {\n let s = channel === X ? '+' : '-';\n if (scalesCompiler.has(selCmpt)) {\n s = s === '+' ? '-' : '+';\n }\n return s;\n}\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, size: string, signals: any[]) {\n let name = selCmpt.name,\n signal:any = signals.filter((s:any) => s.name === name + '_' + channel)[0],\n anchor = name + ANCHOR,\n delta = name + DELTA,\n scale = stringValue(model.scaleName(channel)),\n extent = `.extent_${channel}`,\n sign = getSign(selCmpt, channel),\n offset = `${sign} abs(span(${anchor}${extent})) * ` +\n `${delta}.${channel} / ${anchor}.${size}`,\n range = `[${anchor}${extent}[0] ${offset}, ` +\n `${anchor}${extent}[1] ${offset}]`,\n lo = `invert(${scale}` + (channel === X ? ', 0' : `, unit.${size}`) + ')',\n hi = `invert(${scale}` + (channel === X ? `, unit.${size}` : ', 0') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: scalesCompiler.has(selCmpt) ? range : `clampRange(${range}, ${lo}, ${hi})`\n });\n}\n", + "import parseSelector from 'vega-parser/src/parsers/event-selector';\nimport {UnitModel} from './../../unit';\nimport {SelectionComponent} from '../selection';\nimport {X, Y, Channel} from '../../../channel';\nimport {stringValue} from '../../../util';\nimport {TransformCompiler} from './transforms';\nimport {default as scalesCompiler, domain} from './scales';\nimport {projections as intervalProjections, SIZE as INTERVAL_SIZE, BRUSH as INTERVAL_BRUSH} from '../interval';\n\nconst ANCHOR = '_zoom_anchor',\n DELTA = '_zoom_delta';\n\nconst zoom:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.zoom !== undefined && selCmpt.zoom !== false;\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name,\n delta = name + DELTA,\n events = parseSelector(selCmpt.zoom, 'scope'),\n {x, y} = intervalProjections(selCmpt),\n sx = stringValue(model.scaleName(X)),\n sy = stringValue(model.scaleName(Y));\n\n if (!scalesCompiler.has(selCmpt)) {\n events = events.map((e) => (e.markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: name + ANCHOR,\n on: [{\n events: events,\n update: `{x: invert(${sx}, x(unit)), y: invert(${sy}, y(unit))}`\n }]\n }, {\n name: delta,\n on: [{\n events: events,\n force: true,\n update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))'\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, 'x', 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, 'y', 'height', signals);\n }\n\n let size = signals.filter((s:any) => s.name === name + INTERVAL_SIZE);\n if (size.length) {\n let sname = size[0].name;\n size[0].on.push({\n events: {signal: delta},\n update: `{x: ${sname}.x, y: ${sname}.y, ` +\n `width: ${sname}.width * ${delta} , ` +\n `height: ${sname}.height * ${delta}}`\n });\n }\n\n return signals;\n }\n};\n\nexport {zoom as default};\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, size: string, signals: any[]) {\n let name = selCmpt.name,\n signal:any = signals.filter((s:any) => s.name === name + '_' + channel)[0],\n scales = scalesCompiler.has(selCmpt),\n base = scales ? domain(model, channel) : signal.name,\n anchor = `${name}${ANCHOR}.${channel}`,\n delta = name + DELTA,\n scale = stringValue(model.scaleName(channel)),\n range = `[${anchor} + (${base}[0] - ${anchor}) * ${delta}, ` +\n `${anchor} + (${base}[1] - ${anchor}) * ${delta}]`,\n lo = `invert(${scale}` + (channel === X ? ', 0' : `, unit.${size}`) + ')',\n hi = `invert(${scale}` + (channel === X ? `, unit.${size}` : ', 0') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: scales ? range : `clampRange(${range}, ${lo}, ${hi})`\n });\n}\n", + "\n\nimport {Axis, VlOnlyAxisBase, VL_ONLY_AXIS_PROPERTIES} from '../axis';\nimport {X, Y, X2, Y2, Channel, UNIT_CHANNELS, UNIT_SCALE_CHANNELS, NONSPATIAL_SCALE_CHANNELS} from '../channel';\nimport {defaultConfig, Config, CellConfig} from '../config';\nimport {SOURCE, SUMMARY} from '../data';\nimport {Encoding, dropInvalidFieldDefs} from '../encoding';\nimport * as vlEncoding from '../encoding'; // TODO: remove\nimport {FieldDef, FieldRefOption, field, isFieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Mark, MarkDef, TEXT as TEXT_MARK, FILL_STROKE_CONFIG, isMarkDef} from '../mark';\nimport {Scale, ScaleConfig, hasDiscreteDomain} from '../scale';\nimport {UnitSpec} from '../spec';\nimport {duplicate, extend, mergeDeep, Dict} from '../util';\nimport {VgData} from '../vega.schema';\n\nimport {parseAxisComponent} from './axis/parse';\nimport {applyConfig} from './common';\nimport {assembleData, parseUnitData} from './data/data';\nimport {parseLegendComponent} from './legend/parse';\nimport {assembleLayout, parseUnitLayout} from './layout';\nimport {Model} from './model';\nimport {parseMark} from './mark/mark';\nimport initScale from './scale/init';\nimport parseScaleComponent from './scale/parse';\nimport {stack, StackProperties} from '../stack';\nimport {SelectionDef} from '../selection';\nimport {parseUnitSelection, assembleUnitSignals, assembleUnitData as assembleSelectionData, assembleUnitMarks as assembleSelectionMarks} from './selection/selection';\nimport {initMarkDef, initEncoding} from './mark/init';\n\n/**\n * Internal model of Vega-Lite specification for the compiler.\n */\nexport class UnitModel extends Model {\n /**\n * Fixed width for the unit visualization.\n * If undefined (e.g., for ordinal scale), the width of the\n * visualization will be calculated dynamically.\n */\n public readonly width: number;\n\n /**\n * Fixed height for the unit visualization.\n * If undefined (e.g., for ordinal scale), the height of the\n * visualization will be calculated dynamically.\n */\n public readonly height: number;\n\n public readonly markDef: MarkDef & {filled: boolean};\n public readonly encoding: Encoding;\n\n protected readonly selection: Dict = {};\n protected readonly scales: Dict = {};\n protected readonly axes: Dict = {};\n protected readonly legends: Dict = {};\n public readonly config: Config;\n public readonly stack: StackProperties;\n public children: Model[] = [];\n\n constructor(spec: UnitSpec, parent: Model, parentGivenName: string) {\n super(spec, parent, parentGivenName);\n\n // use top-level width / height or parent's top-level width / height\n\n // FIXME: once facet supports width/height, this is no longer correct!\n const providedWidth = spec.width !== undefined ? spec.width :\n parent ? parent['width'] : undefined; // only exists if parent is layer\n const providedHeight = spec.height !== undefined ? spec.height :\n parent ? parent['height'] : undefined; // only exists if parent is layer\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const encoding = this.encoding = dropInvalidFieldDefs(mark, spec.encoding || {});\n\n // TODO?: ideally we should use config only inside this constructor\n const config = this.config = this.initConfig(spec.config, parent);\n\n // calculate stack properties\n this.stack = stack(mark, encoding, config.stack);\n this.scales = this.initScales(mark, encoding, config, providedWidth, providedHeight);\n\n this.markDef = initMarkDef(spec.mark, encoding, this.scales, config);\n this.encoding = initEncoding(mark, encoding, this.stack, config);\n\n this.axes = this.initAxes(encoding, config);\n this.legends = this.initLegend(encoding, config);\n\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\n\n // width / height\n const {width = this.width, height = this.height} = this.initSize(mark, this.scales,\n providedWidth,\n providedHeight,\n config.cell, config.scale\n );\n this.width = width;\n this.height = height;\n }\n\n\n /**\n * Init config by merging config from parent and, if applicable, from facet config\n */\n private initConfig(specConfig: Config, parent: Model) {\n let config = mergeDeep(duplicate(defaultConfig), parent ? parent.config : {}, specConfig);\n let hasFacetParent = false;\n while (parent !== null) {\n if (parent.isFacet()) {\n hasFacetParent = true;\n break;\n }\n parent = parent.parent;\n }\n\n if (hasFacetParent) {\n config.cell = extend({}, config.cell, config.facet.cell);\n }\n return config;\n }\n\n private initScales(mark: Mark, encoding: Encoding, config: Config, topLevelWidth:number, topLevelHeight: number): Dict {\n const xyRangeSteps: number[] = [];\n\n return UNIT_SCALE_CHANNELS.reduce((scales, channel) => {\n if (vlEncoding.channelHasField(encoding, channel) ||\n (channel === X && vlEncoding.channelHasField(encoding, X2)) ||\n (channel === Y && vlEncoding.channelHasField(encoding, Y2))\n ) {\n const scale = scales[channel] = initScale(\n channel, encoding[channel], config, mark,\n channel === X ? topLevelWidth : channel === Y ? topLevelHeight : undefined,\n xyRangeSteps // for determine point / bar size\n );\n\n if (channel === X || channel === Y) {\n if (scale.rangeStep) {\n xyRangeSteps.push(scale.rangeStep);\n }\n }\n }\n return scales;\n }, {});\n }\n\n // TODO: consolidate this with scale? Current scale range is in parseScale (later),\n // but not in initScale because scale range depends on size,\n // but size depends on scale type and rangeStep\n private initSize(mark: Mark, scale: Dict, width: number, height: number, cellConfig: CellConfig, scaleConfig: ScaleConfig) {\n if (width === undefined) {\n if (scale[X]) {\n if (!hasDiscreteDomain(scale[X].type) || !scale[X].rangeStep) {\n width = cellConfig.width;\n } // else: Do nothing, use dynamic width.\n } else { // No scale X\n if (mark === TEXT_MARK) {\n // for text table without x/y scale we need wider rangeStep\n width = scaleConfig.textXRangeStep;\n } else {\n if (typeof scaleConfig.rangeStep === 'string') {\n throw new Error('_initSize does not handle string rangeSteps');\n }\n width = scaleConfig.rangeStep;\n }\n }\n }\n\n if (height === undefined) {\n if (scale[Y]) {\n if (!hasDiscreteDomain(scale[Y].type) || !scale[Y].rangeStep) {\n height = cellConfig.height;\n } // else: Do nothing, use dynamic height .\n } else {\n if (typeof scaleConfig.rangeStep === 'string') {\n throw new Error('_initSize does not handle string rangeSteps');\n }\n height = scaleConfig.rangeStep;\n }\n }\n\n return {width, height};\n }\n\n private initAxes(encoding: Encoding, config: Config): Dict {\n return [X, Y].reduce(function(_axis, channel) {\n // Position Axis\n\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) ||\n (channel === X && isFieldDef(encoding.x2)) ||\n (channel === Y && isFieldDef(encoding.y2))) {\n\n const axisSpec = isFieldDef(channelDef) ? channelDef.axis : null;\n\n // We no longer support false in the schema, but we keep false here for backward compatability.\n if (axisSpec !== null && axisSpec !== false) {\n let vlOnlyAxisProperties: VlOnlyAxisBase = {};\n VL_ONLY_AXIS_PROPERTIES.forEach(function(property) {\n if (config.axis[property] !== undefined) {\n vlOnlyAxisProperties[property] = config.axis[property];\n }\n });\n _axis[channel] = {\n ...vlOnlyAxisProperties,\n ...axisSpec\n };\n }\n }\n return _axis;\n }, {});\n }\n\n private initLegend(encoding: Encoding, config: Config): Dict {\n return NONSPATIAL_SCALE_CHANNELS.reduce(function(_legend, channel) {\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef)) {\n const legendSpec = channelDef.legend;\n if (legendSpec !== null && legendSpec !== false) {\n _legend[channel] = {...legendSpec};\n }\n }\n return _legend;\n }, {});\n }\n\n public parseData() {\n this.component.data = parseUnitData(this);\n }\n\n public parseSelection() {\n this.component.selection = parseUnitSelection(this, this.selection);\n }\n\n public parseLayoutData() {\n this.component.layout = parseUnitLayout(this);\n }\n\n public parseScale() {\n this.component.scales = parseScaleComponent(this);\n }\n\n public parseMark() {\n this.component.mark = parseMark(this);\n }\n\n public parseAxis() {\n this.component.axes = parseAxisComponent(this, [X, Y]);\n }\n\n public parseAxisGroup(): void {\n return null;\n }\n\n public parseGridGroup(): void {\n return null;\n }\n\n public parseLegend() {\n this.component.legends = parseLegendComponent(this);\n }\n\n public assembleSignals(signals: any[]): any[] {\n return assembleUnitSignals(this, signals);\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return assembleSelectionData(this, data);\n }\n\n public assembleData(data: VgData[]): VgData[] {\n return assembleData(this, data);\n }\n\n public assembleLayout(layoutData: VgData[]): VgData[] {\n return assembleLayout(this, layoutData);\n }\n\n public assembleMarks() {\n return assembleSelectionMarks(this, this.component.mark);\n }\n\n public assembleParentGroupProperties(cellConfig: CellConfig) {\n return applyConfig({}, cellConfig, FILL_STROKE_CONFIG.concat(['clip']));\n }\n\n public channels() {\n return UNIT_CHANNELS;\n }\n\n protected getMapping() {\n return this.encoding;\n }\n\n public toSpec(excludeConfig?: any, excludeData?: any) {\n const encoding = duplicate(this.encoding);\n let spec: any;\n\n spec = {\n mark: this.markDef,\n encoding: encoding\n };\n\n if (!excludeConfig) {\n spec.config = duplicate(this.config);\n }\n\n if (!excludeData) {\n spec.data = duplicate(this.data);\n }\n\n // remove defaults\n return spec;\n }\n\n public mark(): Mark {\n return this.markDef.type;\n }\n\n public channelHasField(channel: Channel) {\n return vlEncoding.channelHasField(this.encoding, channel);\n }\n\n public fieldDef(channel: Channel): FieldDef {\n // TODO: remove this || {}\n // Currently we have it to prevent null pointer exception.\n return this.encoding[channel] || {};\n }\n\n /** Get \"field\" reference for vega */\n public field(channel: Channel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (fieldDef.bin) { // bin has default suffix that depends on scaleType\n opt = extend({\n binSuffix: hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start'\n }, opt);\n }\n\n return field(fieldDef, opt);\n }\n\n public dataTable() {\n return this.dataName(vlEncoding.isAggregate(this.encoding) ? SUMMARY : SOURCE);\n }\n\n public isUnit() {\n return true;\n }\n}\n", + "import {Encoding} from './encoding';\nimport {MarkDef, isMarkDef} from './mark';\nimport {GenericUnitSpec, LayerSpec} from './spec';\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport type UnitNormalizer = (spec: GenericUnitSpec)=> LayerSpec;\n\n/**\n * Registry index for all composite mark's normalizer\n */\nconst normalizerRegistry: {[mark: string]: UnitNormalizer} = {};\n\nexport function add(mark: string, normalizer: UnitNormalizer) {\n normalizerRegistry[mark] = normalizer;\n}\n\nexport function remove(mark: string) {\n delete normalizerRegistry[mark];\n}\n\n/**\n * Transform a unit spec with composite mark into a normal layer spec.\n */\nexport function normalize(\n // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels.\n spec: GenericUnitSpec\n ): LayerSpec {\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const normalizer = normalizerRegistry[mark];\n if (normalizer) {\n return normalizer(spec);\n }\n\n throw new Error(`Unregistered composite mark ${mark}`);\n}\n\n\nadd(ERRORBAR, (spec: GenericUnitSpec): LayerSpec => {\n const {mark: _m, encoding: encoding, ...outerSpec} = spec;\n const {size: _s, ...encodingWithoutSize} = encoding;\n const {x2: _x2, y2: _y2, ...encodingWithoutX2Y2} = encoding;\n\n return {\n ...outerSpec,\n layer: [\n {\n mark: 'rule',\n encoding: encodingWithoutSize\n },{ // Lower tick\n mark: 'tick',\n encoding: encodingWithoutX2Y2\n }, { // Upper tick\n mark: 'tick',\n encoding: {\n ...encodingWithoutX2Y2,\n ...(encoding.x2 ? {x: encoding.x2} : {}),\n ...(encoding.y2 ? {y: encoding.y2} : {})\n }\n }\n ]\n };\n});\n", + "import {AxisConfig, defaultAxisConfig} from './axis';\nimport {LegendConfig, defaultLegendConfig} from './legend';\nimport {MarkConfig, BarConfig, TextConfig, TickConfig} from './mark';\nimport * as mark from './mark';\nimport {ScaleConfig, defaultScaleConfig} from './scale';\nimport {StackOffset} from './stack';\nimport {Padding} from './spec';\nimport {VgRangeScheme} from './vega.schema';\nimport {SelectionConfig, defaultConfig as defaultSelectionConfig} from './selection';\n\nexport interface CellConfig {\n width?: number;\n height?: number;\n\n clip?: boolean;\n\n // FILL_STROKE_CONFIG\n /**\n * The fill color.\n */\n fill?: string;\n\n /** The fill opacity (value between [0,1]). */\n fillOpacity?: number;\n\n /** The stroke color. */\n stroke?: string;\n\n /** The stroke opacity (value between [0,1]). */\n strokeOpacity?: number;\n\n /** The stroke width, in pixels. */\n strokeWidth?: number;\n\n /** An array of alternating stroke, space lengths for creating dashed or dotted lines. */\n strokeDash?: number[];\n\n /** The offset (in pixels) into which to begin drawing with the stroke dash array. */\n strokeDashOffset?: number;\n}\n\nexport const defaultCellConfig: CellConfig = {\n width: 200,\n height: 200,\n fill: 'transparent'\n};\n\nexport const defaultFacetCellConfig: CellConfig = {\n stroke: '#ccc',\n strokeWidth: 1\n};\n\nexport interface FacetConfig {\n /** Facet Axis Config */\n axis?: AxisConfig;\n\n /** Facet Grid Config */\n grid?: FacetGridConfig;\n\n /** Facet Cell Config */\n cell?: CellConfig;\n}\n\nexport interface FacetGridConfig {\n color?: string;\n opacity?: number;\n offset?: number;\n}\n\nconst defaultFacetGridConfig: FacetGridConfig = {\n color: '#000000',\n opacity: 0.4,\n offset: 0\n};\n\nexport const defaultFacetConfig: FacetConfig = {\n axis: {},\n grid: defaultFacetGridConfig,\n cell: defaultFacetCellConfig\n};\n\nexport type AreaOverlay = 'line' | 'linepoint' | 'none';\n\nexport interface OverlayConfig {\n /**\n * Whether to overlay line with point.\n */\n line?: boolean;\n\n /**\n * Type of overlay for area mark (line or linepoint)\n */\n area?: AreaOverlay;\n\n /**\n * Default style for the overlayed point.\n */\n pointStyle?: MarkConfig;\n\n /**\n * Default style for the overlayed point.\n */\n lineStyle?: MarkConfig;\n}\n\nexport const defaultOverlayConfig: OverlayConfig = {\n line: false,\n pointStyle: {filled: true},\n lineStyle: {}\n};\n\nexport type RangeConfig = (number|string)[] | VgRangeScheme | {step: number};\n\nexport interface Config {\n // TODO: add this back once we have top-down layout approach\n // width?: number;\n // height?: number;\n // padding?: number|string;\n /**\n * The width and height of the on-screen viewport, in pixels. If necessary, clipping and scrolling will be applied.\n */\n viewport?: number;\n /**\n * CSS color property to use as background of visualization. Default is `\"transparent\"`.\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. This can be a single number or an object with `\"top\"`, `\"left\"`, `\"right\"`, `\"bottom\"` properties.\n *\n * __Default value__: `5`\n *\n * * @minimum 0\n */\n padding?: Padding;\n\n /**\n * D3 Number format for axis labels and text tables. For example \"s\" for SI units.\n */\n numberFormat?: string;\n\n /**\n * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend.\n */\n timeFormat?: string;\n\n /**\n * Default axis and legend title for count fields.\n * @type {string}\n */\n countTitle?: string;\n\n /** Cell Config */\n cell?: CellConfig;\n\n /** Default stack offset for stackable mark. */\n stack?: StackOffset;\n\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: MarkConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: MarkConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n // OTHER CONFIG\n\n // FIXME: move this to line/area\n /** Mark Overlay Config */\n overlay?: OverlayConfig;\n\n /** Scale Config */\n scale?: ScaleConfig;\n\n /**\n * Scale range config, or properties defining named range arrays\n * that can be used within scale range definitions\n * (such as `{\"type\": \"ordinal\", \"range\": \"category\"}`).\n * For default range that Vega-Lite adopts from Vega, see https://github.com/vega/vega-parser#scale-range-properties.\n */\n range?: {[name: string]: RangeConfig};\n\n /** Axis Config */\n axis?: AxisConfig;\n\n /** Legend Config */\n legend?: LegendConfig;\n\n /** Facet Config */\n facet?: FacetConfig;\n\n /** Selection Config */\n selection?: SelectionConfig;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n numberFormat: 's',\n timeFormat: '%b %d, %Y',\n countTitle: 'Number of Records',\n\n cell: defaultCellConfig,\n\n mark: mark.defaultMarkConfig,\n area: {},\n bar: mark.defaultBarConfig,\n circle: {},\n line: {},\n point: {},\n rect: {},\n rule: {},\n square: {},\n text: mark.defaultTextConfig,\n tick: mark.defaultTickConfig,\n\n overlay: defaultOverlayConfig,\n scale: defaultScaleConfig,\n axis: defaultAxisConfig,\n legend: defaultLegendConfig,\n\n facet: defaultFacetConfig,\n\n selection: defaultSelectionConfig\n};\n", + "/*\n * Constants and utilities for data.\n */\n\nexport interface DataFormat {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`.\n * The default format type is determined by the extension of the file url.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: DataFormatType;\n\n /**\n * A collection of parsing instructions can be used to define the data types of string-valued attributes in the JSON file. Each instruction is a name-value pair, where the name is the name of the attribute, and the value is the desired data type (one of `\"number\"`, `\"boolean\"` or `\"date\"`). For example, `\"parse\": {\"modified_on\":\"date\"}` ensures that the `modified_on` value in each row of the input data is parsed as a Date value. (See Datalib's [`dl.read.types` method](https://github.com/vega/datalib/wiki/Import#dl_read_types) for more information.)\n */\n parse?: any;\n\n /**\n * JSON only) The JSON property containing the desired data.\n * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data.\n * For example `\"property\": \"values.features\"` is equivalent to retrieving `json.values.features`\n * from the loaded JSON object.\n */\n property?: string;\n\n /**\n * The name of the TopoJSON object set to convert to a GeoJSON feature collection.\n * For example, in a map of the world, there may be an object set named `\"countries\"`.\n * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country.\n */\n feature?: string;\n /**\n * The name of the TopoJSON object set to convert to a mesh.\n * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set.\n * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features.\n * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties.\n */\n mesh?: string;\n}\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport interface UrlData {\n /**\n * An object that specifies the format for the data file or values.\n */\n format?: DataFormat;\n\n /**\n * A URL from which to load the data set. Use the format.type property\n * to ensure the loaded data is correctly parsed.\n */\n url: string;\n}\n\nexport interface InlineData {\n /**\n * Pass array of objects instead of a url to a file.\n */\n values: any[];\n}\n\nexport interface NamedData {\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name: string;\n}\n\nexport function isUrlData(data: Data): data is UrlData {\n return !!data['url'];\n}\n\nexport function isInlineData(data: Data): data is InlineData {\n return !!data['values'];\n}\n\nexport function isNamedData(data: Data): data is NamedData {\n return !!data['name'];\n}\n\nexport type DataSourceType = 'source' | 'summary' | 'stacked' | 'layout';\n\nexport const SUMMARY: 'summary' = 'summary';\nexport const SOURCE: 'source' = 'source';\nexport const STACKED: 'stacked' = 'stacked';\nexport const LAYOUT: 'layout' = 'layout';\n", + "// DateTime definition object\n\nimport {duplicate, keys, isNumber} from './util';\nimport * as log from './log';\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing minute segment of a time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing second segment of a time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing millisecond segment of a time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n}\n\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day ||\n !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds);\n}\n\nexport const MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];\nexport const SHORT_MONTHS = MONTHS.map((m) => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map((d) => d.substr(0,3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1) + '';\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1) + '';\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\nexport function timestamp(d: DateTime, normalize: boolean) {\n const date = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date\n\n // FIXME support UTC\n\n if (d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n } else {\n // Use a year that has 1/1 as Sunday so we can setDate below\n date.setFullYear(SUNDAY_YEAR);\n\n const day = normalize ? normalizeDay(d.day) : d.day;\n date.setDate(+day + 1); // +1 since date start at 1 in JS\n }\n }\n\n if (d.year !== undefined) {\n date.setFullYear(d.year);\n }\n\n if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n date.setMonth(+quarter * 3);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n date.setMonth(+month);\n }\n\n if (d.date !== undefined) {\n date.setDate(d.date);\n }\n\n if (d.hours !== undefined) {\n date.setHours(d.hours);\n }\n\n if (d.minutes !== undefined) {\n date.setMinutes(d.minutes);\n }\n\n if (d.seconds !== undefined) {\n date.setSeconds(d.seconds);\n }\n\n if (d.milliseconds !== undefined) {\n date.setMilliseconds(d.milliseconds);\n }\n\n return date.getTime();\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (let timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n return 'datetime(' + units.join(', ') + ')';\n}\n", + "// utility for encoding mapping\nimport {FieldDef, PositionFieldDef, LegendFieldDef, OrderFieldDef, ValueDef, TextFieldDef, isFieldDef, ChannelDef, isValueDef, normalize, ConditionalValueDef} from './fielddef';\nimport {Channel, CHANNELS, supportMark} from './channel';\nimport {Facet} from './facet';\nimport {isArray, some, duplicate} from './util';\nimport {Mark} from './mark';\nimport * as log from './log';\n\nexport interface Encoding {\n /**\n * X coordinates for `point`, `circle`, `square`,\n * `line`, `rule`, `text`, and `tick`\n * (or to width and height for `bar` and `area` marks).\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates for `point`, `circle`, `square`,\n * `line`, `rule`, `text`, and `tick`\n * (or to width and height for `bar` and `area` marks).\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `bar`, `rule`, `area`\n */\n x2?: FieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `bar`, `rule`, `area`\n */\n y2?: FieldDef | ValueDef;\n\n /**\n * Color of the marks – either fill or stroke color based on mark type.\n * (By default, fill color for `area`, `bar`, `tick`, `text`, `circle`, and `square` /\n * stroke color for `line` and `point`.)\n */\n color?: LegendFieldDef | ConditionalValueDef;\n\n /**\n * Opacity of the marks – either can be a value or in a range.\n */\n opacity?: LegendFieldDef | ConditionalValueDef;\n\n /**\n * Size of the mark.\n * - For `point`, `square` and `circle`\n * – the symbol size, or pixel area of the mark.\n * - For `bar` and `tick` – the bar and tick's size.\n * - For `text` – the text's font size.\n * - Size is currently unsupported for `line` and `area`.\n */\n size?: LegendFieldDef | ConditionalValueDef;\n\n /**\n * The symbol's shape (only for `point` marks). The supported values are\n * `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`,\n * or `\"triangle-down\"`, or else a custom SVG path string.\n */\n shape?: LegendFieldDef | ConditionalValueDef; // TODO: maybe distinguish ordinal-only\n\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | FieldDef[];\n\n /**\n * Text of the `text` mark.\n */\n text?: TextFieldDef | ConditionalValueDef;\n\n /**\n * stack order for stacked marks or order of data points in line marks.\n */\n order?: OrderFieldDef | OrderFieldDef[];\n}\n\nexport interface EncodingWithFacet extends Encoding, Facet {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef);\n }\n }\n return false;\n}\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, (channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.aggregate);\n } else {\n return isFieldDef(channelDef) && !!channelDef.aggregate;\n }\n }\n return false;\n });\n}\n\nexport function dropInvalidFieldDefs(mark: Mark, encoding: Encoding): Encoding {\n\n // clone to prevent side effect to the original spec\n encoding = duplicate(encoding);\n\n Object.keys(encoding).forEach((channel: Channel) => {\n if (!supportMark(channel, mark)) {\n // Drop unsupported channel\n\n log.warn(log.message.incompatibleChannel(channel, mark));\n delete encoding[channel];\n return;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) && channelDef.aggregate) {\n log.warn(log.message.incompatibleChannel(channel, mark, 'when the field is aggregated.'));\n delete encoding[channel];\n }\n return;\n }\n\n if (isArray(encoding[channel])) {\n // Array of fieldDefs for detail channel (or production rule)\n encoding[channel] = encoding[channel].reduce((channelDefs: ChannelDef[], channelDef: ChannelDef) => {\n if (!isFieldDef(channelDef) && !isValueDef(channelDef)) { // TODO: datum\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n } else {\n channelDefs.push(normalize(channelDef, channel));\n }\n return channelDefs;\n }, []);\n } else {\n const channelDef = encoding[channel];\n if (!isFieldDef(channelDef) && !isValueDef(channelDef)) { // TODO: datum\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n delete encoding[channel];\n return;\n }\n normalize(channelDef, channel);\n }\n });\n return encoding;\n}\n\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n let arr: FieldDef[] = [];\n CHANNELS.forEach(function(channel) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n arr.push(fieldDef);\n });\n }\n });\n return arr;\n};\n\nexport function forEach(mapping: any,\n f: (fd: FieldDef, c: Channel) => void,\n thisArg?: any) {\n if (!mapping) {\n return;\n }\n\n Object.keys(mapping).forEach((c: any) => {\n const channel: Channel = c;\n if (isArray(mapping[channel])) {\n mapping[channel].forEach(function(channelDef: ChannelDef) {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, mapping[channel], channel);\n }\n });\n}\n\nexport function reduce(mapping: U,\n f: (acc: any, fd: FieldDef, c: Channel) => U,\n init: T, thisArg?: any) {\n if (!mapping) {\n return init;\n }\n\n return Object.keys(mapping).reduce((r: T, c: any) => {\n const channel: Channel = c;\n if (isArray(mapping[channel])) {\n return mapping[channel].reduce(function(r1: T, channelDef: ChannelDef) {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, mapping[channel], channel);\n }\n }, init);\n}\n", + "// utility for a field definition object\n\nimport {AggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {Bin} from './bin';\nimport {Channel, rangeType} from './channel';\nimport {Config} from './config';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {Scale} from './scale';\nimport {StackOffset} from './stack';\nimport {SortField, SortOrder} from './sort';\nimport {TimeUnit, isDiscreteByDefault} from './timeunit';\nimport {Type, getFullName} from './type';\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain.\n */\n value?: T;\n}\n\nexport interface ConditionalValueDef extends ValueDef {\n condition?: Condition;\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef {\n /**\n * Name of the field from which to pull a data value.\n */\n field?: string;\n\n /**\n * The encoded field's type of measurement. This can be either a full type\n * name (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, and `\"nominal\"`)\n * or an initial character of the type name (`\"Q\"`, `\"T\"`, `\"O\"`, `\"N\"`).\n * This property is case insensitive.\n */\n type?: Type;\n\n\n // function\n\n /**\n * Time unit for a `temporal` field (e.g., `year`, `yearmonth`, `month`, `hour`).\n */\n timeUnit?: TimeUnit;\n\n /**\n * Flag for binning a `quantitative` field, or a bin property object\n * for binning parameters.\n */\n bin?: boolean | Bin;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n */\n aggregate?: AggregateOp;\n\n /**\n * Title for axis or legend.\n */\n title?: string;\n}\n\nexport interface Condition {\n selection: string;\n value: T;\n}\n\nexport interface ScaleFieldDef extends FieldDef {\n scale?: Scale;\n sort?: SortField | SortOrder;\n}\n\nexport interface PositionFieldDef extends ScaleFieldDef {\n /**\n * @nullable\n */\n axis?: Axis;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * \"none\" or null, if the field should not be stacked.\n */\n stack?: StackOffset;\n}\nexport interface LegendFieldDef extends ScaleFieldDef {\n /**\n * @nullable\n */\n legend?: Legend;\n\n condition?: Condition;\n}\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDef {\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDef {\n // FIXME: add more reference to Vega's format pattern or d3's format pattern.\n /**\n * The formatting pattern for text value. If not defined, this will be determined automatically.\n */\n format?: string;\n\n condition?: Condition;\n};\n\nexport type ChannelDef = FieldDef | ValueDef;\n\nexport function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | LegendFieldDef | OrderFieldDef | TextFieldDef {\n return channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isValueDef(channelDef: ChannelDef): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\n// TODO: consider if we want to distinguish ordinalOnlyScale from scale\nexport type FacetFieldDef = PositionFieldDef;\n\nexport interface FieldRefOption {\n /** exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field inside datum[...] per Vega convention */\n datum?: boolean;\n /** prepend fn with custom function prefix */\n prefix?: string;\n /** append suffix to the field ref for bin (default='start') */\n binSuffix?: 'start' | 'end' | 'range';\n /** append suffix to the field ref (general) */\n suffix?: string;\n /** Overrride which aggregate to use. Needed for unaggregated domain. */\n aggregate?: AggregateOp;\n}\n\nexport function field(fieldDef: FieldDef, opt: FieldRefOption = {}) {\n let field = fieldDef.field;\n let prefix = opt.prefix;\n let suffix = opt.suffix;\n\n if (isCount(fieldDef)) {\n field = 'count_*';\n } else {\n let fn: string = undefined;\n\n if (!opt.nofn) {\n if (fieldDef.bin) {\n fn = 'bin';\n suffix = opt.binSuffix;\n } else if (fieldDef.aggregate) {\n fn = String(opt.aggregate || fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (!!fn) {\n field = `${fn}_${field}`;\n }\n }\n\n if (!!suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (!!prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.datum) {\n field = `datum[\"${field}\"]`;\n }\n\n return field;\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'temporal':\n // TODO: deal with custom scale type case.\n return isDiscreteByDefault(fieldDef.timeUnit);\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: FieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDef) {\n return fieldDef.aggregate === 'count';\n}\n\nexport function title(fieldDef: FieldDef, config: Config) {\n if (fieldDef.title != null) {\n return fieldDef.title;\n }\n if (isCount(fieldDef)) {\n return config.countTitle;\n }\n const fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin');\n if (fn) {\n return fn.toString().toUpperCase() + '(' + fieldDef.field + ')';\n } else {\n return fieldDef.field;\n }\n}\n\nexport function defaultType(fieldDef: FieldDef, channel: Channel): Type {\n if (!!fieldDef.timeUnit) {\n return 'temporal';\n }\n if (!!fieldDef.bin) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(fieldDef: ChannelDef, channel: Channel) {\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(fieldDef)) { // TODO: or datum\n // convert short type to full type\n const fullType = getFullName(fieldDef.type);\n if (fullType) {\n fieldDef.type = fullType;\n } else {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef, channel);\n log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType));\n fieldDef.type = newType;\n }\n\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n }\n return fieldDef;\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(fieldDef: FieldDef, channel: Channel): {compatible: boolean; warning?: string;} {\n switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef) && !fieldDef.timeUnit) {\n // TODO:(https://github.com/vega/vega-lite/issues/2011):\n // with timeUnit it's not always strictly continuous\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'text':\n case 'detail':\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if (isDiscrete(fieldDef) && !fieldDef.bin) {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with nominal data only'\n };\n } else {\n return COMPATIBLE;\n }\n\n case 'order':\n if (fieldDef.type === 'nominal') {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n", + "import {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {field} from './fielddef';\nimport {TimeUnit, fieldExpr as timeUnitFieldExpr, isSingleTimeUnit} from './timeunit';\nimport {isArray, isString} from './util';\n\nexport type Filter = EqualFilter | RangeFilter | OneOfFilter ;\n\n\nexport interface EqualFilter {\n // TODO: support aggregate\n\n /**\n * Time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered.\n */\n field: string;\n\n /**\n * Value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isEqualFilter(filter: any): filter is EqualFilter {\n return filter && !!filter.field && filter.equal!==undefined;\n}\n\nexport interface RangeFilter {\n // TODO: support aggregate\n\n /**\n * time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered\n */\n field: string;\n\n /**\n * Array of inclusive minimum and maximum values\n * for a field value of a data item to be included in the filtered data.\n * @maxItems 2\n * @minItems 2\n */\n range: (number|DateTime)[];\n\n}\n\nexport function isRangeFilter(filter: any): filter is RangeFilter {\n if (filter && !!filter.field) {\n if (isArray(filter.range) && filter.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface OneOfFilter {\n // TODO: support aggregate\n\n /**\n * time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered\n */\n field: string;\n\n /**\n * A set of values that the `field`'s value should be a member of,\n * for a data item included in the filtered data.\n */\n oneOf: (string|number|boolean|DateTime)[];\n\n}\n\nexport function isOneOfFilter(filter: any): filter is OneOfFilter {\n return filter && !!filter.field && (\n isArray(filter.oneOf) ||\n isArray(filter.in) // backward compatibility\n );\n}\n\nexport function expression(filter: Filter | string) {\n if (isString(filter)) {\n return filter as string;\n } else { // Filter Object\n const fieldExpr = filter.timeUnit ?\n // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly.\n // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline\n // TODO: support utc\n ('time(' + timeUnitFieldExpr(filter.timeUnit, filter.field) + ')') :\n field(filter, {datum: true});\n\n if (isEqualFilter(filter)) {\n return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit);\n } else if (isOneOfFilter(filter)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n const oneOf: OneOfFilter[] = filter.oneOf || filter['in'];\n return 'indexof([' +\n oneOf.map((v) => valueExpr(v, filter.timeUnit)).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isRangeFilter(filter)) {\n const lower = filter.range[0];\n const upper = filter.range[1];\n\n if (lower !== null && upper !== null) {\n return 'inrange(' + fieldExpr + ', ' +\n valueExpr(lower, filter.timeUnit) + ', ' +\n valueExpr(upper, filter.timeUnit) + ')';\n } else if (lower !== null) {\n return fieldExpr + ' >= ' + lower;\n } else if (upper !== null) {\n return fieldExpr + ' <= ' + upper;\n }\n }\n }\n return undefined;\n}\n\nfunction valueExpr(v: any, timeUnit: TimeUnit) {\n if (isDateTime(v)) {\n const expr = dateTimeExpr(v, true);\n return 'time(' + expr + ')';\n }\n if (isSingleTimeUnit(timeUnit)) {\n const datetime: DateTime = {};\n datetime[timeUnit] = v;\n const expr = dateTimeExpr(datetime, true);\n return 'time(' + expr + ')';\n }\n return JSON.stringify(v);\n}\n", + "import {DateTime} from './datetime';\nimport {VgLegendEncode, VgLegendBase, VgLegendConfig} from './vega.schema';\n\nexport interface LegendConfig extends VgLegendConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend extends VgLegendBase {\n /**\n * Optional mark definitions for custom legend encoding.\n */\n encode?: VgLegendEncode;\n\n /**\n * An optional formatting pattern for legend labels. Vega uses D3\\'s format pattern.\n */\n format?: string;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * A title for the legend. (Shows field name and its function by default.)\n */\n title?: string;\n /**\n * Explicitly set the visible legend values.\n */\n values?: number[] | string[] | DateTime[];\n\n /**\n * The name of a scale that maps to a shape value.\n */\n shape?: string;\n\n /**\n * The type of the legend. Use `symbol` to create a discrete legend and `gradient` for a continuous color gradient.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n}\n\nexport const defaultLegendConfig: LegendConfig = {\n orient: undefined, // implicitly \"right\"\n};\n\nexport const LEGEND_PROPERTIES:(keyof Legend)[] = ['entryPadding', 'format', 'offset', 'orient', 'tickCount', 'title', 'type', 'values' ,'zindex'];\n", + "///\n\n/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {logger, LoggerInterface, Warn} from 'vega-util';\n\nimport {AggregateOp} from './aggregate';\nimport {Channel} from './channel';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {TimeUnit} from './timeunit';\nimport {Type} from './type';\nimport {ScaleType} from './scale';\n\nexport {LoggerInterface} from 'vega-util';\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n}\n\nexport function runLocalLogger(f: (localLogger: LocalLogger) => void) {\n const localLogger = current = new LocalLogger();\n f(localLogger);\n reset();\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n const logger = current = new LocalLogger();\n f(logger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(logger: LoggerInterface) {\n current = logger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\nexport namespace message {\n export const INVALID_SPEC = 'Invalid spec';\n\n // DATA\n export const DEPRECATED_FILTER_NULL = 'filterNull is deprecated. Please use filterInvalid instead.';\n\n // ENCODING & FACET\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n }\n\n export function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type) {\n return `Invalid field type (${type}) for channel ${channel}, using ${newType} instead.`;\n }\n\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${JSON.stringify(fieldDef)} from channel ${channel} since it does not contain data field or value.`;\n }\n\n export function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet', when?: string) {\n return `${channel} dropped as it is incompatible with ${markOrFacet}` +\n when ? `when ${when}` : '';\n }\n\n export function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n }\n\n export function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel ${channel} to encode ${type} field can be misleading as it does not encode ${type === 'ordinal' ? 'order' : 'magnitude'}.`;\n }\n\n // Mark\n export const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\n export function unclearOrientContinuous(mark: Mark) {\n return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode continous fields. In this case, we use vertical by default';\n }\n\n export function unclearOrientDiscreteOrEmpty(mark: Mark) {\n return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode discrete or empty fields.';\n }\n\n export function orientOverridden(original: string, actual: string) {\n return `Specified orient ${original} overridden with ${actual}`;\n }\n\n // SCALE\n export const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain';\n\n export function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use ${prop} with non-color channel.`;\n }\n\n export function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef) {\n return `Using unaggregated domain with raw field has no effect (${JSON.stringify(fieldDef)}).`;\n }\n\n export function unaggregateDomainWithNonSharedDomainOp(aggregate: AggregateOp) {\n return `Unaggregated domain not applicable for ${aggregate} since it produces values outside the origin domain of the source data.`;\n }\n\n export function unaggregatedDomainWithLogScale(fieldDef: FieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${JSON.stringify(fieldDef)}).`;\n }\n\n export const CANNOT_USE_RANGE_WITH_POSITION =\n 'Cannot use custom range with x or y channel. Please customize width, height, padding, or rangeStep instead.';\n\n export const CANNOT_USE_PADDING_WITH_FACET = 'Cannot use padding with facet\\'s scale. Please use spacing instead.';\n\n export function cannotUseRangePropertyWithFacet(propName: string) {\n return `Cannot use custom ${propName} with row or column channel. Please use width, height, or spacing instead.`;\n }\n\n export function rangeStepDropped(channel: Channel) {\n return `rangeStep for ${channel} is dropped as top-level ${\n channel === 'x' ? 'width' : 'height'} is provided.`;\n }\n\n export function cannotOverrideBinScaleType(channel: Channel, defaultScaleType: ScaleType) {\n return `Cannot override scale type for binned channel ${channel}. We are using ${defaultScaleType} scale instead.`;\n }\n\n export function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel ${channel} does not work with ${scaleType} scale. We are using ${defaultScaleType} scale instead.`;\n }\n\n export function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n }\n\n export function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark ${mark}.`;\n }\n\n export const INVAID_DOMAIN = 'Invalid scale domain';\n\n export const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\n // AXIS\n export const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n // STACK\n export function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack ${channel} if there is already ${channel}2`;\n }\n\n export function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n }\n\n export function cannotStackNonSummativeAggregate(aggregate: AggregateOp) {\n return `Cannot stack when the aggregate function is non-summative (${aggregate})`;\n }\n\n // TIMEUNIT\n export function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${value}`;\n }\n\n export function dayReplacedWithDate(fullTimeUnit: TimeUnit) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ` +\n (fullTimeUnit+'').replace('day', 'date') + '.';\n }\n\n export function droppedDay(d: DateTime | DateTimeExpr) {\n return 'Dropping day from datetime ' + JSON.stringify(d) +\n ' as day cannot be combined with other units.';\n }\n}\n\n", + "import {toSet} from './util';\nimport {Orient, Interpolate, VgMarkConfig} from './vega.schema';\nexport {Orient} from './vega.schema';\n\nexport namespace Mark {\n export const AREA: 'area' = 'area';\n export const BAR: 'bar' = 'bar';\n export const LINE: 'line' = 'line';\n export const POINT: 'point' = 'point';\n export const RECT: 'rect' = 'rect';\n export const RULE: 'rule' = 'rule';\n export const TEXT: 'text' = 'text';\n export const TICK: 'tick' = 'tick';\n export const CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE;\n\n\nexport const AREA = Mark.AREA;\nexport const BAR = Mark.BAR;\nexport const LINE = Mark.LINE;\nexport const POINT = Mark.POINT;\nexport const TEXT = Mark.TEXT;\nexport const TICK = Mark.TICK;\nexport const RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\n\nexport const CIRCLE = Mark.CIRCLE;\nexport const SQUARE = Mark.SQUARE;\n\nexport const PRIMITIVE_MARKS = [AREA, BAR, LINE, POINT, TEXT, TICK, RECT, RULE, CIRCLE, SQUARE];\n\nexport interface MarkDef {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n}\n\nexport function isMarkDef(mark: string | MarkDef): mark is MarkDef {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: string | MarkDef): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = ['stroke', 'strokeWidth',\n 'strokeDash', 'strokeDashOffset', 'strokeOpacity'];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport interface MarkConfig extends VgMarkConfig {\n\n // ---------- Color ----------\n /**\n * Whether the shape\\'s color should be used as fill color instead of stroke color.\n * This is only applicable for \"bar\", \"point\", and \"area\".\n * All marks except \"point\", \"line\", and \"rule\" are filled by default.\n */\n filled?: boolean;\n\n // TODO: remove this once we correctly integrate theme\n /**\n * Default color.\n */\n color?: string;\n}\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n};\n\nexport interface BarConfig extends MarkConfig {\n /**\n * Offset between bar for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n * @minimum 0\n */\n binSpacing?: number;\n /**\n * Default size of the bars on continuous scales.\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The size of the bars. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 2\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport const defaultTextConfig: TextConfig = {\n baseline: 'middle',\n};\n\nexport interface TickConfig extends MarkConfig {\n /**\n * The width of the ticks.\n * If this value is undefined (by default,), we use 2/3 of rangeStep by default.\n * @minimum 0\n */\n bandSize?: number;\n\n /**\n * Thickness of the tick mark.\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n", + "import * as log from './log';\nimport {Channel} from './channel';\nimport {DateTime} from './datetime';\nimport {contains, toSet} from './util';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const BIN_LINEAR: 'bin-linear' = 'bin-linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n // sequential\n export const SEQUENTIAL: 'sequential' = 'sequential';\n\n // Quantile, Quantize, threshold\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR |\n typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT |\n typeof ScaleType.TIME | typeof ScaleType.UTC |\n // TODO: add 'quantize', 'quantile', 'threshold' back when we really support them\n typeof ScaleType.SEQUENTIAL | // typeof ScaleType.QUANTILE | typeof ScaleType.QUANTIZE | typeof ScaleType.THRESHOLD |\n typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND;\n\nexport const SCALE_TYPES: ScaleType[] = [\n // Continuous - Quantitative\n 'linear', 'bin-linear', 'log', 'pow', 'sqrt',\n // Continuous - Time\n 'time', 'utc',\n // Sequential\n 'sequential', // TODO: add 'quantile', 'quantize' when we really support them\n // Discrete\n 'ordinal', 'bin-ordinal', 'point', 'band',\n];\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nconst BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal' {\n return type in BIN_SCALES_INDEX;\n}\n\nexport function hasContinuousDomain(type: ScaleType):\n type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'|\n 'sequential' /* TODO add | 'quantile' | 'quantize' | 'threshold' */ {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, `size`, `row`, and `column` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` ordinal scale when is mark is `text`.\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n /**\n * Default range step for (1) `y` ordinal scale,\n * and (2) `x` ordinal scale when the mark is not `text`.\n *\n * @minimum 0\n * @nullable\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Default spacing between faceted plots.\n * @TJS-type integer\n * @minimum 0\n */\n facetSpacing?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n * If undefined (default), we will use bandSize - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false\n * If undefined (default), we will use the `continuousBandSize` value for bar and 3 for ticks.\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n * If undefined (default), we will use bandSize - 1.\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n\n /**\n * Default minimum value for point size scale with zero=false.\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for strokeWidth (or rule/line's size) scale with zero=false.\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for strokeWidth (or rule/line's size) scale.\n * @minimum 0\n */\n maxStrokeWidth?: number;\n\n /**\n * The default collection of symbol shapes for mapping nominal fields to shapes of point marks (i.e., range of a `shape` scale).\n * Each value should be one of: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n */\n shapes?: string[];\n}\n\nexport const defaultScaleConfig = {\n round: true,\n textXRangeStep: 90,\n rangeStep: 21,\n pointPadding: 0.5,\n bandPaddingInner: 0.1,\n facetSpacing: 16,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4,\n\n shapes: ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down']\n};\n\nexport interface ExtendedScheme {\n /**\n * Color scheme that determines output color of an ordinal/sequential color scale.\n */\n name: string;\n\n // TODO: add docs\n extent?: number[];\n\n // TODO: add docs\n count?: number;\n}\n\nexport type Domain = number[] | string[] | DateTime[] | 'unaggregated';\nexport type Scheme = string | ExtendedScheme;\n\nexport type Range = number[] | string[] | string;\n\nexport function isExtendedScheme(scheme: string | ExtendedScheme): scheme is ExtendedScheme {\n return scheme && !!scheme['name'];\n}\n\nexport interface Scale {\n type?: ScaleType;\n /**\n * The domain of the scale, representing the set of data values. For quantitative data, this can take the form of a two-element array with minimum and maximum values. For ordinal/categorical data, this may be an array of valid input values.\n *\n * If the domain is 'unaggregated', we use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n */\n domain?: Domain;\n\n /**\n * The range of the scale, representing the set of visual values. For numeric values, the range can take the form of a two-element array with minimum and maximum values. For ordinal or quantized data, the range may by an array of desired output values, which are mapped to elements in the specified domain.\n */\n range?: Range;\n\n /**\n * If true, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default Rule:__ `true` for `\"x\"`, `\"y\"`, `\"row\"`, `\"column\"` channels if scale config's `round` is `true`; `false` otherwise.\n */\n round?: boolean;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in band or point scales.\n * If this value is `null`, this will be determined to fit width (for x) or height (for y) of the plot.\n * If both width and x-scale's rangeStep is provided, rangeStep will be dropped. (The same rule is applied for height and y-scale's rangeStep.)\n *\n * __Default Rule:__ for `x` ordinal scale of a `text` mark, derived from [scale config](config.html#scale-config)'s `textXRangeStep`. Otherwise, derived from [scale config](config.html#scale-config)'s `rangeStep`.\n * __Warning:__ If the cardinality of the scale domain is too high, the rangeStep might become less than one pixel and the mark might not appear correctly.\n * @minimum 0\n * @nullable\n */\n rangeStep?: number | null;\n\n /**\n * Range scheme (e.g., color schemes such as \"category10\" or \"viridis\").\n */\n scheme?: Scheme;\n\n /**\n * (For `row` and `column` only) A pixel value for padding between cells in the trellis plots.\n * @TJS-type integer\n */\n spacing?: number;\n\n /**\n * Applies spacing among ordinal elements in the scale range. The actual effect depends on how the scale is configured. If the __points__ parameter is `true`, the padding value is interpreted as a multiple of the spacing between points. A reasonable value is 1.0, such that the first and last point will be offset from the minimum and maximum value by half the distance between points. Otherwise, padding is typically in the range [0, 1] and corresponds to the fraction of space in the range interval to allocate to padding. A value of 0.5 means that the band size will be equal to the padding width. For more, see the [D3 ordinal scale documentation](https://github.com/mbostock/d3/wiki/Ordinal-Scales).\n * A convenience property for setting the inner and outer padding to the same value.\n * @minimum 0\n * @maximum 1\n */\n padding?: number;\n\n /**\n * The inner padding of a band scale determines the ratio of the range that is reserved for blank space between bands. (For point scale, this property is ignored.)\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding determines the ratio of the range that is reserved for blank space before the first and after the last bands/points.\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * If specified, modifies the scale domain to use a more human-friendly value range. If specified as a true boolean, modifies the scale domain to use a more human-friendly number range (e.g., 7 instead of 6.96). If specified as a string, modifies the scale domain to use a more human-friendly value range. For time and utc scale types only, the nice value should be a string indicating the desired time interval.\n */\n nice?: boolean | NiceTime;\n /**\n * Sets the exponent of the scale transformation. For pow scale types only, otherwise ignored.\n */\n exponent?: number;\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n * Default value: `true` for `x` and `y` channel if the quantitative field is not binned\n * and no custom `domain` is provided; `false` otherwise.\n */\n zero?: boolean;\n\n // FIXME: Add description\n interpolate?: 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n}\n\nexport const SCALE_PROPERTIES:(keyof Scale)[]= [\n 'type', 'domain', 'range', 'round', 'rangeStep', 'scheme', 'padding', 'paddingInner', 'paddingOuter', 'clamp', 'nice',\n 'exponent', 'zero', 'interpolate'\n];\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'range':\n case 'scheme':\n return true;\n case 'interpolate':\n return scaleType === 'linear' || scaleType === 'bin-linear';\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'rangeStep':\n case 'padding':\n case 'paddingOuter':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential';\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType as any === 'quantize';\n case 'exponent':\n return scaleType === 'pow' || scaleType === 'log';\n case 'zero':\n // TODO: what about quantize, threshold?\n return scaleType === 'bin-ordinal' || (!hasDiscreteDomain(scaleType) && !contains(['log', 'time', 'utc'], scaleType));\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'range':\n // User should not customize range for position and facet channel directly.\n if (channel === 'x' || channel === 'y') {\n return log.message.CANNOT_USE_RANGE_WITH_POSITION;\n }\n if (channel === 'row' || channel === 'column') {\n return log.message.cannotUseRangePropertyWithFacet('range');\n }\n return undefined; // GOOD!\n // band / point\n case 'rangeStep':\n if (channel === 'row' || channel === 'column') {\n return log.message.cannotUseRangePropertyWithFacet('rangeStep');\n }\n return undefined; // GOOD!\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n if (channel === 'row' || channel === 'column') {\n /*\n * We do not use d3 scale's padding for row/column because padding there\n * is a ratio ([0, 1]) and it causes the padding to be decimals.\n * Therefore, we manually calculate \"spacing\" in the layout by ourselves.\n */\n return log.message.CANNOT_USE_PADDING_WITH_FACET;\n }\n return undefined; // GOOD!\n case 'interpolate':\n case 'scheme':\n if (channel !== 'color') {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'domain':\n case 'round':\n case 'clamp':\n case 'exponent':\n case 'nice':\n case 'zero':\n // These channel do not have strict requirement\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error('Invalid scale property \"${propName}\".');\n}\n", + "import {VgBinding} from './vega.schema';\n\nexport type SelectionTypes = 'single' | 'multi' | 'interval';\nexport type SelectionDomain = 'data' | 'visual';\nexport type SelectionResolutions = 'single' | 'independent' | 'union' |\n 'union_others' | 'intersect' | 'intersect_others';\n\nexport interface BaseSelectionDef {\n // domain?: SelectionDomain;\n on?: any;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n\n // Transforms\n fields?: string[];\n encodings?: string[];\n toggle?: string | boolean;\n translate?: string | boolean;\n zoom?: string | boolean;\n nearest?: boolean;\n}\n\nexport interface SelectionDef extends BaseSelectionDef {\n type: SelectionTypes;\n}\n\nexport interface SelectionConfig {\n single: BaseSelectionDef;\n multi: BaseSelectionDef;\n interval: BaseSelectionDef;\n}\n\nexport const defaultConfig:SelectionConfig = {\n single: {on: 'click', fields: ['_id']},\n multi: {on: 'click', fields: ['_id'], toggle: 'event.shiftKey'},\n interval: {\n on: '[mousedown, window:mouseup] > window:mousemove!',\n encodings: ['x', 'y'],\n translate: '[mousedown, window:mouseup] > window:mousemove!',\n zoom: 'wheel'\n }\n};\n", + "import {AggregateOp} from './aggregate';\n\nexport type SortOrder = 'ascending' | 'descending' | null;\n\nexport interface SortField {\n /**\n * The field name to aggregate over.\n */\n field: string;\n /**\n * The sort aggregation operator\n */\n op: AggregateOp;\n\n order?: SortOrder;\n}\n\nexport function isSortField(sort: SortOrder | SortField): sort is SortField {\n return !!sort && !!sort['field'] && !!sort['op'];\n}\n", + "/* Package of defining Vega-lite Specification's json schema at its utility functions */\n\nimport {Config, defaultOverlayConfig} from './config';\nimport * as compositeMark from './compositemark';\nimport {Data} from './data';\nimport {EncodingWithFacet, Encoding, channelHasField, isRanged} from './encoding';\nimport {Facet} from './facet';\nimport {FieldDef} from './fielddef';\n\nimport * as log from './log';\nimport {Mark, MarkDef, AREA, LINE, POINT, isPrimitiveMark} from './mark';\nimport {stack} from './stack';\nimport {Transform} from './transform';\nimport {ROW, COLUMN, X, Y, X2, Y2} from './channel';\nimport * as vlEncoding from './encoding';\nimport {contains, duplicate, extend, hash, keys, omit, pick, vals} from './util';\nimport {SelectionDef} from './selection';\n\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\n\nexport interface BaseSpec {\n /**\n * URL to JSON schema for this Vega-Lite specification.\n * @format uri\n */\n $schema?: string;\n\n /**\n * Name of the visualization for later reference.\n */\n name?: string;\n\n /**\n * An optional description of this mark for commenting purpose.\n * This property has no effect on the output visualization.\n */\n description?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. This can be a single number or an object with `\"top\"`, `\"left\"`, `\"right\"`, `\"bottom\"` properties.\n *\n * __Default value__: `5`\n *\n * @minimum 0\n */\n padding?: Padding;\n\n /**\n * An object describing the data source\n */\n data?: Data;\n\n /**\n * An object describing filter and new field calculation.\n */\n transform?: Transform;\n\n /**\n * Configuration object\n */\n config?: Config;\n}\n\nexport interface GenericUnitSpec extends BaseSpec {\n // FIXME description for top-level width\n width?: number;\n\n // FIXME description for top-level width\n height?: number;\n\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, and `\"text\"`.\n */\n mark: M;\n\n /**\n * A key-value mapping between encoding channels and definition of fields.\n */\n encoding: E;\n\n /**\n * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type UnitSpec = GenericUnitSpec;\n\nexport type LayeredUnitSpec = GenericUnitSpec;\n\nexport type FacetedUnitSpec = GenericUnitSpec;\n\nexport interface GenericLayerSpec> extends BaseSpec {\n // FIXME description for top-level width\n width?: number;\n\n // FIXME description for top-level width\n height?: number;\n\n /**\n * Unit specs that will be layered.\n */\n // TODO: support layer of layer\n layer: (GenericLayerSpec | U)[];\n}\n\nexport type LayerSpec = GenericLayerSpec;\n\nexport interface GenericFacetSpec> extends BaseSpec {\n facet: Facet;\n\n // TODO: support facet of facet\n spec: GenericLayerSpec | U;\n}\n\nexport type FacetSpec = GenericFacetSpec;\nexport type ExtendedFacetSpec = GenericFacetSpec;\n\nexport type GenericSpec> = U | GenericLayerSpec | GenericFacetSpec;\n\nexport type ExtendedSpec = GenericSpec;\n\nexport type Spec = GenericSpec;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: GenericSpec>): spec is GenericFacetSpec> {\n return spec['facet'] !== undefined;\n}\n\nexport function isFacetedUnitSpec(spec: ExtendedSpec): spec is FacetedUnitSpec {\n if (isUnitSpec(spec)) {\n const hasRow = channelHasField(spec.encoding, ROW);\n const hasColumn = channelHasField(spec.encoding, COLUMN);\n\n return hasRow || hasColumn;\n }\n\n return false;\n}\n\nexport function isUnitSpec(spec: ExtendedSpec | Spec): spec is FacetedUnitSpec | UnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: ExtendedSpec | Spec): spec is GenericLayerSpec> {\n return spec['layer'] !== undefined;\n}\n\n/**\n * Decompose extended unit specs into composition of pure unit specs.\n */\n// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize\nexport function normalize(spec: ExtendedSpec): Spec {\n if (isFacetSpec(spec)) {\n return normalizeFacet(spec);\n }\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec);\n }\n if (isFacetedUnitSpec(spec)) {\n return normalizeFacetedUnit(spec);\n }\n if (isUnitSpec(spec)) {\n return normalizeNonFacetUnit(spec);\n }\n throw new Error(log.message.INVALID_SPEC);\n}\n\nfunction normalizeNonFacet(spec: GenericLayerSpec | LayeredUnitSpec) {\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec);\n }\n return normalizeNonFacetUnit(spec);\n}\n\nfunction normalizeFacet(spec: GenericFacetSpec): FacetSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalizeNonFacet(subspec)\n };\n}\n\nfunction normalizeLayer(spec: GenericLayerSpec): LayerSpec {\n const {layer: layer, ...rest} = spec;\n return {\n ...rest,\n layer: layer.map(normalizeNonFacet)\n };\n}\n\nfunction normalizeFacetedUnit(spec: FacetedUnitSpec): FacetSpec {\n // New encoding in the inside spec should not contain row / column\n // as row/column should be moved to facet\n const {row: row, column: column, ...encoding} = spec.encoding;\n\n // Mark and encoding should be moved into the inner spec\n const {mark: mark, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\n mark,\n encoding\n })\n };\n}\n\nfunction isNonFacetUnitSpecWithPrimitiveMark(spec: GenericUnitSpec):\n spec is GenericUnitSpec {\n return isPrimitiveMark(spec.mark);\n}\n\nfunction normalizeNonFacetUnit(spec: GenericUnitSpec) {\n const config = spec.config;\n const overlayConfig = config && config.overlay;\n const overlayWithLine = overlayConfig && spec.mark === AREA &&\n contains(['linepoint', 'line'], overlayConfig.area);\n const overlayWithPoint = overlayConfig && (\n (overlayConfig.line && spec.mark === LINE) ||\n (overlayConfig.area === 'linepoint' && spec.mark === AREA)\n );\n\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(spec.encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n // TODO: consider moving this to become another case of compositeMark\n if (overlayWithPoint || overlayWithLine) {\n return normalizeOverlay(spec, overlayWithPoint, overlayWithLine);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec);\n }\n}\n\nfunction normalizeRangedUnit(spec: UnitSpec) {\n const hasX = channelHasField(spec.encoding, X);\n const hasY = channelHasField(spec.encoding, Y);\n const hasX2 = channelHasField(spec.encoding, X2);\n const hasY2 = channelHasField(spec.encoding, Y2);\n if ((hasX2 && !hasX) || (hasY2 && !hasY)) {\n let normalizedSpec = duplicate(spec);\n if (hasX2 && !hasX) {\n normalizedSpec.encoding.x = normalizedSpec.encoding.x2;\n delete normalizedSpec.encoding.x2;\n }\n if (hasY2 && !hasY) {\n normalizedSpec.encoding.y = normalizedSpec.encoding.y2;\n delete normalizedSpec.encoding.y2;\n }\n\n return normalizedSpec;\n }\n return spec;\n}\n\n\n// FIXME(#1804): rewrite this\nfunction normalizeOverlay(spec: UnitSpec, overlayWithPoint: boolean, overlayWithLine: boolean): LayerSpec {\n let outerProps = ['name', 'description', 'data', 'transform'];\n let baseSpec = omit(spec, outerProps.concat('config'));\n\n let baseConfig = duplicate(spec.config);\n delete baseConfig.overlay;\n // TODO: remove shape, size\n\n // Need to copy stack config to overlayed layer\n const stacked = stack(spec.mark,\n spec.encoding,\n spec.config ? spec.config.stack : undefined\n );\n\n const layerSpec = {\n ...pick(spec, outerProps),\n layer: [baseSpec],\n ...(keys(baseConfig).length > 0 ? {config: baseConfig} : {})\n };\n\n if (overlayWithLine) {\n // TODO: add name with suffix\n let lineSpec = duplicate(baseSpec);\n lineSpec.mark = LINE;\n // TODO: remove shape, size\n let markConfig = extend({},\n defaultOverlayConfig.lineStyle,\n spec.config.overlay.lineStyle,\n stacked ? {stacked: stacked.offset} : null\n );\n if (keys(markConfig).length > 0) {\n lineSpec.config = {mark: markConfig};\n }\n\n layerSpec.layer.push(lineSpec);\n }\n\n if (overlayWithPoint) {\n // TODO: add name with suffix\n let pointSpec = duplicate(baseSpec);\n pointSpec.mark = POINT;\n\n let markConfig = extend({},\n defaultOverlayConfig.pointStyle,\n spec.config.overlay.pointStyle,\n stacked ? {stacked: stacked.offset} : null\n );\n if (keys(markConfig).length > 0) {\n pointSpec.config = {mark: markConfig};\n }\n layerSpec.layer.push(pointSpec);\n }\n return layerSpec;\n}\n\n// TODO: add vl.spec.validate & move stuff from vl.validate to here\n\n/* Accumulate non-duplicate fieldDefs in a dictionary */\nfunction accumulate(dict: any, fieldDefs: FieldDef[]): any {\n fieldDefs.forEach(function(fieldDef) {\n // Consider only pure fieldDef properties (ignoring scale, axis, legend)\n const pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce((f, key) => {\n if (fieldDef[key] !== undefined) {\n f[key] = fieldDef[key];\n }\n return f;\n }, {});\n let key = hash(pureFieldDef);\n dict[key] = dict[key] || fieldDef;\n });\n return dict;\n}\n\n/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */\nfunction fieldDefIndex(spec: ExtendedSpec | ExtendedFacetSpec, dict: any = {}): any {\n // TODO: Support repeat and concat\n if (isLayerSpec(spec)) {\n spec.layer.forEach(function(layer) {\n if (isUnitSpec(layer)) {\n accumulate(dict, vlEncoding.fieldDefs(layer.encoding));\n } else {\n fieldDefIndex(layer, dict);\n }\n });\n } else if (isFacetSpec(spec)) {\n accumulate(dict, vlEncoding.fieldDefs(spec.facet));\n fieldDefIndex(spec.spec, dict);\n } else { // Unit Spec\n accumulate(dict, vlEncoding.fieldDefs(spec.encoding));\n }\n return dict;\n}\n\n/* Returns all non-duplicate fieldDefs in a spec in a flat array */\nexport function fieldDefs(spec: ExtendedSpec | ExtendedFacetSpec): FieldDef[] {\n return vals(fieldDefIndex(spec));\n};\n\nexport function isStacked(spec: FacetedUnitSpec): boolean {\n if (isPrimitiveMark(spec.mark)) {\n return stack(spec.mark, spec.encoding,\n spec.config ? spec.config.stack : undefined\n ) !== null;\n }\n return false;\n}\n", + "import * as log from './log';\n\nimport {SUM_OPS} from './aggregate';\nimport {Channel, STACK_GROUP_CHANNELS, X, Y, X2, Y2} from './channel';\nimport {Encoding, channelHasField, isAggregate} from './encoding';\nimport {FieldDef, PositionFieldDef, isFieldDef} from './fielddef';\nimport {Mark, BAR, AREA, POINT, CIRCLE, SQUARE, LINE, RULE, TEXT, TICK, MarkDef, isMarkDef} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, isArray} from './util';\n\n\n\nexport type StackOffset = 'zero' | 'center' | 'normalize' | 'none';\n\nexport interface StackProperties {\n /** Dimension axis of the stack ('x' or 'y'). */\n groupbyChannel: Channel;\n\n /** Measure axis of the stack ('x' or 'y'). */\n fieldChannel: Channel;\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: FieldDef,\n channel: Channel\n }[];\n\n /**\n * Modes for stacking marks:\n * - `zero`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](mark.html#stacked-bar-chart) and [area](mark.html#stacked-area-chart) chart).\n * - `normalize` - stacking with normalized domain (for creating normalized stacked [bar](mark.html#normalized-stacked-bar-chart) and [area](mark.html#normalized-stacked-area-chart) chart).
\n * -`center` - stacking with center baseline (for [streamgraph](mark.html#streamgraph)).\n * - `none` - No-stacking. This will produce layered [bar](mark.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions: (1) `bar` or `area` marks (2) `color`, `opacity`, `size`, or `detail` channel mapped to a group-by field (3) One ordinal or nominal axis, and (4) one quantitative axis with linear scale and summative aggregation function (e.g., `sum`, `count`).\n */\n offset: StackOffset;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\n\nexport function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n // Should be aggregate plot\n if (!isAggregate(encoding)) {\n return null;\n }\n\n // Should have grouping level of detail\n const stackBy = STACK_GROUP_CHANNELS.reduce((sc, channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (isFieldDef(fieldDef) && !fieldDef.aggregate) {\n sc.push({\n channel: channel,\n fieldDef: fieldDef\n });\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Has only one aggregate axis\n const hasXField = isFieldDef(encoding.x);\n const hasYField = isFieldDef(encoding.y);\n const xIsAggregate = isFieldDef(encoding.x) && !!encoding.x.aggregate;\n const yIsAggregate = isFieldDef(encoding.y) && !!encoding.y.aggregate;\n\n if (xIsAggregate !== yIsAggregate) {\n const fieldChannel = xIsAggregate ? X : Y;\n const fieldDef = encoding[fieldChannel] as PositionFieldDef;\n const fieldChannelAggregate = fieldDef.aggregate;\n const fieldChannelScale = fieldDef.scale;\n\n let stackOffset: StackOffset = null;\n if (fieldDef.stack !== undefined) {\n stackOffset = fieldDef.stack;\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n stackOffset = stackConfig === undefined ? 'zero' : stackConfig;\n } else {\n stackOffset = stackConfig;\n }\n\n if (!stackOffset || stackOffset === 'none') {\n return null;\n }\n\n // If stacked, check if it qualifies for stacking (and log warning if not qualified.)\n if (fieldChannelScale && fieldChannelScale.type && fieldChannelScale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(fieldChannelScale.type));\n return null;\n }\n\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n return null;\n }\n\n if (!contains(SUM_OPS, fieldChannelAggregate)) {\n log.warn(log.message.cannotStackNonSummativeAggregate(fieldChannelAggregate));\n return null;\n }\n\n return {\n groupbyChannel: xIsAggregate ? (hasYField ? Y : null) : (hasXField ? X : null),\n fieldChannel: fieldChannel,\n stackBy: stackBy,\n offset: stackOffset\n };\n }\n return null;\n}\n", + "import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport {Dict, keys} from './util';\nimport * as log from './log';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' = 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n}\n\nexport type TimeUnit = typeof TimeUnit.YEAR | typeof TimeUnit.MONTH | typeof TimeUnit.DAY | typeof TimeUnit.DATE | typeof TimeUnit.HOURS\n | typeof TimeUnit.MINUTES | typeof TimeUnit.SECONDS | typeof TimeUnit.MILLISECONDS | typeof TimeUnit.YEARMONTH\n | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES\n | typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS | typeof TimeUnit.MONTHDATE | typeof TimeUnit.HOURSMINUTES\n | typeof TimeUnit.HOURSMINUTESSECONDS | typeof TimeUnit.MINUTESSECONDS | typeof TimeUnit.SECONDSMILLISECONDS\n | typeof TimeUnit.QUARTER | typeof TimeUnit.YEARQUARTER | typeof TimeUnit.QUARTERMONTH | typeof TimeUnit.YEARQUARTERMONTH;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nexport const SINGLE_TIMEUNITS = [\n TimeUnit.YEAR,\n TimeUnit.QUARTER,\n TimeUnit.MONTH,\n TimeUnit.DAY,\n TimeUnit.DATE,\n TimeUnit.HOURS,\n TimeUnit.MINUTES,\n TimeUnit.SECONDS,\n TimeUnit.MILLISECONDS,\n];\n\nconst SINGLE_TIMEUNIT_INDEX: Dict = SINGLE_TIMEUNITS.reduce((d, timeUnit) => {\n d[timeUnit] = true;\n return d;\n}, {});\n\nexport function isSingleTimeUnit(timeUnit: TimeUnit) {\n return !!SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const result: Date = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date\n SINGLE_TIMEUNITS.forEach(function(singleUnit) {\n if (containsTimeUnit(unit, singleUnit)) {\n switch (singleUnit) {\n case TimeUnit.DAY:\n throw new Error('Cannot convert to TimeUnits containing \\'day\\'');\n case TimeUnit.YEAR:\n result.setFullYear(date.getFullYear());\n break;\n case TimeUnit.QUARTER:\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result.setMonth((Math.floor(date.getMonth() / 3)) * 3);\n break;\n case TimeUnit.MONTH:\n result.setMonth(date.getMonth());\n break;\n case TimeUnit.DATE:\n result.setDate(date.getDate());\n break;\n case TimeUnit.HOURS:\n result.setHours(date.getHours());\n break;\n case TimeUnit.MINUTES:\n result.setMinutes(date.getMinutes());\n break;\n case TimeUnit.SECONDS:\n result.setSeconds(date.getSeconds());\n break;\n case TimeUnit.MILLISECONDS:\n result.setMilliseconds(date.getMilliseconds());\n break;\n }\n }\n });\n\n return result;\n}\n\nexport const MULTI_TIMEUNITS = [\n TimeUnit.YEARQUARTER,\n TimeUnit.YEARQUARTERMONTH,\n TimeUnit.YEARMONTH,\n TimeUnit.YEARMONTHDATE,\n TimeUnit.YEARMONTHDATEHOURS,\n TimeUnit.YEARMONTHDATEHOURSMINUTES,\n TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS,\n TimeUnit.QUARTERMONTH,\n TimeUnit.HOURSMINUTES,\n TimeUnit.HOURSMINUTESSECONDS,\n TimeUnit.MINUTESSECONDS,\n TimeUnit.SECONDSMILLISECONDS,\n];\n\nconst MULTI_TIMEUNIT_INDEX: Dict = MULTI_TIMEUNITS.reduce((d, timeUnit) => {\n d[timeUnit] = true;\n return d;\n}, {});\n\nexport function isMultiTimeUnit(timeUnit: TimeUnit) {\n return !!MULTI_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport const TIMEUNITS = [\n TimeUnit.YEAR,\n TimeUnit.QUARTER,\n TimeUnit.MONTH,\n TimeUnit.DAY,\n TimeUnit.DATE,\n TimeUnit.HOURS,\n TimeUnit.MINUTES,\n TimeUnit.SECONDS,\n TimeUnit.MILLISECONDS,\n TimeUnit.YEARQUARTER,\n TimeUnit.YEARQUARTERMONTH,\n TimeUnit.YEARMONTH,\n TimeUnit.YEARMONTHDATE,\n TimeUnit.YEARMONTHDATEHOURS,\n TimeUnit.YEARMONTHDATEHOURSMINUTES,\n TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS,\n TimeUnit.QUARTERMONTH,\n TimeUnit.HOURSMINUTES,\n TimeUnit.HOURSMINUTESSECONDS,\n TimeUnit.MINUTESSECONDS,\n TimeUnit.SECONDSMILLISECONDS\n];\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n let fullTimeUnitStr = fullTimeUnit.toString();\n let timeUnitStr = timeUnit.toString();\n const index = fullTimeUnitStr.indexOf(timeUnitStr);\n return index > -1 &&\n (\n timeUnit !== TimeUnit.SECONDS ||\n index === 0 ||\n fullTimeUnitStr.charAt(index-1) !== 'i' // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = `datum[\"${field}\"]`;\n\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(quarter(${fieldRef})-1)`;\n } else {\n return `${timeUnit}(${fieldRef})`;\n }\n }\n\n let d = SINGLE_TIMEUNITS.reduce((_d: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n _d[tu] = func(tu);\n }\n return _d;\n }, {});\n\n if (d.day && keys(d).length > 1) {\n log.warn(log.message.dayReplacedWithDate(fullTimeUnit));\n delete d.day;\n d.date = func(TimeUnit.DATE);\n }\n\n return dateTimeExpr(d);\n}\n\n/** returns the smallest nice unit for scale.nice */\nexport function smallestUnit(timeUnit: TimeUnit): string {\n if (!timeUnit) {\n return undefined;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n return 'second';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n return 'minute';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n return 'hour';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY) ||\n containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n return 'day';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n return 'month';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.YEAR)) {\n return 'year';\n }\n return undefined;\n}\n\n/** returns the signal expression used for axis labels for a time unit */\nexport function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean): string {\n if (!timeUnit) {\n return undefined;\n }\n\n let dateComponents: string[] = [];\n let expression = '';\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n let timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n let dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function isDiscreteByDefault(timeUnit: TimeUnit) {\n switch (timeUnit) {\n // These time unit use discrete scale by default\n case 'hours':\n case 'day':\n case 'month':\n case 'quarter':\n return true;\n }\n return false;\n}\n", + "/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport namespace Type {\n export const QUANTITATIVE: 'quantitative' = 'quantitative';\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const TEMPORAL: 'temporal' = 'temporal';\n export const NOMINAL: 'nominal' = 'nominal';\n}\nexport type Type = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\n\nexport const QUANTITATIVE = Type.QUANTITATIVE;\nexport const ORDINAL = Type.ORDINAL;\nexport const TEMPORAL = Type.TEMPORAL;\nexport const NOMINAL = Type.NOMINAL;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type|string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n", + "import * as stringify from 'json-stable-stringify';\nexport {extend, isArray, isObject, isNumber, isString, truncate, toSet, stringValue} from 'vega-util';\nimport {isNumber, isString, isArray} from 'vega-util';\n\n/**\n * Creates an object composed of the picked object properties.\n *\n * Example: (from lodash)\n *\n * var object = {'a': 1, 'b': '2', 'c': 3};\n * pick(object, ['a', 'c']);\n * // → {'a': 1, 'c': 3}\n *\n */\nexport function pick(obj: any, props: string[]) {\n const copy = {};\n props.forEach((prop) => {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n });\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: any, props: string[]) {\n const copy = duplicate(obj);\n props.forEach((prop) => {\n delete copy[prop];\n });\n return copy;\n}\n\nexport function hash(a: any) {\n if (isString(a) || isNumber(a) || isBoolean(a)) {\n return String(a);\n }\n return stringify(a);\n}\n\nexport function contains(array: Array, item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: Array, excludedItems: Array) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: Array, other: Array) {\n return array.concat(without(other, array));\n}\n\nexport function reduce(obj: any, f: (a: any, i: any, d: any, k: any, o: any) => any, init: any, thisArg?: any) {\n if (obj.reduce) {\n return obj.reduce.call(thisArg, f, init);\n } else {\n for (const k in obj) {\n if (obj.hasOwnProperty(k)) {\n init = f.call(thisArg, init, obj[k], k, obj);\n }\n }\n return init;\n }\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: Array, f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(arr: Array, f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(values: T[], f: (item: T) => string): T[] {\n const results: any[] = [];\n const u = {};\n let v: string;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n};\n\nexport interface Dict {\n [key: string]: T;\n}\n\nexport type StringSet = Dict;\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function differ(dict: Dict, other: Dict) {\n for (const key in dict) {\n if (dict.hasOwnProperty(key)) {\n if (other[key] && dict[key] && other[key] !== dict[key]) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport const keys = Object.keys;\n\nexport function vals(x: any) {\n const _vals: any[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n};\n\nexport function duplicate(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n};\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n", + "import {FacetedUnitSpec} from './spec';\nimport {isMarkDef} from './mark';\n\n// TODO: move to vl.spec.validator?\n\nimport {toSet} from './util';\nimport {BAR} from './mark';\n\nexport interface RequiredChannelMap {\n [mark: string]: Array;\n}\n\n/**\n * Required Encoding Channels for each mark type\n * @type {Object}\n */\nexport const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap = {\n text: ['text'],\n line: ['x', 'y'],\n area: ['x', 'y']\n};\n\nexport interface SupportedChannelMap {\n [mark: string]: {\n [channel: string]: number\n };\n}\n\n/**\n * Supported Encoding Channel for each mark type\n */\nexport const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap = {\n bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'detail']), // TODO: add size when Vega supports\n area: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', 'text']) // TODO(#724) revise\n};\n\n// TODO: consider if we should add validate method and\n// requires ZSchema in the main vega-lite repo\n\n/**\n * Further check if encoding mapping of a spec is invalid and\n * return error if it is invalid.\n *\n * This checks if\n * (1) all the required encoding channels for the mark type are specified\n * (2) all the specified encoding channels are supported by the mark type\n * @param {[type]} spec [description]\n * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap\n * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap\n * @return {String} Return one reason why the encoding is invalid,\n * or null if the encoding is valid.\n */\nexport function getEncodingMappingError(spec: FacetedUnitSpec,\n requiredChannelMap: RequiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP,\n supportedChannelMap: SupportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE\n ) {\n let mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n let encoding = spec.encoding;\n let requiredChannels = requiredChannelMap[mark];\n let supportedChannels = supportedChannelMap[mark];\n\n for (let i in requiredChannels) { // all required channels are in encoding`\n if (!(requiredChannels[i] in encoding)) {\n return 'Missing encoding channel \\\"' + requiredChannels[i] +\n '\\\" for mark \\\"' + mark + '\\\"';\n }\n }\n\n for (let channel in encoding) { // all channels in encoding are supported\n if (!supportedChannels[channel]) {\n return 'Encoding channel \\\"' + channel +\n '\\\" is not supported by mark type \\\"' + mark + '\\\"';\n }\n }\n\n if (mark === BAR && !encoding.x && !encoding.y) {\n return 'Missing both x and y for bar';\n }\n\n return null;\n}\n", + "import {StackOffset} from './stack';\nimport {ScaleType, NiceTime} from './scale';\nimport {isArray} from './util';\n\nexport interface VgData {\n name: string;\n source?: string;\n values?: any;\n format?: any;\n url?: any;\n transform?: any;\n}\n\n\nexport type VgParentRef = {\n parent: string\n};\n\nexport type VgFieldRef = string | VgParentRef | VgParentRef[];\n\nexport type VgSortField = boolean | {\n field: VgFieldRef,\n op: string\n};\n\nexport type VgDataRef = {\n data: string,\n field: VgFieldRef,\n sort?: VgSortField\n};\n\nexport type VgSignalRef = {\n signal: string\n};\n\n// TODO: add type of value (Make it VgValueRef {value?:T ...})\nexport type VgValueRef = {\n value?: number | string | boolean,\n field?: string | {\n datum?: string,\n group?: string,\n parent?: string\n },\n signal?: string;\n scale?: string, // TODO: object\n mult?: number,\n offset?: number | VgValueRef,\n band?: boolean | number\n};\n\n// TODO: add vg prefix\nexport type DataRefUnionDomain = {\n fields: (any[] | VgDataRef)[],\n sort?: boolean | {\n op: 'count'\n }\n};\n\n// TODO: add vg prefix\nexport type FieldRefUnionDomain = {\n data: string,\n fields: VgFieldRef[],\n sort?: boolean | {\n op: 'count'\n }\n};\n\nexport type VgRangeScheme = {scheme: string, extent?: number[], count?: number};\nexport type VgRange = string | VgDataRef | (number|string|VgDataRef)[] | VgRangeScheme | {step: number};\n\nexport type VgDomain = any[] | VgDataRef | DataRefUnionDomain | FieldRefUnionDomain | VgSignalRef;\n\nexport type VgScale = {\n name: string,\n type: ScaleType,\n domain: VgDomain,\n domainRaw?: VgSignalRef,\n range: VgRange,\n\n clamp?: boolean,\n exponent?: number,\n nice?: boolean | NiceTime,\n padding?: number,\n paddingInner?: number,\n paddingOuter?: number,\n reverse?: boolean,\n round?: boolean,\n zero?: boolean\n};\n\nexport function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && !('data' in domain);\n }\n return false;\n}\n\nexport function isFieldRefUnionDomain(domain: VgDomain): domain is FieldRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isDataRefDomain(domain: VgDomain): domain is VgDataRef {\n if (!isArray(domain)) {\n return 'field' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef {\n if (!isArray(domain)) {\n return 'signal' in domain;\n }\n return false;\n}\n\nexport type VgEncodeEntry = any;\n// TODO: make export interface VgEncodeEntry {\n// x?: VgValueRef\n// y?: VgValueRef\n// ...\n// color?: VgValueRef\n// ...\n// }\n\nexport type VgAxis = any;\nexport type VgLegend = any;\n\nexport interface VgBinTransform {\n type: 'bin';\n field: string;\n as: string;\n extent?: {signal: string};\n // TODO: add other properties\n}\n\nexport interface VgExtentTransform {\n type: 'extent';\n field: string;\n signal: string;\n}\n\nexport interface VgFormulaTransform {\n type: 'formula';\n as: string;\n expr: string;\n}\n\nexport interface VgAxisEncode {\n ticks?: VgGuideEncode;\n labels?: VgGuideEncode;\n title?: VgGuideEncode;\n grid?: VgGuideEncode;\n domain?: VgGuideEncode;\n}\n\nexport interface VgLegendEncode {\n title?: VgGuideEncode;\n labels?: VgGuideEncode;\n legend?: VgGuideEncode;\n symbols?: VgGuideEncode;\n gradient?: VgGuideEncode;\n}\n\nexport type VgGuideEncode = any; // TODO: replace this (See guideEncode in Vega Schema)\n\nexport type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | any;\n\nexport interface VgStackTransform {\n type: 'stack';\n offset?: StackOffset;\n groupby: string[];\n field: string;\n sort: VgSort;\n as: string[];\n}\n\nexport type VgSort = {\n field: string;\n order: 'ascending' | 'descending';\n} | {\n field: string[];\n order: ('ascending' | 'descending')[];\n};\n\nexport interface VgImputeTransform {\n type: 'impute';\n groupby?: string[];\n field: string;\n orderby?: string[];\n method?: 'value' | 'median' | 'max' | 'min' | 'mean';\n value?: any;\n};\n\nexport type VgCheckboxBinding = {\n input: 'checkbox';\n element?: string;\n};\n\nexport type VgRadioBinding = {\n input: 'radio';\n options: string[];\n element?: string;\n};\n\nexport type VgSelectBinding = {\n input: 'select';\n options: string[];\n element?: string;\n};\n\nexport type VgRangeBinding = {\n input: 'range';\n min?: number;\n max?: number;\n step?: number;\n element?: string;\n};\n\nexport type VgGenericBinding = {\n input: string;\n element?: string;\n};\n\nexport type VgBinding = VgCheckboxBinding | VgRadioBinding |\n VgSelectBinding | VgRangeBinding | VgGenericBinding;\n\n\n/**\n * Base object for Vega's Axis and Axis Config.\n * All of these properties are both properties of Vega's Axis and Axis Config.\n */\nexport interface VgAxisBase {\n /**\n * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis (default true).\n */\n domain?: boolean;\n\n /**\n * A flag indicate if gridlines should be created in addition to ticks. If `grid` is unspecified, the default value is `true` for ROW and COL. For X and Y, the default value is `true` for quantitative and time fields and `false` otherwise.\n */\n grid?: boolean;\n\n /**\n * A boolean flag indicating if labels should be included as part of the axis (default true).\n */\n labels?: boolean;\n\n /**\n * The rotation angle of the axis labels.\n * @minimum 0\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * Whether the axis should include ticks.\n */\n ticks?: boolean;\n\n /**\n * The size, in pixels, of major, minor and end ticks.\n * @minimum 0\n */\n tickSize?: number;\n\n /**\n * Max length for axis title if the title is automatically generated from the field's description. By default, this is automatically based on cell size and characterWidth property.\n * @minimum 0\n * @TJS-type integer\n */\n titleMaxLength?: number;\n\n /**\n * The padding, in pixels, between title and axis.\n */\n titlePadding?: number;\n\n /**\n * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n */\n minExtent?: number;\n\n /**\n * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n */\n maxExtent?: number;\n}\n\nexport interface VgAxisConfig extends VgAxisBase {\n // ---------- Axis ----------\n /**\n * Stroke width of axis domain line\n */\n domainWidth?: number;\n\n /**\n * Color of axis domain line.\n */\n domainColor?: string;\n\n // ---------- Grid ----------\n /**\n * Color of gridlines.\n */\n gridColor?: string;\n\n /**\n * The offset (in pixels) into which to begin drawing with the grid dash array.\n * @minimum 0\n */\n gridDash?: number[];\n\n /**\n * The stroke opacity of grid (value between [0,1])\n * @minimum 0\n * @maximum 1\n */\n gridOpacity?: number;\n\n /**\n * The grid width, in pixels.\n * @minimum 0\n */\n gridWidth?: number;\n\n // ---------- Ticks ----------\n /**\n * The color of the axis's tick.\n */\n tickColor?: string;\n\n /**\n * The color of the tick label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the tick label.\n */\n labelFont?: string;\n\n /**\n * The font size of label, in pixels.\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The width, in pixels, of ticks.\n * @minimum 0\n */\n tickWidth?: number;\n\n // ---------- Title ----------\n /**\n * Color of the title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the title.\n */\n titleFont?: string;\n\n /**\n * Font size of the title.\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the title.\n */\n titleFontWeight?: string | number;\n}\n\nexport interface VgLegendBase {\n /**\n * Padding (in pixels) between legend entries in a symbol legend.\n */\n entryPadding?: number;\n\n /**\n * The orientation of the legend. One of \"left\" or \"right\". This determines how the legend is positioned within the scene. The default is \"right\".\n */\n orient?: string;\n\n /**\n * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle.\n */\n offset?: number;\n\n /**\n * The padding, in pixels, between the legend and axis.\n */\n padding?: number;\n}\n\nexport interface VgLegendConfig extends VgLegendBase {\n // ---------- Gradient ----------\n /**\n * The color of the gradient stroke, can be in hex color code or regular color name.\n */\n gradientStrokeColor?: string;\n\n /**\n * The width of the gradient stroke, in pixels.\n * @minimum 0\n */\n gradientStrokeWidth?: number;\n\n /**\n * The height of the gradient, in pixels.\n * @minimum 0\n */\n gradientHeight?: number;\n\n /**\n * The width of the gradient, in pixels.\n * @minimum 0\n */\n gradientWidth?: number;\n\n // ---------- Label ----------\n /**\n * The alignment of the legend label, can be left, middle or right.\n */\n labelAlign?: string;\n\n /**\n * The position of the baseline of legend label, can be top, middle or bottom.\n */\n labelBaseline?: string;\n\n /**\n * The color of the legend label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the legend label.\n */\n labelFont?: string;\n\n /**\n * The font size of legend label.\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The offset of the legend label.\n * @minimum 0\n */\n labelOffset?: number;\n\n // ---------- Symbols ----------\n /**\n * The color of the legend symbol,\n */\n symbolColor?: string;\n\n /**\n * Default shape type (such as \"circle\") for legend symbols.\n */\n symbolType?: string;\n\n /**\n * The size of the legend symbol, in pixels.\n * @minimum 0\n */\n symbolSize?: number;\n\n /**\n * The width of the symbol's stroke.\n * @minimum 0\n */\n symbolStrokeWidth?: number;\n\n // ---------- Title ----------\n /**\n * Optional mark property definitions for custom legend styling.\n */\n /**\n * The color of the legend title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * The font of the legend title.\n */\n titleFont?: string;\n\n /**\n * The font size of the legend title.\n */\n titleFontSize?: number;\n\n /**\n * The font weight of the legend title.\n */\n titleFontWeight?: string | number;\n\n /**\n * The padding, in pixels, between title and legend.\n */\n titlePadding?: number;\n}\n\nexport type FontStyle = 'normal' | 'italic';\nexport type FontWeight = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\nexport type HorizontalAlign = 'left' | 'right' | 'center';\nexport type Interpolate = 'linear' | 'linear-closed' |\n 'step' | 'step-before' | 'step-after' |\n 'basis' | 'basis-open' | 'basis-closed' |\n 'cardinal' | 'cardinal-open' | 'cardinal-closed' |\n 'bundle' | 'monotone';\nexport type Orient = 'horizontal' | 'vertical';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\n\nexport interface VgMarkConfig {\n\n /**\n * Default Fill Color. This has higher precedence than config.color\n */\n fill?: string;\n\n /**\n * Default Stroke Color. This has higher precedence than config.color\n */\n stroke?: string;\n\n // ---------- Opacity ----------\n /**\n * @minimum 0\n * @maximum 1\n */\n opacity?: number;\n\n\n /**\n * @minimum 0\n * @maximum 1\n */\n fillOpacity?: number;\n\n /**\n * @minimum 0\n * @maximum 1\n */\n strokeOpacity?: number;\n\n // ---------- Stroke Style ----------\n /**\n * @minimum 0\n */\n strokeWidth?: number;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n */\n strokeDashOffset?: number;\n\n // ---------- Orientation: Bar, Tick, Line, Area ----------\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n // ---------- Interpolation: Line / area ----------\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n\n /**\n * The default symbol shape to use. One of: `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n */\n shape?: string;\n\n /**\n * The pixel area each the point/circle/square.\n * For example: in the case of circles, the radius is determined in part by the square root of the size value.\n * @minimum 0\n */\n size?: number;\n\n // Text / Label Mark Config\n\n /**\n * The horizontal alignment of the text. One of left, right, center.\n */\n align?: HorizontalAlign;\n\n /**\n * The rotation angle of the text, in degrees.\n * @minimum 0\n * @maximum 360\n */\n angle?: number;\n\n /**\n * The vertical alignment of the text. One of top, middle, bottom.\n */\n baseline?: VerticalAlign;\n\n /**\n * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property.\n */\n dx?: number;\n\n /**\n * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property.\n */\n dy?: number;\n\n /**\n * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the x and y properties.\n * @minimum 0\n */\n radius?: number;\n\n /**\n * Polar coordinate angle, in radians, of the text label from the origin determined by the x and y properties. Values for theta follow the same convention of arc mark startAngle and endAngle properties: angles are measured in radians, with 0 indicating \"north\".\n */\n theta?: number;\n\n /**\n * The typeface to set the text in (e.g., Helvetica Neue).\n * @minimum 0\n */\n font?: string;\n\n /**\n * The font size, in pixels.\n * @minimum 0\n */\n fontSize?: number;\n\n /**\n * The font style (e.g., italic).\n */\n fontStyle?: FontStyle;\n /**\n * The font weight (e.g., `\"normal\"`, `\"bold\"`, `900`).\n */\n fontWeight?: FontWeight | FontWeightNumber;\n\n /**\n * Placeholder Text\n */\n text?: string;\n}\n", + "export import axis = require('./axis');\nexport import aggregate = require('./aggregate');\nexport import bin = require('./bin');\nexport import channel = require('./channel');\nexport import compositeMark = require('./compositemark');\nexport {compile} from './compile/compile';\nexport import config = require('./config');\nexport import data = require('./data');\nexport import datetime = require('./datetime');\nexport import encoding = require('./encoding');\nexport import facet = require('./facet');\nexport import fieldDef = require('./fielddef');\nexport import legend = require('./legend');\nexport import mark = require('./mark');\nexport import scale = require('./scale');\nexport import sort = require('./sort');\nexport import spec = require('./spec');\nexport import stack = require('./stack');\nexport import timeUnit = require('./timeunit');\nexport import transform = require('./transform');\nexport import type = require('./type');\nexport import util = require('./util');\nexport import validate = require('./validate');\n\nexport const version: string = require('../package.json').version;\n" + ] +} \ No newline at end of file diff --git a/build/vega-lite.min.js b/build/vega-lite.min.js new file mode 100644 index 0000000000..5a8505c820 --- /dev/null +++ b/build/vega-lite.min.js @@ -0,0 +1,6 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.vl=e()}}(function(){var e;return function e(t,n,r){function i(o,s){if(!n[o]){if(!t[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(a)return a(o,!0);var l=new Error("Cannot find module '"+o+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[o]={exports:{}};t[o][0].call(c.exports,function(e){var n=t[o][1][e];return i(n?n:e)},c,c.exports,e,t,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o="0"&&i<="9";)t+=i,c();if("."===i)for(t+=".";c()&&i>="0"&&i<="9";)t+=i;if("e"===i||"E"===i)for(t+=i,c(),"-"!==i&&"+"!==i||(t+=i,c());i>="0"&&i<="9";)t+=i,c();if(e=+t,isFinite(e))return e;l("Bad number")},d=function e(){var t,n,r,e="";if('"'===i)for(;c();){if('"'===i)return c(),e;if("\\"===i)if(c(),"u"===i){for(r=0,n=0;n<4&&(t=parseInt(c(),16),isFinite(t));n+=1)r=16*r+t;e+=String.fromCharCode(r)}else{if("string"!=typeof u[i])break;e+=u[i]}else e+=i}l("Bad string")},p=function(){for(;i&&i<=" ";)c()},m=function(){switch(i){case"t":return c("t"),c("r"),c("u"),c("e"),!0;case"f":return c("f"),c("a"),c("l"),c("s"),c("e"),!1;case"n":return c("n"),c("u"),c("l"),c("l"),null}l("Unexpected '"+i+"'")},g=function e(){var e=[];if("["===i){if(c("["),p(),"]"===i)return c("]"),e;for(;i;){if(e.push(o()),p(),"]"===i)return c("]"),e;c(","),p()}}l("Bad array")},h=function e(){var t,e={};if("{"===i){if(c("{"),p(),"}"===i)return c("}"),e;for(;i;){if(t=d(),p(),c(":"),Object.hasOwnProperty.call(e,t)&&l('Duplicate key "'+t+'"'),e[t]=o(),p(),"}"===i)return c("}"),e;c(","),p()}}l("Bad object")};o=function(){switch(p(),i){case"{":return h();case"[":return g();case'"':return d();case"-":return f();default:return i>="0"&&i<="9"?f():m()}},t.exports=function(e,t){var n;return a=e,r=0,i=" ",n=o(),p(),i&&l("Syntax error"),"function"==typeof t?function e(n,r){var i,a,o=n[""];if(o&&"object"===(void 0===o?"undefined":s(o)))for(i in o)Object.prototype.hasOwnProperty.call(o,i)&&(a=e(o,i),void 0!==a?o[i]=a:delete o[i]);return t.call(n,"",o)}({"":n},""):n}},{}],4:[function(e,t,n){"use strict";function r(e){return l.lastIndex=0,l.test(e)?'"'+e.replace(l,function(e){var t=c[e];return"string"==typeof t?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function i(e,t){var n,l,c,f,d,p=a,m=t[e];switch(m&&"object"===(void 0===m?"undefined":u(m))&&"function"==typeof m.toJSON&&(m=m.toJSON(e)),"function"==typeof s&&(m=s.call(t,e,m)),void 0===m?"undefined":u(m)){case"string":return r(m);case"number":return isFinite(m)?String(m):"null";case"boolean":case"null":return String(m);case"object":if(!m)return"null";if(a+=o,d=[],"[object Array]"===Object.prototype.toString.apply(m)){for(f=m.length,n=0;n=0;s--)(i=e[s])&&(o=(a<3?i(o):a>3?i(t,n,o):i(t,n))||o);return a>3&&o&&Object.defineProperty(t,n,o),o},s=function(e,t){return function(n,r){t(n,r,e)}},u=function(e,t){if("object"===("undefined"==typeof Reflect?"undefined":y(Reflect))&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},l=function(e,t,n,r){return new(n||(n=Promise))(function(i,a){function o(e){try{u(r.next(e))}catch(e){a(e)}}function s(e){try{u(r.throw(e))}catch(e){a(e)}}function u(e){e.done?i(e.value):new n(function(t){t(e.value)}).then(o,s)}u((r=r.apply(e,t||[])).next())})},c=function(e,t){function n(e){return function(t){return r([e,t])}}function r(n){if(i)throw new TypeError("Generator is already executing.");for(;u;)try{if(i=1,a&&(o=a[2&n[0]?"return":n[0]?"throw":"next"])&&!(o=o.call(a,n[1])).done)return o;switch(a=0,o&&(n=[0,o.value]),n[0]){case 0:case 1:o=n;break;case 4:return u.label++,{value:n[1],done:!1};case 5:u.label++,a=n[1],n=[0];continue;case 7:n=u.ops.pop(),u.trys.pop();continue;default:if(o=u.trys,!(o=o.length>0&&o[o.length-1])&&(6===n[0]||2===n[0])){u=0;continue}if(3===n[0]&&(!o||n[1]>o[0]&&n[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}}},p=function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,i,a=n.call(e),o=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)o.push(r.value)}catch(e){i={error:e}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(i)throw i.error}}return o},m=function(){for(var e=[],t=0;t=0?--o:r&&r.indexOf(a)>=0&&++o}return t}function i(e){for(var t=[],n=0,i=e.length,a=0;a"!==e[0])throw"Expected '>' after between selector: "+e;return t=t.map(a),n=a(e.slice(1).trim()),n.between?{between:t,stream:n}:(n.between=t,n)}function s(e){var t,n,i={source:l},a=[],o=[0,0],s=0,f=0,p=e.length,m=0;if("}"===e[p-1]){if(m=e.lastIndexOf("{"),!(m>=0))throw"Unmatched right brace: "+e;try{o=u(e.substring(m+1,p-1))}catch(t){throw"Invalid throttle specification: "+e}e=e.slice(0,m).trim(),p=e.length,m=0}if(!p)throw e;if("@"===e[0]&&(s=++m),t=r(e,m,":"),t1?(i.type=a[1],s?i.markname=a[0].slice(1):(0,c.isMarkType)(a[0])?i.marktype=a[0]:i.source=a[0]):i.type=a[0],"!"===i.type.slice(-1)&&(i.consume=!0,i.type=i.type.slice(0,-1)),null!=n&&(i.filter=n),o[0]&&(i.throttle=o[0]),o[1]&&(i.debounce=o[1]),i}function u(e){var t=e.split(",");if(!e.length||t.length>2)throw e;return t.map(function(t){var n=+t;if(n!==n)throw e;return n})}Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(e,t){return l=t||f,i(e.trim()).map(a)};var l,c=e("./marks/marktypes"),f="view",d=/[\[\]\{\}]/},{"./marks/marktypes":7}],7:[function(e,t,n){"use strict";function r(e){return a.hasOwnProperty(e)}Object.defineProperty(n,"__esModule",{value:!0}),n.marktypes=n.TextMark=n.SymbolMark=n.ShapeMark=n.RuleMark=n.RectMark=n.PathMark=n.LineMark=n.ImageMark=n.GroupMark=n.AreaMark=n.ArcMark=void 0,n.isMarkType=r;var i=e("vega-util"),a=(n.ArcMark="arc",n.AreaMark="area",n.GroupMark="group",n.ImageMark="image",n.LineMark="line",n.PathMark="path",n.RectMark="rect",n.RuleMark="rule",n.ShapeMark="shape",n.SymbolMark="symbol",n.TextMark="text",n.marktypes=(0,i.toSet)(["*","arc","area","group","image","line","path","rect","rule","shape","symbol","text"]))},{"vega-util":8}],8:[function(t,n,r){"use strict";var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};!function(t,a){"object"===(void 0===r?"undefined":i(r))&&void 0!==n?a(r):"function"==typeof e&&e.amd?e(["exports"],a):a(t.vega=t.vega||{})}(void 0,function(e){function t(e){return null==e?null:e.fname}function n(e){return null==e?null:e.fields}function r(e){return u(e)?"["+e.map(r)+"]":l(e)||c(e)?JSON.stringify(e).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):e}function i(e,t,n){var r=[t].concat([].slice.call(n));console[e].apply(console,r)}var a=function(e,t,n){return e.fields=t||[],e.fname=n,e},o=function(e){throw Error(e)},s=function(e){function t(){a.push(c+e.substring(n,r)),c="",n=r+1}var n,r,i,a=[],s=null,u=0,l=e.length,c="";for(e+="",n=r=0;rn&&t(),u=n=r+1):"]"===i&&(u||o("Access path missing open bracket: "+e),u>0&&t(),u=0,n=r+1):r>n?t():n=r+1}return u&&o("Access path missing closing bracket: "+e),s&&o("Access path missing closing quote: "+e),r>n&&(++r,t()),a},u=Array.isArray,l=function(e){return e===Object(e)},c=function(e){return"string"==typeof e},f=function(e,t){var n=s(e),i="return _["+n.map(r).join("][")+"];";return a(Function("_",i),[e=1===n.length?n[0]:e],t||e)},d=[],p=f("id"),m=a(function(e){return e},d,"identity"),g=a(function(){return 0},d,"zero"),h=a(function(){return 1},d,"one"),v=a(function(){return!0},d,"true"),y=a(function(){return!1},d,"false"),b=function(e){var t=e||0;return{level:function(e){return arguments.length?(t=+e,this):t},warn:function(){return t>=1&&i("warn","WARN",arguments),this},info:function(){return t>=2&&i("log","INFO",arguments),this},debug:function(){return t>=3&&i("log","DEBUG",arguments),this}}},S=function(e){return null!=e?u(e)?e:[e]:[]},O=function(e,t){var n,i,o,u,l,c,f,d,p=[],m=(e=S(e)).map(function(e,t){return null==e?null:(p.push(t),s(e).map(r).join("]["))}),g=p.length-1,h=S(t),v="var u,v;return ";if(g<0)return null;for(i=0;i<=g;++i)n=p[i],o=m[n],u="(u=a["+o+"])",l="(v=b["+o+"])",c="((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))",f="descending"!==h[n]?(d=1,-1):(d=-1,1),v+="("+u+"<"+l+"||u==null)&&v!=null?"+f+":(u>v||v==null)&&u!=null?"+d+":"+c+"!==u&&v===v?"+f+":v!==v&&u===u?"+d+(n=r){n=i=r;break}for(a=o=s;++sr&&(n=r,a=s),i=r){n=i=r;break}for(a=o=s;++sr&&(n=r,a=s),i0?n[u++]:t[s++];for(;s=0;)n+=e;return n},P=function(e,t,n,r){var i=n||" ",a=e+"",o=t-a.length;return o<=0?a:"left"===r?w(i,o)+a:"center"===r?w(i,~~(o/2))+a+w(i,Math.ceil(o/2)):a+w(i,o)},C=function(e){return e[e.length-1]},I=function(e){for(var t={},n=0,r=e.length;n (http://kanitw.yellowpigz.com)","Dominik Moritz (https://www.domoritz.de)","Jeffrey Heer (http://jheer.org)"],homepage:"https://vega.github.io/vega-lite/",description:"Vega-lite provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.",main:"build/src/vl.js",types:"build/src/vl.d.ts",bin:{vl2png:"./bin/vl2png",vl2svg:"./bin/vl2svg",vl2vg:"./bin/vl2vg"},directories:{test:"test"},scripts:{prebuild:"mkdir -p build/site build/examples/images build/test-gallery",build:"tsc && cp package.json build && browserify src/vl.ts -p tsify -g [ babelify ] -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js",postbuild:"uglifyjs build/vega-lite.js -cm --in-source-map build/vega-lite.js.map --source-map build/vega-lite.min.js.map > build/vega-lite.min.js && npm run schema","build:images":"npm run data && scripts/generate-images.sh","build:toc":"bundle exec jekyll build -q && scripts/generate-toc","build:site":"browserify site/static/main.ts -p [tsify -p site] -d > build/site/main.js","build:versions":"scripts/update-version.sh","build:test-gallery":"browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js",checkschema:"scripts/check-schema.sh",clean:"rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\.(js|js.map|d.ts)' -delete & rm -rf examples/_diff examples/_original examples/_output examples/images && rm -rf data",data:"rsync -r node_modules/vega-datasets/data/* data",deploy:"scripts/deploy.sh","deploy:gh":"scripts/deploy-gh.sh","deploy:schema":"scripts/deploy-schema.sh",prestart:"npm run data && npm run build && scripts/index-examples",start:"nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'",poststart:"rm examples/all-examples.json",preschema:"npm run prebuild",schema:"typescript-json-schema --required true --noExtraProps true src/spec.ts ExtendedSpec > build/vega-lite-schema.json",presite:"npm run build && npm run data && npm run build:site && npm run build:toc && npm run build:versions",site:"bundle exec jekyll serve",lint:"tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'",test:"tsc && npm run schema && npm run data && npm run test:nocompile","test:nocompile":"npm run test:only && npm run lint && npm run mocha:examples","test:only":"nyc --reporter=html --reporter=text-summary npm run mocha:test","test:debug":"tsc && npm run schema && npm run data && mocha --recursive --require ./test/babel.ts --debug-brk build/test build/examples","mocha:test":"mocha --reporter dot --recursive build/test","mocha:examples":"mocha --require ./test/babel.ts --reporter dot --recursive build/examples",codecov:"nyc report --reporter=json && codecov -f coverage/*.json","watch:build":"watchify src/vl.ts -p tsify -g [ babelify ] -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'","watch:test":"nodemon -x 'npm test'",watch:"nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build","x-compile":"./scripts/examples-compile.sh","x-diff":"./scripts/examples-diff.sh"},repository:{type:"git",url:"https://github.com/vega/vega-lite.git"},license:"BSD-3-Clause",bugs:{url:"https://github.com/vega/vega-lite/issues"},devDependencies:{"@types/chai":"^3.4.35","@types/highlight.js":"^9.1.9","@types/d3":"^4.5.0","@types/json-stable-stringify":"^1.0.30","@types/mocha":"^2.2.39","@types/node":"^7.0.5",ajv:"5.0.1-beta.1","babel-preset-es2015":"^6.22.0",babelify:"^7.3.0","browser-sync":"~2.18.8",browserify:"~14.1.0","browserify-shim":"^3.8.13",chai:"~3.5.0",cheerio:"~0.22.0",codecov:"~1.0.1",d3:"^4.7.0",exorcist:"~0.4.0","highlight.js":"^9.9.0",mocha:"~3.2.0",nodemon:"~1.11.0",nyc:"~10.1.2","source-map-support":"~0.4.11",tsify:"~3.0.1",tslint:"~4.5.1","tslint-eslint-rules":"^3.4.0",typescript:"^2.2.1","typescript-json-schema":"^0.10.0","uglify-js":"~2.8.4",vega:"3.0.0-beta.25","vega-datasets":"vega/vega-datasets#gh-pages","vega-embed":"3.0.0-beta.5","vega-parser":"^1.0.0-beta.38",watchify:"~3.9.0","yaml-front-matter":"~3.4.0"},dependencies:{"json-stable-stringify":"~1.0.1",tslib:"^1.6.0","vega-util":"~1.1.4",yargs:"~6.6.0"}}},{}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.AGGREGATE_OPS=["values","count","valid","missing","distinct","sum","mean","average","variance","variancep","stdev","stdevp","median","q1","q3","modeskew","min","max","argmin","argmax"],n.SUM_OPS=["count","sum","distinct","valid","missing"],n.SHARED_DOMAIN_OPS=["mean","average","median","q1","q3","min","max"]},{}],11:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.defaultAxisConfig={labelMaxLength:25},n.AXIS_PROPERTIES=["domain","format","grid","labelPadding","labels","maxExtent","minExtent","offset","orient","position","tickCount","ticks","tickSize","title","titlePadding","values","zindex"],n.VL_ONLY_AXIS_PROPERTIES=["labelMaxLength"]},{}],12:[function(e,t,n){"use strict";function r(e){switch(e){case i.ROW:case i.COLUMN:case i.SIZE:case i.SHAPE:return 6;default:return 10}}Object.defineProperty(n,"__esModule",{value:!0});var i=e("./channel");n.autoMaxBins=r},{"./channel":13}],13:[function(e,t,n){"use strict";function r(e,t){return t in i(e)}function i(e){switch(e){case n.X:case n.Y:case n.COLOR:case n.DETAIL:case n.ORDER:case n.OPACITY:case n.ROW:case n.COLUMN:return{point:!0,tick:!0,rule:!0,circle:!0,square:!0,bar:!0,rect:!0,line:!0,area:!0,text:!0};case n.X2:case n.Y2:return{rule:!0,bar:!0,rect:!0,area:!0};case n.SIZE:return{point:!0,tick:!0,rule:!0,circle:!0,square:!0,bar:!0,text:!0,line:!0};case n.SHAPE:return{point:!0};case n.TEXT:return{text:!0}}return{}}function a(e){return!c.contains([n.DETAIL,n.TEXT,n.ORDER],e)}function o(e,t){switch(e){case n.ROW:case n.COLUMN:return"band"===t;case n.X:case n.Y:case n.SIZE:case n.OPACITY:return t in f;case n.COLOR:return"band"!==t;case n.SHAPE:return"ordinal"===t}return!1}function s(e){switch(e){case n.X:case n.Y:case n.SIZE:case n.OPACITY:return"continuous";case n.ROW:case n.COLUMN:case n.SHAPE:return"discrete";case n.COLOR:return"flexible";case n.X2:case n.Y2:case n.DETAIL:case n.TEXT:case n.ORDER:return}throw new Error("getSupportedRole not implemented for "+e)}Object.defineProperty(n,"__esModule",{value:!0});var u,l=e("./scale"),c=e("./util");!function(e){e.ROW="row",e.COLUMN="column",e.X="x",e.Y="y",e.X2="x2",e.Y2="y2",e.COLOR="color",e.SHAPE="shape",e.SIZE="size",e.OPACITY="opacity",e.TEXT="text",e.ORDER="order",e.DETAIL="detail"}(u=n.Channel||(n.Channel={})),n.X=u.X,n.Y=u.Y,n.X2=u.X2,n.Y2=u.Y2,n.ROW=u.ROW,n.COLUMN=u.COLUMN,n.SHAPE=u.SHAPE,n.SIZE=u.SIZE,n.COLOR=u.COLOR,n.TEXT=u.TEXT,n.DETAIL=u.DETAIL,n.ORDER=u.ORDER,n.OPACITY=u.OPACITY,n.CHANNELS=[n.X,n.Y,n.X2,n.Y2,n.ROW,n.COLUMN,n.SIZE,n.SHAPE,n.COLOR,n.ORDER,n.OPACITY,n.TEXT,n.DETAIL],n.UNIT_CHANNELS=[n.X,n.Y,n.X2,n.Y2,n.SIZE,n.SHAPE,n.COLOR,n.ORDER,n.OPACITY,n.TEXT,n.DETAIL],n.UNIT_SCALE_CHANNELS=[n.X,n.Y,n.SIZE,n.SHAPE,n.COLOR,n.OPACITY],n.SCALE_CHANNELS=[n.X,n.Y,n.SIZE,n.SHAPE,n.COLOR,n.OPACITY,n.ROW,n.COLUMN],n.NONSPATIAL_CHANNELS=[n.SIZE,n.SHAPE,n.COLOR,n.ORDER,n.OPACITY,n.TEXT,n.DETAIL],n.NONSPATIAL_SCALE_CHANNELS=[n.SIZE,n.SHAPE,n.COLOR,n.OPACITY],n.STACK_GROUP_CHANNELS=[n.COLOR,n.DETAIL,n.ORDER,n.OPACITY,n.SIZE],n.supportMark=r,n.getSupportedMark=i,n.hasScale=a;var f=c.toSet(c.without(l.SCALE_TYPES,["ordinal","sequential"]));n.supportScaleType=o,n.rangeType=s},{"./scale":80,"./util":88}],14:[function(e,t,n){"use strict";function r(e,t,n,r){var u=e.fieldDef(t),l=e.axis(t),c=e.config;return o.contains([a.NOMINAL,a.ORDINAL],u.type)&&l.labelMaxLength?n=o.extend({text:{signal:"truncate(datum.value, "+l.labelMaxLength+")"}},n||{}):u.type===a.TEMPORAL&&(n=o.extend({text:{signal:s.timeFormatExpression("datum.value",u.timeUnit,l.format,c.axis.shortTimeLabels,c.timeFormat)}},n)),void 0!==l.labelAngle?n.angle={value:l.labelAngle}:t===i.X&&(o.contains([a.NOMINAL,a.ORDINAL],u.type)||u.bin||u.type===a.TEMPORAL)&&(n.angle={value:270}),n.angle&&(270===n.angle.value?n.align={value:"top"===r.orient?"left":t===i.X||t===i.COLUMN?"right":"center"}:90===n.angle.value&&(n.align={value:"center"})),n.angle&&(270===n.angle.value?n.baseline={value:t===i.X||t===i.COLUMN?"middle":"bottom"}:90===n.angle.value&&(n.baseline={value:"bottom"})),0===o.keys(n).length?void 0:n}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../channel"),a=e("../../type"),o=e("../../util"),s=e("../common");n.labels=r},{"../../channel":13,"../../type":87,"../../util":88,"../common":17}],15:[function(e,t,n){"use strict";function r(e,t){return t.reduce(function(t,n){var r=[];if(e.axis(n)){var i=u(n,e);i&&a(i)&&r.push(i);var o=s(n,e);o&&a(o)&&r.push(o),r.length>0&&(t[n]=r)}return t},{})}function i(e){return e===!1||null===e}function a(e){return m.some(g,function(t){return o(e,t)})}function o(e,t){return"grid"===t||"title"===t?!!e[t]:!i(e[t])}function s(e,t){return l(e,t,!0)}function u(e,t){return l(e,t,!1)}function l(e,t,n){var r=t.axis(e),i={scale:t.scaleName(e)};f.AXIS_PROPERTIES.forEach(function(a){var o=c(a,r,e,t,n);void 0!==o&&(i[a]=o)});var a=c("gridScale",r,e,t,n);void 0!==a&&(i.gridScale=a);var s=r.encode||{};return g.forEach(function(n){if(o(i,n)){var r;r="labels"===n?d.labels(t,e,s.labels||{},i):s[n]||{},void 0!==r&&m.keys(r).length>0&&(i.encode=i.encode||{},i.encode[n]={update:r})}}),i}function c(e,t,n,r,i){var a=r.fieldDef(n);switch(e){case"labels":return!i&&t[e];case"domain":return p.domain(e,t,i,n);case"ticks":return p.ticks(e,t,i,n);case"format":return p.format(t,n,a,r.config);case"grid":return p.grid(r,n,i);case"gridScale":return p.gridScale(r,n,i);case"orient":return p.orient(t,n);case"tickCount":return p.tickCount(t,n,a);case"title":return p.title(t,a,r.config,i);case"values":return p.values(t);case"zindex":return p.zindex(t,i)}return t[e]}Object.defineProperty(n,"__esModule",{value:!0});var f=e("../../axis"),d=e("./encode"),p=e("./rules"),m=e("../../util"),g=["domain","grid","labels","ticks","title"];n.parseAxisComponent=r,n.parseGridAxis=s,n.parseMainAxis=u},{"../../axis":11,"../../util":88,"./encode":14,"./rules":16}],16:[function(e,t,n){"use strict";function r(e,t,n,r){return y.numberFormat(n,e.format,r,t)}function i(e,t){var n=e.axis(t).grid;return void 0!==n?n:!e.hasDiscreteScale(t)&&!e.fieldDef(t).bin}function a(e,t,n){if(t===m.ROW||t===m.COLUMN)return!1;if(n)return i(e,t)}function o(e,t,n){if(n){var r="x"===t?"y":"x";if(e.scale(r))return e.scaleName(r)}}function s(e,t){var n=e.orient;if(n)return n;switch(t){case m.COLUMN:return"top";case m.X:return"bottom";case m.ROW:case m.Y:return"left"}throw new Error(p.message.INVALID_CHANNEL_FOR_AXIS)}function u(e,t,n){var r=e.tickCount;return void 0!==r?r:t!==m.X||n.bin?void 0:5}function l(e,t,n,r){if(!r){if(void 0!==e.title)return e.title;var i=h.title(t,n),a=e.titleMaxLength;return a?v.truncate(i,a):i}}function c(e){var t=e.values;return e.values&&g.isDateTime(t[0])?t.map(function(e){return g.timestamp(e,!0)}):t}function f(e,t){var n=e.zindex;return void 0!==n?n:t?0:1}function d(e,t,n,r){return!n&&r!==m.ROW&&r!==m.COLUMN&&t[e]}Object.defineProperty(n,"__esModule",{value:!0});var p=e("../../log"),m=e("../../channel"),g=e("../../datetime"),h=e("../../fielddef"),v=e("../../util"),y=e("../common");n.format=r,n.gridShow=i,n.grid=a,n.gridScale=o,n.orient=s,n.tickCount=u,n.title=l,n.values=c,n.zindex=f,n.domainAndTicks=d,n.domain=d,n.ticks=d},{"../../channel":13,"../../datetime":72,"../../fielddef":75,"../../log":78,"../../util":88,"../common":17}],17:[function(e,t,n){"use strict";function r(e,t,n){if(b.isFacetSpec(e))return new g.FacetModel(e,t,n);if(b.isLayerSpec(e))return new h.LayerModel(e,t,n);if(b.isUnitSpec(e))return new y.UnitModel(e,t,n);throw new Error(c.message.INVALID_SPEC)}function i(e,t,n){return n.forEach(function(n){var r=t[n];void 0!==r&&(e[n]={value:r})}),e}function a(e,t,n){return n.forEach(function(n){var r=o(n,t.mark(),t.config) +;void 0!==r&&(e[n]={value:r})}),e}function o(e,t,n){var r=n[t];return void 0!==r[e]?r[e]:n.mark[e]}function s(e,t,n,r){if(e.type===p.QUANTITATIVE)return t?t:"count"===e.aggregate&&r===f.TEXT?"d":n.numberFormat}function u(e,t,n,r,i){if(!t||n){return"timeFormat("+e+", '"+(n||i)+"')"}return v.formatExpression(t,e,r)}function l(e){return(m.isArray(e)?e:[e]).reduce(function(e,t){return e.field.push(d.field(t,{binSuffix:"start"})),e.order.push(t.sort||"ascending"),e},{field:[],order:[]})}Object.defineProperty(n,"__esModule",{value:!0});var c=e("../log"),f=e("../channel"),d=e("../fielddef"),p=e("../type"),m=e("../util"),g=e("./facet"),h=e("./layer"),v=e("../timeunit"),y=e("./unit"),b=e("../spec");n.buildModel=r,n.applyConfig=i,n.applyMarkConfig=a,n.getMarkConfig=o,n.numberFormat=s,n.timeFormatExpression=u,n.sortParams=l},{"../channel":13,"../fielddef":75,"../log":78,"../spec":83,"../timeunit":85,"../type":87,"../util":88,"./facet":31,"./layer":32,"./unit":68}],18:[function(e,t,n){"use strict";function r(e,t){t&&u.set(t);try{var n=l.normalize(e),r=d.buildModel(n,null,"");return r.parse(),i(r)}finally{t&&u.reset()}}function i(e){return{spec:c.extend({$schema:"http://vega.github.io/schema/vega/v3.0.json"},a(e),{signals:[{name:"width",update:"data('layout')[0].width"},{name:"height",update:"data('layout')[0].height"}].concat(f.assembleTopLevelSignals(e))},{data:[].concat(e.assembleData([]),e.assembleLayout([]),e.assembleSelectionData([])),marks:[o(e)]})}}function a(e){var t=e.config;return c.extend({padding:e.padding||t.padding},{autosize:"pad"},t.viewport?{viewport:t.viewport}:{},t.background?{background:t.background}:{})}function o(e){var t=c.extend({name:e.getName("main"),type:"group"},e.description?{description:e.description}:{},{from:{data:e.getName(s.LAYOUT+"")},encode:{update:c.extend({width:{field:e.getName("width")},height:{field:e.getName("height")}},e.assembleParentGroupProperties(e.config.cell))}});return c.extend(t,e.assembleGroup())}Object.defineProperty(n,"__esModule",{value:!0});var s=e("../data"),u=e("../log"),l=e("../spec"),c=e("../util"),f=e("./selection/selection"),d=e("./common");n.compile=r,n.topLevelBasicProperties=a,n.assembleRootGroup=o},{"../data":71,"../log":78,"../spec":83,"../util":88,"./common":17,"./selection/selection":58}],19:[function(e,t,n){"use strict";function r(e,t){return"format("+e+", '"+t+"')"}function i(e){return e.reduceFieldDef(function(t,n,i){var l=e.fieldDef(i).bin;if(l){var c=s.extend({type:"bin",field:n.field,as:[o.field(n,{binSuffix:"start"}),o.field(n,{binSuffix:"end"})],signal:e.getName(n.field+"_bins")},"boolean"==typeof l?{}:l),f=[];if(!c.extent){var d=e.getName(n.field+"_extent");f.push({type:"extent",field:n.field,signal:d}),c.extent={signal:d}}c.maxbins||c.step||(c.maxbins=a.autoMaxBins(i)),f.push(c);var p=u.hasDiscreteDomain(e.scale(i).type);if(p){var m=(e.axis(i)||e.legend(i)||{}).format||e.config.numberFormat,g=o.field(n,{datum:!0,binSuffix:"start"}),h=o.field(n,{datum:!0,binSuffix:"end"});f.push({type:"formula",as:o.field(n,{binSuffix:"range"}),expr:r(g,m)+" + ' - ' + "+r(h,m)})}t[s.hash(l)+"_"+n.field+"oc:"+p]=f}return t},{})}Object.defineProperty(n,"__esModule",{value:!0});var a=e("../../bin"),o=e("../../fielddef"),s=e("../../util"),u=e("../../scale");n.bin={parseUnit:i,parseFacet:function(e){var t=i(e),n=e.child.component.data;return n.source||(s.extend(t,n.bin),delete n.bin),t},parseLayer:function(e){var t=i(e);return e.children.forEach(function(e){var n=e.component.data;n.source||(s.extend(t,n.bin),delete n.bin)}),t},assemble:function(e){return s.flatten(s.vals(e))}}},{"../../bin":12,"../../fielddef":75,"../../scale":80,"../../util":88}],20:[function(e,t,n){"use strict";function r(e){return{formatParse:l.formatParse.parseUnit(e),nullFilter:c.nullFilter.parseUnit(e),filter:f.filter.parseUnit(e),nonPositiveFilter:g.nonPositiveFilter.parseUnit(e),pathOrder:m.pathOrder.parseUnit(e),source:u.source.parseUnit(e),bin:d.bin.parseUnit(e),calculate:p.formula.parseUnit(e),timeUnit:y.timeUnit.parseUnit(e),summary:h.summary.parseUnit(e),stack:v.stack.parseUnit(e)}}function i(e){return{formatParse:l.formatParse.parseFacet(e),nullFilter:c.nullFilter.parseFacet(e),filter:f.filter.parseFacet(e),nonPositiveFilter:g.nonPositiveFilter.parseFacet(e),pathOrder:m.pathOrder.parseFacet(e),source:u.source.parseFacet(e),bin:d.bin.parseFacet(e),calculate:p.formula.parseFacet(e),timeUnit:y.timeUnit.parseFacet(e),summary:h.summary.parseFacet(e),stack:v.stack.parseFacet(e)}}function a(e){return{filter:f.filter.parseLayer(e),formatParse:l.formatParse.parseLayer(e),nullFilter:c.nullFilter.parseLayer(e),nonPositiveFilter:g.nonPositiveFilter.parseLayer(e),pathOrder:m.pathOrder.parseLayer(e),source:u.source.parseLayer(e),bin:d.bin.parseLayer(e),calculate:p.formula.parseLayer(e),timeUnit:y.timeUnit.parseLayer(e),summary:h.summary.parseLayer(e),stack:v.stack.parseLayer(e)}}function o(e,t){var n=e.component.data,r=u.source.assemble(n);r&&t.push(r),h.summary.assemble(n.summary||[],e.dataName(s.SOURCE)).forEach(function(e){t.push(e)});var i=g.nonPositiveFilter.assemble(n.nonPositiveFilter);if(i.length>0){if(!(t.length>0))throw new Error("Invalid nonPositiveFilter not merged");var a=t[t.length-1];a.transform=(a.transform||[]).concat(i)}var o=v.stack.assemble(n.stack);o&&t.push(o);var l=m.pathOrder.assemble(n.pathOrder);if(l){var a=t[t.length-1];if(!(t.length>0))throw new Error("Invalid path order collect transform not added");a.transform=(a.transform||[]).concat([l])}return t}Object.defineProperty(n,"__esModule",{value:!0});var s=e("../../data"),u=e("./source"),l=e("./formatparse"),c=e("./nullfilter"),f=e("./filter"),d=e("./bin"),p=e("./formula"),m=e("./pathorder"),g=e("./nonpositivefilter"),h=e("./summary"),v=e("./stack"),y=e("./timeunit");n.parseUnitData=r,n.parseFacetData=i,n.parseLayerData=a,n.assembleData=o},{"../../data":71,"./bin":19,"./filter":21,"./formatparse":22,"./formula":23,"./nonpositivefilter":24,"./nullfilter":25,"./pathorder":26,"./source":27,"./stack":28,"./summary":29,"./timeunit":30}],21:[function(e,t,n){"use strict";function r(e){var t=e.filter();return a.isArray(t)?"("+t.map(function(e){return i.expression(e)}).filter(function(e){return void 0!==e}).join(") && (")+")":t?i.expression(t):void 0}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../filter"),a=e("../../util");n.filter={parseUnit:r,parseFacet:function(e){var t=r(e),n=e.child.component.data;return!n.source&&n.filter&&(t=(t?t+" && ":"")+n.filter,delete n.filter),t},parseLayer:function(e){var t=r(e);return e.children.forEach(function(n){var r=n.component.data;e.compatibleSource(n)&&r.filter&&r.filter===t&&delete r.filter}),t},assemble:function(e){return e?[{type:"filter",expr:e}]:[]}}},{"../../filter":76,"../../util":88}],22:[function(e,t,n){"use strict";function r(e){var t=(e.calculate()||[]).reduce(function(e,t){return e[t.as]=!0,e},{}),n={},r=e.filter();l.isArray(r)||(r=[r]),r.forEach(function(e){var t=null;s.isEqualFilter(e)?t=e.equal:s.isRangeFilter(e)?t=e.range[0]:s.isOneOfFilter(e)&&(t=(e.oneOf||e.in)[0]),t&&(i.isDateTime(t)?n[e.field]="date":l.isNumber(t)?n[e.field]="number":l.isString(t)&&(n[e.field]="string"))}),e.forEachFieldDef(function(e){if(e.type===u.TEMPORAL)n[e.field]="date";else if(e.type===u.QUANTITATIVE){if(o.isCount(e)||t[e.field])return;n[e.field]="number"}});var c=e.data;if(c&&a.isUrlData(c)&&c.format&&c.format.parse){var f=c.format.parse;l.keys(f).forEach(function(e){n[e]=f[e]})}return n}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../datetime"),a=e("../../data"),o=e("../../fielddef"),s=e("../../filter"),u=e("../../type"),l=e("../../util");n.formatParse={parseUnit:r,parseFacet:function(e){var t=r(e),n=e.child.component.data;return!n.source&&n.formatParse&&(l.extend(t,n.formatParse),delete n.formatParse),t},parseLayer:function(e){var t=r(e);return e.children.forEach(function(n){var r=n.component.data;e.compatibleSource(n)&&!l.differ(r.formatParse,t)&&(l.extend(t,r.formatParse),delete r.formatParse)}),t},assemble:function(e){return e}}},{"../../data":71,"../../datetime":72,"../../fielddef":75,"../../filter":76,"../../type":87,"../../util":88}],23:[function(e,t,n){"use strict";function r(e){return(e.calculate()||[]).reduce(function(e,t){return e[i.hash(t)]=t,e},{})}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../util");n.formula={parseUnit:r,parseFacet:function(e){var t=r(e),n=e.child.component.data;return n.source||(i.extend(t,n.calculate),delete n.calculate),t},parseLayer:function(e){var t=r(e);return e.children.forEach(function(e){var n=e.component.data;!n.source&&n.calculate&&(i.extend(t||{},n.calculate),delete n.calculate)}),t},assemble:function(e){return i.vals(e).reduce(function(e,t){return e.push(i.extend({type:"formula"},t)),e},[])}}},{"../../util":88}],24:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../scale"),i=e("../../util");n.nonPositiveFilter={parseUnit:function(e){return e.channels().reduce(function(t,n){var i=e.scale(n);return e.field(n)&&i?(t[e.field(n)]=i.type===r.ScaleType.LOG,t):t},{})},parseFacet:function(e){var t=e.child.component.data;if(!t.source){var n=t.nonPositiveFilter;return delete t.nonPositiveFilter,n}return{}},parseLayer:function(e){var t={};return e.children.forEach(function(n){var r=n.component.data;e.compatibleSource(n)&&!i.differ(r.nonPositiveFilter,t)&&(i.extend(t,r.nonPositiveFilter),delete r.nonPositiveFilter)}),t},assemble:function(e){return e?i.keys(e).filter(function(t){return e[t]}).map(function(e){return{type:"filter",expr:'datum["'+e+'"] > 0'}}):[]}}},{"../../scale":80,"../../util":88}],25:[function(e,t,n){"use strict";function r(e){var t=e.filterInvalid();return e.reduceFieldDef(function(e,n){return"*"!==n.field&&(t||void 0===t&&n.field&&o[n.type]?e[n.field]=n:e[n.field]=null),e},{})}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../type"),a=e("../../util"),o={nominal:!1,ordinal:!1,quantitative:!0,temporal:!0};n.nullFilter={parseUnit:r,parseFacet:function(e){var t=r(e),n=e.child.component.data;return n.source||(a.extend(t,n.nullFilter),delete n.nullFilter),t},parseLayer:function(e){var t=r(e);return e.children.forEach(function(n){var r=n.component.data;e.compatibleSource(n)&&!a.differ(r.nullFilter,t)&&(a.extend(t,r.nullFilter),delete r.nullFilter)}),t},assemble:function(e){var t=a.keys(e).reduce(function(t,n){var r=e[n];return null!==r&&(t.push('datum["'+r.field+'"] !== null'),a.contains([i.QUANTITATIVE,i.TEMPORAL],r.type)&&t.push('!isNaN(datum["'+r.field+'"])')),t},[]);return t.length>0?[{type:"filter",expr:t.join(" && ")}]:[]}}},{"../../type":87,"../../util":88}],26:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("json-stable-stringify"),i=e("../../encoding"),a=e("../../fielddef"),o=e("../../sort"),s=e("../../util"),u=e("../common");n.pathOrder={parseUnit:function(e){if(s.contains(["line","area"],e.mark())){if("line"===e.mark()&&e.channelHasField("order"))return u.sortParams(e.encoding.order);var t="horizontal"===e.markDef.orient?"y":"x",n=e.sort(t);return{field:o.isSortField(n)?a.field({aggregate:i.isAggregate(e.encoding)?n.op:void 0,field:n.field}):e.field(t,{binSuffix:"start"}),order:"descending"}}return null},parseFacet:function(e){var t=e.child.component.data;if(!t.source){var n=t.pathOrder;return delete t.pathOrder,n}return null},parseLayer:function(e){for(var t=null,n=null,i=0,a=e.children;i0){var o=a.keys(r),s=a.reduce(i,function(e,t,n){for(var r=a.keys(t),i=0,o=r;i0)return!0}return!1},t.prototype.facetedTable=function(){return"faceted-"+this.getName("data")},t.prototype.dataTable=function(){return this.component.data.stack?"stacked":this.hasSummary()?"summary":"source"},t.prototype.fieldDef=function(e){return this.facet[e]},t.prototype.parseData=function(){this.child.parseData(),this.component.data=E.parseFacetData(this)},t.prototype.parseSelection=function(){},t.prototype.parseLayoutData=function(){this.child.parseLayoutData(),this.component.layout=_.parseFacetLayout(this)},t.prototype.parseScale=function(){var e=this.child,t=this;e.parseScale();var n=this.component.scales=T.default(this);y.keys(e.component.scales).forEach(function(r){var i=n[r]=e.component.scales[r],a=i.name.substr(e.getName("").length),o=t.scaleName(a,!0);e.renameScale(i.name,o),delete e.component.scales[r]})},t.prototype.parseMark=function(){this.child.parseMark(),this.component.mark=y.extend({name:this.getName("cell"),type:"group",from:y.extend({facet:{name:this.facetedTable(),data:this.dataTable(),groupby:[].concat(this.channelHasField(m.ROW)?[this.field(m.ROW)]:[],this.channelHasField(m.COLUMN)?[this.field(m.COLUMN)]:[])}}),encode:{update:a(this)}},this.child.assembleGroup())},t.prototype.parseAxis=function(){this.child.parseAxis(),this.component.axes=b.parseAxisComponent(this,[m.ROW,m.COLUMN])},t.prototype.parseAxisGroup=function(){var e=s(this,m.X),t=s(this,m.Y);this.component.axisGroups=y.extend(e?{x:e}:{},t?{y:t}:{})},t.prototype.parseGridGroup=function(){var e=this.child;this.component.gridGroups=y.extend(!e.channelHasField(m.X)&&this.channelHasField(m.COLUMN)?{column:c(this)}:{},!e.channelHasField(m.Y)&&this.channelHasField(m.ROW)?{row:l(this)}:{})},t.prototype.parseLegend=function(){this.child.parseLegend(),this.component.legends=this.child.component.legends,this.child.component.legends={}},t.prototype.assembleParentGroupProperties=function(){return null},t.prototype.assembleSignals=function(e){return[]},t.prototype.assembleSelectionData=function(e){return[]},t.prototype.assembleData=function(e){return E.assembleData(this,e),this.child.assembleData(e),o(this,e),e},t.prototype.assembleLayout=function(e){return this.child.assembleLayout(e),_.assembleLayout(this,e)},t.prototype.assembleMarks=function(){return[].concat(y.vals(this.component.axisGroups),y.flatten(y.vals(this.component.gridGroups)),this.component.mark)},t.prototype.channels=function(){return[m.ROW,m.COLUMN]},t.prototype.getMapping=function(){return this.facet},t.prototype.spacing=function(e){return this._spacing[e]},t.prototype.isFacet=function(){return!0},t}(x.Model);n.FacetModel=A,n.hasSubPlotWithXy=r,n.spacing=i,n.assembleAxesGroupData=o,n.getSharedAxisGroup=u},{"../axis":11,"../channel":13,"../config":70,"../encoding":73,"../fielddef":75,"../log":78,"../util":88,"./axis/parse":15,"./axis/rules":16,"./common":17,"./data/data":20,"./layout":33,"./model":49,"./scale/init":51,"./scale/parse":52,tslib:5}],32:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("tslib"),i=e("../config"),a=e("../mark"),o=e("../util"),s=e("../vega.schema"),u=e("../data"),l=e("./data/data"),c=e("./common"),f=e("./layout"),d=e("./model"),p=e("./scale/domain"),m=function(e){function t(t,n,r){var i=e.call(this,t,n,r)||this;return i.scales={},i.axes={},i.legends={},i.stack=null,i.width=t.width,i.height=t.height,i.config=i.initConfig(t.config,n),i.children=t.layer.map(function(e,t){return c.buildModel(e,i,i.getName("layer_"+t))}),i}return r.__extends(t,e),t.prototype.initConfig=function(e,t){return o.mergeDeep(o.duplicate(i.defaultConfig),e,t?t.config:{})},t.prototype.channelHasField=function(e){return!1},t.prototype.hasDiscreteScale=function(e){return this.children[0].hasDiscreteScale(e)},t.prototype.dataTable=function(){return this.children[0].dataTable()},t.prototype.fieldDef=function(e){return null},t.prototype.parseData=function(){this.children.forEach(function(e){e.parseData()}),this.component.data=l.parseLayerData(this)},t.prototype.parseSelection=function(){},t.prototype.parseLayoutData=function(){this.children.forEach(function(e){e.parseLayoutData()}),this.component.layout=f.parseLayerLayout(this)},t.prototype.parseScale=function(){var e=this,t=this.component.scales={};this.children.forEach(function(n){n.parseScale(),o.keys(n.component.scales).forEach(function(r){var i=n.component.scales[r],a=t[r];if(!(!i||s.isSignalRefDomain(i.domain)||a&&s.isSignalRefDomain(a.domain))){a?a.domain=p.unionDomains(a.domain,i.domain):t[r]=i;var o=i.name.substr(n.getName("").length),u=e.scaleName(o,!0);n.renameScale(i.name,u),delete n.component.scales[r]}})})},t.prototype.parseMark=function(){this.children.forEach(function(e){e.parseMark()})},t.prototype.parseAxis=function(){var e=this.component.axes={};this.children.forEach(function(t){t.parseAxis(),o.keys(t.component.axes).forEach(function(n){e[n]||(e[n]=t.component.axes[n])})})},t.prototype.parseAxisGroup=function(){return null},t.prototype.parseGridGroup=function(){return null},t.prototype.parseLegend=function(){var e=this.component.legends={};this.children.forEach(function(t){t.parseLegend(),o.keys(t.component.legends).forEach(function(n){e[n]||(e[n]=t.component.legends[n])})})},t.prototype.assembleParentGroupProperties=function(e){return c.applyConfig({},e,a.FILL_STROKE_CONFIG.concat(["clip"]))},t.prototype.assembleSignals=function(e){return[]},t.prototype.assembleSelectionData=function(e){return[]},t.prototype.assembleScales=function(){return this.children.reduce(function(e,t){return e.concat(t.assembleScales())},e.prototype.assembleScales.call(this))},t.prototype.assembleData=function(e){return l.assembleData(this,e),this.children.forEach(function(t){t.assembleData(e)}),e},t.prototype.assembleLayout=function(e){return this.children.forEach(function(t){t.assembleLayout(e)}),f.assembleLayout(this,e)},t.prototype.assembleMarks=function(){return o.flatten(this.children.map(function(e){return e.assembleMarks()}))},t.prototype.channels=function(){return[]},t.prototype.getMapping=function(){return null},t.prototype.isLayer=function(){return!0},t.prototype.compatibleSource=function(e){var t=this.data,n=e.component.data;return!n.source||t&&u.isUrlData(t)&&t.url===n.source.url},t}(d.Model);n.LayerModel=m},{"../config":70,"../data":71,"../mark":79,"../util":88,"../vega.schema":90,"./common":17,"./data/data":20,"./layout":33,"./model":49,"./scale/domain":50,tslib:5}],33:[function(e,t,n){"use strict";function r(e,t){var n=e.component.layout;if(!n.width&&!n.height)return t;var r=v.keys(v.extend(n.width.distinct,n.height.distinct)),i=n.width.formula.concat(n.height.formula).map(function(e){return v.extend({type:"formula"},e)});return[r.length>0?{name:e.dataName(g.LAYOUT),source:e.dataTable(),transform:[{type:"aggregate",fields:r,ops:r.map(function(){return"distinct"})}].concat(i)}:{name:e.dataName(g.LAYOUT),values:[{}],transform:i}]}function i(e){return{width:a(e,m.X),height:a(e,m.Y)}}function a(e,t){return{distinct:d(e,t),formula:[{as:e.channelSizeName(t),expr:o(e,t)}]}}function o(e,t){var n=e.scale(t);if(n&&h.hasDiscreteDomain(n.type)&&n.rangeStep){var r=p(e,t),i=void 0!==n.paddingOuter?n.paddingOuter:n.padding,a="band"===n.type?void 0!==n.paddingInner?n.paddingInner:n.padding:1;return"max("+(r+(a?" - "+a:"")+(i?" + 2*"+i:""))+", 0) * "+n.rangeStep}return(t===m.X?e.width:e.height)+""}function s(e){return{width:u(e,m.COLUMN),height:u(e,m.ROW)}}function u(e,t){var n=e.child.component.layout,r=t===m.ROW?"height":"width",i=n[r],a=v.extend(d(e,t),i.distinct),o=i.formula.concat([{as:e.channelSizeName(t),expr:l(e,t,e.child.channelSizeName(t))}]);return delete n[r],{distinct:a,formula:o}}function l(e,t,n){return e.channelHasField(t)?'(datum["'+n+'"] + '+e.spacing(t)+") * "+p(e,t):'datum["'+n+'"] + '+e.config.scale.facetSpacing}function c(e){return{width:f(e,m.X),height:f(e,m.Y)}}function f(e,t){var n=e.children[0].component.layout,r=t===m.Y?"height":"width",i=n[r],a=i.distinct,o=[{as:e.channelSizeName(t),expr:i.formula[0].expr}];return e.children.forEach(function(e){delete e.component.layout[r]}),{distinct:a,formula:o}}function d(e,t){if(e.channelHasField(t)&&e.hasDiscreteScale(t)){var n=e.scale(t);if(h.hasDiscreteDomain(n.type)&&!(n.domain instanceof Array)){var r=e.field(t),i={};return i[r]=!0,i}}return{}}function p(e,t){var n=e.scale(t);return n.domain instanceof Array?n.domain.length+"":e.field(t,{datum:!0,prefix:"distinct"})}Object.defineProperty(n,"__esModule",{value:!0});var m=e("../channel"),g=e("../data"),h=e("../scale"),v=e("../util");n.assembleLayout=r,n.parseUnitLayout=i,n.unitSizeExpr=o,n.parseFacetLayout=s,n.parseLayerLayout=c,n.cardinalityExpr=p},{"../channel":13,"../data":71,"../scale":80,"../util":88}],34:[function(e,t,n){"use strict";function r(e,t,n,r){var i={},u=n.mark();switch(u){case s.BAR:case s.TICK:case s.TEXT:i.shape={value:"square"};break;case s.CIRCLE:case s.SQUARE:i.shape={ +value:u};break;case s.POINT:case s.LINE:case s.AREA:}var f=n.config,d=n.markDef.filled,p=r===a.COLOR?l.without(s.FILL_STROKE_CONFIG,[d?"fill":"stroke","strokeDash","strokeDashOffset"]):s.FILL_STROKE_CONFIG;p=l.without(p,["strokeDash","strokeDashOffset"]),c.applyMarkConfig(i,n,p),d&&(i.strokeWidth={value:0});var m,g=n.encoding.color;o.isValueDef(g)&&(m={value:g.value}),void 0!==m?d?i.fill=m:i.stroke=m:r!==a.COLOR&&(i[d?"fill":"stroke"]=i[d?"fill":"stroke"]||{value:f.mark.color}),void 0===i.fill&&(void 0!==f.mark.fill?i.fill={value:f.mark.fill}:void 0!==f.mark.stroke&&(i.stroke={value:f.mark.stroke}));var h=n.encoding.shape;return r!==a.SHAPE&&o.isValueDef(h)&&(i.shape={value:h.value}),i=l.extend(i,t||{}),l.keys(i).length>0?i:void 0}function i(e,t,n,r){var i=n.legend(r),a=n.config,o={};return e.type===u.TEMPORAL&&(t=l.extend({text:{signal:c.timeFormatExpression("datum.value",e.timeUnit,i.format,a.legend.shortTimeLabels,a.timeFormat)}},t||{})),o=l.extend(o,t||{}),l.keys(o).length>0?o:void 0}Object.defineProperty(n,"__esModule",{value:!0});var a=e("../../channel"),o=e("../../fielddef"),s=e("../../mark"),u=e("../../type"),l=e("../../util"),c=e("../common");n.symbols=r,n.labels=i},{"../../channel":13,"../../fielddef":75,"../../mark":79,"../../type":87,"../../util":88,"../common":17}],35:[function(e,t,n){"use strict";function r(e){return[s.COLOR,s.SIZE,s.SHAPE,s.OPACITY].reduce(function(t,n){return e.legend(n)&&(t[n]=a(e,n)),t},{})}function i(e,t){switch(t){case s.COLOR:var n=e.scaleName(s.COLOR);return e.markDef.filled?{fill:n}:{stroke:n};case s.SIZE:return{size:e.scaleName(s.SIZE)};case s.SHAPE:return{shape:e.scaleName(s.SHAPE)};case s.OPACITY:return{opacity:e.scaleName(s.OPACITY)}}return null}function a(e,t){var n=e.fieldDef(t),r=e.legend(t),a=i(e,t);l.LEGEND_PROPERTIES.forEach(function(n){var i=o(n,r,t,e);void 0!==i&&(a[n]=i)});var s=r.encode||{};return["labels","legend","title","symbols"].forEach(function(r){var i=f[r]?f[r](n,s[r],e,t):s[r];void 0!==i&&u.keys(i).length>0&&(a.encode=a.encode||{},a.encode[r]={update:i})}),a}function o(e,t,n,r){var i=r.fieldDef(n);switch(e){case"format":return c.numberFormat(i,t.format,r.config,n);case"title":return d.title(t,i,r.config);case"values":return d.values(t);case"type":d.type(t,i,n)}return t[e]}Object.defineProperty(n,"__esModule",{value:!0});var s=e("../../channel"),u=e("../../util"),l=e("../../legend"),c=e("../common"),f=e("./encode"),d=e("./rules");n.parseLegendComponent=r,n.parseLegend=a},{"../../channel":13,"../../legend":77,"../../util":88,"../common":17,"./encode":34,"./rules":36}],36:[function(e,t,n){"use strict";function r(e,t,n){return void 0!==e.title?e.title:u.title(t,n)}function i(e){var t=e.values;return t&&s.isDateTime(t[0])?t.map(function(e){return s.timestamp(e,!0)}):t}function a(e,t,n){return e.type?e.type:n!==o.COLOR||t.bin||t.timeUnit||!c.contains([l.QUANTITATIVE,l.TEMPORAL],t.type)?void 0:"gradient"}Object.defineProperty(n,"__esModule",{value:!0});var o=e("../../channel"),s=e("../../datetime"),u=e("../../fielddef"),l=e("../../type"),c=e("../../util");n.title=r,n.values=i,n.type=a},{"../../channel":13,"../../datetime":72,"../../fielddef":75,"../../type":87,"../../util":88}],37:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("tslib"),i=e("./mixins");n.area={vgMark:"area",role:void 0,encodeEntry:function(e){e.markDef.orient;return r.__assign({},i.pointPosition("x",e,"zeroOrMin"),i.pointPosition("y",e,"zeroOrMin"),i.pointPosition2(e,"zeroOrMin"),i.color(e),i.nonPosition("opacity",e),i.markDefProperties(e.markDef,["orient","interpolate","tension"]))}}},{"./mixins":42,tslib:5}],38:[function(e,t,n){"use strict";function r(e,t){var n=e.config,r=e.markDef.orient,i=e.encoding.size,c=e.encoding.x,p=e.scaleName(s.X),m=e.scale(s.X);if("horizontal"===r)return o.__assign({},f.pointPosition("x",e,"zeroOrMin"),f.pointPosition2(e,"zeroOrMin"));if(u.isFieldDef(c)){if(!i&&l.isBinScale(m.type))return f.binnedPosition("x",e,n.bar.binSpacing);if(m.type===l.ScaleType.BAND)return f.bandPosition("x",e)}return f.centeredBandPosition("x",e,o.__assign({},d.midX(n),{offset:1}),a(p,e.scale(s.X),n))}function i(e,t){var n=e.config,r=e.encoding,i=e.markDef.orient,c=r.size,p=r.y,m=e.scaleName(s.Y),g=e.scale(s.Y);if("vertical"===i)return o.__assign({},f.pointPosition("y",e,"zeroOrMin"),f.pointPosition2(e,"zeroOrMin"));if(u.isFieldDef(p)){if(p.bin&&!c)return f.binnedPosition("y",e,n.bar.binSpacing);if(g.type===l.ScaleType.BAND)return f.bandPosition("y",e)}return f.centeredBandPosition("y",e,d.midY(n),a(m,e.scale(s.Y),n))}function a(e,t,n){if(n.bar.discreteBandSize)return{value:n.bar.discreteBandSize};if(t){if(t.type!==l.ScaleType.POINT)return t.type===l.ScaleType.BAND?d.band(e):{value:n.bar.continuousBandSize};if(null!==t.rangeStep)return{value:t.rangeStep-1};c.warn(c.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL)}return n.scale.rangeStep&&null!==n.scale.rangeStep?{value:n.scale.rangeStep-1}:{value:20}}Object.defineProperty(n,"__esModule",{value:!0});var o=e("tslib"),s=e("../../channel"),u=e("../../fielddef"),l=e("../../scale"),c=e("../../log"),f=e("./mixins"),d=e("./valueref");n.bar={vgMark:"rect",role:"bar",encodeEntry:function(e){var t=e.stack;return o.__assign({},r(e,t),i(e,t),f.color(e),f.nonPosition("opacity",e))}}},{"../../channel":13,"../../fielddef":75,"../../log":78,"../../scale":80,"./mixins":42,"./valueref":48,tslib:5}],39:[function(e,t,n){"use strict";function r(e,t,n,r){var i=l.isMarkDef(e)?e:{type:e},a=i.orient||h.getMarkConfig("orient",i.type,r);return i.orient=s(i.type,t,n,a),void 0!==a&&a!==i.orient&&f.warn(f.message.orientOverridden(i.orient,a)),u.__assign({},i,{filled:o(i.type,r)})}function i(e,t,n,r){var i=h.getMarkConfig("opacity",e,r);if(!t.opacity&&void 0===i){var o=a(e,t,n);void 0!==o&&(t.opacity={value:o})}return t}function a(e,t,n){return!d.contains([l.POINT,l.TICK,l.CIRCLE,l.SQUARE],e)||c.isAggregate(t)&&!c.channelHasField(t,"detail")?e===l.BAR&&!n&&(c.channelHasField(t,"color")||c.channelHasField(t,"detail")||c.channelHasField(t,"size"))?.7:e===l.AREA?.7:void 0:.7}function o(e,t){var n=h.getMarkConfig("filled",e,t);return void 0!==n?n:e!==l.POINT&&e!==l.LINE&&e!==l.RULE}function s(e,t,n,r){switch(e){case l.POINT:case l.CIRCLE:case l.SQUARE:case l.TEXT:case l.RECT:return}var i=t.y&&t.y2,a=t.x&&t.x2;switch(e){case l.TICK:var o=n.x?n.x.type:null,s=n.y?n.y.type:null;return!p.hasDiscreteDomain(o)&&(!t.y||p.hasDiscreteDomain(s)||m.isFieldDef(t.y)&&t.y.bin)?"vertical":"horizontal";case l.RULE:case l.BAR:case l.AREA:if(i)return"vertical";if(a)return"horizontal";if(e===l.RULE){if(t.x&&!t.y)return"vertical";if(t.y&&!t.x)return"horizontal"}case l.LINE:var u=m.isFieldDef(t.x)&&m.isContinuous(t.x),c=m.isFieldDef(t.y)&&m.isContinuous(t.y);if(u&&!c)return"horizontal";if(!u&&c)return"vertical";if(u&&c){var d=t.x,h=t.y,v=d.type===g.TEMPORAL,y=h.type===g.TEMPORAL;return v&&!y?"vertical":!v&&y?"horizontal":!d.aggregate&&h.aggregate?"vertical":d.aggregate&&!h.aggregate?"horizontal":r?r:(e===l.LINE&&t.order||f.warn(f.message.unclearOrientContinuous(e)),"vertical")}return void f.warn(f.message.unclearOrientDiscreteOrEmpty(e))}return"vertical"}Object.defineProperty(n,"__esModule",{value:!0});var u=e("tslib"),l=e("../../mark"),c=e("../../encoding"),f=e("../../log"),d=e("../../util"),p=e("../../scale"),m=e("../../fielddef"),g=e("../../type"),h=e("../common");n.initMarkDef=r,n.initEncoding=i},{"../../encoding":73,"../../fielddef":75,"../../log":78,"../../mark":79,"../../scale":80,"../../type":87,"../../util":88,"../common":17,tslib:5}],40:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("tslib"),i=e("./mixins");n.line={vgMark:"line",role:void 0,encodeEntry:function(e){return r.__assign({},i.pointPosition("x",e,"zeroOrMin"),i.pointPosition("y",e,"zeroOrMin"),i.color(e),i.nonPosition("opacity",e),i.nonPosition("size",e,{vgChannel:"strokeWidth"}),i.markDefProperties(e.markDef,["interpolate","tension"]))}}},{"./mixins":42,tslib:5}],41:[function(e,t,n){"use strict";function r(e){return f.contains([c.LINE,c.AREA],e.mark())?a(e):o(e)}function i(e){var t=e.parent;return t&&t.isFacet()?t.facetedTable():e.stack?e.dataName("stacked"):e.dataTable()}function a(e){var t=e.mark(),n=s(e),r=[{name:e.getName("marks"),type:S[t].vgMark,from:{data:(n.length>0?"faceted-path-":"")+i(e)},encode:{update:S[t].encodeEntry(e)}}];return n.length>0?[{name:e.getName("pathgroup"),type:"group",from:{facet:{name:"faceted-path-"+i(e),data:i(e),groupby:n}},encode:{update:{width:{field:{group:"width"}},height:{field:{group:"height"}}}},marks:r}]:r}function o(e){var t=e.mark(),n=S[t].role,r=[];return r.push(u.__assign({name:e.getName("marks"),type:S[t].vgMark},n?{role:n}:{},{from:{data:i(e)},encode:{update:S[t].encodeEntry(e)}})),r}function s(e){return O.reduce(function(t,n){return e.channelHasField(n)&&!e.fieldDef(n).aggregate&&t.push(e.field(n)),t},[])}Object.defineProperty(n,"__esModule",{value:!0});var u=e("tslib"),l=e("../../channel"),c=e("../../mark"),f=e("../../util"),d=e("./area"),p=e("./bar"),m=e("./line"),g=e("./point"),h=e("./rect"),v=e("./rule"),y=e("./text"),b=e("./tick"),S={area:d.area,bar:p.bar,line:m.line,point:g.point,text:y.text,tick:b.tick,rect:h.rect,rule:v.rule,circle:g.circle,square:g.square};n.parseMark=r;var O=f.without(l.NONSPATIAL_CHANNELS,["order"])},{"../../channel":13,"../../mark":79,"../../util":88,"./area":37,"./bar":38,"./line":40,"./point":43,"./rect":44,"./rule":45,"./text":46,"./tick":47,tslib:5}],42:[function(e,t,n){"use strict";function r(e){var t=e.config,n=e.markDef.filled,r=o("color",e,{vgChannel:n?"fill":"stroke",defaultValue:v.getMarkConfig("color",e.mark(),t)});return!r.fill&&h.contains(["bar","point","circle","square"],e.mark())&&(r.fill={value:"transparent"}),r}function i(e,t){return t.reduce(function(t,n){return e[n]&&(t[n]={value:e[n]}),t},{})}function a(e,t){if(void 0!==t)return n={},n[e]={value:t},n;return;var n}function o(e,t,n){void 0===n&&(n={});var r=n.defaultValue,i=n.vgChannel,a=n.defaultRef||(void 0!==r?{value:r}:void 0),o=t.encoding[e],u=y.midPoint(e,o,t.scaleName(e),t.scale(e),a);return s(t,o&&o.condition,i||e,u)}function s(e,t,n,r){if(t){var i=t.selection,a=t.value;return o={},o[n]=[{test:u(e,i),value:a}].concat(void 0!==r?[r]:[]),o}return void 0!==r?(s={},s[n]=r,s):{};var o,s}function u(e,t){var n="!"===t.charAt(0),r=n?t.slice(1):t;return(n?"!":"")+b.predicate(e.component.selection[r])}function l(e){var t=e.encoding.text;return s(e,t&&t.condition,"text",y.text(t,e.config))}function c(e,t){var n=t.encoding[e],r=t.scaleName(e),i="x"===e?"width":"height";return a={},a[e]=y.fieldRef(n,r,{}),a[i]=y.band(r),a;var a}function f(e,t,n,r){var i="x"===e?"xc":"yc",a="x"===e?"width":"height";return g.__assign({},p(e,t,n,i),o("size",t,{defaultRef:r,vgChannel:a}))}function d(e,t,n){var r=t.encoding[e],i=t.scaleName(e);return"x"===e?{x2:y.bin(r,i,"start",n),x:y.bin(r,i,"end")}:{y2:y.bin(r,i,"start"),y:y.bin(r,i,"end",n)}}function p(e,t,n,r){var i=t.encoding,a=t.stack,o=y.stackable(e,i[e],t.scaleName(e),t.scale(e),a,n);return s={},s[r||e]=o,s;var s}function m(e,t,n){var r=e.encoding,i=e.markDef,a=e.stack;n=n||("horizontal"===i.orient?"x2":"y2");var o="x2"===n?"x":"y",s=y.stackable2(n,r[o],r[n],e.scaleName(o),e.scale(o),a,t);return u={},u[n]=s,u;var u}Object.defineProperty(n,"__esModule",{value:!0});var g=e("tslib"),h=e("../../util"),v=e("../common"),y=e("./valueref"),b=e("../selection/selection");n.color=r,n.markDefProperties=i,n.valueIfDefined=a,n.nonPosition=o,n.text=l,n.bandPosition=c,n.centeredBandPosition=f,n.binnedPosition=d,n.pointPosition=p,n.pointPosition2=m},{"../../util":88,"../common":17,"../selection/selection":58,"./valueref":48,tslib:5}],43:[function(e,t,n){"use strict";function r(e,t){var n=e.config;return a.__assign({},o.pointPosition("x",e,s.midX(n)),o.pointPosition("y",e,s.midY(n)),o.color(e),o.nonPosition("size",e),i(e,n,t),o.nonPosition("opacity",e))}function i(e,t,n){return n?{shape:{value:n}}:o.nonPosition("shape",e,{defaultValue:u.getMarkConfig("shape","point",t)})}Object.defineProperty(n,"__esModule",{value:!0});var a=e("tslib"),o=e("./mixins"),s=e("./valueref"),u=e("../common");n.shapeMixins=i,n.point={vgMark:"symbol",role:"point",encodeEntry:function(e){return r(e)}},n.circle={vgMark:"symbol",role:"circle",encodeEntry:function(e){return r(e,"circle")}},n.square={vgMark:"symbol",role:"square",encodeEntry:function(e){return r(e,"square")}}},{"../common":17,"./mixins":42,"./valueref":48,tslib:5}],44:[function(e,t,n){"use strict";function r(e){var t=e.encoding.x,n=e.encoding.x2,r=e.scale(o.X);if(s.isFieldDef(t)&&t.bin&&!n)return f.binnedPosition("x",e,0);if(r&&u.hasDiscreteDomain(r.type)){if(r.type===u.ScaleType.BAND)return f.bandPosition("x",e);throw new Error(c.message.scaleTypeNotWorkWithMark(l.RECT,r.type))}return a.__assign({},f.pointPosition("x",e,"zeroOrMax"),f.pointPosition2(e,"zeroOrMin","x2"))}function i(e){var t=e.encoding.y,n=e.encoding.y2,r=e.scale(o.Y);if(s.isFieldDef(t)&&t.bin&&!n)return f.binnedPosition("y",e,0);if(r&&u.hasDiscreteDomain(r.type)){if(r.type===u.ScaleType.BAND)return f.bandPosition("y",e);throw new Error(c.message.scaleTypeNotWorkWithMark(l.RECT,r.type))}return a.__assign({},f.pointPosition("y",e,"zeroOrMax"),f.pointPosition2(e,"zeroOrMin","y2"))}Object.defineProperty(n,"__esModule",{value:!0});var a=e("tslib"),o=e("../../channel"),s=e("../../fielddef"),u=e("../../scale"),l=e("../../mark"),c=e("../../log"),f=e("./mixins");n.rect={vgMark:"rect",role:void 0,encodeEntry:function(e){return a.__assign({},r(e),i(e),f.color(e),f.nonPosition("opacity",e))}}},{"../../channel":13,"../../fielddef":75,"../../log":78,"../../mark":79,"../../scale":80,"./mixins":42,tslib:5}],45:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("tslib"),i=e("./mixins");n.rule={vgMark:"rule",role:void 0,encodeEntry:function(e){return r.__assign({},i.pointPosition("x",e,"zeroOrMin"),i.pointPosition("y",e,"zeroOrMin"),i.pointPosition2(e,"zeroOrMax"),i.color(e),i.nonPosition("opacity",e),i.nonPosition("size",e,{vgChannel:"strokeWidth"}))}}},{"./mixins":42,tslib:5}],46:[function(e,t,n){"use strict";function r(e,t){return l.isFieldDef(t)&&t.type===c.QUANTITATIVE?{field:{group:"width"},offset:-5}:{value:e.scale.textXRangeStep/2}}function i(e,t){if(void 0===s.getMarkConfig("align","text",t))return d.channelHasField(e,o.X)?"center":"right"}Object.defineProperty(n,"__esModule",{value:!0});var a=e("tslib"),o=e("../../channel"),s=e("../common"),u=e("./mixins"),l=e("../../fielddef"),c=e("../../type"),f=e("./valueref"),d=e("../../encoding");n.text={vgMark:"text",role:void 0,encodeEntry:function(e){var t=e.config,n=e.encoding,o=n.text;return a.__assign({},u.pointPosition("x",e,r(t,o)),u.pointPosition("y",e,f.midY(t)),u.text(e),u.color(e),u.nonPosition("opacity",e),u.nonPosition("size",e,{vgChannel:"fontSize"}),u.valueIfDefined("align",i(n,t)))}}},{"../../channel":13,"../../encoding":73,"../../fielddef":75,"../../type":87,"../common":17,"./mixins":42,"./valueref":48,tslib:5}],47:[function(e,t,n){"use strict";function r(e){var t=e.config,n=e.markDef.orient,r=(e.scale("horizontal"===n?"x":"y")||{}).rangeStep;if(void 0!==t.tick.bandSize)return t.tick.bandSize;var i=void 0!==r?r:t.scale.rangeStep;if("number"!=typeof i)throw new Error("Function does not handle non-numeric rangeStep");return i/1.5}Object.defineProperty(n,"__esModule",{value:!0});var i=e("tslib"),a=e("./mixins"),o=e("./valueref");n.tick={vgMark:"rect",role:"tick",encodeEntry:function(e){var t=e.config,n=e.markDef,s=n.orient,u="horizontal"===s?"width":"height",l="horizontal"===s?"height":"width";return i.__assign({},a.pointPosition("x",e,o.midX(t),"xc"),a.pointPosition("y",e,o.midY(t),"yc"),a.nonPosition("size",e,{defaultValue:r(e),vgChannel:u}),(c={},c[l]={value:t.tick.thickness},c),a.color(e),a.nonPosition("opacity",e));var c}}},{"./mixins":42,"./valueref":48,tslib:5}],48:[function(e,t,n){"use strict";function r(e,t,n,r,i,a){return t&&i&&e===i.fieldChannel?o(t,n,{suffix:"end"}):l(e,t,n,r,a)}function i(e,t,n,r,i,a,s){return t&&a&&e.charAt(0)===a.fieldChannel.charAt(0)?o(t,r,{suffix:"start"}):l(e,n,r,i,s)}function a(e,t,n,r){return o(e,t,{binSuffix:n},r)}function o(e,t,n,r){var i={scale:t,field:y.field(e,n)};return r&&(i.offset=r),i}function s(e,t){return void 0===t&&(t=!0),{scale:e,band:t}}function u(e,t){return{signal:'(scale("'+t+'", '+y.field(e,{binSuffix:"start",datum:!0})+') + scale("'+t+'", '+y.field(e,{binSuffix:"end",datum:!0})+"))/2"}}function l(e,t,n,r,i){if(t){if(y.isFieldDef(t))return"bin-linear"===r.type?u(t,n):"bin-ordinal"===r.type?o(t,n,{binSuffix:"start"}):b.hasDiscreteDomain(r.type)?"band"===r.type?o(t,n,{binSuffix:"range"},s(n,.5)):o(t,n,{binSuffix:"range"}):o(t,n,{});if(t.value)return{value:t.value};throw new Error("FieldDef without field or value.")}if("zeroOrMin"===i){if(e===v.X||e===v.X2)return p(n,r);if(e===v.Y||e===v.Y2)return g(n,r);throw new Error("Unsupported channel "+e+" for base function")}if("zeroOrMax"===i){if(e===v.X||e===v.X2)return m(n,r);if(e===v.Y||e===v.Y2)return h(n,r);throw new Error("Unsupported channel "+e+" for base function")}return i}function c(e,t){if(e){if(y.isFieldDef(e)){if("quantitative"===e.type){var n=O.numberFormat(e,e.format,t,"text");return{signal:"format("+y.field(e,{datum:!0})+", '"+n+"')"}}return"temporal"===e.type?{signal:O.timeFormatExpression(y.field(e,{datum:!0}),e.timeUnit,e.format,t.text.shortTimeLabels,t.timeFormat)}:{field:e.field}}if(e.value)return{value:e.value}}return{value:t.text.text}}function f(e){if("string"==typeof e.scale.rangeStep)throw new Error("midX can not handle string rangeSteps");return{value:e.scale.rangeStep/2}}function d(e){if("string"==typeof e.scale.rangeStep)throw new Error("midX can not handle string rangeSteps");return{value:e.scale.rangeStep/2}}function p(e,t){return e&&!S.contains([b.ScaleType.LOG,b.ScaleType.TIME,b.ScaleType.UTC],t.type)&&t.zero!==!1?{scale:e,value:0}:{value:0}}function m(e,t){return e&&!S.contains([b.ScaleType.LOG,b.ScaleType.TIME,b.ScaleType.UTC],t.type)&&t.zero!==!1?{scale:e,value:0}:{field:{group:"width"}}}function g(e,t){return e&&!S.contains([b.ScaleType.LOG,b.ScaleType.TIME,b.ScaleType.UTC],t.type)&&t.zero!==!1?{scale:e,value:0}:{field:{group:"height"}}}function h(e,t){return e&&!S.contains([b.ScaleType.LOG,b.ScaleType.TIME,b.ScaleType.UTC],t.type)&&t.zero!==!1?{scale:e,value:0}:{value:0}}Object.defineProperty(n,"__esModule",{value:!0});var v=e("../../channel"),y=e("../../fielddef"),b=e("../../scale"),S=e("../../util"),O=e("../common");n.stackable=r,n.stackable2=i,n.bin=a,n.fieldRef=o,n.band=s,n.midPoint=l,n.text=c,n.midX=f,n.midY=d},{"../../channel":13,"../../fielddef":75,"../../scale":80,"../../util":88,"../common":17}],49:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../log"),i=e("../channel"),a=e("../data"),o=e("../encoding"),s=e("../fielddef"),u=e("../scale"),l=e("../util"),c=function(){function e(){this.nameMap={}}return e.prototype.rename=function(e,t){this.nameMap[e]=t},e.prototype.has=function(e){return void 0!==this.nameMap[e]},e.prototype.get=function(e){for(;this.nameMap[e];)e=this.nameMap[e];return e},e}();n.NameMap=c;var f=function(){function e(e,t,n){this.scales={},this.axes={},this.legends={},this.children=[],this.parent=t,this.name=e.name||n,this.dataNameMap=t?t.dataNameMap:new c,this.scaleNameMap=t?t.scaleNameMap:new c,this.sizeNameMap=t?t.sizeNameMap:new c,this.data=e.data,this.description=e.description,this.padding=e.padding,this.transform=e.transform,e.transform&&void 0===e.transform.filterInvalid&&void 0!==e.transform.filterNull&&(e.transform.filterInvalid=e.transform.filterNull,r.warn(r.message.DEPRECATED_FILTER_NULL)),this.component={data:null,layout:null,mark:null,scales:null,axes:null,axisGroups:null,gridGroups:null,legends:null,selection:null}}return e.prototype.parse=function(){this.parseData(),this.parseLayoutData(),this.parseScale(),this.parseSelection(),this.parseAxis(),this.parseLegend(),this.parseAxisGroup(),this.parseGridGroup(),this.parseMark()},e.prototype.assembleScales=function(){return l.flatten(l.vals(this.component.scales).map(function(e){return[e]}))},e.prototype.assembleAxes=function(){return[].concat.apply([],l.vals(this.component.axes))},e.prototype.assembleLegends=function(){return l.vals(this.component.legends)},e.prototype.assembleGroup=function(){var e={},t=this.assembleSignals(e.signals||[]);t.length>0&&(e.signals=t),e.marks=this.assembleMarks();var n=this.assembleScales();n.length>0&&(e.scales=n);var r=this.assembleAxes();r.length>0&&(e.axes=r);var i=this.assembleLegends();return i.length>0&&(e.legends=i),e},e.prototype.reduceFieldDef=function(e,t,n){return o.reduce(this.getMapping(),function(t,n,r){return s.isFieldDef(n)?e(t,n,r):t},t,n)},e.prototype.forEachFieldDef=function(e,t){o.forEach(this.getMapping(),function(t,n){s.isFieldDef(t)&&e(t,n)},t)},e.prototype.hasDescendantWithFieldOnChannel=function(e){for(var t=0,n=this.children;t1){var a=i.map(function(e){return h.isDataRefDomain(e)?e.data:null});return 1===v.unique(a,function(e){return e}).length&&null!==a[0]?{data:a[0],fields:i.map(function(e){return e.field})}:{fields:i,sort:!0}}return i[0]}Object.defineProperty(n,"__esModule",{value:!0});var c=e("../../log"),f=e("../../aggregate"),d=e("../../data"),p=e("../../datetime"),m=e("../../scale"),g=e("../../sort"),h=e("../../vega.schema"),v=e("../../util");n.initDomain=r,n.parseDomain=i,n.domainSort=o,n.canUseUnaggregatedDomain=s,n.unionDomains=l},{"../../aggregate":10,"../../data":71,"../../datetime":72,"../../log":78,"../../scale":80,"../../sort":82,"../../util":88,"../../vega.schema":90}],51:[function(e,t,n){"use strict";function r(e,t,r,a,u,c){var p=(t||{}).scale||{},m={type:f.default(p.type,e,t,a,void 0!==u,p.rangeStep,r.scale)};return n.NON_TYPE_RANGE_SCALE_PROPERTIES.forEach(function(n){var a=p[n],u=s.scaleTypeSupportProperty(m.type,n),l=s.channelScalePropertyIncompatability(e,n);if(void 0!==a&&(u?l&&o.warn(l):o.warn(o.message.scalePropertyNotWorkWithScaleType(m.type,n,e))),u&&void 0===l){var c=i(a,n,m,e,t,r.scale);void 0!==c&&(m[n]=c)}}),d.extend(m,l.default(e,m.type,t.type,p,r,m.zero,a,u,c))}function i(e,t,n,r,i,o){return"domain"===t?u.initDomain(e,i,n.type,o):void 0!==e?e:a(t,n,r,i,o)}function a(e,t,n,r,i){switch(e){case"nice":return c.nice(t.type,n,r);case"padding":return c.padding(n,t.type,i);case"paddingInner":return c.paddingInner(t.padding,n,i);case"paddingOuter":return c.paddingOuter(t.padding,n,t.type,t.paddingInner,i);case"round":return c.round(n,i);case"zero":return c.zero(t,n,r)}return i[e]}Object.defineProperty(n,"__esModule",{value:!0});var o=e("../../log"),s=e("../../scale"),u=e("./domain"),l=e("./range"),c=e("./rules"),f=e("./type"),d=e("../../util");n.NON_TYPE_RANGE_SCALE_PROPERTIES=["domain","round","clamp","nice","exponent","zero","interpolate","padding","paddingInner","paddingOuter"],n.default=r},{"../../log":78,"../../scale":80,"../../util":88,"./domain":50,"./range":53,"./rules":54,"./type":55}],52:[function(e,t,n){"use strict";function r(e){return e.channels().reduce(function(t,n){var r=i(e,n);return r&&(t[n]=r),t},{})}function i(e,t){if(!e.scale(t))return null;var r=e.scale(t),i=e.sort(t),u={name:e.scaleName(t+"",!0),type:r.type,domain:o.parseDomain(e,t),range:s.parseRange(r)};return n.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES.forEach(function(e){u[e]=r[e]}),i&&"descending"===(a.isSortField(i)?i.order:i)&&(u.reverse=!0),u}Object.defineProperty(n,"__esModule",{value:!0});var a=e("../../sort"),o=e("./domain"),s=e("./range");n.default=r,n.NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES=["round","clamp","nice","exponent","interpolate","zero","padding","paddingInner","paddingOuter"],n.parseScale=i},{"../../sort":82,"./domain":50,"./range":53}],53:[function(e,t,n){"use strict";function r(e){if(e.rangeStep)return{step:e.rangeStep};if(e.scheme){var t=e.scheme;if(f.isExtendedScheme(t)){var n={scheme:t.name};return t.count&&(n.count=t.count),t.extent&&(n.extent=t.extent),n}return{scheme:t}}return e.range}function i(e,t,r,i,u,p,m,g,h){for(var v=!1,y=0,b=n.RANGE_PROPERTIES;y0?Math.min.apply(null,e):t.rangeStep?t.rangeStep:21}Object.defineProperty(n,"__esModule",{value:!0});var l=e("../../log"),c=e("../../channel"),f=e("../../scale"),d=e("../../util");n.parseRange=r,n.RANGE_PROPERTIES=["range","rangeStep","scheme"],n.default=i},{"../../channel":13,"../../log":78,"../../scale":80,"../../util":88}],54:[function(e,t,n){"use strict";function r(e,t,n){return d.contains([c.ScaleType.TIME,c.ScaleType.UTC],e)?f.smallestUnit(n.timeUnit):d.contains([l.X,l.Y],t)}function i(e,t,n){if(d.contains([l.X,l.Y],e)&&t===c.ScaleType.POINT)return n.pointPadding}function a(e,t,n){if(void 0===e)return d.contains([l.X,l.Y],t)?n.bandPaddingInner:void 0}function o(e,t,n,r,i){if(void 0===e)return d.contains([l.X,l.Y],t)&&n===c.ScaleType.BAND?void 0!==i.bandPaddingOuter?i.bandPaddingOuter:r/2:void 0}function s(e,t){if(d.contains(["x","y","row","column"],e))return t.round}function u(e,t,n){return"size"===t&&"quantitative"===n.type||!(e.domain||n.bin||!d.contains([l.X,l.Y],t))}Object.defineProperty(n,"__esModule",{value:!0});var l=e("../../channel"),c=e("../../scale"),f=e("../../timeunit"),d=e("../../util");n.nice=r,n.padding=i,n.paddingInner=a, +n.paddingOuter=o,n.round=s,n.zero=u},{"../../channel":13,"../../scale":80,"../../timeunit":85,"../../util":88}],55:[function(e,t,n){"use strict";function r(e,t,n,r,a,o,l){var c=i(t,n,r,a,o,l);return u.hasScale(t)?void 0!==e?n.bin?(s.warn(s.message.cannotOverrideBinScaleType(t,c)),c):u.supportScaleType(t,e)?e:(s.warn(s.message.scaleTypeNotWorkWithChannel(t,e,c)),c):c:null}function i(e,t,n,r,i,o){if(c.contains(["row","column"],e))return"band";switch(t.type){case"nominal":return"color"===e||"discrete"===u.rangeType(e)?"ordinal":a(e,n,r,i,o);case"ordinal":return"color"===e?"ordinal":"discrete"===u.rangeType(e)?(s.warn(s.message.discreteChannelCannotEncode(e,"ordinal")),"ordinal"):a(e,n,r,i,o);case"temporal":return"color"===e?"sequential":"discrete"===u.rangeType(e)?(s.warn(s.message.discreteChannelCannotEncode(e,"temporal")),"ordinal"):l.isDiscreteByDefault(t.timeUnit)?a(e,n,r,i,o):"time";case"quantitative":return"color"===e?t.bin?"bin-ordinal":"sequential":"discrete"===u.rangeType(e)?(s.warn(s.message.discreteChannelCannotEncode(e,"quantitative")),"ordinal"):t.bin?"bin-linear":"linear"}throw new Error(s.message.invalidFieldType(t.type))}function a(e,t,n,r,i){if(c.contains(["x","y"],e)){if("rect"===t)return"band";if("bar"===t)return o(n,r,i)?"point":"band"}return"point"}function o(e,t,n){return!e&&(void 0!==t?null!==t:!!n.rangeStep)}Object.defineProperty(n,"__esModule",{value:!0});var s=e("../../log"),u=e("../../channel"),l=e("../../timeunit"),c=e("../../util");n.default=r},{"../../channel":13,"../../log":78,"../../timeunit":85,"../../util":88}],56:[function(e,t,n){"use strict";function r(e){var t=null,n=null;return e.project.forEach(function(e,r){e.encoding===s.X?t=r:e.encoding===s.Y&&(n=r)}),{x:t,y:n}}function i(e,t,n){var r=o.channelSignalName(t,n),i=n===s.X?"width":"height",u=n+"(unit)",l=o.invert.bind(null,e,t,n);return{name:r,value:[],on:c.default.has(t)?[]:a(t,function(e,t){return e.push({events:t.between[0],update:l("["+u+", "+u+"]")}),e.push({events:t,update:"["+r+"[0], "+l("clamp("+u+", 0, "+i+")")+"]"}),e})}}function a(e,t){return e.events.reduce(function(e,n){return n.between?t(e,n):(l.warn(n+" is not an ordered event stream for interval selections"),e)},[])}Object.defineProperty(n,"__esModule",{value:!0});var o=e("./selection"),s=e("../../channel"),u=e("../../util"),l=e("../../log"),c=e("./transforms/scales");n.BRUSH="_brush",n.SIZE="_size";var f={predicate:"vlInterval",signals:function(e,t){var r=[],o=[],f=t.name,d=f+n.SIZE;return t.translate&&!c.default.has(t)&&a(t,function(e,t){(t.between[0].filter||(t.between[0].filter=[])).push("!event.item || (event.item && event.item.mark.name !== "+u.stringValue(f+n.BRUSH)+")")}),t.project.forEach(function(n){if(n.encoding!==s.X&&n.encoding!==s.Y)return void l.warn("Interval selections only support x and y encoding channels.");var a=i(e,t,n.encoding);r.push(a),o.push("{field: "+u.stringValue(n.field)+", extent: "+a.name+"}")}),r.push({name:d,value:[],on:a(t,function(e,t){return e.push({events:t.between[0],update:"{x: x(unit), y: y(unit), width: 0, height: 0}"}),e.push({events:t,update:"{x: "+d+".x, y: "+d+".y, width: abs(x(unit) - "+d+".x), height: abs(y(unit) - "+d+".y)}"}),e})},{name:f,update:"["+o.join(", ")+"]"}),r},tupleExpr:function(e,t){return"intervals: "+t.name},modifyExpr:function(e,t){var n=t.name+o.TUPLE;return n+", {unit: "+n+".unit}"},marks:function(e,t,i){var a=t.name,o=r(t),l=o.x,f=o.y;if(c.default.has(t))return i;var d={x:u.extend({},null!==l?{scale:e.scaleName(s.X),signal:a+"["+l+"].extent[0]"}:{value:0}),x2:u.extend({},null!==l?{scale:e.scaleName(s.X),signal:a+"["+l+"].extent[1]"}:{field:{group:"width"}}),y:u.extend({},null!==f?{scale:e.scaleName(s.Y),signal:a+"["+f+"].extent[0]"}:{value:0}),y2:u.extend({},null!==f?{scale:e.scaleName(s.Y),signal:a+"["+f+"].extent[1]"}:{field:{group:"height"}})};return[{name:void 0,type:"rect",encode:{enter:{fill:{value:"#eee"}},update:d}}].concat(i,{name:a+n.BRUSH,type:"rect",encode:{enter:{fill:{value:"transparent"}},update:d}})}};n.default=f,n.projections=r},{"../../channel":13,"../../log":78,"../../util":88,"./selection":58,"./transforms/scales":63}],57:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./selection"),i=e("../../util"),a={predicate:"vlPoint",signals:function(e,t){var n=t.project,r=n.map(function(e){return i.stringValue(e.field)}).join(", "),a=n.map(function(e){return"(item().isVoronoi ? datum.datum : datum)["+i.stringValue(e.field)+"]"}).join(", ");return[{name:t.name,value:{},on:[{events:t.events,update:"{fields: ["+r+"], values: ["+a+"]}"}]}]},tupleExpr:function(e,t){var n=t.name;return"fields: "+n+".fields, values: "+n+".values"},modifyExpr:function(e,t){return t.name+r.TUPLE}};n.default=a},{"../../util":88,"./selection":58}],58:[function(e,t,n){"use strict";function r(e,t){var n={},r=e.config.selection,i=function(i){if(!t.hasOwnProperty(i))return"continue";var a=t[i],o=r[a.type];for(var s in o)"encodings"===s&&a.fields||"fields"===s&&a.encodings||void 0!==a[s]&&a[s]!==!0||(a[s]=o[s]||a[s]);var u=n[i]=p.extend({},a,{name:e.getName(i),events:p.isString(a.on)?g.default(a.on,"scope"):a.on,domain:"data",resolve:"union"});m.forEachTransform(u,function(t){t.parse&&t.parse(e,a,u)})};for(var a in t)i(a);return n}function i(e,t){return l(e,function(r,i){var a=r.name,o=i.tupleExpr(e,r),s=i.modifyExpr(e,r);t.push.apply(t,i.signals(e,r)),m.forEachTransform(r,function(n){n.signals&&(t=n.signals(e,r,t)),n.modifyExpr&&(s=n.modifyExpr(e,r,s))}),t.push({name:a+n.TUPLE,on:[{events:{signal:a},update:"{unit: unit.datum && unit.datum._id, "+o+"}"}]},{name:a+n.MODIFY,on:[{events:{signal:a},update:"modify("+p.stringValue(a+n.STORE)+", "+s+")"}]})}),t}function a(e){var t=[{name:"unit",value:{},on:[{events:"mousemove",update:"group()._id ? group() : unit"}]}];return l(e,function(n,r){r.topLevelSignals&&t.push.apply(t,r.topLevelSignals(e,n)),m.forEachTransform(n,function(r){r.topLevelSignals&&(t=r.topLevelSignals(e,n,t))})}),t}function o(e,t){return t.concat(Object.keys(e.component.selection).map(function(e){return{name:e+n.STORE}}))}function s(e,t){var n=!1,r=t;return l(e,function(i,a){r=a.marks?a.marks(e,i,r):r,m.forEachTransform(i,function(a){n=n||a.clippedGroup,a.marks&&(r=a.marks(e,i,t,r))})}),n&&(r=[{type:"group",encode:{enter:{width:{field:{group:"width"}},height:{field:{group:"height"}},fill:{value:"transparent"},clip:{value:!0}}},marks:r}]),r}function u(e,t){var r=p.stringValue(e.name+n.STORE),i=b[e.resolve];return t=t||"datum",c(e).predicate+"("+r+", parent._id, "+t+", "+i+")"}function l(e,t){var n=e.component.selection;for(var r in n)if(n.hasOwnProperty(r)){var i=n[r];t(i,c(i))}}function c(e){switch(e.type){case"single":return h.default;case"multi":return v.default;case"interval":return y.default}return null}function f(e,t,n,r){var i=p.stringValue(e.scaleName(n));return"data"===t.domain?"invert("+i+", "+r+")":r}function d(e,t){return e.name+"_"+t}Object.defineProperty(n,"__esModule",{value:!0});var p=e("../../util"),m=e("./transforms/transforms"),g=e("vega-parser/src/parsers/event-selector"),h=e("./single"),v=e("./multi"),y=e("./interval");n.STORE="_store",n.TUPLE="_tuple",n.MODIFY="_modify",n.parseUnitSelection=r,n.assembleUnitSignals=i,n.assembleTopLevelSignals=a,n.assembleUnitData=o,n.assembleUnitMarks=s;var b={single:'"intersect", "all"',independent:'"intersect", "unit"',union:'"union", "all"',union_others:'"union", "others"',intersect:'"intersect", "all"',intersect_others:'"intersect", "others'};n.predicate=u,n.invert=f,n.channelSignalName=d},{"../../util":88,"./interval":56,"./multi":57,"./single":59,"./transforms/transforms":65,"vega-parser/src/parsers/event-selector":6}],59:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./selection"),i=e("./multi"),a=e("../../util"),o={predicate:i.default.predicate,signals:i.default.signals,topLevelSignals:function(e,t){var n=t.name;return[{name:n,update:"data("+a.stringValue(n+r.STORE)+")[0]"}]},tupleExpr:function(e,t){var n=t.name,r=n+".values";return"fields: "+n+".fields, values: "+r+", "+t.project.map(function(e,t){return e.field+": "+r+"["+t+"]"}).join(", ")},modifyExpr:function(e,t){return t.name+r.TUPLE+", true"}};n.default=o},{"../../util":88,"./multi":57,"./selection":58}],60:[function(e,t,n){"use strict";function r(e){return"_"+e.replace(/\W/g,"_")}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../../util"),a={has:function(e){return"single"===e.type&&e.bind&&"scales"!==e.bind},topLevelSignals:function(e,t,n){var a=t.name,o=t.project,s=t.bind;return o.forEach(function(e){n.unshift({name:a+r(e.field),value:"",on:[{events:t.events,update:"(item().isVoronoi ? datum.datum : datum)["+i.stringValue(e.field)+"]"}],bind:s[e.field]||s[e.encoding]||s})}),n},signals:function(e,t,n){var a=t.name,o=t.project,s=n.filter(function(e){return e.name===a})[0],u=o.map(function(e){return i.stringValue(e.field)}).join(", "),l=o.map(function(e){return a+r(e.field)}).join(", ");return s.update="{fields: ["+u+"], values: ["+l+"]}",delete s.value,delete s.on,n}};n.default=a},{"../../../util":88}],61:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r={has:function(e){return void 0!==e.nearest&&e.nearest!==!1},marks:function(e,t,n,r){var i=n[0],a=r.indexOf(i),o=i.name===e.getName("pathgroup"),s=function(e){return e.name&&e.name.indexOf("voronoi")>=0},u={name:e.getName("voronoi"),type:"path",from:{data:e.getName("marks")},encode:{enter:{fill:{value:"transparent"},strokeWidth:{value:.35},stroke:{value:"transparent"},isVoronoi:{value:!0}}},transform:[{type:"voronoi",x:"datum.x",y:"datum.y",size:[{signal:"width"},{signal:"height"}]}]};return o&&!i.marks.filter(s).length?(i.marks.push(u),r.splice(a,1,i)):o||r.filter(s).length||r.splice(a+1,0,u),r}};n.default=r},{}],62:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r={has:function(e){return void 0!==e.fields||void 0!==e.encodings},parse:function(e,t,n){var r={};(t.fields||[]).forEach(function(e){return r[e]=null}),(t.encodings||[]).forEach(function(t){return r[e.field(t)]=t});var i=n.project||(n.project=[]);for(var a in r)r.hasOwnProperty(a)&&i.push({field:a,encoding:r[a]})}};n.default=r},{}],63:[function(e,t,n){"use strict";function r(e,t){return"domain("+u.stringValue(e.scaleName(t))+")"}Object.defineProperty(n,"__esModule",{value:!0});var i=e("../../../log"),a=e("../../../scale"),o=e("../selection"),s=e("../interval"),u=e("../../../util"),l={clippedGroup:!0,has:function(e){return"interval"===e.type&&e.bind&&"scales"===e.bind},parse:function(e,t,n){var r=e.component.scales,s=n.scales=[];n.project.forEach(function(e){var t=e.encoding,u=r[t];if(!u||!a.hasContinuousDomain(u.type))return void i.warn("Scale bindings are currently only supported for scales with continuous domains.");u.domainRaw={signal:o.channelSignalName(n,t)},s.push(t)})},topLevelSignals:function(e,t,n){return n.concat(t.scales.map(function(e){return{name:o.channelSignalName(t,e)}}))},signals:function(e,t,n){var r=t.name;return n=n.filter(function(e){return e.name!==r+s.SIZE&&e.name!==r+o.TUPLE&&e.name!==o.MODIFY}),t.scales.forEach(function(e){var t=n.filter(function(t){return t.name===r+"_"+e})[0];t.push="outer",delete t.value,delete t.update}),n}};n.default=l,n.domain=r},{"../../../log":78,"../../../scale":80,"../../../util":88,"../interval":56,"../selection":58}],64:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../selection"),i={has:function(e){return void 0!==e.toggle&&e.toggle!==!1},signals:function(e,t,n){return n.concat({name:t.name+"_toggle",value:!1,on:[{events:t.events,update:t.toggle}]})},modifyExpr:function(e,t,n){var i=t.name+r.TUPLE,a=t.name+"_toggle";return a+" ? null : "+i+", "+a+" ? null : true, "+a+" ? "+i+" : null"}};n.default=i},{"../selection":58}],65:[function(e,t,n){"use strict";function r(e,t){for(var n in f)f[n].has(e)&&t(f[n])}Object.defineProperty(n,"__esModule",{value:!0});var i=e("./project"),a=e("./toggle"),o=e("./translate"),s=e("./zoom"),u=e("./scales"),l=e("./inputs"),c=e("./nearest"),f={project:i.default,toggle:a.default,scales:u.default,translate:o.default,zoom:s.default,inputs:l.default,nearest:c.default};n.forEachTransform=r},{"./inputs":60,"./nearest":61,"./project":62,"./scales":63,"./toggle":64,"./translate":66,"./zoom":67}],66:[function(e,t,n){"use strict";function r(e,t){var n=t===o.X?"+":"-";return u.default.has(e)&&(n="+"===n?"-":"+"),n}function i(e,t,n,i,a){var l=t.name,f=a.filter(function(e){return e.name===l+"_"+n})[0],d=l+"_translate_anchor",p=l+c,m=s.stringValue(e.scaleName(n)),g=".extent_"+n,h=r(t,n),v=h+" abs(span("+d+g+")) * "+p+"."+n+" / "+d+"."+i,y="["+d+g+"[0] "+v+", "+d+g+"[1] "+v+"]",b="invert("+m+(n===o.X?", 0":", unit."+i)+")",S="invert("+m+(n===o.X?", unit."+i:", 0")+")";f.on.push({events:{signal:p},update:u.default.has(t)?y:"clampRange("+y+", "+b+", "+S+")"})}Object.defineProperty(n,"__esModule",{value:!0});var a=e("vega-parser/src/parsers/event-selector"),o=e("../../../channel"),s=e("../../../util"),u=e("./scales"),l=e("../interval"),c="_translate_delta",f={has:function(e){return"interval"===e.type&&void 0!==e.translate&&e.translate!==!1},signals:function(e,t,n){var r=t.name,s=u.default.has(t),f=s?"unit":r+l.SIZE,d=r+"_translate_anchor",p=a.default(t.translate,"scope"),m=l.projections(t),g=m.x,h=m.y;return s||(p=p.map(function(e){return e.between[0].markname=r+l.BRUSH,e})),n.push({name:d,value:{},on:[{events:p.map(function(e){return e.between[0]}),update:"{x: x(unit), y: y(unit), width: "+f+".width, height: "+f+".height, "+(null!==g?"extent_x: "+(s?u.domain(e,o.X):"slice("+r+"_x)")+", ":"")+(null!==h?"extent_y: "+(s?u.domain(e,o.Y):"slice("+r+"_y)")+", ":"")+"}"}]},{name:r+c,value:{},on:[{events:p,update:"{x: x(unit) - "+d+".x, y: y(unit) - "+d+".y}"}]}),null!==g&&i(e,t,o.X,"width",n),null!==h&&i(e,t,o.Y,"height",n),n}};n.default=f},{"../../../channel":13,"../../../util":88,"../interval":56,"./scales":63,"vega-parser/src/parsers/event-selector":6}],67:[function(e,t,n){"use strict";function r(e,t,n,r,i){var u=t.name,l=i.filter(function(e){return e.name===u+"_"+n})[0],c=s.default.has(t),f=c?s.domain(e,n):l.name,d=""+u+"_zoom_anchor."+n,p=u+"_zoom_delta",m=o.stringValue(e.scaleName(n)),g="["+d+" + ("+f+"[0] - "+d+") * "+p+", "+d+" + ("+f+"[1] - "+d+") * "+p+"]",h="invert("+m+(n===a.X?", 0":", unit."+r)+")",v="invert("+m+(n===a.X?", unit."+r:", 0")+")";l.on.push({events:{signal:p},update:c?g:"clampRange("+g+", "+h+", "+v+")"})}Object.defineProperty(n,"__esModule",{value:!0});var i=e("vega-parser/src/parsers/event-selector"),a=e("../../../channel"),o=e("../../../util"),s=e("./scales"),u=e("../interval"),l={has:function(e){return"interval"===e.type&&void 0!==e.zoom&&e.zoom!==!1},signals:function(e,t,n){var l=t.name,c=l+"_zoom_delta",f=i.default(t.zoom,"scope"),d=u.projections(t),p=d.x,m=d.y,g=o.stringValue(e.scaleName(a.X)),h=o.stringValue(e.scaleName(a.Y));s.default.has(t)||(f=f.map(function(e){return e.markname=l+u.BRUSH,e})),n.push({name:l+"_zoom_anchor",on:[{events:f,update:"{x: invert("+g+", x(unit)), y: invert("+h+", y(unit))}"}]},{name:c,on:[{events:f,force:!0,update:"pow(1.001, event.deltaY * pow(16, event.deltaMode))"}]}),null!==p&&r(e,t,"x","width",n),null!==m&&r(e,t,"y","height",n);var v=n.filter(function(e){return e.name===l+u.SIZE});if(v.length){var y=v[0].name;v[0].on.push({events:{signal:c},update:"{x: "+y+".x, y: "+y+".y, width: "+y+".width * "+c+" , height: "+y+".height * "+c+"}"})}return n}};n.default=l},{"../../../channel":13,"../../../util":88,"../interval":56,"./scales":63,"vega-parser/src/parsers/event-selector":6}],68:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("tslib"),i=e("../axis"),a=e("../channel"),o=e("../config"),s=e("../data"),u=e("../encoding"),l=e("../encoding"),c=e("../fielddef"),f=e("../mark"),d=e("../scale"),p=e("../util"),m=e("./axis/parse"),g=e("./common"),h=e("./data/data"),v=e("./legend/parse"),y=e("./layout"),b=e("./model"),S=e("./mark/mark"),O=e("./scale/init"),E=e("./scale/parse"),_=e("../stack"),x=e("./selection/selection"),N=e("./mark/init"),T=function(e){function t(t,n,r){var i=e.call(this,t,n,r)||this;i.selection={},i.scales={},i.axes={},i.legends={},i.children=[];var a=void 0!==t.width?t.width:n?n.width:void 0,o=void 0!==t.height?t.height:n?n.height:void 0,s=f.isMarkDef(t.mark)?t.mark.type:t.mark,l=i.encoding=u.dropInvalidFieldDefs(s,t.encoding||{}),c=i.config=i.initConfig(t.config,n);i.stack=_.stack(s,l,c.stack),i.scales=i.initScales(s,l,c,a,o),i.markDef=N.initMarkDef(t.mark,l,i.scales,c),i.encoding=N.initEncoding(s,l,i.stack,c),i.axes=i.initAxes(l,c),i.legends=i.initLegend(l,c),i.selection=t.selection;var d=i.initSize(s,i.scales,a,o,c.cell,c.scale),p=d.width,m=void 0===p?i.width:p,g=d.height,h=void 0===g?i.height:g;return i.width=m,i.height=h,i}return r.__extends(t,e),t.prototype.initConfig=function(e,t){for(var n=p.mergeDeep(p.duplicate(o.defaultConfig),t?t.config:{},e),r=!1;null!==t;){if(t.isFacet()){r=!0;break}t=t.parent}return r&&(n.cell=p.extend({},n.cell,n.facet.cell)),n},t.prototype.initScales=function(e,t,n,r,i){var o=[];return a.UNIT_SCALE_CHANNELS.reduce(function(s,u){if(l.channelHasField(t,u)||u===a.X&&l.channelHasField(t,a.X2)||u===a.Y&&l.channelHasField(t,a.Y2)){var c=s[u]=O.default(u,t[u],n,e,u===a.X?r:u===a.Y?i:void 0,o);u!==a.X&&u!==a.Y||c.rangeStep&&o.push(c.rangeStep)}return s},{})},t.prototype.initSize=function(e,t,n,r,i,o){if(void 0===n)if(t[a.X])d.hasDiscreteDomain(t[a.X].type)&&t[a.X].rangeStep||(n=i.width);else if(e===f.TEXT)n=o.textXRangeStep;else{if("string"==typeof o.rangeStep)throw new Error("_initSize does not handle string rangeSteps");n=o.rangeStep}if(void 0===r)if(t[a.Y])d.hasDiscreteDomain(t[a.Y].type)&&t[a.Y].rangeStep||(r=i.height);else{if("string"==typeof o.rangeStep)throw new Error("_initSize does not handle string rangeSteps");r=o.rangeStep}return{width:n,height:r}},t.prototype.initAxes=function(e,t){return[a.X,a.Y].reduce(function(n,o){var s=e[o];if(c.isFieldDef(s)||o===a.X&&c.isFieldDef(e.x2)||o===a.Y&&c.isFieldDef(e.y2)){var u=c.isFieldDef(s)?s.axis:null;if(null!==u&&u!==!1){var l={};i.VL_ONLY_AXIS_PROPERTIES.forEach(function(e){void 0!==t.axis[e]&&(l[e]=t.axis[e])}),n[o]=r.__assign({},l,u)}}return n},{})},t.prototype.initLegend=function(e,t){return a.NONSPATIAL_SCALE_CHANNELS.reduce(function(t,n){var i=e[n];if(c.isFieldDef(i)){var a=i.legend;null!==a&&a!==!1&&(t[n]=r.__assign({},a))}return t},{})},t.prototype.parseData=function(){this.component.data=h.parseUnitData(this)},t.prototype.parseSelection=function(){this.component.selection=x.parseUnitSelection(this,this.selection)},t.prototype.parseLayoutData=function(){this.component.layout=y.parseUnitLayout(this)},t.prototype.parseScale=function(){this.component.scales=E.default(this)},t.prototype.parseMark=function(){this.component.mark=S.parseMark(this)},t.prototype.parseAxis=function(){this.component.axes=m.parseAxisComponent(this,[a.X,a.Y])},t.prototype.parseAxisGroup=function(){return null},t.prototype.parseGridGroup=function(){return null},t.prototype.parseLegend=function(){this.component.legends=v.parseLegendComponent(this)},t.prototype.assembleSignals=function(e){return x.assembleUnitSignals(this,e)},t.prototype.assembleSelectionData=function(e){return x.assembleUnitData(this,e)},t.prototype.assembleData=function(e){return h.assembleData(this,e)},t.prototype.assembleLayout=function(e){return y.assembleLayout(this,e)},t.prototype.assembleMarks=function(){return x.assembleUnitMarks(this,this.component.mark)},t.prototype.assembleParentGroupProperties=function(e){return g.applyConfig({},e,f.FILL_STROKE_CONFIG.concat(["clip"]))},t.prototype.channels=function(){return a.UNIT_CHANNELS},t.prototype.getMapping=function(){return this.encoding},t.prototype.toSpec=function(e,t){var n,r=p.duplicate(this.encoding);return n={mark:this.markDef,encoding:r},e||(n.config=p.duplicate(this.config)),t||(n.data=p.duplicate(this.data)),n},t.prototype.mark=function(){return this.markDef.type},t.prototype.channelHasField=function(e){return l.channelHasField(this.encoding,e)},t.prototype.fieldDef=function(e){return this.encoding[e]||{}},t.prototype.field=function(e,t){void 0===t&&(t={});var n=this.fieldDef(e);return n.bin&&(t=p.extend({binSuffix:d.hasDiscreteDomain(this.scale(e).type)?"range":"start"},t)),c.field(n,t)},t.prototype.dataTable=function(){return this.dataName(l.isAggregate(this.encoding)?s.SUMMARY:s.SOURCE)},t.prototype.isUnit=function(){return!0},t}(b.Model);n.UnitModel=T},{"../axis":11,"../channel":13,"../config":70,"../data":71,"../encoding":73,"../fielddef":75,"../mark":79,"../scale":80,"../stack":84,"../util":88,"./axis/parse":15,"./common":17,"./data/data":20,"./layout":33,"./legend/parse":35,"./mark/init":39,"./mark/mark":41,"./model":49,"./scale/init":51,"./scale/parse":52,"./selection/selection":58,tslib:5}],69:[function(e,t,n){"use strict";function r(e,t){u[e]=t}function i(e){delete u[e]}function a(e){var t=s.isMarkDef(e.mark)?e.mark.type:e.mark,n=u[t];if(n)return n(e);throw new Error("Unregistered composite mark "+t)}Object.defineProperty(n,"__esModule",{value:!0});var o=e("tslib"),s=e("./mark");n.ERRORBAR="error-bar";var u={};n.add=r,n.remove=i,n.normalize=a,r(n.ERRORBAR,function(e){var t=(e.mark,e.encoding),n=o.__rest(e,["mark","encoding"]),r=(t.size,o.__rest(t,["size"])),i=(t.x2,t.y2,o.__rest(t,["x2","y2"]));return o.__assign({},n,{layer:[{mark:"rule",encoding:r},{mark:"tick",encoding:i},{mark:"tick",encoding:o.__assign({},i,t.x2?{x:t.x2}:{},t.y2?{y:t.y2}:{})}]})})},{"./mark":79,tslib:5}],70:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("./axis"),i=e("./legend"),a=e("./mark"),o=e("./scale"),s=e("./selection");n.defaultCellConfig={width:200,height:200,fill:"transparent"},n.defaultFacetCellConfig={stroke:"#ccc",strokeWidth:1};var u={color:"#000000",opacity:.4,offset:0};n.defaultFacetConfig={axis:{},grid:u,cell:n.defaultFacetCellConfig},n.defaultOverlayConfig={line:!1,pointStyle:{filled:!0},lineStyle:{}},n.defaultConfig={padding:5,numberFormat:"s",timeFormat:"%b %d, %Y",countTitle:"Number of Records",cell:n.defaultCellConfig,mark:a.defaultMarkConfig,area:{},bar:a.defaultBarConfig,circle:{},line:{},point:{},rect:{},rule:{},square:{},text:a.defaultTextConfig,tick:a.defaultTickConfig,overlay:n.defaultOverlayConfig,scale:o.defaultScaleConfig,axis:r.defaultAxisConfig,legend:i.defaultLegendConfig,facet:n.defaultFacetConfig,selection:s.defaultConfig}},{"./axis":11,"./legend":77,"./mark":79,"./scale":80,"./selection":81}],71:[function(e,t,n){"use strict";function r(e){return!!e.url}function i(e){return!!e.values}function a(e){return!!e.name}Object.defineProperty(n,"__esModule",{value:!0}),n.isUrlData=r,n.isInlineData=i,n.isNamedData=a,n.SUMMARY="summary",n.SOURCE="source",n.STACKED="stacked",n.LAYOUT="layout"},{}],72:[function(e,t,n){"use strict";function r(e){return!!(e&&(e.year||e.quarter||e.month||e.date||e.day||e.hours||e.minutes||e.seconds||e.milliseconds))}function i(e){if(l.isNumber(e))return e>4&&c.warn(c.message.invalidTimeUnit("quarter",e)),e-1+"";throw new Error(c.message.invalidTimeUnit("quarter",e))}function a(e){if(l.isNumber(e))return e-1+"";var t=e.toLowerCase(),r=n.MONTHS.indexOf(t);if(r!==-1)return r+"";var i=t.substr(0,3),a=n.SHORT_MONTHS.indexOf(i);if(a!==-1)return a+"";throw new Error(c.message.invalidTimeUnit("month",e))}function o(e){if(l.isNumber(e))return e%7+"";var t=e.toLowerCase(),r=n.DAYS.indexOf(t);if(r!==-1)return r+"";var i=t.substr(0,3),a=n.SHORT_DAYS.indexOf(i);if(a!==-1)return a+"";throw new Error(c.message.invalidTimeUnit("day",e))}function s(e,t){var n=new Date(0,0,1,0,0,0,0);if(void 0!==e.day)if(l.keys(e).length>1)c.warn(c.message.droppedDay(e)),e=l.duplicate(e),delete e.day;else{n.setFullYear(2006);var r=t?o(e.day):e.day;n.setDate(+r+1)}if(void 0!==e.year&&n.setFullYear(e.year),void 0!==e.quarter){var s=t?i(e.quarter):e.quarter;n.setMonth(3*+s)}if(void 0!==e.month){var u=t?a(e.month):e.month;n.setMonth(+u)}return void 0!==e.date&&n.setDate(e.date),void 0!==e.hours&&n.setHours(e.hours),void 0!==e.minutes&&n.setMinutes(e.minutes),void 0!==e.seconds&&n.setSeconds(e.seconds),void 0!==e.milliseconds&&n.setMilliseconds(e.milliseconds),n.getTime()}function u(e,t){void 0===t&&(t=!1);var n=[];if(t&&void 0!==e.day&&l.keys(e).length>1&&(c.warn(c.message.droppedDay(e)),e=l.duplicate(e),delete e.day),void 0!==e.year?n.push(e.year):void 0!==e.day?n.push(2006):n.push(0),void 0!==e.month){var r=t?a(e.month):e.month;n.push(r)}else if(void 0!==e.quarter){var s=t?i(e.quarter):e.quarter;n.push(s+"*3")}else n.push(0);if(void 0!==e.date)n.push(e.date);else if(void 0!==e.day){var u=t?o(e.day):e.day;n.push(u+"+1")}else n.push(1);for(var f=0,d=["hours","minutes","seconds","milliseconds"];f= "+n;if(null!==o)return t+" <= "+o}}function s(e,t){if(u.isDateTime(e)){var n=u.dateTimeExpr(e,!0);return"time("+n+")"}if(c.isSingleTimeUnit(t)){var r={};r[t]=e;var n=u.dateTimeExpr(r,!0);return"time("+n+")"}return JSON.stringify(e)}Object.defineProperty(n,"__esModule",{value:!0});var u=e("./datetime"),l=e("./fielddef"),c=e("./timeunit"),f=e("./util");n.isEqualFilter=r,n.isRangeFilter=i,n.isOneOfFilter=a,n.expression=o},{"./datetime":72,"./fielddef":75,"./timeunit":85,"./util":88}],77:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.defaultLegendConfig={orient:void 0},n.LEGEND_PROPERTIES=["entryPadding","format","offset","orient","tickCount","title","type","values","zindex"]},{}],78:[function(e,t,n){"use strict";function r(e){e(d=new p),o()}function i(e){return function(){e(d=new p),o()}}function a(e){return d=e}function o(){return d=f}function s(){for(var e=[],t=0;t window:mousemove!",encodings:["x","y"],translate:"[mousedown, window:mouseup] > window:mousemove!",zoom:"wheel"}}},{}],82:[function(e,t,n){"use strict";function r(e){return!!e&&!!e.field&&!!e.op}Object.defineProperty(n,"__esModule",{value:!0}),n.isSortField=r},{}],83:[function(e,t,n){"use strict";function r(e){return void 0!==e.facet}function i(e){if(a(e)){var t=_.channelHasField(e.encoding,A.ROW),n=_.channelHasField(e.encoding,A.COLUMN);return t||n}return!1}function a(e){return!!e.mark}function o(e){return void 0!==e.layer}function s(e){if(r(e))return l(e);if(o(e))return c(e);if(i(e))return f(e);if(a(e))return p(e);throw new Error(x.message.INVALID_SPEC)}function u(e){return o(e)?c(e):p(e)}function l(e){var t=e.spec,n=S.__rest(e,["spec"]);return S.__assign({},n,{spec:u(t)})}function c(e){var t=e.layer,n=S.__rest(e,["layer"]);return S.__assign({},n,{layer:t.map(u)})}function f(e){var t=e.encoding,n=t.row,r=t.column,i=S.__rest(t,["row","column"]),a=e.mark,o=(e.encoding,S.__rest(e,["mark","encoding"]));return S.__assign({},o,{facet:S.__assign({},n?{row:n}:{},r?{column:r}:{}),spec:p({mark:a,encoding:i})})}function d(e){return N.isPrimitiveMark(e.mark)}function p(e){var t=e.config,n=t&&t.overlay,r=n&&e.mark===N.AREA&&M.contains(["linepoint","line"],n.area),i=n&&(n.line&&e.mark===N.LINE||"linepoint"===n.area&&e.mark===N.AREA);return d(e)?_.isRanged(e.encoding)?m(e):i||r?g(e,i,r):e:E.normalize(e)}function m(e){var t=_.channelHasField(e.encoding,A.X),n=_.channelHasField(e.encoding,A.Y),r=_.channelHasField(e.encoding,A.X2),i=_.channelHasField(e.encoding,A.Y2);if(r&&!t||i&&!n){var a=M.duplicate(e);return r&&!t&&(a.encoding.x=a.encoding.x2,delete a.encoding.x2),i&&!n&&(a.encoding.y=a.encoding.y2,delete a.encoding.y2),a}return e}function g(e,t,n){var r=["name","description","data","transform"],i=M.omit(e,r.concat("config")),a=M.duplicate(e.config);delete a.overlay;var o=T.stack(e.mark,e.encoding,e.config?e.config.stack:void 0),s=S.__assign({},M.pick(e,r),{layer:[i]},M.keys(a).length>0?{config:a}:{});if(n){var u=M.duplicate(i);u.mark=N.LINE;var l=M.extend({},O.defaultOverlayConfig.lineStyle,e.config.overlay.lineStyle,o?{stacked:o.offset}:null);M.keys(l).length>0&&(u.config={mark:l}),s.layer.push(u)}if(t){var c=M.duplicate(i);c.mark=N.POINT;var l=M.extend({},O.defaultOverlayConfig.pointStyle,e.config.overlay.pointStyle,o?{stacked:o.offset}:null);M.keys(l).length>0&&(c.config={mark:l}),s.layer.push(c)}return s}function h(e,t){return t.forEach(function(t){var n=["field","type","value","timeUnit","bin","aggregate"].reduce(function(e,n){return void 0!==t[n]&&(e[n]=t[n]),e},{}),r=M.hash(n);e[r]=e[r]||t}),e}function v(e,t){return void 0===t&&(t={}),o(e)?e.layer.forEach(function(e){a(e)?h(t,k.fieldDefs(e.encoding)):v(e,t)}):r(e)?(h(t,k.fieldDefs(e.facet)),v(e.spec,t)):h(t,k.fieldDefs(e.encoding)),t}function y(e){return M.vals(v(e))}function b(e){return!!N.isPrimitiveMark(e.mark)&&null!==T.stack(e.mark,e.encoding,e.config?e.config.stack:void 0)}Object.defineProperty(n,"__esModule",{value:!0});var S=e("tslib"),O=e("./config"),E=e("./compositemark"),_=e("./encoding"),x=e("./log"),N=e("./mark"),T=e("./stack"),A=e("./channel"),k=e("./encoding"),M=e("./util");n.isFacetSpec=r,n.isFacetedUnitSpec=i,n.isUnitSpec=a,n.isLayerSpec=o,n.normalize=s,n.fieldDefs=y,n.isStacked=b},{"./channel":13,"./compositemark":69,"./config":70,"./encoding":73,"./log":78,"./mark":79,"./stack":84,"./util":88,tslib:5}],84:[function(e,t,n){"use strict";function r(e,t,r){var d=l.isMarkDef(e)?e.type:e;if(!f.contains(n.STACKABLE_MARKS,d))return null;if(!s.isAggregate(t))return null;var p=o.STACK_GROUP_CHANNELS.reduce(function(e,n){if(s.channelHasField(t,n)){var r=t[n];(f.isArray(r)?r:[r]).forEach(function(t){u.isFieldDef(t)&&!t.aggregate&&e.push({channel:n,fieldDef:t})})}return e},[]);if(0===p.length)return null;var m=u.isFieldDef(t.x),g=u.isFieldDef(t.y),h=u.isFieldDef(t.x)&&!!t.x.aggregate;if(h!==(u.isFieldDef(t.y)&&!!t.y.aggregate)){var v=h?o.X:o.Y,y=t[v],b=y.aggregate,S=y.scale,O=null;return O=void 0!==y.stack?y.stack:f.contains(n.STACK_BY_DEFAULT_MARKS,d)&&void 0===r?"zero":r,O&&"none"!==O?S&&S.type&&S.type!==c.ScaleType.LINEAR?(i.warn(i.message.cannotStackNonLinearScale(S.type)),null):s.channelHasField(t,v===o.X?o.X2:o.Y2)?(i.warn(i.message.cannotStackRangedMark(v)),null):f.contains(a.SUM_OPS,b)?{groupbyChannel:h?g?o.Y:null:m?o.X:null,fieldChannel:v,stackBy:p,offset:O}:(i.warn(i.message.cannotStackNonSummativeAggregate(b)),null):null}return null}Object.defineProperty(n,"__esModule",{value:!0});var i=e("./log"),a=e("./aggregate"),o=e("./channel"),s=e("./encoding"),u=e("./fielddef"),l=e("./mark"),c=e("./scale"),f=e("./util");n.STACKABLE_MARKS=[l.BAR,l.AREA,l.RULE,l.POINT,l.CIRCLE,l.SQUARE,l.LINE,l.TEXT,l.TICK],n.STACK_BY_DEFAULT_MARKS=[l.BAR,l.AREA],n.stack=r},{"./aggregate":10,"./channel":13,"./encoding":73,"./fielddef":75,"./log":78,"./mark":79,"./scale":80,"./util":88}],85:[function(e,t,n){"use strict";function r(e){return!!g[e]}function i(e,t){var r=new Date(0,0,1,0,0,0,0);return n.SINGLE_TIMEUNITS.forEach(function(n){if(o(e,n))switch(n){case f.DAY:throw new Error("Cannot convert to TimeUnits containing 'day'");case f.YEAR:r.setFullYear(t.getFullYear());break;case f.QUARTER:r.setMonth(3*Math.floor(t.getMonth()/3));break;case f.MONTH:r.setMonth(t.getMonth());break;case f.DATE:r.setDate(t.getDate());break;case f.HOURS:r.setHours(t.getHours());break;case f.MINUTES:r.setMinutes(t.getMinutes());break;case f.SECONDS:r.setSeconds(t.getSeconds());break;case f.MILLISECONDS:r.setMilliseconds(t.getMilliseconds())}}),r}function a(e){return!!h[e]}function o(e,t){var n=e.toString(),r=t.toString(),i=n.indexOf(r);return i>-1&&(t!==f.SECONDS||0===i||"i"!==n.charAt(i-1))}function s(e,t){function r(e){return e===f.QUARTER?"(quarter("+i+")-1)":e+"("+i+")"}var i='datum["'+t+'"]',a=n.SINGLE_TIMEUNITS.reduce(function(t,n){return o(e,n)&&(t[n]=r(n)),t},{});return a.day&&p.keys(a).length>1&&(m.warn(m.message.dayReplacedWithDate(e)),delete a.day,a.date=r(f.DATE)),d.dateTimeExpr(a)}function u(e){if(e)return o(e,f.SECONDS)?"second":o(e,f.MINUTES)?"minute":o(e,f.HOURS)?"hour":o(e,f.DAY)||o(e,f.DATE)?"day":o(e,f.MONTH)?"month":o(e,f.YEAR)?"year":void 0}function l(e,t,n){if(e){var r=[],i="",a=o(e,f.YEAR);o(e,f.QUARTER)&&(i="'Q' + quarter("+t+")"),o(e,f.MONTH)&&r.push(n!==!1?"%b":"%B"),o(e,f.DAY)?r.push(n?"%a":"%A"):o(e,f.DATE)&&r.push("%d"+(a?",":"")),a&&r.push(n?"%y":"%Y");var s=[];o(e,f.HOURS)&&s.push("%H"),o(e,f.MINUTES)&&s.push("%M"),o(e,f.SECONDS)&&s.push("%S"),o(e,f.MILLISECONDS)&&s.push("%L");var u=[];return r.length>0&&u.push(r.join(" ")),s.length>0&&u.push(s.join(":")),u.length>0&&(i&&(i+=" + ' ' + "),i+="timeFormat("+t+", '"+u.join(" ")+"')"),i||void 0}}function c(e){switch(e){case"hours":case"day":case"month":case"quarter":return!0}return!1}Object.defineProperty(n,"__esModule",{value:!0});var f,d=e("./datetime"),p=e("./util"),m=e("./log");!function(e){e.YEAR="year",e.MONTH="month",e.DAY="day",e.DATE="date",e.HOURS="hours",e.MINUTES="minutes",e.SECONDS="seconds",e.MILLISECONDS="milliseconds",e.YEARMONTH="yearmonth",e.YEARMONTHDATE="yearmonthdate",e.YEARMONTHDATEHOURS="yearmonthdatehours",e.YEARMONTHDATEHOURSMINUTES="yearmonthdatehoursminutes",e.YEARMONTHDATEHOURSMINUTESSECONDS="yearmonthdatehoursminutesseconds",e.MONTHDATE="monthdate",e.HOURSMINUTES="hoursminutes",e.HOURSMINUTESSECONDS="hoursminutesseconds",e.MINUTESSECONDS="minutesseconds",e.SECONDSMILLISECONDS="secondsmilliseconds",e.QUARTER="quarter",e.YEARQUARTER="yearquarter",e.QUARTERMONTH="quartermonth",e.YEARQUARTERMONTH="yearquartermonth"}(f=n.TimeUnit||(n.TimeUnit={})),n.SINGLE_TIMEUNITS=[f.YEAR,f.QUARTER,f.MONTH,f.DAY,f.DATE,f.HOURS,f.MINUTES,f.SECONDS,f.MILLISECONDS];var g=n.SINGLE_TIMEUNITS.reduce(function(e,t){return e[t]=!0,e},{});n.isSingleTimeUnit=r,n.convert=i,n.MULTI_TIMEUNITS=[f.YEARQUARTER,f.YEARQUARTERMONTH,f.YEARMONTH,f.YEARMONTHDATE,f.YEARMONTHDATEHOURS,f.YEARMONTHDATEHOURSMINUTES,f.YEARMONTHDATEHOURSMINUTESSECONDS,f.QUARTERMONTH,f.HOURSMINUTES,f.HOURSMINUTESSECONDS,f.MINUTESSECONDS,f.SECONDSMILLISECONDS];var h=n.MULTI_TIMEUNITS.reduce(function(e,t){return e[t]=!0,e},{});n.isMultiTimeUnit=a,n.TIMEUNITS=[f.YEAR,f.QUARTER,f.MONTH,f.DAY,f.DATE,f.HOURS,f.MINUTES,f.SECONDS,f.MILLISECONDS,f.YEARQUARTER,f.YEARQUARTERMONTH,f.YEARMONTH,f.YEARMONTHDATE,f.YEARMONTHDATEHOURS,f.YEARMONTHDATEHOURSMINUTES,f.YEARMONTHDATEHOURSMINUTESSECONDS,f.QUARTERMONTH,f.HOURSMINUTES,f.HOURSMINUTESSECONDS,f.MINUTESSECONDS,f.SECONDSMILLISECONDS],n.containsTimeUnit=o,n.fieldExpr=s,n.smallestUnit=u,n.formatExpression=l,n.isDiscreteByDefault=c},{"./datetime":72,"./log":78,"./util":88}],86:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0})},{}],87:[function(e,t,n){"use strict";function r(e){if(e)switch(e=e.toLowerCase()){case"q":case n.QUANTITATIVE:return"quantitative";case"t":case n.TEMPORAL:return"temporal";case"o":case n.ORDINAL:return"ordinal";case"n":case n.NOMINAL:return"nominal"}}Object.defineProperty(n,"__esModule",{value:!0});var i;!function(e){e.QUANTITATIVE="quantitative",e.ORDINAL="ordinal",e.TEMPORAL="temporal",e.NOMINAL="nominal"}(i=n.Type||(n.Type={})),n.QUANTITATIVE=i.QUANTITATIVE,n.ORDINAL=i.ORDINAL,n.TEMPORAL=i.TEMPORAL,n.NOMINAL=i.NOMINAL,n.getFullName=r},{}],88:[function(e,t,n){"use strict";function r(e,t){var n={};return t.forEach(function(t){e.hasOwnProperty(t)&&(n[t]=e[t])}),n}function i(e,t){var n=y(e);return t.forEach(function(e){delete n[e]}),n}function a(e){return E.isString(e)||E.isNumber(e)||b(e)?String(e):S(e)}function o(e,t){return e.indexOf(t)>-1}function s(e,t){return e.filter(function(e){return!o(t,e)})}function u(e,t){return e.concat(s(t,e))}function l(e,t,n,r){if(e.reduce)return e.reduce.call(r,t,n);for(var i in e)e.hasOwnProperty(i)&&(n=t.call(r,n,e[i],i,e));return n}function c(e,t){for(var n=0,r=0;r= '0' && ch <= '9') {\n string += ch;\n next();\n }\n if (ch === '.') {\n string += '.';\n while (next() && ch >= '0' && ch <= '9') {\n string += ch;\n }\n }\n if (ch === 'e' || ch === 'E') {\n string += ch;\n next();\n if (ch === '-' || ch === '+') {\n string += ch;\n next();\n }\n while (ch >= '0' && ch <= '9') {\n string += ch;\n next();\n }\n }\n number = +string;\n if (!isFinite(number)) {\n error(\"Bad number\");\n } else {\n return number;\n }\n },\n \n string = function () {\n // Parse a string value.\n var hex,\n i,\n string = '',\n uffff;\n \n // When parsing for string values, we must look for \" and \\ characters.\n if (ch === '\"') {\n while (next()) {\n if (ch === '\"') {\n next();\n return string;\n } else if (ch === '\\\\') {\n next();\n if (ch === 'u') {\n uffff = 0;\n for (i = 0; i < 4; i += 1) {\n hex = parseInt(next(), 16);\n if (!isFinite(hex)) {\n break;\n }\n uffff = uffff * 16 + hex;\n }\n string += String.fromCharCode(uffff);\n } else if (typeof escapee[ch] === 'string') {\n string += escapee[ch];\n } else {\n break;\n }\n } else {\n string += ch;\n }\n }\n }\n error(\"Bad string\");\n },\n\n white = function () {\n\n// Skip whitespace.\n\n while (ch && ch <= ' ') {\n next();\n }\n },\n\n word = function () {\n\n// true, false, or null.\n\n switch (ch) {\n case 't':\n next('t');\n next('r');\n next('u');\n next('e');\n return true;\n case 'f':\n next('f');\n next('a');\n next('l');\n next('s');\n next('e');\n return false;\n case 'n':\n next('n');\n next('u');\n next('l');\n next('l');\n return null;\n }\n error(\"Unexpected '\" + ch + \"'\");\n },\n\n value, // Place holder for the value function.\n\n array = function () {\n\n// Parse an array value.\n\n var array = [];\n\n if (ch === '[') {\n next('[');\n white();\n if (ch === ']') {\n next(']');\n return array; // empty array\n }\n while (ch) {\n array.push(value());\n white();\n if (ch === ']') {\n next(']');\n return array;\n }\n next(',');\n white();\n }\n }\n error(\"Bad array\");\n },\n\n object = function () {\n\n// Parse an object value.\n\n var key,\n object = {};\n\n if (ch === '{') {\n next('{');\n white();\n if (ch === '}') {\n next('}');\n return object; // empty object\n }\n while (ch) {\n key = string();\n white();\n next(':');\n if (Object.hasOwnProperty.call(object, key)) {\n error('Duplicate key \"' + key + '\"');\n }\n object[key] = value();\n white();\n if (ch === '}') {\n next('}');\n return object;\n }\n next(',');\n white();\n }\n }\n error(\"Bad object\");\n };\n\nvalue = function () {\n\n// Parse a JSON value. It could be an object, an array, a string, a number,\n// or a word.\n\n white();\n switch (ch) {\n case '{':\n return object();\n case '[':\n return array();\n case '\"':\n return string();\n case '-':\n return number();\n default:\n return ch >= '0' && ch <= '9' ? number() : word();\n }\n};\n\n// Return the json_parse function. It will have access to all of the above\n// functions and variables.\n\nmodule.exports = function (source, reviver) {\n var result;\n \n text = source;\n at = 0;\n ch = ' ';\n result = value();\n white();\n if (ch) {\n error(\"Syntax error\");\n }\n\n // If there is a reviver function, we recursively walk the new structure,\n // passing each name/value pair to the reviver function for possible\n // transformation, starting with a temporary root object that holds the result\n // in an empty key. If there is not a reviver function, we simply return the\n // result.\n\n return typeof reviver === 'function' ? (function walk(holder, key) {\n var k, v, value = holder[key];\n if (value && typeof value === 'object') {\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = walk(value, k);\n if (v !== undefined) {\n value[k] = v;\n } else {\n delete value[k];\n }\n }\n }\n }\n return reviver.call(holder, key, value);\n }({'': result}, '')) : result;\n};\n","var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n gap,\n indent,\n meta = { // table of character substitutions\n '\\b': '\\\\b',\n '\\t': '\\\\t',\n '\\n': '\\\\n',\n '\\f': '\\\\f',\n '\\r': '\\\\r',\n '\"' : '\\\\\"',\n '\\\\': '\\\\\\\\'\n },\n rep;\n\nfunction quote(string) {\n // If the string contains no control characters, no quote characters, and no\n // backslash characters, then we can safely slap some quotes around it.\n // Otherwise we must also replace the offending characters with safe escape\n // sequences.\n \n escapable.lastIndex = 0;\n return escapable.test(string) ? '\"' + string.replace(escapable, function (a) {\n var c = meta[a];\n return typeof c === 'string' ? c :\n '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n }) + '\"' : '\"' + string + '\"';\n}\n\nfunction str(key, holder) {\n // Produce a string from holder[key].\n var i, // The loop counter.\n k, // The member key.\n v, // The member value.\n length,\n mind = gap,\n partial,\n value = holder[key];\n \n // If the value has a toJSON method, call it to obtain a replacement value.\n if (value && typeof value === 'object' &&\n typeof value.toJSON === 'function') {\n value = value.toJSON(key);\n }\n \n // If we were called with a replacer function, then call the replacer to\n // obtain a replacement value.\n if (typeof rep === 'function') {\n value = rep.call(holder, key, value);\n }\n \n // What happens next depends on the value's type.\n switch (typeof value) {\n case 'string':\n return quote(value);\n \n case 'number':\n // JSON numbers must be finite. Encode non-finite numbers as null.\n return isFinite(value) ? String(value) : 'null';\n \n case 'boolean':\n case 'null':\n // If the value is a boolean or null, convert it to a string. Note:\n // typeof null does not produce 'null'. The case is included here in\n // the remote chance that this gets fixed someday.\n return String(value);\n \n case 'object':\n if (!value) return 'null';\n gap += indent;\n partial = [];\n \n // Array.isArray\n if (Object.prototype.toString.apply(value) === '[object Array]') {\n length = value.length;\n for (i = 0; i < length; i += 1) {\n partial[i] = str(i, value) || 'null';\n }\n \n // Join all of the elements together, separated with commas, and\n // wrap them in brackets.\n v = partial.length === 0 ? '[]' : gap ?\n '[\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + ']' :\n '[' + partial.join(',') + ']';\n gap = mind;\n return v;\n }\n \n // If the replacer is an array, use it to select the members to be\n // stringified.\n if (rep && typeof rep === 'object') {\n length = rep.length;\n for (i = 0; i < length; i += 1) {\n k = rep[i];\n if (typeof k === 'string') {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n else {\n // Otherwise, iterate through all of the keys in the object.\n for (k in value) {\n if (Object.prototype.hasOwnProperty.call(value, k)) {\n v = str(k, value);\n if (v) {\n partial.push(quote(k) + (gap ? ': ' : ':') + v);\n }\n }\n }\n }\n \n // Join all of the member texts together, separated with commas,\n // and wrap them in braces.\n\n v = partial.length === 0 ? '{}' : gap ?\n '{\\n' + gap + partial.join(',\\n' + gap) + '\\n' + mind + '}' :\n '{' + partial.join(',') + '}';\n gap = mind;\n return v;\n }\n}\n\nmodule.exports = function (value, replacer, space) {\n var i;\n gap = '';\n indent = '';\n \n // If the space parameter is a number, make an indent string containing that\n // many spaces.\n if (typeof space === 'number') {\n for (i = 0; i < space; i += 1) {\n indent += ' ';\n }\n }\n // If the space parameter is a string, it will be used as the indent string.\n else if (typeof space === 'string') {\n indent = space;\n }\n\n // If there is a replacer, it must be a function or an array.\n // Otherwise, throw an error.\n rep = replacer;\n if (replacer && typeof replacer !== 'function'\n && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {\n throw new Error('JSON.stringify');\n }\n \n // Make a fake root object containing our value under the key of ''.\n // Return the result of stringifying the value.\n return str('', {'': value});\n};\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global global, define, System, Reflect, Promise */\r\nvar __extends;\r\nvar __assign;\r\nvar __rest;\r\nvar __decorate;\r\nvar __param;\r\nvar __metadata;\r\nvar __awaiter;\r\nvar __generator;\r\nvar __exportStar;\r\nvar __values;\r\nvar __read;\r\nvar __spread;\r\nvar __asyncGenerator;\r\nvar __asyncDelegator;\r\nvar __asyncValues;\r\n(function (factory) {\r\n var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\r\n if (typeof define === \"function\" && define.amd) {\r\n define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\r\n }\r\n else if (typeof module === \"object\" && typeof module.exports === \"object\") {\r\n factory(createExporter(root, createExporter(module.exports)));\r\n }\r\n else {\r\n factory(createExporter(root));\r\n }\r\n function createExporter(exports, previous) {\r\n return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\r\n }\r\n})\r\n(function (exporter) {\r\n var extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n\r\n __extends = function (d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n };\r\n\r\n __assign = Object.assign || function (t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n\r\n __rest = function (s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n };\r\n\r\n __decorate = function (decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n };\r\n\r\n __param = function (paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n };\r\n\r\n __metadata = function (metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n };\r\n\r\n __awaiter = function (thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n };\r\n\r\n __generator = function (thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [0, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n };\r\n\r\n __exportStar = function (m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n };\r\n\r\n __values = function (o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n };\r\n\r\n __read = function (o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n };\r\n\r\n __spread = function () {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n };\r\n\r\n __asyncGenerator = function (thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), q = [], c, i;\r\n return i = { next: verb(\"next\"), \"throw\": verb(\"throw\"), \"return\": verb(\"return\") }, i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }\r\n function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }\r\n function step(r) { r.done ? settle(c[2], r) : r.value[0] === \"yield\" ? settle(c[2], { value: r.value[1], done: false }) : Promise.resolve(r.value[1]).then(r.value[0] === \"delegate\" ? delegate : fulfill, reject); }\r\n function delegate(r) { step(r.done ? r : { value: [\"yield\", r.value], done: false }); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { c = void 0, f(v), next(); }\r\n };\r\n\r\n __asyncDelegator = function (o) {\r\n var i = { next: verb(\"next\"), \"throw\": verb(\"throw\", function (e) { throw e; }), \"return\": verb(\"return\", function (v) { return { value: v, done: true }; }) };\r\n return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { return function (v) { return { value: [\"delegate\", (o[n] || f).call(o, v)], done: false }; }; }\r\n };\r\n\r\n __asyncValues = function (o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator];\r\n return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\r\n };\r\n\r\n exporter(\"__extends\", __extends);\r\n exporter(\"__assign\", __assign);\r\n exporter(\"__rest\", __rest);\r\n exporter(\"__decorate\", __decorate);\r\n exporter(\"__param\", __param);\r\n exporter(\"__metadata\", __metadata);\r\n exporter(\"__awaiter\", __awaiter);\r\n exporter(\"__generator\", __generator);\r\n exporter(\"__exportStar\", __exportStar);\r\n exporter(\"__values\", __values);\r\n exporter(\"__read\", __read);\r\n exporter(\"__spread\", __spread);\r\n exporter(\"__asyncGenerator\", __asyncGenerator);\r\n exporter(\"__asyncDelegator\", __asyncDelegator);\r\n exporter(\"__asyncValues\", __asyncValues);\r\n});","import {isMarkType} from './marks/marktypes';\n\n/**\n * Parse an event selector string.\n * Returns an array of event stream definitions.\n */\nexport default function(selector, source) {\n DEFAULT_SOURCE = source || VIEW;\n return parseMerge(selector.trim()).map(parseSelector);\n}\n\nvar VIEW = 'view',\n LBRACK = '[',\n RBRACK = ']',\n LBRACE = '{',\n RBRACE = '}',\n COLON = ':',\n COMMA = ',',\n NAME = '@',\n GT = '>';\n\nvar ILLEGAL = /[\\[\\]\\{\\}]/,\n DEFAULT_SOURCE;\n\nfunction find(s, i, endChar, pushChar, popChar) {\n var count = 0,\n n = s.length,\n c;\n for (; i= 0) --count;\n else if (pushChar && pushChar.indexOf(c) >= 0) ++count;\n }\n return i;\n}\n\nfunction parseMerge(s) {\n var output = [],\n start = 0,\n n = s.length,\n i = 0;\n\n while (i < n) {\n i = find(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE);\n output.push(s.substring(start, i).trim());\n start = ++i;\n }\n\n if (output.length === 0) {\n throw 'Empty event selector: ' + s;\n }\n return output;\n}\n\nfunction parseSelector(s) {\n return s[0] === '['\n ? parseBetween(s)\n : parseStream(s);\n}\n\nfunction parseBetween(s) {\n var start = 1,\n n = s.length,\n i = 1,\n b, stream;\n\n i = find(s, i, RBRACK, LBRACK, RBRACK);\n if (i === n) {\n throw 'Empty between selector: ' + s;\n }\n\n b = parseMerge(s.substring(start, i));\n if (b.length !== 2) {\n throw 'Between selector must have two elements: ' + s;\n }\n\n s = s.slice(i + 1).trim();\n if (s[0] !== GT) {\n throw 'Expected \\'>\\' after between selector: ' + s;\n }\n\n b = b.map(parseSelector);\n\n stream = parseSelector(s.slice(1).trim());\n if (stream.between) {\n return {\n between: b,\n stream: stream\n };\n } else {\n stream.between = b;\n }\n\n return stream;\n}\n\nfunction parseStream(s) {\n var stream = {source: DEFAULT_SOURCE},\n source = [],\n throttle = [0, 0],\n markname = 0,\n start = 0,\n n = s.length,\n i = 0, j,\n filter;\n\n // extract throttle from end\n if (s[n-1] === RBRACE) {\n i = s.lastIndexOf(LBRACE);\n if (i >= 0) {\n try {\n throttle = parseThrottle(s.substring(i+1, n-1));\n } catch (e) {\n throw 'Invalid throttle specification: ' + s;\n }\n s = s.slice(0, i).trim();\n n = s.length;\n } else throw 'Unmatched right brace: ' + s;\n i = 0;\n }\n\n if (!n) throw s;\n\n // set name flag based on first char\n if (s[0] === NAME) markname = ++i;\n\n // extract first part of multi-part stream selector\n j = find(s, i, COLON);\n if (j < n) {\n source.push(s.substring(start, j).trim());\n start = i = ++j;\n }\n\n // extract remaining part of stream selector\n i = find(s, i, LBRACK);\n if (i === n) {\n source.push(s.substring(start, n).trim());\n } else {\n source.push(s.substring(start, i).trim());\n filter = [];\n start = ++i;\n if (start === n) throw 'Unmatched left bracket: ' + s;\n }\n\n // extract filters\n while (i < n) {\n i = find(s, i, RBRACK);\n if (i === n) throw 'Unmatched left bracket: ' + s;\n filter.push(s.substring(start, i).trim());\n if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s;\n start = ++i;\n }\n\n // marshall event stream specification\n if (!(n = source.length) || ILLEGAL.test(source[n-1])) {\n throw 'Invalid event selector: ' + s;\n }\n\n if (n > 1) {\n stream.type = source[1];\n if (markname) {\n stream.markname = source[0].slice(1);\n } else if (isMarkType(source[0])) {\n stream.marktype = source[0];\n } else {\n stream.source = source[0];\n }\n } else {\n stream.type = source[0];\n }\n if (stream.type.slice(-1) === '!') {\n stream.consume = true;\n stream.type = stream.type.slice(0, -1)\n }\n if (filter != null) stream.filter = filter;\n if (throttle[0]) stream.throttle = throttle[0];\n if (throttle[1]) stream.debounce = throttle[1];\n\n return stream;\n}\n\nfunction parseThrottle(s) {\n var a = s.split(COMMA);\n if (!s.length || a.length > 2) throw s;\n return a.map(function(_) {\n var x = +_;\n if (x !== x) throw s;\n return x;\n });\n}\n","import {toSet} from 'vega-util';\n\nexport var ArcMark = 'arc';\nexport var AreaMark = 'area';\nexport var GroupMark = 'group';\nexport var ImageMark = 'image';\nexport var LineMark = 'line';\nexport var PathMark = 'path';\nexport var RectMark = 'rect';\nexport var RuleMark = 'rule';\nexport var ShapeMark = 'shape';\nexport var SymbolMark = 'symbol';\nexport var TextMark = 'text';\n\nexport var marktypes = toSet([\n '*',\n 'arc',\n 'area',\n 'group',\n 'image',\n 'line',\n 'path',\n 'rect',\n 'rule',\n 'shape',\n 'symbol',\n 'text'\n]);\n\nexport function isMarkType(type) {\n return marktypes.hasOwnProperty(type);\n}\n","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (factory((global.vega = global.vega || {})));\n}(this, (function (exports) { 'use strict';\n\nvar accessor = function(fn, fields, name) {\n return (\n fn.fields = fields || [],\n fn.fname = name,\n fn\n );\n}\n\nfunction accessorName(fn) {\n return fn == null ? null : fn.fname;\n}\n\nfunction accessorFields(fn) {\n return fn == null ? null : fn.fields;\n}\n\nvar error = function(message) {\n throw Error(message);\n}\n\nvar splitAccessPath = function(p) {\n var path = [],\n q = null,\n b = 0,\n n = p.length,\n s = '',\n i, j, c;\n\n p = p + '';\n\n function push() {\n path.push(s + p.substring(i, j));\n s = '';\n i = j + 1;\n }\n\n for (i=j=0; j i) ? push() : (i = j + 1);\n else if (c === '[') {\n if (j > i) push();\n b = i = j + 1;\n }\n else if (c === ']') {\n if (!b) error('Access path missing open bracket: ' + p);\n if (b > 0) push();\n b = 0;\n i = j + 1;\n }\n }\n\n if (b) error('Access path missing closing bracket: ' + p);\n if (q) error('Access path missing closing quote: ' + p);\n if (j > i) ++j, push();\n return path;\n}\n\nvar isArray = Array.isArray;\n\nvar isObject = function(_) {\n return _ === Object(_);\n}\n\nvar isString = function(_) {\n return typeof _ === 'string';\n}\n\nfunction $(x) {\n return isArray(x) ? '[' + x.map($) + ']'\n : isObject(x) || isString(x) ?\n // Output valid JSON and JS source strings.\n // See http://timelessrepo.com/json-isnt-a-javascript-subset\n JSON.stringify(x).replace('\\u2028','\\\\u2028').replace('\\u2029', '\\\\u2029')\n : x;\n}\n\nvar field = function(field, name) {\n var path = splitAccessPath(field),\n code = 'return _[' + path.map($).join('][') + '];';\n\n return accessor(\n Function('_', code),\n [(field = path.length===1 ? path[0] : field)],\n name || field\n );\n}\n\nvar empty = [];\n\nvar id = field('id');\n\nvar identity = accessor(function(_) { return _; }, empty, 'identity');\n\nvar zero = accessor(function() { return 0; }, empty, 'zero');\n\nvar one = accessor(function() { return 1; }, empty, 'one');\n\nvar truthy = accessor(function() { return true; }, empty, 'true');\n\nvar falsy = accessor(function() { return false; }, empty, 'false');\n\nfunction log(method, level, input) {\n var args = [level].concat([].slice.call(input));\n console[method].apply(console, args); // eslint-disable-line no-console\n}\n\nvar None = 0;\nvar Warn = 1;\nvar Info = 2;\nvar Debug = 3;\n\nvar logger = function(_) {\n var level = _ || None;\n return {\n level: function(_) {\n return arguments.length ? (level = +_, this) : level;\n },\n warn: function() {\n if (level >= Warn) log('warn', 'WARN', arguments);\n return this;\n },\n info: function() {\n if (level >= Info) log('log', 'INFO', arguments);\n return this;\n },\n debug: function() {\n if (level >= Debug) log('log', 'DEBUG', arguments);\n return this;\n }\n }\n}\n\nvar array = function(_) {\n return _ != null ? (isArray(_) ? _ : [_]) : [];\n}\n\nvar compare = function(fields, orders) {\n var idx = [],\n cmp = (fields = array(fields)).map(function(f, i) {\n return f == null ? null\n : (idx.push(i), splitAccessPath(f).map($).join(']['));\n }),\n n = idx.length - 1,\n ord = array(orders),\n code = 'var u,v;return ',\n i, j, f, u, v, d, lt, gt;\n\n if (n < 0) return null;\n\n for (j=0; j<=n; ++j) {\n i = idx[j];\n f = cmp[i];\n u = '(u=a['+f+'])';\n v = '(v=b['+f+'])';\n d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))';\n lt = ord[i] !== 'descending' ? (gt=1, -1) : (gt=-1, 1);\n code += '(' + u+'<'+v+'||u==null)&&v!=null?' + lt\n + ':(u>v||v==null)&&u!=null?' + gt\n + ':'+d+'!==u&&v===v?' + lt\n + ':v!==v&&u===u?' + gt\n + (i < n ? ':' : ':0');\n }\n\n return accessor(\n Function('a', 'b', code + ';'),\n fields.filter(function(_) { return _ != null; })\n );\n}\n\nvar isFunction = function(_) {\n return typeof _ === 'function';\n}\n\nvar constant = function(_) {\n return isFunction(_) ? _ : function() { return _; };\n}\n\nvar extend = function(_) {\n for (var x, k, i=1, len=arguments.length; i= b) { a = c = b; break; }\n u = v = i;\n while (++i < n) if ((b = array[i]) != null) {\n if (a > b) a = b, u = i;\n if (c < b) c = b, v = i;\n }\n } else {\n while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; }\n u = v = i;\n while (++i < n) if ((b = f(array[i], i, array)) != null) {\n if (a > b) a = b, u = i;\n if (c < b) c = b, v = i;\n }\n }\n\n return [u, v];\n}\n\nvar NULL = {};\n\nvar fastmap = function(input) {\n var obj = {},\n map,\n test;\n\n function has(key) {\n return obj.hasOwnProperty(key) && obj[key] !== NULL;\n }\n\n map = {\n size: 0,\n empty: 0,\n object: obj,\n has: has,\n get: function(key) {\n return has(key) ? obj[key] : undefined;\n },\n set: function(key, value) {\n if (!has(key)) {\n ++map.size;\n if (obj[key] === NULL) --map.empty;\n }\n obj[key] = value;\n return this;\n },\n delete: function(key) {\n if (has(key)) {\n --map.size;\n ++map.empty;\n obj[key] = NULL;\n }\n return this;\n },\n clear: function() {\n map.size = map.empty = 0;\n map.object = obj = {};\n },\n test: function(_) {\n return arguments.length ? (test = _, map) : test;\n },\n clean: function() {\n var next = {},\n size = 0,\n key, value;\n for (key in obj) {\n value = obj[key];\n if (value !== NULL && (!test || !test(value))) {\n next[key] = value;\n ++size;\n }\n }\n map.size = size;\n map.empty = 0;\n map.object = (obj = next);\n }\n };\n\n if (input) Object.keys(input).forEach(function(key) {\n map.set(key, input[key]);\n });\n\n return map;\n}\n\nvar inherits = function(child, parent) {\n var proto = (child.prototype = Object.create(parent.prototype));\n proto.constructor = child;\n return proto;\n}\n\nvar isNumber = function(_) {\n return typeof _ === 'number';\n}\n\nvar key = function(fields) {\n fields = fields ? array(fields) : fields;\n var fn = !(fields && fields.length)\n ? function() { return ''; }\n : Function('_', 'return \\'\\'+' +\n fields.map(function(f) {\n return '_[' + splitAccessPath(f).map($).join('][') + ']';\n }).join('+\\'|\\'+') + ';');\n return accessor(fn, fields, 'key');\n}\n\nvar merge = function(compare, array0, array1, output) {\n var n0 = array0.length,\n n1 = array1.length;\n\n if (!n1) return array0;\n if (!n0) return array1;\n\n var merged = output || new array0.constructor(n0 + n1),\n i0 = 0, i1 = 0, i = 0;\n\n for (; i0 0\n ? array1[i1++]\n : array0[i0++];\n }\n\n for (; i0= 0) s += str;\n return s;\n}\n\nvar pad = function(str, length, padchar, align) {\n var c = padchar || ' ',\n s = str + '',\n n = length - s.length;\n\n return n <= 0 ? s\n : align === 'left' ? repeat(c, n) + s\n : align === 'center' ? repeat(c, ~~(n/2)) + s + repeat(c, Math.ceil(n/2))\n : s + repeat(c, n);\n}\n\nvar peek = function(array) {\n return array[array.length - 1];\n}\n\nvar toSet = function(_) {\n for (var s={}, i=0, n=_.length; i (http://kanitw.yellowpigz.com)\",\n \"Dominik Moritz (https://www.domoritz.de)\",\n \"Jeffrey Heer (http://jheer.org)\"\n ],\n \"homepage\": \"https://vega.github.io/vega-lite/\",\n \"description\": \"Vega-lite provides a higher-level grammar for visual analysis, comparable to ggplot or Tableau, that generates complete Vega specifications.\",\n \"main\": \"build/src/vl.js\",\n \"types\": \"build/src/vl.d.ts\",\n \"bin\": {\n \"vl2png\": \"./bin/vl2png\",\n \"vl2svg\": \"./bin/vl2svg\",\n \"vl2vg\": \"./bin/vl2vg\"\n },\n \"directories\": {\n \"test\": \"test\"\n },\n \"scripts\": {\n \"prebuild\": \"mkdir -p build/site build/examples/images build/test-gallery\",\n \"build\": \"tsc && cp package.json build && browserify src/vl.ts -p tsify -g [ babelify ] -d -s vl | exorcist build/vega-lite.js.map > build/vega-lite.js\",\n \"postbuild\": \"uglifyjs build/vega-lite.js -cm --in-source-map build/vega-lite.js.map --source-map build/vega-lite.min.js.map > build/vega-lite.min.js && npm run schema\",\n \"build:images\": \"npm run data && scripts/generate-images.sh\",\n \"build:toc\": \"bundle exec jekyll build -q && scripts/generate-toc\",\n \"build:site\": \"browserify site/static/main.ts -p [tsify -p site] -d > build/site/main.js\",\n \"build:versions\": \"scripts/update-version.sh\",\n \"build:test-gallery\": \"browserify test-gallery/main.ts -p [tsify -p test-gallery] -d > build/test-gallery/main.js\",\n \"checkschema\": \"scripts/check-schema.sh\",\n \"clean\": \"rm -rf build && rm -f vega-lite.* & find -E src test site examples -regex '.*\\\\.(js|js.map|d.ts)' -delete & rm -rf examples/_diff examples/_original examples/_output examples/images && rm -rf data\",\n \"data\": \"rsync -r node_modules/vega-datasets/data/* data\",\n\n \"deploy\": \"scripts/deploy.sh\",\n \"deploy:gh\": \"scripts/deploy-gh.sh\",\n \"deploy:schema\": \"scripts/deploy-schema.sh\",\n\n \"prestart\": \"npm run data && npm run build && scripts/index-examples\",\n \"start\": \"nodemon -x 'npm run build:test-gallery' & browser-sync start --server --files 'build/test-gallery/main.js' --index 'test-gallery/index.html'\",\n \"poststart\": \"rm examples/all-examples.json\",\n\n \"preschema\": \"npm run prebuild\",\n \"schema\": \"typescript-json-schema --required true --noExtraProps true src/spec.ts ExtendedSpec > build/vega-lite-schema.json\",\n\n \"presite\": \"npm run build && npm run data && npm run build:site && npm run build:toc && npm run build:versions\",\n \"site\": \"bundle exec jekyll serve\",\n\n \"lint\": \"tslint -c tslint.json 'src/**/*.ts' 'test/**/*.ts'\",\n\n \"test\": \"tsc && npm run schema && npm run data && npm run test:nocompile\",\n \"test:nocompile\": \"npm run test:only && npm run lint && npm run mocha:examples\",\n \"test:only\": \"nyc --reporter=html --reporter=text-summary npm run mocha:test\",\n \"test:debug\": \"tsc && npm run schema && npm run data && mocha --recursive --require ./test/babel.ts --debug-brk build/test build/examples\",\n \"mocha:test\": \"mocha --reporter dot --recursive build/test\",\n \"mocha:examples\": \"mocha --require ./test/babel.ts --reporter dot --recursive build/examples\",\n\n \"codecov\": \"nyc report --reporter=json && codecov -f coverage/*.json\",\n \"watch:build\": \"watchify src/vl.ts -p tsify -g [ babelify ] -v -d -s vl -o 'exorcist build/vega-lite.js.map > build/vega-lite.js'\",\n \"watch:test\": \"nodemon -x 'npm test'\",\n \"watch\": \"nodemon -x 'npm run build && npm run test:nocompile' # already ran schema in build\",\n \"x-compile\": \"./scripts/examples-compile.sh\",\n \"x-diff\": \"./scripts/examples-diff.sh\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/vega/vega-lite.git\"\n },\n \"license\": \"BSD-3-Clause\",\n \"bugs\": {\n \"url\": \"https://github.com/vega/vega-lite/issues\"\n },\n \"devDependencies\": {\n \"@types/chai\": \"^3.4.35\",\n \"@types/highlight.js\": \"^9.1.9\",\n \"@types/d3\": \"^4.5.0\",\n \"@types/json-stable-stringify\": \"^1.0.30\",\n \"@types/mocha\": \"^2.2.39\",\n \"@types/node\": \"^7.0.5\",\n \"ajv\": \"5.0.1-beta.1\",\n \"babel-preset-es2015\": \"^6.22.0\",\n \"babelify\": \"^7.3.0\",\n \"browser-sync\": \"~2.18.8\",\n \"browserify\": \"~14.1.0\",\n \"browserify-shim\": \"^3.8.13\",\n \"chai\": \"~3.5.0\",\n \"cheerio\": \"~0.22.0\",\n \"codecov\": \"~1.0.1\",\n \"d3\": \"^4.7.0\",\n \"exorcist\": \"~0.4.0\",\n \"highlight.js\": \"^9.9.0\",\n \"mocha\": \"~3.2.0\",\n \"nodemon\": \"~1.11.0\",\n \"nyc\": \"~10.1.2\",\n \"source-map-support\": \"~0.4.11\",\n \"tsify\": \"~3.0.1\",\n \"tslint\": \"~4.5.1\",\n \"tslint-eslint-rules\": \"^3.4.0\",\n \"typescript\": \"^2.2.1\",\n \"typescript-json-schema\": \"^0.10.0\",\n \"uglify-js\": \"~2.8.4\",\n \"vega\": \"3.0.0-beta.25\",\n \"vega-datasets\": \"vega/vega-datasets#gh-pages\",\n \"vega-embed\": \"3.0.0-beta.5\",\n \"vega-parser\": \"^1.0.0-beta.38\",\n \"watchify\": \"~3.9.0\",\n \"yaml-front-matter\": \"~3.4.0\"\n },\n \"dependencies\": {\n \"json-stable-stringify\": \"~1.0.1\",\n \"tslib\": \"^1.6.0\",\n \"vega-util\": \"~1.1.4\",\n \"yargs\": \"~6.6.0\"\n }\n}\n","\nexport type AggregateOp = 'argmax' | 'argmin' | 'average' | 'count'\n | 'distinct' | 'max' | 'mean' | 'median' | 'min' | 'missing' | 'modeskew'\n | 'q1' | 'q3' | 'stdev' | 'stdevp' | 'sum' | 'valid' | 'values' | 'variance'\n | 'variancep';\n\nexport const AGGREGATE_OPS: AggregateOp[] = [\n 'values',\n 'count',\n 'valid',\n 'missing',\n 'distinct',\n 'sum',\n 'mean',\n 'average',\n 'variance',\n 'variancep',\n 'stdev',\n 'stdevp',\n 'median',\n 'q1',\n 'q3',\n 'modeskew',\n 'min',\n 'max',\n 'argmin',\n 'argmax',\n];\n\n/** Additive-based aggregation operations. These can be applied to stack. */\nexport const SUM_OPS: AggregateOp[] = [\n 'count',\n 'sum',\n 'distinct',\n 'valid',\n 'missing'\n];\n\n/**\n * Aggregation operators that always produce values within the range [domainMin, domainMax].\n */\nexport const SHARED_DOMAIN_OPS: AggregateOp[] = [\n 'mean',\n 'average',\n 'median',\n 'q1',\n 'q3',\n 'min',\n 'max',\n];\n","import {DateTime} from './datetime';\nimport {VgAxisEncode, VgAxisBase, VgAxisConfig} from './vega.schema';\n\nexport type AxisOrient = 'top' | 'right' | 'left' | 'bottom';\n\nexport interface AxisConfig extends VgAxisConfig, VlOnlyAxisBase {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport const defaultAxisConfig: AxisConfig = {\n labelMaxLength: 25,\n};\n\nexport interface Axis extends VgAxisBase, VlOnlyAxisBase {\n /**\n * The padding, in pixels, between axis and text labels.\n */\n labelPadding?: number;\n\n /**\n * The formatting pattern for axis labels.\n */\n format?: string; // default value determined by config.format anyway\n\n /**\n * The orientation of the axis. One of top, bottom, left or right. The orientation can be used to further specialize the axis type (e.g., a y axis oriented for the right edge of the chart).\n */\n orient?: AxisOrient;\n\n /**\n * The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n */\n offset?: number;\n\n /**\n * The anchor position of the axis in pixels. For x-axis with top or bottom orientation, this sets the axis group x coordinate. For y-axis with left or right orientation, this sets the axis group y coordinate.\n *\n * __Default value__: `0`\n */\n position?: number;\n\n /**\n * A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n * @minimum 0\n * @TJS-type integer\n */\n tickCount?: number;\n\n /**\n * A title for the axis. Shows field name and its function by default.\n */\n title?: string;\n\n values?: number[] | DateTime[];\n\n /**\n * A non-positive integer indicating z-index of the axis.\n * If zindex is 0, axes should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n\n /**\n * Optional mark definitions for custom axis encoding.\n */\n encode?: VgAxisEncode;\n}\n\n\n/**\n * Base object for properties that are shared between Axis and Axis Config.\n * These properties are not in Vega Axis and Axis Config.\n */\nexport interface VlOnlyAxisBase {\n /**\n * Truncate labels that are too long.\n * @minimum 1\n * @TJS-type integer\n */\n labelMaxLength?: number;\n}\n\nexport const AXIS_PROPERTIES:(keyof Axis)[] = [\n 'domain', 'format', 'grid', 'labelPadding', 'labels', 'maxExtent', 'minExtent', 'offset', 'orient', 'position', 'tickCount', 'ticks', 'tickSize', 'title', 'titlePadding', 'values', 'zindex'\n];\n\nexport const VL_ONLY_AXIS_PROPERTIES:(keyof VlOnlyAxisBase)[] = ['labelMaxLength'];\n","import {Channel, ROW, COLUMN, SHAPE, SIZE} from './channel';\n\n/**\n * Binning properties or boolean flag for determining whether to bin data or not.\n */\nexport interface Bin {\n /**\n * A two-element (`[min, max]`) array indicating the range of desired bin values.\n * @minItems 2\n * @maxItems 2\n */\n extent?: number[];\n\n /**\n * The number base to use for automatic bin determination (default is base 10).\n */\n base?: number;\n /**\n * An exact step size to use between bins. If provided, options such as maxbins will be ignored.\n */\n step?: number;\n /**\n * An array of allowable step sizes to choose from.\n * @minItems 1\n */\n steps?: number[];\n /**\n * A minimum allowable step size (particularly useful for integer values).\n */\n minstep?: number;\n /**\n * Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n * @minItems 1\n */\n divide?: number[];\n /**\n * Maximum number of bins.\n * @minimum 2\n */\n maxbins?: number;\n}\n\nexport function autoMaxBins(channel: Channel): number {\n switch (channel) {\n case ROW:\n case COLUMN:\n case SIZE:\n // Facets and Size shouldn't have too many bins\n // We choose 6 like shape to simplify the rule\n case SHAPE:\n return 6; // Vega's \"shape\" has 6 distinct values\n default:\n return 10;\n }\n}\n","/*\n * Constants and utilities for encoding channels (Visual variables)\n * such as 'x', 'y', 'color'.\n */\n\nimport {Encoding} from './encoding';\nimport {Facet} from './facet';\nimport {Mark} from './mark';\nimport {RangeType} from './compile/scale/type';\nimport {ScaleType, SCALE_TYPES} from './scale';\nimport {contains, toSet, without} from './util';\n\nexport namespace Channel {\n // Facet\n export const ROW: 'row' = 'row';\n export const COLUMN: 'column' = 'column';\n\n // Position\n export const X: 'x' = 'x';\n export const Y: 'y' = 'y';\n export const X2: 'x2' = 'x2';\n export const Y2: 'y2' = 'y2';\n\n // Mark property with scale\n export const COLOR: 'color' = 'color';\n export const SHAPE: 'shape' = 'shape';\n export const SIZE: 'size' = 'size';\n export const OPACITY: 'opacity' = 'opacity';\n\n // Non-scale channel\n export const TEXT: 'text' = 'text';\n export const ORDER: 'order' = 'order';\n export const DETAIL: 'detail' = 'detail';\n}\n\nexport type Channel = keyof Encoding | keyof Facet;\n\nexport const X = Channel.X;\nexport const Y = Channel.Y;\nexport const X2 = Channel.X2;\nexport const Y2 = Channel.Y2;\nexport const ROW = Channel.ROW;\nexport const COLUMN = Channel.COLUMN;\nexport const SHAPE = Channel.SHAPE;\nexport const SIZE = Channel.SIZE;\nexport const COLOR = Channel.COLOR;\nexport const TEXT = Channel.TEXT;\nexport const DETAIL = Channel.DETAIL;\nexport const ORDER = Channel.ORDER;\nexport const OPACITY = Channel.OPACITY;\n\n\nexport const CHANNELS = [X, Y, X2, Y2, ROW, COLUMN, SIZE, SHAPE, COLOR, ORDER, OPACITY, TEXT, DETAIL];\n\n// CHANNELS without COLUMN, ROW\nexport const UNIT_CHANNELS = [X, Y, X2, Y2, SIZE, SHAPE, COLOR, ORDER, OPACITY, TEXT, DETAIL];\n\n// UNIT_CHANNELS without X2, Y2, ORDER, DETAIL, TEXT\nexport const UNIT_SCALE_CHANNELS = [X, Y, SIZE, SHAPE, COLOR, OPACITY];\n\n// UNIT_SCALE_CHANNELS with ROW, COLUMN\nexport const SCALE_CHANNELS = [X, Y, SIZE, SHAPE, COLOR, OPACITY, ROW, COLUMN];\n\n// UNIT_CHANNELS without X, Y, X2, Y2;\nexport const NONSPATIAL_CHANNELS = [SIZE, SHAPE, COLOR, ORDER, OPACITY, TEXT, DETAIL];\n\n// UNIT_SCALE_CHANNELS without X, Y;\nexport const NONSPATIAL_SCALE_CHANNELS = [SIZE, SHAPE, COLOR, OPACITY];\n\n/** Channels that can serve as groupings for stacked charts. */\nexport const STACK_GROUP_CHANNELS = [COLOR, DETAIL, ORDER, OPACITY, SIZE];\n\nexport interface SupportedMark {\n point?: boolean;\n tick?: boolean;\n rule?: boolean;\n circle?: boolean;\n square?: boolean;\n bar?: boolean;\n rect?: boolean;\n line?: boolean;\n area?: boolean;\n text?: boolean;\n};\n\n/**\n * Return whether a channel supports a particular mark type.\n * @param channel channel name\n * @param mark the mark type\n * @return whether the mark supports the channel\n */\nexport function supportMark(channel: Channel, mark: Mark) {\n return mark in getSupportedMark(channel);\n}\n\n/**\n * Return a dictionary showing whether a channel supports mark type.\n * @param channel\n * @return A dictionary mapping mark types to boolean values.\n */\nexport function getSupportedMark(channel: Channel): SupportedMark {\n switch (channel) {\n case X:\n case Y:\n case COLOR:\n case DETAIL:\n case ORDER: // TODO: revise (order might not support rect, which is not stackable?)\n case OPACITY:\n case ROW:\n case COLUMN:\n return { // all marks\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, rect: true, line: true, area: true, text: true\n };\n case X2:\n case Y2:\n return {\n rule: true, bar: true, rect: true, area: true\n };\n case SIZE:\n return {\n point: true, tick: true, rule: true, circle: true, square: true,\n bar: true, text: true, line: true\n };\n case SHAPE:\n return {point: true};\n case TEXT:\n return {text: true};\n }\n return {};\n}\n\nexport function hasScale(channel: Channel) {\n return !contains([DETAIL, TEXT, ORDER], channel);\n}\n\n// Position does not work with ordinal (lookup) scale and sequential (which is only for color)\nconst POSITION_SCALE_TYPE_INDEX = toSet(without(SCALE_TYPES, ['ordinal', 'sequential'] as ScaleType[]));\n\nexport function supportScaleType(channel: Channel, scaleType: ScaleType): boolean {\n switch (channel) {\n case ROW:\n case COLUMN:\n return scaleType === 'band'; // row / column currently supports band only\n case X:\n case Y:\n case SIZE: // TODO: size and opacity can support ordinal with more modification\n case OPACITY:\n // Although it generally doesn't make sense to use band with size and opacity,\n // it can also work since we use band: 0.5 to get midpoint.\n return scaleType in POSITION_SCALE_TYPE_INDEX;\n case COLOR:\n return scaleType !== 'band'; // band does not make sense with color\n case SHAPE:\n return scaleType === 'ordinal'; // shape = lookup only\n }\n /* istanbul ignore next: it should never reach here */\n return false;\n}\n\nexport function rangeType(channel: Channel): RangeType {\n switch (channel) {\n case X:\n case Y:\n case SIZE:\n case OPACITY:\n return 'continuous';\n\n case ROW:\n case COLUMN:\n case SHAPE:\n return 'discrete';\n\n // Color can be either continuous or discrete, depending on scale type.\n case COLOR:\n return 'flexible';\n\n // No scale, no range type.\n case X2:\n case Y2:\n case DETAIL:\n case TEXT:\n case ORDER:\n return undefined;\n }\n /* istanbul ignore next: should never reach here. */\n throw new Error('getSupportedRole not implemented for ' + channel);\n}\n","import {COLUMN, X, Channel} from '../../channel';\nimport {NOMINAL, ORDINAL, TEMPORAL} from '../../type';\nimport {contains, keys, extend} from '../../util';\nimport {VgAxis} from '../../vega.schema';\n\nimport {timeFormatExpression} from '../common';\nimport {Model} from '../model';\n\nexport function labels(model: Model, channel: Channel, labelsSpec: any, def: VgAxis) {\n const fieldDef = model.fieldDef(channel);\n const axis = model.axis(channel);\n const config = model.config;\n\n // Text\n if (contains([NOMINAL, ORDINAL], fieldDef.type) && axis.labelMaxLength) {\n // TODO replace this with Vega's labelMaxLength once it is introduced\n labelsSpec = extend({\n text: {\n signal: `truncate(datum.value, ${axis.labelMaxLength})`\n }\n }, labelsSpec || {});\n } else if (fieldDef.type === TEMPORAL) {\n labelsSpec = extend({\n text: {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, axis.format, config.axis.shortTimeLabels, config.timeFormat)\n }\n }, labelsSpec);\n }\n\n // Label Angle\n if (axis.labelAngle !== undefined) {\n labelsSpec.angle = {value: axis.labelAngle};\n } else {\n // auto rotate for X\n if (channel === X && (contains([NOMINAL, ORDINAL], fieldDef.type) || !!fieldDef.bin || fieldDef.type === TEMPORAL)) {\n labelsSpec.angle = {value: 270};\n }\n }\n\n // Auto set align if rotated\n // TODO: consider other value besides 270, 90\n if (labelsSpec.angle) {\n if (labelsSpec.angle.value === 270) {\n labelsSpec.align = {\n value: def.orient === 'top' ? 'left':\n (channel === X || channel === COLUMN) ? 'right' :\n 'center'\n };\n } else if (labelsSpec.angle.value === 90) {\n labelsSpec.align = {value: 'center'};\n }\n }\n\n if (labelsSpec.angle) {\n // Auto set baseline if rotated\n // TODO: consider other value besides 270, 90\n if (labelsSpec.angle.value === 270) {\n labelsSpec.baseline = {value: (channel === X || channel === COLUMN) ? 'middle' : 'bottom'};\n } else if (labelsSpec.angle.value === 90) {\n labelsSpec.baseline = {value: 'bottom'};\n }\n }\n\n return keys(labelsSpec).length === 0 ? undefined : labelsSpec;\n}\n","import {Axis, AXIS_PROPERTIES} from '../../axis';\nimport {Channel} from '../../channel';\nimport {VgAxis} from '../../vega.schema';\n\nimport * as encode from './encode';\nimport * as rules from './rules';\n\nimport {Model} from '../model';\nimport {Dict, keys, some} from '../../util';\n\ntype AxisPart = 'domain' | 'grid' | 'labels' | 'ticks' | 'title';\nconst AXIS_PARTS: AxisPart[] = ['domain', 'grid', 'labels', 'ticks', 'title'];\n\nexport function parseAxisComponent(model: Model, axisChannels: Channel[]): Dict {\n return axisChannels.reduce(function(axis, channel) {\n const vgAxes: VgAxis[] = [];\n if (model.axis(channel)) {\n const main = parseMainAxis(channel, model);\n if (main && isVisibleAxis(main)) {\n vgAxes.push(main);\n }\n\n const grid = parseGridAxis(channel, model);\n if (grid && isVisibleAxis(grid)) {\n vgAxes.push(grid);\n }\n\n if (vgAxes.length > 0) {\n axis[channel] = vgAxes;\n }\n }\n return axis;\n }, {});\n}\n\nfunction isFalseOrNull(v: boolean | null) {\n return v === false || v === null;\n}\n\n/**\n * Return if an axis is visible (shows at least one part of the axis).\n */\nfunction isVisibleAxis(axis: VgAxis) {\n return some(AXIS_PARTS, (part) => hasAxisPart(axis, part));\n}\n\nfunction hasAxisPart(axis: VgAxis, part: AxisPart) {\n // FIXME this method can be wrong if users use a Vega theme.\n // (Not sure how to correctly handle that yet.).\n\n if (part === 'grid' || part === 'title') {\n return !!axis[part];\n }\n // Other parts are enabled by default, so they should not be false or null.\n return !isFalseOrNull(axis[part]);\n}\n\n/**\n * Make an inner axis for showing grid for shared axis.\n */\nexport function parseGridAxis(channel: Channel, model: Model): VgAxis {\n // FIXME: support adding ticks for grid axis that are inner axes of faceted plots.\n return parseAxis(channel, model, true);\n}\n\nexport function parseMainAxis(channel: Channel, model: Model) {\n return parseAxis(channel, model, false);\n}\n\nfunction parseAxis(channel: Channel, model: Model, isGridAxis: boolean): VgAxis {\n const axis = model.axis(channel);\n\n let vgAxis: VgAxis = {\n scale: model.scaleName(channel)\n };\n\n // 1.2. Add properties\n AXIS_PROPERTIES.forEach(function(property) {\n const value = getSpecifiedOrDefaultValue(property, axis, channel, model, isGridAxis);\n if (value !== undefined) {\n vgAxis[property] = value;\n }\n });\n\n // Special case for gridScale since gridScale is not a Vega-Lite Axis property.\n const gridScale = getSpecifiedOrDefaultValue('gridScale', axis, channel, model, isGridAxis);\n if (gridScale !== undefined) {\n vgAxis.gridScale = gridScale;\n }\n\n // 2) Add guide encode definition groups\n\n const encodeSpec = axis.encode || {};\n AXIS_PARTS.forEach(function(part) {\n if (!hasAxisPart(vgAxis, part)) {\n // No need to create encode for a disabled part.\n return;\n }\n // TODO(@yuhanlu): instead of calling encode[part], break this line based on part type\n // as different require different parameters.\n let value;\n if (part === 'labels') {\n value = encode.labels(model, channel, encodeSpec.labels || {}, vgAxis);\n } else {\n value = encodeSpec[part] || {};\n }\n\n if (value !== undefined && keys(value).length > 0) {\n vgAxis.encode = vgAxis.encode || {};\n vgAxis.encode[part] = {update: value};\n }\n });\n\n return vgAxis;\n}\n\nfunction getSpecifiedOrDefaultValue(property: keyof VgAxis, specifiedAxis: Axis, channel: Channel, model: Model, isGridAxis: boolean) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'labels':\n return isGridAxis ? false : specifiedAxis[property];\n case 'domain':\n return rules.domain(property, specifiedAxis, isGridAxis, channel);\n case 'ticks':\n return rules.ticks(property, specifiedAxis, isGridAxis, channel);\n case 'format':\n return rules.format(specifiedAxis, channel, fieldDef, model.config);\n case 'grid':\n return rules.grid(model, channel, isGridAxis); // FIXME: refactor this\n case 'gridScale':\n return rules.gridScale(model, channel, isGridAxis);\n case 'orient':\n return rules.orient(specifiedAxis, channel);\n case 'tickCount':\n return rules.tickCount(specifiedAxis, channel, fieldDef); // TODO: scaleType\n case 'title':\n return rules.title(specifiedAxis, fieldDef, model.config, isGridAxis);\n case 'values':\n return rules.values(specifiedAxis);\n case 'zindex':\n return rules.zindex(specifiedAxis, isGridAxis);\n }\n // Otherwise, return specified property.\n return specifiedAxis[property];\n}\n","import * as log from '../../log';\n\nimport {Axis} from '../../axis';\nimport {VgAxis} from '../../vega.schema';\nimport {COLUMN, ROW, X, Y, Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {DateTime, isDateTime, timestamp} from '../../datetime';\nimport {title as fieldDefTitle, FieldDef} from '../../fielddef';\nimport {truncate} from '../../util';\n\nimport {numberFormat} from '../common';\nimport {Model} from '../model';\n\nexport function format(specifiedAxis: Axis, channel: Channel, fieldDef: FieldDef, config: Config) {\n return numberFormat(fieldDef, specifiedAxis.format, config, channel);\n}\n\n// TODO: we need to refactor this method after we take care of config refactoring\n/**\n * Default rules for whether to show a grid should be shown for a channel.\n * If `grid` is unspecified, the default value is `true` for ordinal scales that are not binned\n */\nexport function gridShow(model: Model, channel: Channel) {\n const grid = model.axis(channel).grid;\n if (grid !== undefined) {\n return grid;\n }\n\n return !model.hasDiscreteScale(channel) && !model.fieldDef(channel).bin;\n}\n\nexport function grid(model: Model, channel: Channel, isGridAxis: boolean) {\n if (channel === ROW || channel === COLUMN) {\n // never apply grid for ROW and COLUMN since we manually create rule-group for them\n return false;\n }\n\n if (!isGridAxis) {\n return undefined;\n }\n\n return gridShow(model, channel);\n}\n\nexport function gridScale(model: Model, channel: Channel, isGridAxis: boolean) {\n if (isGridAxis) {\n const gridChannel: Channel = channel === 'x' ? 'y' : 'x';\n if (model.scale(gridChannel)) {\n return model.scaleName(gridChannel);\n }\n }\n return undefined;\n}\n\nexport function orient(specifiedAxis: Axis, channel: Channel) {\n const orient = specifiedAxis.orient;\n if (orient) {\n return orient;\n }\n\n switch (channel) {\n case COLUMN:\n // FIXME test and decide\n return 'top';\n case X:\n return 'bottom';\n case ROW:\n case Y:\n return 'left';\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVALID_CHANNEL_FOR_AXIS);\n}\n\nexport function tickCount(specifiedAxis: Axis, channel: Channel, fieldDef: FieldDef) {\n const count = specifiedAxis.tickCount;\n if (count !== undefined) {\n return count;\n }\n\n // FIXME depends on scale type too\n if (channel === X && !fieldDef.bin) {\n // Vega's default tickCount often lead to a lot of label occlusion on X without 90 degree rotation\n return 5;\n }\n\n return undefined;\n}\n\nexport function title(specifiedAxis: Axis, fieldDef: FieldDef, config: Config, isGridAxis: boolean) {\n if (isGridAxis) {\n return undefined;\n }\n if (specifiedAxis.title !== undefined) {\n return specifiedAxis.title;\n }\n\n // if not defined, automatically determine axis title from field def\n const fieldTitle = fieldDefTitle(fieldDef, config);\n\n let maxLength: number = specifiedAxis.titleMaxLength;\n return maxLength ? truncate(fieldTitle, maxLength) : fieldTitle;\n}\n\nexport function values(specifiedAxis: Axis) {\n const vals = specifiedAxis.values;\n if (specifiedAxis.values && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return timestamp(dt, true);\n });\n }\n return vals;\n}\n\nexport function zindex(specifiedAxis: Axis, isGridAxis: boolean) {\n const z = specifiedAxis.zindex;\n if (z !== undefined) {\n return z;\n }\n if (isGridAxis) {\n // if grid is true, need to put layer on the back so that grid is behind marks\n return 0;\n }\n return 1; // otherwise return undefined and use Vega's default.\n};\n\nexport function domainAndTicks(property: keyof VgAxis, specifiedAxis: Axis, isGridAxis: boolean, channel: Channel) {\n if (isGridAxis || channel === ROW || channel === COLUMN) {\n return false;\n }\n return specifiedAxis[property];\n}\n\nexport const domain = domainAndTicks;\nexport const ticks = domainAndTicks;\n","import * as log from '../log';\n\nimport {TEXT, Channel} from '../channel';\nimport {Config, CellConfig} from '../config';\nimport {FieldDef, OrderFieldDef, field} from '../fielddef';\nimport {Mark, MarkConfig, TextConfig} from '../mark';\nimport {TimeUnit} from '../timeunit';\nimport {QUANTITATIVE} from '../type';\nimport {isArray} from '../util';\n\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {formatExpression} from '../timeunit';\nimport {UnitModel} from './unit';\nimport {Spec, isUnitSpec, isFacetSpec, isLayerSpec} from '../spec';\nimport {VgEncodeEntry, VgSort} from '../vega.schema';\n\nexport function buildModel(spec: Spec, parent: Model, parentGivenName: string): Model {\n if (isFacetSpec(spec)) {\n return new FacetModel(spec, parent, parentGivenName);\n }\n\n if (isLayerSpec(spec)) {\n return new LayerModel(spec, parent, parentGivenName);\n }\n\n if (isUnitSpec(spec)) {\n return new UnitModel(spec, parent, parentGivenName);\n }\n\n throw new Error(log.message.INVALID_SPEC);\n}\n\nexport function applyConfig(e: VgEncodeEntry,\n config: CellConfig | MarkConfig | TextConfig, // TODO(#1842): consolidate MarkConfig | TextConfig?\n propsList: string[]) {\n propsList.forEach((property) => {\n const value = config[property];\n if (value !== undefined) {\n e[property] = {value: value};\n }\n });\n return e;\n}\n\nexport function applyMarkConfig(e: VgEncodeEntry, model: UnitModel, propsList: (keyof MarkConfig)[]) {\n propsList.forEach((property) => {\n const value = getMarkConfig(property, model.mark(), model.config);\n if (value !== undefined) {\n e[property] = {value: value};\n }\n });\n return e;\n}\n\n/**\n * Return value mark specific config property if exists.\n * Otherwise, return general mark specific config.\n */\nexport function getMarkConfig

(prop: P, mark: Mark, config: Config): MarkConfig[P] {\n const markSpecificConfig = config[mark];\n if (markSpecificConfig[prop] !== undefined) {\n return markSpecificConfig[prop];\n }\n return config.mark[prop];\n}\n\n/**\n * Returns number format for a fieldDef\n *\n * @param format explicitly specified format\n */\nexport function numberFormat(fieldDef: FieldDef, format: string, config: Config, channel: Channel) {\n if (fieldDef.type === QUANTITATIVE) {\n // add number format for quantitative type only\n\n if (format) {\n return format;\n } else if (fieldDef.aggregate === 'count' && channel === TEXT) {\n // FIXME: need a more holistic way to deal with this.\n return 'd';\n }\n // TODO: need to make this work correctly for numeric ordinal / nominal type\n return config.numberFormat;\n }\n return undefined;\n}\n\n/**\n * Returns the time expression used for axis/legend labels or text mark for a temporal field\n */\nexport function timeFormatExpression(field: string, timeUnit: TimeUnit, format: string, shortTimeLabels: boolean, timeFormatConfig: string): string {\n if (!timeUnit || format) {\n // If there is not time unit, or if user explicitly specify format for axis/legend/text.\n const _format = format || timeFormatConfig; // only use config.timeFormat if there is no timeUnit.\n return `timeFormat(${field}, '${_format}')`;\n } else {\n return formatExpression(timeUnit, field, shortTimeLabels);\n }\n}\n\n/**\n * Return Vega sort parameters (tuple of field and order).\n */\nexport function sortParams(orderDef: OrderFieldDef | OrderFieldDef[]): VgSort {\n return (isArray(orderDef) ? orderDef : [orderDef]).reduce((s, orderChannelDef) => {\n s.field.push(field(orderChannelDef, {binSuffix: 'start'}));\n s.order.push(orderChannelDef.sort || 'ascending');\n return s;\n }, {field:[], order: []});\n}\n","/**\n * Module for compiling Vega-lite spec into Vega spec.\n */\n\nimport {LAYOUT} from '../data';\nimport * as log from '../log';\nimport {Model} from './model';\nimport {normalize, ExtendedSpec} from '../spec';\nimport {extend} from '../util';\nimport {assembleTopLevelSignals} from './selection/selection';\nimport {buildModel} from './common';\n\nexport function compile(inputSpec: ExtendedSpec, logger?: log.LoggerInterface) {\n if (logger) {\n // set the singleton logger to the provided logger\n log.set(logger);\n }\n\n try {\n // 1. Convert input spec into a normal form\n // (Decompose all extended unit specs into composition of unit spec.)\n const spec = normalize(inputSpec);\n\n // 2. Instantiate the model with default properties\n const model = buildModel(spec, null, '');\n\n // 3. Parse each part of the model to produce components that will be assembled later\n // We traverse the whole tree to parse once for each type of components\n // (e.g., data, layout, mark, scale).\n // Please see inside model.parse() for order for compilation.\n model.parse();\n\n // 4. Assemble a Vega Spec from the parsed components in 3.\n return assemble(model);\n } finally {\n // Reset the singleton logger if a logger is provided\n if (logger) {\n log.reset();\n }\n }\n}\n\nfunction assemble(model: Model) {\n // TODO: change type to become VgSpec\n const output = extend(\n {\n $schema: 'http://vega.github.io/schema/vega/v3.0.json',\n },\n topLevelBasicProperties(model),\n {\n // Map calculated layout width and height to width and height signals.\n signals: [\n {\n name: 'width',\n update: \"data('layout')[0].width\"\n },\n {\n name: 'height',\n update: \"data('layout')[0].height\"\n }\n ].concat(assembleTopLevelSignals(model))\n },{\n data: [].concat(\n model.assembleData([]),\n model.assembleLayout([]),\n model.assembleSelectionData([])\n ),\n marks: [assembleRootGroup(model)]\n });\n\n return {\n spec: output\n // TODO: add warning / errors here\n };\n}\n\nexport function topLevelBasicProperties(model: Model) {\n const config = model.config;\n return extend(\n // TODO: Add other top-level basic properties (#1778)\n {padding: model.padding || config.padding},\n {autosize: 'pad'},\n config.viewport ? {viewport: config.viewport} : {},\n config.background ? {background: config.background} : {}\n );\n}\n\nexport function assembleRootGroup(model: Model) {\n let rootGroup:any = extend(\n {\n name: model.getName('main'),\n type: 'group',\n },\n model.description ? {description: model.description} : {},\n {\n from: {data: model.getName(LAYOUT +'')},\n encode: {\n update: extend(\n {\n width: {field: model.getName('width')},\n height: {field: model.getName('height')}\n },\n model.assembleParentGroupProperties(model.config.cell)\n )\n }\n });\n\n return extend(rootGroup, model.assembleGroup());\n}\n","import {DataComponentCompiler} from './base';\n\nimport {autoMaxBins} from '../../bin';\nimport {Channel} from '../../channel';\nimport {field, FieldDef} from '../../fielddef';\nimport {extend, vals, flatten, hash, Dict} from '../../util';\nimport {VgTransform} from '../../vega.schema';\nimport {hasDiscreteDomain} from '../../scale';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\n\nfunction numberFormatExpr(expr: string, format: string) {\n return `format(${expr}, '${format}')`;\n}\n\nfunction parse(model: Model): Dict {\n return model.reduceFieldDef(function(binComponent: Dict, fieldDef: FieldDef, channel: Channel) {\n const bin = model.fieldDef(channel).bin;\n if (bin) {\n\n let binTrans: VgTransform = extend({\n type: 'bin',\n field: fieldDef.field,\n as: [field(fieldDef, {binSuffix: 'start'}), field(fieldDef, {binSuffix: 'end'})],\n signal: model.getName(fieldDef.field + '_bins')\n },\n // if bin is an object, load parameter here!\n typeof bin === 'boolean' ? {} : bin\n );\n\n const transform: VgTransform[] = [];\n if (!binTrans.extent) {\n const extentSignal = model.getName(fieldDef.field + '_extent');\n transform.push({\n type: 'extent',\n field: fieldDef.field,\n signal: extentSignal\n });\n\n binTrans.extent = {signal: extentSignal};\n }\n\n if (!binTrans.maxbins && !binTrans.step) {\n // if both maxbins and step are not specified, need to automatically determine bin\n binTrans.maxbins = autoMaxBins(channel);\n }\n\n transform.push(binTrans);\n\n const discreteDomain = hasDiscreteDomain(model.scale(channel).type);\n if (discreteDomain) {\n // read format from axis or legend, if there is no format then use config.numberFormat\n const format = (model.axis(channel) || model.legend(channel) || {}).format ||\n model.config.numberFormat;\n\n const startField = field(fieldDef, {datum: true, binSuffix: 'start'});\n const endField = field(fieldDef, {datum: true, binSuffix: 'end'});\n\n transform.push({\n type: 'formula',\n as: field(fieldDef, {binSuffix: 'range'}),\n expr: `${numberFormatExpr(startField, format)} + ' - ' + ${numberFormatExpr(endField, format)}`\n });\n }\n // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color\n const key = hash(bin) + '_' + fieldDef.field + 'oc:' + discreteDomain;\n binComponent[key] = transform;\n }\n return binComponent;\n }, {});\n}\n\nexport const bin: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n let binComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n // FIXME: current merging logic can produce redundant transforms when a field is binned for color and for non-color\n extend(binComponent, childDataComponent.bin);\n delete childDataComponent.bin;\n }\n return binComponent;\n },\n\n parseLayer: function (model: LayerModel) {\n let binComponent = parse(model);\n\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(binComponent, childDataComponent.bin);\n delete childDataComponent.bin;\n }\n });\n\n return binComponent;\n },\n\n assemble: function (component: Dict) {\n return flatten(vals(component));\n }\n};\n","import {SOURCE} from '../../data';\nimport {FieldDef} from '../../fielddef';\nimport {Formula} from '../../transform';\nimport {Dict, StringSet} from '../../util';\nimport {VgData, VgSort, VgTransform} from '../../vega.schema';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\nimport {UnitModel} from './../unit';\n\nimport {source} from './source';\nimport {formatParse} from './formatparse';\nimport {nullFilter} from './nullfilter';\nimport {filter} from './filter';\nimport {bin} from './bin';\nimport {formula} from './formula';\nimport {pathOrder} from './pathorder';\nimport {nonPositiveFilter} from './nonpositivefilter';\nimport {summary} from './summary';\nimport {stack, StackComponent} from './stack';\nimport {timeUnit} from './timeunit';\n\n/**\n * Composable component instance of a model's data.\n */\nexport interface DataComponent {\n source: VgData;\n\n /** Mapping from field name to primitive data type. */\n formatParse: Dict;\n\n /** String set of fields for null filtering */\n nullFilter: Dict;\n\n /** Hashset of a formula object */\n calculate: Dict;\n\n /** Filter test expression */\n filter: string;\n\n /** Dictionary mapping a bin parameter hash to transforms of the binned field */\n bin: Dict;\n\n /** Dictionary mapping an output field name (hash) to the time unit transform */\n timeUnit: Dict;\n\n /** String set of fields to be filtered */\n nonPositiveFilter: Dict;\n\n /** Sort order to apply at the end */\n pathOrder: VgSort;\n\n /**\n * Stack transforms to be applied.\n */\n stack: StackComponent;\n\n /** Array of summary component object for producing summary (aggregate) data source */\n summary: SummaryComponent[];\n}\n\n/**\n * Composable component for a model's summary data\n */\nexport interface SummaryComponent {\n /** Name of the summary data source */\n name: string;\n\n /** String set for all dimension fields */\n dimensions: StringSet;\n\n /** dictionary mapping field name to string set of aggregate ops */\n measures: Dict;\n}\n\n// TODO: split this file into multiple files and remove this linter flag\n/* tslint:disable:no-use-before-declare */\n\nexport function parseUnitData(model: UnitModel): DataComponent {\n return {\n formatParse: formatParse.parseUnit(model),\n nullFilter: nullFilter.parseUnit(model),\n filter: filter.parseUnit(model),\n nonPositiveFilter: nonPositiveFilter.parseUnit(model),\n pathOrder: pathOrder.parseUnit(model),\n\n source: source.parseUnit(model),\n bin: bin.parseUnit(model),\n calculate: formula.parseUnit(model),\n timeUnit: timeUnit.parseUnit(model),\n summary: summary.parseUnit(model),\n stack: stack.parseUnit(model)\n };\n}\n\nexport function parseFacetData(model: FacetModel): DataComponent {\n return {\n formatParse: formatParse.parseFacet(model),\n nullFilter: nullFilter.parseFacet(model),\n filter: filter.parseFacet(model),\n nonPositiveFilter: nonPositiveFilter.parseFacet(model),\n pathOrder: pathOrder.parseFacet(model),\n\n source: source.parseFacet(model),\n bin: bin.parseFacet(model),\n calculate: formula.parseFacet(model),\n timeUnit: timeUnit.parseFacet(model),\n summary: summary.parseFacet(model),\n stack: stack.parseFacet(model)\n };\n}\n\nexport function parseLayerData(model: LayerModel): DataComponent {\n return {\n // filter and formatParse could cause us to not be able to merge into parent\n // so let's parse them first\n filter: filter.parseLayer(model),\n formatParse: formatParse.parseLayer(model),\n nullFilter: nullFilter.parseLayer(model),\n nonPositiveFilter: nonPositiveFilter.parseLayer(model),\n pathOrder: pathOrder.parseLayer(model),\n\n // everything after here does not affect whether we can merge child data into parent or not\n source: source.parseLayer(model),\n bin: bin.parseLayer(model),\n calculate: formula.parseLayer(model),\n timeUnit: timeUnit.parseLayer(model),\n summary: summary.parseLayer(model),\n stack: stack.parseLayer(model)\n };\n}\n\n/* tslint:enable:no-use-before-declare */\n\n/**\n * Creates Vega Data array from a given compiled model and append all of them to the given array\n *\n * @param model\n * @param data array\n * @return modified data array\n */\nexport function assembleData(model: Model, data: VgData[]) {\n const dataComponent = model.component.data;\n\n const sourceData = source.assemble(dataComponent);\n if (sourceData) {\n data.push(sourceData);\n }\n\n summary.assemble(dataComponent.summary || [], model.dataName(SOURCE)).forEach(function(summaryData) {\n data.push(summaryData);\n });\n\n // nonPositiveFilter\n const nonPositiveFilterTransform = nonPositiveFilter.assemble(dataComponent.nonPositiveFilter);\n if (nonPositiveFilterTransform.length > 0) {\n if (data.length > 0) {\n const dataTable = data[data.length - 1];\n dataTable.transform = (dataTable.transform || []).concat(nonPositiveFilterTransform);\n } else { /* istanbul ignore else: should never reach here */\n throw new Error('Invalid nonPositiveFilter not merged');\n }\n }\n\n // stack\n const stackData = stack.assemble(dataComponent.stack);\n if (stackData) {\n data.push(stackData);\n }\n\n // Path Order\n const pathOrderCollectTransform = pathOrder.assemble(dataComponent.pathOrder);\n if (pathOrderCollectTransform) {\n const dataTable = data[data.length - 1];\n if (data.length > 0) {\n dataTable.transform = (dataTable.transform || []).concat([pathOrderCollectTransform]);\n } else { /* istanbul ignore else: should never reach here */\n throw new Error('Invalid path order collect transform not added');\n }\n }\n\n return data;\n}\n","import {DataComponentCompiler} from './base';\n\nimport {expression} from '../../filter';\nimport {isArray} from '../../util';\n\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {Model} from '../model';\n\n/**\n * @param v value to be converted into Vega Expression\n * @param timeUnit\n * @return Vega Expression of the value v. This could be one of:\n * - a timestamp value of datetime object\n * - a timestamp value of casted single time unit value\n * - stringified value\n */\n\nfunction parse(model: Model): string {\n const filter = model.filter();\n if (isArray(filter)) {\n return '(' +\n filter.map((f) => expression(f))\n .filter((f) => f !==undefined)\n .join(') && (') +\n ')';\n } else if (filter) {\n return expression(filter);\n }\n return undefined;\n}\n\nexport const filter: DataComponentCompiler = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n let filterComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source but has filter, then merge\n if (!childDataComponent.source && childDataComponent.filter) {\n // merge by adding &&\n filterComponent =\n (filterComponent ? filterComponent + ' && ' : '') +\n childDataComponent.filter;\n delete childDataComponent.filter;\n }\n return filterComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n // Note that this `filter.parseLayer` method is called before `source.parseLayer`\n let filterComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && childDataComponent.filter && childDataComponent.filter === filterComponent) {\n // same filter in child so we can just delete it\n delete childDataComponent.filter;\n }\n });\n return filterComponent;\n },\n\n assemble: function(filterComponent: string) {\n return filterComponent ? [{\n type: 'filter',\n expr: filterComponent\n }] : [];\n }\n};\n","import {DataComponentCompiler} from './base';\n\nimport {isDateTime, DateTime} from '../../datetime';\nimport {isUrlData} from '../../data';\nimport {FieldDef, isCount} from '../../fielddef';\nimport {isOneOfFilter, isEqualFilter, isRangeFilter} from '../../filter';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {extend, differ, keys, isArray, isNumber, isString, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nfunction parse(model: Model): Dict {\n const calcFieldMap = (model.calculate() || []).reduce(function(fieldMap, formula) {\n fieldMap[formula.as] = true;\n return fieldMap;\n }, {});\n\n let parseComponent: Dict = {};\n\n // Parse filter fields\n let filter = model.filter();\n if (!isArray(filter)) {\n filter = [filter];\n }\n filter.forEach(f => {\n let val: string | number | boolean | DateTime = null;\n // For EqualFilter, just use the equal property.\n // For RangeFilter and OneOfFilter, all array members should have\n // the same type, so we only use the first one.\n if (isEqualFilter(f)) {\n val = f.equal;\n } else if (isRangeFilter(f)) {\n val = f.range[0];\n } else if (isOneOfFilter(f)) {\n val = (f.oneOf || f['in'])[0];\n } // else -- for filter expression, we can't infer anything\n\n if (!!val) {\n if (isDateTime(val)) {\n parseComponent[f['field']] = 'date';\n } else if (isNumber(val)) {\n parseComponent[f['field']] = 'number';\n } else if (isString(val)) {\n parseComponent[f['field']] = 'string';\n }\n }\n });\n\n // Parse encoded fields\n model.forEachFieldDef(function(fieldDef: FieldDef) {\n if (fieldDef.type === TEMPORAL) {\n parseComponent[fieldDef.field] = 'date';\n } else if (fieldDef.type === QUANTITATIVE) {\n if (isCount(fieldDef) || calcFieldMap[fieldDef.field]) {\n return;\n }\n parseComponent[fieldDef.field] = 'number';\n }\n });\n\n // Custom parse should override inferred parse\n const data = model.data;\n if (data && isUrlData(data) && data.format && data.format.parse) {\n const parse = data.format.parse;\n keys(parse).forEach((field) => {\n parseComponent[field] = parse[field];\n });\n }\n\n return parseComponent;\n}\n\nexport const formatParse: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n let parseComponent = parse(model);\n\n // If child doesn't have its own data source, but has its own parse, then merge\n const childDataComponent = model.child.component.data;\n if (!childDataComponent.source && childDataComponent.formatParse) {\n extend(parseComponent, childDataComponent.formatParse);\n delete childDataComponent.formatParse;\n }\n return parseComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n let parseComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && !differ(childDataComponent.formatParse, parseComponent)) {\n // merge parse up if the child does not have an incompatible parse\n extend(parseComponent, childDataComponent.formatParse);\n delete childDataComponent.formatParse;\n }\n });\n return parseComponent;\n },\n\n // identity function\n assemble: function (x) {return x;}\n};\n","import {DataComponentCompiler} from './base';\n\nimport {Formula} from '../../transform';\nimport {extend, vals, hash, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nfunction parse(model: Model): Dict {\n return (model.calculate() || []).reduce(function(formulaComponent, formula) {\n formulaComponent[hash(formula)] = formula;\n return formulaComponent;\n }, {});\n}\n\nexport const formula: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel): Dict {\n let formulaComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(formulaComponent, childDataComponent.calculate);\n delete childDataComponent.calculate;\n }\n return formulaComponent;\n },\n\n parseLayer: function(model: LayerModel): Dict {\n let formulaComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (!childDataComponent.source && childDataComponent.calculate) {\n extend(formulaComponent || {}, childDataComponent.calculate);\n delete childDataComponent.calculate;\n }\n });\n return formulaComponent;\n },\n\n assemble: function(component: Dict) {\n return vals(component).reduce(function(transform: any, f: any) {\n transform.push(extend({type: 'formula'}, f));\n return transform;\n }, []);\n }\n};\n","import {DataComponentCompiler} from './base';\n\nimport {ScaleType} from '../../scale';\nimport {extend, keys, differ, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\n\nexport const nonPositiveFilter: DataComponentCompiler> = {\n parseUnit: function(model: Model): Dict {\n return model.channels().reduce(function(nonPositiveComponent, channel) {\n const scale = model.scale(channel);\n if (!model.field(channel) || !scale) {\n // don't set anything\n return nonPositiveComponent;\n }\n nonPositiveComponent[model.field(channel)] = scale.type === ScaleType.LOG;\n return nonPositiveComponent;\n }, {});\n },\n\n parseFacet: function(model: FacetModel) {\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then consider merging\n if (!childDataComponent.source) {\n // For now, let's assume it always has union scale\n const nonPositiveFilterComponent = childDataComponent.nonPositiveFilter;\n delete childDataComponent.nonPositiveFilter;\n return nonPositiveFilterComponent;\n }\n return {};\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n let nonPositiveFilterComponent = {};\n\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && !differ(childDataComponent.nonPositiveFilter, nonPositiveFilterComponent)) {\n extend(nonPositiveFilterComponent, childDataComponent.nonPositiveFilter);\n delete childDataComponent.nonPositiveFilter;\n }\n });\n\n return nonPositiveFilterComponent;\n },\n\n assemble: function(nonPositiveFilterComponent: Dict) {\n if (nonPositiveFilterComponent) {\n return keys(nonPositiveFilterComponent).filter((field) => {\n // Only filter fields (keys) with value = true\n return nonPositiveFilterComponent[field];\n }).map(function(field) {\n return {\n type: 'filter',\n expr: 'datum[\"' + field + '\"] > 0'\n };\n });\n }\n return [];\n }\n};\n","import {DataComponentCompiler} from './base';\n\nimport {FieldDef} from '../../fielddef';\nimport {QUANTITATIVE, TEMPORAL} from '../../type';\nimport {contains, extend, keys, differ, Dict} from '../../util';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nconst DEFAULT_NULL_FILTERS = {\n nominal: false,\n ordinal: false,\n quantitative: true,\n temporal: true\n};\n\n/** Return Hashset of fields for null filtering (key=field, value = true). */\nfunction parse(model: Model): Dict {\n const filterInvalid = model.filterInvalid();\n\n return model.reduceFieldDef(function(aggregator: Dict, fieldDef: FieldDef) {\n if (fieldDef.field !== '*') { // Ignore * for count(*) fields.\n if (filterInvalid ||\n (filterInvalid === undefined && fieldDef.field && DEFAULT_NULL_FILTERS[fieldDef.type])) {\n aggregator[fieldDef.field] = fieldDef;\n } else {\n // define this so we know that we don't filter nulls for this field\n // this makes it easier to merge into parents\n aggregator[fieldDef.field] = null;\n }\n }\n return aggregator;\n }, {});\n}\n\nexport const nullFilter: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function(model: FacetModel) {\n const nullFilterComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(nullFilterComponent, childDataComponent.nullFilter);\n delete childDataComponent.nullFilter;\n }\n return nullFilterComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n\n // FIXME: null filters are not properly propagated right now\n let nullFilterComponent = parse(model);\n\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && !differ(childDataComponent.nullFilter, nullFilterComponent)) {\n extend(nullFilterComponent, childDataComponent.nullFilter);\n delete childDataComponent.nullFilter;\n }\n });\n\n return nullFilterComponent;\n },\n\n assemble: function(component: Dict) {\n const filters = keys(component).reduce((_filters, field) => {\n const fieldDef = component[field];\n if (fieldDef !== null) {\n _filters.push('datum[\"' + fieldDef.field + '\"] !== null');\n if (contains([QUANTITATIVE, TEMPORAL], fieldDef.type)) {\n // TODO(https://github.com/vega/vega-lite/issues/1436):\n // We can be even smarter and add NaN filter for N,O that are numbers\n // based on the `parse` property once we have it.\n _filters.push('!isNaN(datum[\"'+ fieldDef.field + '\"])');\n }\n }\n return _filters;\n }, []);\n\n return filters.length > 0 ?\n [{\n type: 'filter',\n expr: filters.join(' && ')\n }] : [];\n }\n};\n","import * as stringify from 'json-stable-stringify';\n\nimport {DataComponentCompiler} from './base';\n\nimport {isAggregate} from '../../encoding';\nimport {field} from '../../fielddef';\nimport {isSortField} from '../../sort';\nimport {VgSort} from '../../vega.schema';\nimport {contains} from '../../util';\n\nimport {sortParams} from '../common';\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {UnitModel} from '../unit';\n\nexport const pathOrder: DataComponentCompiler = {\n parseUnit: function(model: UnitModel): VgSort {\n if (contains(['line', 'area'], model.mark())) {\n if (model.mark() === 'line' && model.channelHasField('order')) {\n // For only line, sort by the order field if it is specified.\n return sortParams(model.encoding.order);\n } else {\n // For both line and area, we sort values based on dimension by default\n const dimensionChannel: 'x' | 'y' = model.markDef.orient === 'horizontal' ? 'y' : 'x';\n const sort = model.sort(dimensionChannel);\n const sortField = isSortField(sort) ?\n field({\n // FIXME: this op might not already exist?\n // FIXME: what if dimensionChannel (x or y) contains custom domain?\n aggregate: isAggregate(model.encoding) ? sort.op : undefined,\n field: sort.field\n }) :\n model.field(dimensionChannel, {binSuffix: 'start'});\n\n return {\n field: sortField,\n order: 'descending'\n };\n }\n\n }\n return null;\n },\n\n parseFacet: function(model: FacetModel) {\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then consider merging\n if (!childDataComponent.source) {\n // For now, let's assume it always has union scale\n const pathOrderComponent = childDataComponent.pathOrder;\n delete childDataComponent.pathOrder;\n return pathOrderComponent;\n }\n return null;\n },\n\n parseLayer: function(model: LayerModel) {\n // note that we run this before source.parseLayer\n let pathOrderComponent: VgSort = null;\n let stringifiedPathOrder: string = null;\n\n for (let child of model.children) {\n const childDataComponent = child.component.data;\n if (model.compatibleSource(child) && childDataComponent.pathOrder !== null) {\n if (pathOrderComponent === null) {\n pathOrderComponent = childDataComponent.pathOrder;\n stringifiedPathOrder = stringify(pathOrderComponent);\n } else if (stringifiedPathOrder !== stringify(childDataComponent.pathOrder)) {\n pathOrderComponent = null;\n break;\n }\n }\n }\n\n if (pathOrderComponent !== null) {\n // If we merge pathOrderComponent, remove them from children.\n for (let child of model.children) {\n delete child.component.data.pathOrder;\n }\n }\n\n return pathOrderComponent;\n },\n\n assemble: function(pathOrderComponent: VgSort) {\n if (pathOrderComponent) {\n return {\n type: 'collect',\n sort: pathOrderComponent\n };\n }\n return null;\n }\n};\n","import {DataFormat, isNamedData, isInlineData, isUrlData, SOURCE} from '../../data';\nimport {contains, extend} from '../../util';\nimport {VgData} from '../../vega.schema';\n\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {Model} from './../model';\n\nimport {DataComponent} from './data';\nimport {nullFilter} from './nullfilter';\nimport {filter} from './filter';\nimport {bin} from './bin';\nimport {formula} from './formula';\nimport {timeUnit} from './timeunit';\n\nexport namespace source {\n function parse(model: Model): VgData {\n let data = model.data;\n\n if (data) {\n // If data is explicitly provided\n\n let sourceData: VgData = {name: model.dataName(SOURCE)};\n if (isInlineData(data)) {\n sourceData.values = data.values;\n sourceData.format = {type: 'json'};\n } else if (isUrlData(data)) {\n sourceData.url = data.url;\n\n // Extract extension from URL using snippet from\n // http://stackoverflow.com/questions/680929/how-to-extract-extension-from-filename-string-in-javascript\n let defaultExtension = /(?:\\.([^.]+))?$/.exec(sourceData.url)[1];\n if (!contains(['json', 'csv', 'tsv', 'topojson'], defaultExtension)) {\n defaultExtension = 'json';\n }\n const dataFormat: DataFormat = data.format || {};\n\n // For backward compatibility for former `data.formatType` property\n const formatType: DataFormat = dataFormat.type || data['formatType'];\n sourceData.format =\n extend(\n {type: formatType ? formatType : defaultExtension},\n dataFormat.property ? {property: dataFormat.property} : {},\n // Feature and mesh are two mutually exclusive properties\n dataFormat.feature ?\n {feature : dataFormat.feature} :\n dataFormat.mesh ?\n {mesh : dataFormat.mesh} :\n {}\n );\n } else if (isNamedData(data)) {\n return {name: data.name};\n }\n\n return sourceData;\n } else if (!model.parent) {\n // If data is not explicitly provided but the model is a root,\n // need to produce a source as well\n return {name: model.dataName(SOURCE)};\n }\n return undefined;\n }\n\n export const parseUnit: (model: Model) => VgData = parse;\n\n export function parseFacet(model: FacetModel) {\n let sourceData = parse(model);\n if (!model.child.component.data.source) {\n // If the child does not have its own source, have to rename its source.\n model.child.renameData(model.child.dataName(SOURCE), model.dataName(SOURCE));\n }\n\n return sourceData;\n }\n\n export function parseLayer(model: LayerModel) {\n let sourceData = parse(model);\n model.children.forEach((child) => {\n const childData = child.component.data;\n\n if (model.compatibleSource(child)) {\n // we cannot merge if the child has filters defined even after we tried to move them up\n const canMerge = !childData.filter && !childData.formatParse && !childData.nullFilter;\n if (canMerge) {\n // rename source because we can just remove it\n child.renameData(child.dataName(SOURCE), model.dataName(SOURCE));\n delete childData.source;\n } else {\n // child does not have data defined or the same source so just use the parents source\n childData.source = {\n name: child.dataName(SOURCE),\n source: model.dataName(SOURCE)\n };\n }\n }\n });\n return sourceData;\n }\n\n export function assemble(component: DataComponent) {\n if (component.source) {\n let sourceData: VgData = component.source;\n\n if (component.formatParse) {\n component.source.format = component.source.format || {};\n component.source.format.parse = component.formatParse;\n }\n\n sourceData.transform = [].concat(\n formula.assemble(component.calculate),\n nullFilter.assemble(component.nullFilter),\n filter.assemble(component.filter),\n bin.assemble(component.bin),\n timeUnit.assemble(component.timeUnit)\n );\n\n return sourceData;\n }\n return null;\n }\n}\n","import {DataComponentCompiler} from './base';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {UnitModel} from './../unit';\n\nimport {sortParams} from '../common';\nimport {STACKED, SUMMARY} from '../../data';\nimport {FieldDef, field} from '../../fielddef';\nimport {hasDiscreteDomain} from '../../scale';\nimport {StackOffset} from '../../stack';\nimport {contains} from '../../util';\nimport {VgData, VgSort, VgStackTransform, VgImputeTransform} from '../../vega.schema';\n\nexport interface StackComponent {\n /**\n * Name of the output stacked data source\n */\n name: string;\n\n /**\n * Name of the input source data for stacked data source\n */\n source: string;\n\n /**\n * Grouping fields for stacked charts. This includes one of x- or 'y-field and may include faceted field.\n */\n groupby: string[];\n\n /**\n * Stack measure's field\n */\n field: string;\n\n /**\n * Level of detail fields for each level in the stacked charts such as color or detail.\n */\n stackby: string[];\n\n /**\n * Field that determines order of levels in the stacked charts.\n */\n sort: VgSort;\n\n /** Mode for stacking marks. */\n offset: StackOffset;\n\n /**\n * Whether to impute the data before stacking.\n */\n impute: boolean;\n}\n\n\nfunction getStackByFields(model: UnitModel) {\n return model.stack.stackBy.reduce((fields, by) => {\n const channel = by.channel;\n const fieldDef = by.fieldDef;\n\n const scale = model.scale(channel);\n const _field = field(fieldDef, {\n binSuffix: scale && hasDiscreteDomain(scale.type) ? 'range' : 'start'\n });\n if (!!_field) {\n fields.push(_field);\n }\n return fields;\n }, [] as string[]);\n}\n\n/**\n * Stack data compiler\n */\nexport const stack: DataComponentCompiler = {\n\n parseUnit: function(model: UnitModel): StackComponent {\n const stackProperties = model.stack;\n if (!stackProperties) {\n return undefined;\n }\n\n const groupby = [];\n if (stackProperties.groupbyChannel) {\n const groupbyFieldDef = model.fieldDef(stackProperties.groupbyChannel);\n if (groupbyFieldDef.bin) {\n // For Bin, we need to add both start and end to ensure that both get imputed\n // and included in the stack output (https://github.com/vega/vega-lite/issues/1805).\n groupby.push(model.field(stackProperties.groupbyChannel, {binSuffix: 'start'}));\n groupby.push(model.field(stackProperties.groupbyChannel, {binSuffix: 'end'}));\n } else {\n groupby.push(model.field(stackProperties.groupbyChannel));\n }\n }\n\n const stackby = getStackByFields(model);\n const orderDef = model.encoding.order;\n\n let sort: VgSort;\n if (orderDef) {\n sort = sortParams(orderDef);\n } else {\n // default = descending by stackFields\n // FIXME is the default here correct for binned fields?\n sort = stackby.reduce((s, field) => {\n s.field.push(field);\n s.order.push('descending');\n return s;\n }, {field:[], order: []});\n }\n\n return {\n name: model.dataName(STACKED),\n source: model.dataName(SUMMARY),\n groupby: groupby,\n field: model.field(stackProperties.fieldChannel),\n stackby: stackby,\n sort: sort,\n offset: stackProperties.offset,\n impute: contains(['area', 'line'], model.mark())\n };\n },\n\n parseLayer: function(model: LayerModel): StackComponent {\n // FIXME: merge if identical\n // FIXME: Correctly support facet of layer of stack.\n return undefined;\n },\n\n parseFacet: function(model: FacetModel): StackComponent {\n const child = model.child;\n const childDataComponent = child.component.data;\n // FIXME: Correctly support facet of layer of stack.\n if (childDataComponent.stack) {\n let stackComponent = childDataComponent.stack;\n\n const newName = model.dataName(STACKED);\n child.renameData(stackComponent.name, newName);\n stackComponent.name = newName;\n\n // Refer to facet's summary instead (always summary because stacked only works with aggregation)\n stackComponent.source = model.dataName(SUMMARY);\n\n // Add faceted field to groupby\n stackComponent.groupby = model.reduceFieldDef((groupby: string[], fieldDef: FieldDef) => {\n const facetedField = field(fieldDef, {binSuffix: 'start'});\n if (!contains(groupby, facetedField)) {\n groupby.push(facetedField);\n }\n return groupby;\n }, stackComponent.groupby);\n\n delete childDataComponent.stack;\n return stackComponent;\n }\n return undefined;\n },\n assemble: (stackComponent: StackComponent): VgData => {\n if (!stackComponent) {\n return undefined;\n }\n\n let transform: (VgStackTransform|VgImputeTransform)[] = [];\n // Impute\n if (stackComponent.impute) {\n transform.push({\n type: 'impute',\n field: stackComponent.field,\n groupby: stackComponent.stackby,\n orderby: stackComponent.groupby,\n method: 'value',\n value: 0\n });\n }\n\n // Stack\n transform.push({\n type: 'stack',\n groupby: stackComponent.groupby,\n field: stackComponent.field,\n sort: stackComponent.sort,\n as: [\n stackComponent.field + '_start',\n stackComponent.field + '_end'\n ],\n offset: stackComponent.offset\n });\n\n return {\n name: stackComponent.name,\n source: stackComponent.source,\n transform: transform\n };\n }\n};\n","import {SUMMARY} from '../../data';\nimport {field, FieldDef} from '../../fielddef';\nimport {keys, vals, reduce, hash, Dict, StringSet} from '../../util';\nimport {VgData} from '../../vega.schema';\n\nimport {FacetModel} from './../facet';\nimport {LayerModel} from './../layer';\nimport {Model} from './../model';\n\nimport {SummaryComponent} from './data';\n\n\nexport namespace summary {\n function addDimension(dims: {[field: string]: boolean}, fieldDef: FieldDef) {\n if (fieldDef.bin) {\n dims[field(fieldDef, {binSuffix: 'start'})] = true;\n dims[field(fieldDef, {binSuffix: 'end'})] = true;\n\n // const scale = model.scale(channel);\n // if (scaleType(scale, fieldDef, channel, model.mark()) === ScaleType.ORDINAL) {\n // also produce bin_range if the binned field use ordinal scale\n dims[field(fieldDef, {binSuffix: 'range'})] = true;\n // }\n } else {\n dims[field(fieldDef)] = true;\n }\n return dims;\n }\n\n export function parseUnit(model: Model): SummaryComponent[] {\n /* string set for dimensions */\n const dims: StringSet = {};\n\n /* dictionary mapping field name => dict set of aggregation functions */\n const meas: Dict = {};\n\n model.forEachFieldDef(function(fieldDef, channel) {\n if (fieldDef.aggregate) {\n if (fieldDef.aggregate === 'count') {\n meas['*'] = meas['*'] || {};\n /* tslint:disable:no-string-literal */\n meas['*']['count'] = true;\n /* tslint:enable:no-string-literal */\n } else {\n meas[fieldDef.field] = meas[fieldDef.field] || {};\n meas[fieldDef.field][fieldDef.aggregate] = true;\n\n // add min/max so we can use their union as unaggregated domain\n const scale = model.scale(channel);\n if (scale && scale.domain === 'unaggregated') {\n meas[fieldDef.field]['min'] = true;\n meas[fieldDef.field]['max'] = true;\n }\n }\n } else {\n addDimension(dims, fieldDef);\n };\n });\n\n return [{\n name: model.dataName(SUMMARY),\n dimensions: dims,\n measures: meas\n }];\n }\n\n export function parseFacet(model: FacetModel): SummaryComponent[] {\n const childDataComponent = model.child.component.data;\n\n // FIXME: this could be incorrect for faceted layer charts.\n\n // If child doesn't have its own data source but has a summary data source, merge\n if (!childDataComponent.source && childDataComponent.summary) {\n let summaryComponents = childDataComponent.summary.map(function(summaryComponent) {\n // add facet fields as dimensions\n summaryComponent.dimensions = model.reduceFieldDef(addDimension, summaryComponent.dimensions);\n\n const summaryNameWithoutPrefix = summaryComponent.name.substr(model.child.getName('').length);\n model.child.renameData(summaryComponent.name, summaryNameWithoutPrefix);\n summaryComponent.name = summaryNameWithoutPrefix;\n return summaryComponent;\n });\n\n delete childDataComponent.summary;\n return summaryComponents;\n }\n return [];\n }\n\n function mergeMeasures(parentMeasures: Dict>, childMeasures: Dict>) {\n for (const field in childMeasures) {\n if (childMeasures.hasOwnProperty(field)) {\n // when we merge a measure, we either have to add an aggregation operator or even a new field\n const ops = childMeasures[field];\n for (const op in ops) {\n if (ops.hasOwnProperty(op)) {\n if (field in parentMeasures) {\n // add operator to existing measure field\n parentMeasures[field][op] = true;\n } else {\n parentMeasures[field] = {op: true};\n }\n }\n }\n }\n }\n }\n\n export function parseLayer(model: LayerModel): SummaryComponent[] {\n // Index by the fields we are grouping by\n let summaries = {};\n\n // Combine summaries for children that don't have a distinct source\n // (either having its own data source, or its own tranformation of the same data source).\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (!childDataComponent.source && childDataComponent.summary) {\n // Merge the summaries if we can\n childDataComponent.summary.forEach((childSummary) => {\n // The key is a hash based on the dimensions;\n // we use it to find out whether we have a summary that uses the same group by fields.\n const key = hash(childSummary.dimensions);\n if (key in summaries) {\n // yes, there is a summary hat we need to merge into\n // we know that the dimensions are the same so we only need to merge the measures\n mergeMeasures(summaries[key].measures, childSummary.measures);\n } else {\n // give the summary a new name\n childSummary.name = model.dataName(SUMMARY) + '_' + keys(summaries).length;\n summaries[key] = childSummary;\n }\n\n // remove summary from child\n child.renameData(child.dataName(SUMMARY), summaries[key].name);\n delete childDataComponent.summary;\n });\n }\n });\n\n return vals(summaries);\n }\n\n /**\n * Assemble the summary. Needs a rename function because we cannot guarantee that the\n * parent data before the children data.\n */\n export function assemble(component: SummaryComponent[], sourceName: string): VgData[] {\n return component.reduce(function(summaryData, summaryComponent) {\n const dims = summaryComponent.dimensions;\n const meas = summaryComponent.measures;\n\n if (keys(meas).length > 0) { // has aggregate\n const groupby = keys(dims);\n const transform = reduce(meas, function(t, fnDictSet, field) {\n const ops = keys(fnDictSet);\n for (const op of ops) {\n t.fields.push(field);\n t.ops.push(op);\n }\n return t;\n }, {\n type: 'aggregate',\n groupby: groupby,\n fields: [],\n ops: []\n });\n\n summaryData.push({\n name: summaryComponent.name,\n source: sourceName,\n transform: [transform]\n });\n }\n return summaryData;\n }, []);\n }\n}\n","import {DataComponentCompiler} from './base';\n\nimport {field, FieldDef} from '../../fielddef';\nimport {fieldExpr} from '../../timeunit';\nimport {TEMPORAL} from '../../type';\nimport {extend, vals, Dict} from '../../util';\nimport {VgFormulaTransform} from '../../vega.schema';\n\nimport {FacetModel} from '../facet';\nimport {LayerModel} from '../layer';\nimport {Model} from '../model';\n\nfunction parse(model: Model): Dict {\n return model.reduceFieldDef(function(timeUnitComponent: Dict, fieldDef: FieldDef) {\n if (fieldDef.type === TEMPORAL && fieldDef.timeUnit) {\n\n const f = field(fieldDef);\n timeUnitComponent[f] = {\n type: 'formula',\n as: f,\n expr: fieldExpr(fieldDef.timeUnit, fieldDef.field)\n };\n }\n return timeUnitComponent;\n }, {});\n}\n\nexport const timeUnit: DataComponentCompiler> = {\n parseUnit: parse,\n\n parseFacet: function (model: FacetModel) {\n let timeUnitComponent = parse(model);\n\n const childDataComponent = model.child.component.data;\n\n // If child doesn't have its own data source, then merge\n if (!childDataComponent.source) {\n extend(timeUnitComponent, childDataComponent.timeUnit);\n delete childDataComponent.timeUnit;\n }\n return timeUnitComponent;\n },\n\n parseLayer: function(model: LayerModel) {\n let timeUnitComponent = parse(model);\n model.children.forEach((child) => {\n const childDataComponent = child.component.data;\n if (!childDataComponent.source) {\n extend(timeUnitComponent, childDataComponent.timeUnit);\n delete childDataComponent.timeUnit;\n }\n });\n return timeUnitComponent;\n },\n assemble: function(component: Dict) {\n // just join the values, which are already transforms\n return vals(component);\n }\n};\n","import * as log from '../log';\n\nimport {Axis, VlOnlyAxisBase, VL_ONLY_AXIS_PROPERTIES} from '../axis';\nimport {COLUMN, ROW, X, Y, Channel} from '../channel';\nimport {defaultConfig, Config} from '../config';\nimport {Facet} from '../facet';\nimport {forEach} from '../encoding';\nimport {FieldDef, normalize} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Scale} from '../scale';\nimport {FacetSpec} from '../spec';\nimport {contains, extend, keys, vals, flatten, duplicate, mergeDeep, Dict} from '../util';\nimport {VgData, VgEncodeEntry} from '../vega.schema';\nimport {StackProperties} from '../stack';\n\nimport {parseMainAxis, parseGridAxis, parseAxisComponent} from './axis/parse';\nimport {gridShow} from './axis/rules';\nimport {buildModel} from './common';\nimport {assembleData, parseFacetData} from './data/data';\nimport {assembleLayout, parseFacetLayout} from './layout';\nimport {Model} from './model';\n\nimport initScale from './scale/init';\nimport parseScaleComponent from './scale/parse';\n\n/**\n * Prefix for special data sources for driving column's axis group.\n */\n\nexport const COLUMN_AXES_DATA_PREFIX = 'column-';\n\n/**\n * Prefix for special data sources for driving row's axis group.\n */\nexport const ROW_AXES_DATA_PREFIX = 'row-';\n\nexport class FacetModel extends Model {\n public readonly facet: Facet;\n\n public readonly child: Model;\n\n public readonly children: Model[];\n protected readonly scales: Dict = {};\n\n protected readonly axes: Dict = {};\n\n protected readonly legends: Dict = {};\n\n public readonly config: Config;\n\n public readonly stack: StackProperties = null;\n\n private readonly _spacing: {\n row?: number;\n column?: number;\n } = {};\n\n constructor(spec: FacetSpec, parent: Model, parentGivenName: string) {\n super(spec, parent, parentGivenName);\n\n // Config must be initialized before child as it gets cascaded to the child\n const config = this.config = this.initConfig(spec.config, parent);\n\n const child = this.child = buildModel(spec.spec, this, this.getName('child'));\n this.children = [child];\n\n const facet = this.facet = this.initFacet(spec.facet);\n this.scales = this.initScalesAndSpacing(facet, config);\n this.axes = this.initAxis(facet, config, child);\n this.legends = {};\n }\n\n private initConfig(specConfig: Config, parent: Model) {\n return mergeDeep(duplicate(defaultConfig), parent ? parent.config : {}, specConfig);\n }\n\n private initFacet(facet: Facet) {\n // clone to prevent side effect to the original spec\n facet = duplicate(facet);\n\n forEach(facet, function(fieldDef: FieldDef, channel: Channel) {\n if (!contains([ROW, COLUMN], channel)) {\n // Drop unsupported channel\n log.warn(log.message.incompatibleChannel(channel, 'facet'));\n delete facet[channel];\n return;\n }\n\n // TODO: array of row / column ?\n if (fieldDef.field === undefined) { // TODO: datum\n log.warn(log.message.emptyFieldDef(fieldDef, channel));\n delete facet[channel];\n return;\n }\n\n // Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n normalize(fieldDef, channel);\n });\n return facet;\n }\n\n private initScalesAndSpacing(facet: Facet, config: Config): Dict {\n const model = this;\n return [ROW, COLUMN].reduce(function(_scale, channel) {\n if (facet[channel]) {\n _scale[channel] = initScale(\n channel, facet[channel], config,\n undefined, // Facet doesn't have one single mark\n undefined, // TODO(#1647): support width / height here\n [] // There is no xyRangeSteps here and there is no need to input\n );\n\n model._spacing[channel] = spacing(facet[channel].scale || {}, model, config);\n }\n return _scale;\n }, {});\n }\n\n private initAxis(facet: Facet, config: Config, child: Model): Dict {\n const model = this;\n return [ROW, COLUMN].reduce(function(_axis, channel) {\n if (facet[channel]) {\n const axisSpec = facet[channel].axis;\n if (axisSpec !== false) {\n let vlOnlyAxisProperties: VlOnlyAxisBase = {};\n VL_ONLY_AXIS_PROPERTIES.forEach(function(property) {\n if (config.facet.axis[property] !== undefined) {\n vlOnlyAxisProperties[property] = config.facet.axis[property];\n }\n });\n\n const modelAxis = _axis[channel] = {\n ...vlOnlyAxisProperties,\n ...axisSpec\n };\n\n if (channel === ROW) {\n const yAxis: any = child.axis(Y);\n if (yAxis && yAxis.orient !== 'right' && !modelAxis.orient) {\n modelAxis.orient = 'right';\n }\n if (model.hasDescendantWithFieldOnChannel(X) && !modelAxis.labelAngle) {\n modelAxis.labelAngle = modelAxis.orient === 'right' ? 90 : 270;\n }\n }\n }\n }\n return _axis;\n }, {});\n }\n\n public channelHasField(channel: Channel): boolean {\n return !!this.facet[channel];\n }\n\n private hasSummary() {\n const summary = this.component.data.summary;\n for (const s of summary) {\n if (keys(s.measures).length > 0) {\n return true;\n }\n }\n return false;\n }\n\n public facetedTable(): string {\n // FIXME: revise if the suffix should be 'data'\n return 'faceted-' + this.getName('data');\n }\n\n public dataTable(): string {\n // FIXME: shouldn't we apply data renaming here?\n if (this.component.data.stack) {\n return 'stacked';\n }\n if (this.hasSummary()) {\n return 'summary';\n }\n return 'source';\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return this.facet[channel];\n }\n\n public parseData() {\n this.child.parseData();\n this.component.data = parseFacetData(this);\n }\n\n public parseSelection() {\n // TODO: @arvind can write this\n // We might need to split this into compileSelectionData and compileSelectionSignals?\n }\n\n public parseLayoutData() {\n this.child.parseLayoutData();\n this.component.layout = parseFacetLayout(this);\n }\n\n public parseScale() {\n const child = this.child;\n const model = this;\n\n child.parseScale();\n\n // TODO: support scales for field reference of parent data (e.g., for SPLOM)\n\n // First, add scale for row and column.\n let scaleComponent = this.component.scales = parseScaleComponent(this);\n\n // Then, move shared/union from its child spec.\n keys(child.component.scales).forEach(function(channel) {\n // TODO: correctly implement independent scale\n if (true) { // if shared/union scale\n const scale = scaleComponent[channel] = child.component.scales[channel];\n\n const scaleNameWithoutPrefix = scale.name.substr(child.getName('').length);\n const newName = model.scaleName(scaleNameWithoutPrefix, true);\n child.renameScale(scale.name, newName);\n\n // Once put in parent, just remove the child's scale.\n delete child.component.scales[channel];\n }\n });\n }\n\n public parseMark() {\n this.child.parseMark();\n\n this.component.mark = extend(\n {\n name: this.getName('cell'),\n type: 'group',\n from: extend(\n {\n facet: {\n name: this.facetedTable(),\n data: this.dataTable(),\n groupby: [].concat(\n this.channelHasField(ROW) ? [this.field(ROW)] : [],\n this.channelHasField(COLUMN) ? [this.field(COLUMN)] : []\n )\n }\n }\n ),\n encode: {\n update: getFacetGroupProperties(this)\n }\n },\n // FIXME: move this call to assembleMarks()\n // Call child's assembleGroup to add marks, scales, axes, and legends.\n // Note that we can call child's assembleGroup() here because parseMark()\n // is the last method in compile() and thus the child is completely compiled\n // at this point.\n this.child.assembleGroup()\n );\n }\n\n public parseAxis() {\n this.child.parseAxis();\n this.component.axes = parseAxisComponent(this, [ROW, COLUMN]);\n }\n\n public parseAxisGroup() {\n // TODO: with nesting, we might need to consider calling child\n // this.child.parseAxisGroup();\n\n const xAxisGroup = parseAxisGroups(this, X);\n const yAxisGroup = parseAxisGroups(this, Y);\n\n this.component.axisGroups = extend(\n xAxisGroup ? {x: xAxisGroup} : {},\n yAxisGroup ? {y: yAxisGroup} : {}\n );\n }\n\n public parseGridGroup() {\n // TODO: with nesting, we might need to consider calling child\n // this.child.parseGridGroup();\n\n const child = this.child;\n\n this.component.gridGroups = extend(\n !child.channelHasField(X) && this.channelHasField(COLUMN) ? {column: getColumnGridGroups(this)} : {},\n !child.channelHasField(Y) && this.channelHasField(ROW) ? {row: getRowGridGroups(this)} : {}\n );\n }\n\n public parseLegend() {\n this.child.parseLegend();\n\n // TODO: support legend for independent non-position scale across facets\n // TODO: support legend for field reference of parent data (e.g., for SPLOM)\n\n // For now, assuming that non-positional scales are always shared across facets\n // Thus, just move all legends from its child\n this.component.legends = this.child.component.legends;\n this.child.component.legends = {};\n }\n\n public assembleParentGroupProperties(): any {\n return null;\n }\n\n public assembleSignals(signals: any): any[] {\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return [];\n }\n\n public assembleData(data: VgData[]): VgData[] {\n // Prefix traversal – parent data might be referred by children data\n assembleData(this, data);\n this.child.assembleData(data);\n assembleAxesGroupData(this, data);\n\n return data;\n }\n\n\n public assembleLayout(layoutData: VgData[]): VgData[] {\n // Postfix traversal – layout is assembled bottom-up\n this.child.assembleLayout(layoutData);\n return assembleLayout(this, layoutData);\n }\n\n public assembleMarks(): any[] {\n return [].concat(\n // axisGroup is a mapping to VgMarkGroup\n vals(this.component.axisGroups),\n flatten(vals(this.component.gridGroups)),\n this.component.mark\n );\n }\n\n public channels() {\n return [ROW, COLUMN];\n }\n\n protected getMapping() {\n return this.facet;\n }\n\n public spacing(channel: Channel) {\n return this._spacing[channel];\n }\n\n public isFacet() {\n return true;\n }\n}\n\nexport function hasSubPlotWithXy(model: FacetModel) {\n return model.hasDescendantWithFieldOnChannel('x') ||\n model.hasDescendantWithFieldOnChannel('y');\n}\n\nexport function spacing(scale: Scale, model: FacetModel, config: Config) {\n if (scale.spacing !== undefined) {\n return scale.spacing;\n }\n\n if (!hasSubPlotWithXy(model)) {\n // If there is no subplot with x/y, it's a simple table so there should be no spacing.\n return 0;\n }\n return config.scale.facetSpacing;\n}\n\nfunction getFacetGroupProperties(model: FacetModel) {\n const child = model.child;\n const mergedCellConfig = extend({}, child.config.cell, child.config.facet.cell);\n\n return extend({\n x: model.channelHasField(COLUMN) ? {\n scale: model.scaleName(COLUMN),\n field: model.field(COLUMN),\n // offset by the spacing / 2\n offset: model.spacing(COLUMN) / 2\n } : {value: model.config.scale.facetSpacing / 2},\n\n y: model.channelHasField(ROW) ? {\n scale: model.scaleName(ROW),\n field: model.field(ROW),\n // offset by the spacing / 2\n offset: model.spacing(ROW) / 2\n } : {value: model.config.scale.facetSpacing / 2},\n\n width: {field: {parent: model.child.sizeName('width')}},\n height: {field: {parent: model.child.sizeName('height')}}\n },\n hasSubPlotWithXy(model) ? child.assembleParentGroupProperties(mergedCellConfig) : {}\n );\n}\n\n// TODO: move the rest of the file src/compile/facet/*.ts\n\n/**\n * Add data for driving row/column axes when there are both row and column\n * Note that we don't have to deal with these in the parse step at all\n * because these items never get merged with any other items.\n */\nexport function assembleAxesGroupData(model: FacetModel, data: VgData[]) {\n if (model.facet.column) {\n data.push({\n name: COLUMN_AXES_DATA_PREFIX + model.dataTable(),\n source: model.dataTable(),\n transform: [{\n type: 'aggregate',\n groupby: [model.field(COLUMN)]\n }]\n });\n }\n\n if (model.facet.row) {\n data.push({\n name: ROW_AXES_DATA_PREFIX + model.dataTable(),\n source: model.dataTable(),\n transform: [{\n type: 'aggregate',\n groupby: [model.field(ROW)]\n }]\n });\n }\n return data;\n}\n\nfunction parseAxisGroups(model: FacetModel, channel: 'x' | 'y') {\n // TODO: add a case where inner spec is not a unit (facet/layer/concat)\n let axisGroup: any = null;\n\n const child = model.child;\n if (child.channelHasField(channel)) {\n if (child.axis(channel)) {\n if (true) { // the channel has shared axes\n\n // add a group for the shared axes\n axisGroup = getSharedAxisGroup(model, channel);\n\n if (child.axis(channel) && gridShow(child, channel)) { // show inner grid\n // add inner axis (aka axis that shows only grid to )\n child.component.axes[channel] = [parseGridAxis(channel, child)];\n } else {\n // Delete existing child axes\n delete child.component.axes[channel];\n }\n } else {\n // TODO: implement independent axes support\n }\n }\n }\n return axisGroup;\n}\n\n\nexport function getSharedAxisGroup(model: FacetModel, channel: 'x' | 'y'): VgEncodeEntry {\n const isX = channel === 'x' ;\n const facetChannel = isX ? 'column' : 'row';\n const hasFacet = !!model.facet[facetChannel];\n const dataPrefix = isX ? COLUMN_AXES_DATA_PREFIX : ROW_AXES_DATA_PREFIX;\n\n let axesGroup: VgEncodeEntry = {\n name: model.getName(channel + '-axes'),\n type: 'group'\n };\n\n if (hasFacet) {\n // Need to drive this with special data source that has one item for each column/row value.\n\n // TODO: We might only need to drive this with special data source if there are both row and column\n // However, it might be slightly difficult as we have to merge this with the main group.\n axesGroup.from = {data: dataPrefix + model.dataTable()};\n }\n\n if (isX) {\n axesGroup.encode = {\n update: {\n width: {field: {parent: model.child.sizeName('width')}},\n height: {field: {group: 'height'}},\n x: hasFacet ? {\n scale: model.scaleName(COLUMN),\n field: model.field(COLUMN),\n // offset by the spacing\n offset: model.spacing(COLUMN) / 2\n } : {\n // TODO: support custom spacing here\n // offset by the spacing\n value: model.config.scale.facetSpacing / 2\n }\n }\n };\n } else {\n axesGroup.encode = {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {parent: model.child.sizeName('height')}},\n y: hasFacet ? {\n scale: model.scaleName(ROW),\n field: model.field(ROW),\n // offset by the spacing\n offset: model.spacing(ROW) / 2\n } : {\n // offset by the spacing\n value: model.config.scale.facetSpacing / 2\n }\n }\n };\n }\n\n axesGroup.axes = [parseMainAxis(channel, model.child)];\n return axesGroup;\n}\n\n\nfunction getRowGridGroups(model: Model): any[] { // TODO: VgMarks\n const facetGridConfig = model.config.facet.grid;\n\n const rowGrid = {\n name: model.getName('row-grid'),\n type: 'rule',\n from: {\n data: ROW_AXES_DATA_PREFIX + model.dataTable()\n },\n encode: {\n update: {\n y: {\n scale: model.scaleName(ROW),\n field: model.field(ROW)\n },\n x: {value: 0, offset: -facetGridConfig.offset},\n x2: {field: {group: 'width'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n };\n\n return [rowGrid, {\n name: model.getName('row-grid-end'),\n type: 'rule',\n encode: {\n update: {\n y: {field: {group: 'height'}},\n x: {value: 0, offset: -facetGridConfig.offset},\n x2: {field: {group: 'width'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n }];\n}\n\nfunction getColumnGridGroups(model: Model): any { // TODO: VgMarks\n const facetGridConfig = model.config.facet.grid;\n\n const columnGrid = {\n name: model.getName('column-grid'),\n type: 'rule',\n from: {\n data: COLUMN_AXES_DATA_PREFIX + model.dataTable()\n },\n encode: {\n update: {\n x: {\n scale: model.scaleName(COLUMN),\n field: model.field(COLUMN)\n },\n y: {value: 0, offset: -facetGridConfig.offset},\n y2: {field: {group: 'height'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n };\n\n return [columnGrid, {\n name: model.getName('column-grid-end'),\n type: 'rule',\n encode: {\n update: {\n x: {field: {group: 'width'}},\n y: {value: 0, offset: -facetGridConfig.offset},\n y2: {field: {group: 'height'}, offset: facetGridConfig.offset},\n stroke: {value: facetGridConfig.color},\n strokeOpacity: {value: facetGridConfig.opacity},\n strokeWidth: {value: 0.5}\n }\n }\n }];\n}\n","import {Channel} from '../channel';\nimport {defaultConfig, CellConfig, Config} from '../config';\nimport {FieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Scale} from '../scale';\nimport {Axis} from '../axis';\nimport {LayerSpec} from '../spec';\nimport {StackProperties} from '../stack';\nimport {FILL_STROKE_CONFIG} from '../mark';\nimport {keys, duplicate, mergeDeep, flatten, Dict} from '../util';\nimport {VgData, VgEncodeEntry, isSignalRefDomain, VgScale} from '../vega.schema';\nimport {isUrlData} from '../data';\n\nimport {assembleData, parseLayerData} from './data/data';\nimport {applyConfig, buildModel} from './common';\nimport {assembleLayout, parseLayerLayout} from './layout';\nimport {Model} from './model';\nimport {UnitModel} from './unit';\n\nimport {unionDomains} from './scale/domain';\n\n\nexport class LayerModel extends Model {\n public readonly children: UnitModel[];\n\n protected readonly scales: Dict = {};\n\n protected readonly axes: Dict = {};\n\n protected readonly legends: Dict = {};\n\n public readonly config: Config;\n\n public readonly stack: StackProperties = null;\n\n /**\n * Fixed width for the unit visualization.\n * If undefined (e.g., for ordinal scale), the width of the\n * visualization will be calculated dynamically.\n */\n public readonly width: number;\n\n /**\n * Fixed height for the unit visualization.\n * If undefined (e.g., for ordinal scale), the height of the\n * visualization will be calculated dynamically.\n */\n public readonly height: number;\n\n constructor(spec: LayerSpec, parent: Model, parentGivenName: string) {\n super(spec, parent, parentGivenName);\n\n this.width = spec.width;\n this.height = spec.height;\n\n this.config = this.initConfig(spec.config, parent);\n this.children = spec.layer.map((layer, i) => {\n // we know that the model has to be a unit model because we pass in a unit spec\n return buildModel(layer, this, this.getName('layer_' + i)) as UnitModel;\n });\n }\n\n private initConfig(specConfig: Config, parent: Model) {\n return mergeDeep(duplicate(defaultConfig), specConfig, parent ? parent.config : {});\n }\n\n public channelHasField(channel: Channel): boolean {\n // layer does not have any channels\n return false;\n }\n\n public hasDiscreteScale(channel: Channel) {\n // since we assume shared scales we can just ask the first child\n return this.children[0].hasDiscreteScale(channel);\n }\n\n public dataTable() {\n // FIXME: don't just use the first child\n return this.children[0].dataTable();\n }\n\n public fieldDef(channel: Channel): FieldDef {\n return null; // layer does not have field defs\n }\n\n public parseData() {\n this.children.forEach((child) => {\n child.parseData();\n });\n this.component.data = parseLayerData(this);\n }\n\n public parseSelection() {\n // TODO: @arvind can write this\n // We might need to split this into compileSelectionData and compileSelectionSignals?\n }\n\n public parseLayoutData() {\n // TODO: correctly union ordinal scales rather than just using the layout of the first child\n this.children.forEach(child => {\n child.parseLayoutData();\n });\n this.component.layout = parseLayerLayout(this);\n }\n\n public parseScale(this: LayerModel) {\n const model = this;\n\n const scaleComponent: Dict = this.component.scales = {};\n\n this.children.forEach(function(child) {\n child.parseScale();\n\n // FIXME(#1602): correctly implement independent scale\n // Also need to check whether the scales are actually compatible, e.g. use the same sort or throw error\n if (true) { // if shared/union scale\n keys(child.component.scales).forEach(function(channel) {\n let childScale = child.component.scales[channel];\n const modelScale = scaleComponent[channel];\n\n if (!childScale || isSignalRefDomain(childScale.domain) || (modelScale && isSignalRefDomain(modelScale.domain))) {\n // TODO: merge signal ref domains\n return;\n }\n\n if (modelScale) {\n modelScale.domain = unionDomains(modelScale.domain, childScale.domain);\n } else {\n scaleComponent[channel] = childScale;\n }\n\n // rename child scale to parent scales\n const scaleNameWithoutPrefix = childScale.name.substr(child.getName('').length);\n const newName = model.scaleName(scaleNameWithoutPrefix, true);\n child.renameScale(childScale.name, newName);\n\n // remove merged scales from children\n delete child.component.scales[channel];\n });\n }\n });\n }\n\n public parseMark() {\n this.children.forEach(function(child) {\n child.parseMark();\n });\n }\n\n public parseAxis() {\n let axisComponent = this.component.axes = {};\n\n this.children.forEach(function(child) {\n child.parseAxis();\n\n // TODO: correctly implement independent axes\n if (true) { // if shared/union scale\n keys(child.component.axes).forEach(function(channel) {\n // TODO: support multiple axes for shared scale\n\n // just use the first axis definition for each channel\n if (!axisComponent[channel]) {\n axisComponent[channel] = child.component.axes[channel];\n }\n });\n }\n });\n }\n\n public parseAxisGroup(): void {\n return null;\n }\n\n public parseGridGroup(): void {\n return null;\n }\n\n public parseLegend() {\n let legendComponent = this.component.legends = {};\n\n this.children.forEach(function(child) {\n child.parseLegend();\n\n // TODO: correctly implement independent axes\n if (true) { // if shared/union scale\n keys(child.component.legends).forEach(function(channel) {\n // just use the first legend definition for each channel\n if (!legendComponent[channel]) {\n legendComponent[channel] = child.component.legends[channel];\n }\n });\n }\n });\n }\n\n public assembleParentGroupProperties(cellConfig: CellConfig): VgEncodeEntry {\n return applyConfig({}, cellConfig, FILL_STROKE_CONFIG.concat(['clip']));\n }\n\n public assembleSignals(signals: any[]): any[] {\n return [];\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return [];\n }\n\n public assembleScales(): VgScale[] {\n // combine with scales from children\n return this.children.reduce((scales, c) => {\n return scales.concat(c.assembleScales());\n }, super.assembleScales());\n }\n\n public assembleData(data: VgData[]): VgData[] {\n // Prefix traversal – parent data might be referred to by children data\n assembleData(this, data);\n this.children.forEach((child) => {\n child.assembleData(data);\n });\n return data;\n }\n\n public assembleLayout(layoutData: VgData[]): VgData[] {\n // Postfix traversal – layout is assembled bottom-up\n this.children.forEach((child) => {\n child.assembleLayout(layoutData);\n });\n return assembleLayout(this, layoutData);\n }\n\n public assembleMarks(): any[] {\n // only children have marks\n return flatten(this.children.map((child) => {\n return child.assembleMarks();\n }));\n }\n\n public channels(): Channel[] {\n return [];\n }\n\n protected getMapping(): any {\n return null;\n }\n\n public isLayer() {\n return true;\n }\n\n /**\n * Returns true if the child either has no source defined or uses the same url.\n * This is useful if you want to know whether it is possible to move a filter up.\n *\n * This function can only be called once th child has been parsed.\n */\n public compatibleSource(child: UnitModel) {\n const data = this.data;\n const childData = child.component.data;\n const compatible = !childData.source || (data && isUrlData(data) && data.url === childData.source.url);\n return compatible;\n }\n}\n","\nimport {Channel, X, Y, ROW, COLUMN} from '../channel';\nimport {LAYOUT} from '../data';\nimport {hasDiscreteDomain} from '../scale';\nimport {Formula} from '../transform';\nimport {extend, keys, StringSet} from '../util';\nimport {VgData} from '../vega.schema';\n\nimport {FacetModel} from './facet';\nimport {LayerModel} from './layer';\nimport {Model} from './model';\nimport {UnitModel} from './unit';\n\n// FIXME: for nesting x and y, we need to declare x,y layout separately before joining later\n// For now, let's always assume shared scale\nexport interface LayoutComponent {\n width: SizeComponent;\n height: SizeComponent;\n}\n\nexport interface SizeComponent {\n /** Field that we need to calculate distinct */\n distinct: StringSet;\n\n /** Array of formulas */\n formula: Formula[];\n}\n\nexport function assembleLayout(model: Model, layoutData: VgData[]): VgData[] {\n const layoutComponent = model.component.layout;\n if (!layoutComponent.width && !layoutComponent.height) {\n return layoutData; // Do nothing\n }\n\n if (true) { // if both are shared scale, we can simply merge data source for width and for height\n const distinctFields = keys(extend(layoutComponent.width.distinct, layoutComponent.height.distinct));\n const formula = layoutComponent.width.formula.concat(layoutComponent.height.formula)\n .map(f => extend({type: 'formula'}, f));\n\n return [\n distinctFields.length > 0 ? {\n name: model.dataName(LAYOUT),\n source: model.dataTable(),\n transform: [{\n type: 'aggregate',\n fields: distinctFields,\n ops: distinctFields.map(() => 'distinct')\n } as any].concat(formula)\n } : {\n name: model.dataName(LAYOUT),\n values: [{}],\n transform: formula\n }\n ];\n }\n // FIXME: implement\n // otherwise, we need to join width and height (cross)\n}\n\n// FIXME: for nesting x and y, we need to declare x,y layout separately before joining later\n// For now, let's always assume shared scale\nexport function parseUnitLayout(model: UnitModel): LayoutComponent {\n return {\n width: parseUnitSizeLayout(model, X),\n height: parseUnitSizeLayout(model, Y)\n };\n}\n\nfunction parseUnitSizeLayout(model: UnitModel, channel: Channel): SizeComponent {\n return {\n distinct: getDistinct(model, channel),\n formula: [{\n as: model.channelSizeName(channel),\n expr: unitSizeExpr(model, channel)\n }]\n };\n}\n\nexport function unitSizeExpr(model: UnitModel, channel: Channel): string {\n const scale = model.scale(channel);\n if (scale) {\n\n if (hasDiscreteDomain(scale.type) && scale.rangeStep) {\n // If the spec has top level size or specified rangeStep = fit, it will be undefined here.\n\n const cardinality = cardinalityExpr(model, channel);\n const paddingOuter = scale.paddingOuter !== undefined ? scale.paddingOuter : scale.padding;\n const paddingInner = scale.type === 'band' ?\n // only band has real paddingInner\n (scale.paddingInner !== undefined ? scale.paddingInner : scale.padding) :\n // For point, as calculated in https://github.com/vega/vega-scale/blob/master/src/band.js#L128,\n // it's equivalent to have paddingInner = 1 since there is only n-1 steps between n points.\n 1;\n\n let space = cardinality +\n (paddingInner ? ` - ${paddingInner}` : '') +\n (paddingOuter ? ` + 2*${paddingOuter}` : '');\n\n // This formula is equivalent to\n // space = count - inner + outer * 2\n // range = rangeStep * (space > 0 ? space : 0)\n // in https://github.com/vega/vega-encode/blob/master/src/Scale.js#L112\n return `max(${space}, 0) * ${scale.rangeStep}`;\n }\n }\n return (channel === X ? model.width : model.height) + '';\n}\n\nexport function parseFacetLayout(model: FacetModel): LayoutComponent {\n return {\n width: parseFacetSizeLayout(model, COLUMN),\n height: parseFacetSizeLayout(model, ROW)\n };\n}\n\nfunction parseFacetSizeLayout(model: FacetModel, channel: Channel): SizeComponent {\n const childLayoutComponent = model.child.component.layout;\n const sizeType = channel === ROW ? 'height' : 'width';\n const childSizeComponent: SizeComponent = childLayoutComponent[sizeType];\n\n if (true) { // assume shared scale\n // For shared scale, we can simply merge the layout into one data source\n\n const distinct = extend(getDistinct(model, channel), childSizeComponent.distinct);\n const formula = childSizeComponent.formula.concat([{\n as: model.channelSizeName(channel),\n expr: facetSizeFormula(model, channel, model.child.channelSizeName(channel))\n }]);\n\n delete childLayoutComponent[sizeType];\n return {\n distinct: distinct,\n formula: formula\n };\n }\n // FIXME implement independent scale as well\n // TODO: - also consider when children have different data source\n}\n\nfunction facetSizeFormula(model: FacetModel, channel: Channel, innerSize: string) {\n if (model.channelHasField(channel)) {\n return '(datum[\"' + innerSize + '\"] + ' + model.spacing(channel) + ')' + ' * ' + cardinalityExpr(model, channel);\n } else {\n return 'datum[\"' + innerSize + '\"] + ' + model.config.scale.facetSpacing; // need to add outer padding for facet\n }\n}\n\nexport function parseLayerLayout(model: LayerModel): LayoutComponent {\n return {\n width: parseLayerSizeLayout(model, X),\n height: parseLayerSizeLayout(model, Y)\n };\n}\n\nfunction parseLayerSizeLayout(model: LayerModel, channel: Channel): SizeComponent {\n if (true) {\n // For shared scale, we can simply merge the layout into one data source\n // TODO: don't just take the layout from the first child\n\n const childLayoutComponent = model.children[0].component.layout;\n const sizeType = channel === Y ? 'height' : 'width';\n const childSizeComponent: SizeComponent = childLayoutComponent[sizeType];\n\n const distinct = childSizeComponent.distinct;\n const formula: Formula[] = [{\n as: model.channelSizeName(channel),\n expr: childSizeComponent.formula[0].expr\n }];\n\n model.children.forEach((child) => {\n delete child.component.layout[sizeType];\n });\n\n return {\n distinct: distinct,\n formula: formula\n };\n }\n}\n\nfunction getDistinct(model: Model, channel: Channel): StringSet {\n if (model.channelHasField(channel) && model.hasDiscreteScale(channel)) {\n const scale = model.scale(channel);\n if (hasDiscreteDomain(scale.type) && !(scale.domain instanceof Array)) {\n // if explicit domain is declared, use array length\n const distinctField = model.field(channel);\n let distinct: StringSet = {};\n distinct[distinctField] = true;\n return distinct;\n }\n }\n return {};\n}\n\nexport function cardinalityExpr(model: Model, channel: Channel):string {\n const scale = model.scale(channel);\n if (scale.domain instanceof Array) {\n return scale.domain.length + '';\n }\n\n return model.field(channel, {datum: true, prefix: 'distinct'});\n}\n","import {COLOR, SHAPE, Channel} from '../../channel';\nimport {FieldDef, isValueDef} from '../../fielddef';\nimport {AREA, BAR, TICK, TEXT, LINE, POINT, CIRCLE, SQUARE, FILL_STROKE_CONFIG} from '../../mark';\nimport {TEMPORAL} from '../../type';\nimport {extend, keys, without} from '../../util';\n\nimport {VgValueRef} from '../../vega.schema';\n\nimport {applyMarkConfig, timeFormatExpression} from '../common';\nimport {UnitModel} from '../unit';\n\nexport function symbols(fieldDef: FieldDef, symbolsSpec: any, model: UnitModel, channel: Channel) {\n let symbols:any = {};\n const mark = model.mark();\n\n switch (mark) {\n case BAR:\n case TICK:\n case TEXT:\n symbols.shape = {value: 'square'};\n break;\n case CIRCLE:\n case SQUARE:\n symbols.shape = {value: mark};\n break;\n case POINT:\n case LINE:\n case AREA:\n // use default circle\n break;\n }\n\n const cfg = model.config;\n const filled = model.markDef.filled;\n\n let config = channel === COLOR ?\n /* For color's legend, do not set fill (when filled) or stroke (when unfilled) property from config because the legend's `fill` or `stroke` scale should have precedence */\n without(FILL_STROKE_CONFIG, [ filled ? 'fill' : 'stroke', 'strokeDash', 'strokeDashOffset']) :\n /* For other legend, no need to omit. */\n FILL_STROKE_CONFIG;\n\n config = without(config, ['strokeDash', 'strokeDashOffset']);\n\n applyMarkConfig(symbols, model, config);\n\n if (filled) {\n symbols.strokeWidth = {value: 0};\n }\n\n let value: VgValueRef;\n const colorDef = model.encoding.color;\n if (isValueDef(colorDef)) {\n value = {value: colorDef.value};\n }\n\n if (value !== undefined) {\n // apply the value\n if (filled) {\n symbols.fill = value;\n } else {\n symbols.stroke = value;\n }\n } else if (channel !== COLOR) {\n // For non-color legend, apply color config if there is no fill / stroke config.\n // (For color, do not override scale specified!)\n symbols[filled ? 'fill' : 'stroke'] = symbols[filled ? 'fill' : 'stroke'] ||\n {value: cfg.mark.color};\n }\n\n if (symbols.fill === undefined) {\n // fall back to mark config colors for legend fill\n if (cfg.mark.fill !== undefined) {\n symbols.fill = {value: cfg.mark.fill};\n } else if (cfg.mark.stroke !== undefined) {\n symbols.stroke = {value: cfg.mark.stroke};\n }\n }\n\n const shapeDef = model.encoding.shape;\n if (channel !== SHAPE) {\n if (isValueDef(shapeDef)) {\n symbols.shape = {value: shapeDef.value};\n }\n }\n\n symbols = extend(symbols, symbolsSpec || {});\n\n return keys(symbols).length > 0 ? symbols : undefined;\n}\n\nexport function labels(fieldDef: FieldDef, labelsSpec: any, model: UnitModel, channel: Channel) {\n const legend = model.legend(channel);\n const config = model.config;\n\n let labels:any = {};\n\n if (fieldDef.type === TEMPORAL) {\n labelsSpec = extend({\n text: {\n signal: timeFormatExpression('datum.value', fieldDef.timeUnit, legend.format, config.legend.shortTimeLabels, config.timeFormat)\n }\n }, labelsSpec || {});\n }\n\n labels = extend(labels, labelsSpec || {});\n\n return keys(labels).length > 0 ? labels : undefined;\n}\n\n","import {COLOR, SIZE, SHAPE, OPACITY, Channel} from '../../channel';\nimport {keys, Dict} from '../../util';\nimport {VgLegend} from '../../vega.schema';\nimport {Legend, LEGEND_PROPERTIES} from '../../legend';\n\nimport {Model} from '../model';\nimport {numberFormat} from '../common';\nimport {UnitModel} from '../unit';\n\nimport * as encode from './encode';\nimport * as rules from './rules';\n\nexport function parseLegendComponent(model: UnitModel): Dict {\n return [COLOR, SIZE, SHAPE, OPACITY].reduce(function(legendComponent, channel) {\n if (model.legend(channel)) {\n legendComponent[channel] = parseLegend(model, channel);\n }\n return legendComponent;\n }, {});\n}\n\nfunction getLegendDefWithScale(model: UnitModel, channel: Channel): VgLegend {\n // For binned field with continuous scale, use a special scale so we can overrride the mark props and labels\n switch (channel) {\n case COLOR:\n const scale = model.scaleName(COLOR);\n return model.markDef.filled ? {fill: scale} : {stroke: scale};\n case SIZE:\n return {size: model.scaleName(SIZE)};\n case SHAPE:\n return {shape: model.scaleName(SHAPE)};\n case OPACITY:\n return {opacity: model.scaleName(OPACITY)};\n }\n return null;\n}\n\nexport function parseLegend(model: UnitModel, channel: Channel): VgLegend {\n const fieldDef = model.fieldDef(channel);\n const legend = model.legend(channel);\n\n let def: VgLegend = getLegendDefWithScale(model, channel);\n\n LEGEND_PROPERTIES.forEach(function(property) {\n const value = getSpecifiedOrDefaultValue(property, legend, channel, model);\n if (value !== undefined) {\n def[property] = value;\n }\n });\n\n // 2) Add mark property definition groups\n const encodeSpec = legend.encode || {};\n ['labels', 'legend', 'title', 'symbols'].forEach(function(part) {\n let value = encode[part] ?\n encode[part](fieldDef, encodeSpec[part], model, channel) : // apply rule\n encodeSpec[part]; // no rule -- just default values\n if (value !== undefined && keys(value).length > 0) {\n def.encode = def.encode || {};\n def.encode[part] = {update: value};\n }\n });\n\n return def;\n}\n\nfunction getSpecifiedOrDefaultValue(property: keyof VgLegend, specifiedLegend: Legend, channel: Channel, model: Model) {\n const fieldDef = model.fieldDef(channel);\n\n switch (property) {\n case 'format':\n return numberFormat(fieldDef, specifiedLegend.format, model.config, channel);\n case 'title':\n return rules.title(specifiedLegend, fieldDef, model.config);\n case 'values':\n return rules.values(specifiedLegend);\n case 'type':\n rules.type(specifiedLegend, fieldDef, channel);\n }\n\n // Otherwise, return specified property.\n return specifiedLegend[property];\n}\n\n","import {COLOR, Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {DateTime, isDateTime, timestamp} from '../../datetime';\nimport {FieldDef} from '../../fielddef';\nimport {Legend} from '../../legend';\nimport {title as fieldTitle} from '../../fielddef';\nimport {TEMPORAL, QUANTITATIVE} from '../../type';\nimport {contains} from '../../util';\n\nexport function title(legend: Legend, fieldDef: FieldDef, config: Config) {\n if (legend.title !== undefined) {\n return legend.title;\n }\n\n return fieldTitle(fieldDef, config);\n}\n\nexport function values(legend: Legend) {\n const vals = legend.values;\n if (vals && isDateTime(vals[0])) {\n return (vals as DateTime[]).map((dt) => {\n // normalize = true as end user won't put 0 = January\n return timestamp(dt, true);\n });\n }\n return vals;\n}\n\nexport function type(legend: Legend, fieldDef: FieldDef, channel: Channel) {\n if (legend.type) {\n return legend.type;\n }\n\n if (channel === COLOR && !fieldDef.bin && !fieldDef.timeUnit && contains([QUANTITATIVE, TEMPORAL], fieldDef.type)) {\n return 'gradient';\n }\n return undefined;\n}\n","import * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\n\nexport const area: MarkCompiler = {\n vgMark: 'area',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n const orient = model.markDef.orient;\n\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.markDefProperties(model.markDef, ['orient', 'interpolate', 'tension']),\n };\n }\n};\n","import {X, Y} from '../../channel';\nimport {Config} from '../../config';\nimport {isFieldDef} from '../../fielddef';\nimport {Scale, ScaleType, isBinScale} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport * as log from '../../log';\nimport {VgEncodeEntry} from '../../vega.schema';\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\nimport {VgValueRef} from '../../vega.schema';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\n\nexport const bar: MarkCompiler = {\n vgMark: 'rect',\n role: 'bar',\n encodeEntry: (model: UnitModel) => {\n const stack = model.stack;\n return {\n ...x(model, stack),\n ...y(model, stack),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model)\n };\n }\n};\n\nfunction x(model: UnitModel, stack: StackProperties): VgEncodeEntry {\n const {config} = model;\n const orient = model.markDef.orient;\n const sizeDef = model.encoding.size;\n\n const xDef = model.encoding.x;\n const xScaleName = model.scaleName(X);\n const xScale = model.scale(X);\n // x, x2, and width -- we must specify two of these in all conditions\n if (orient === 'horizontal') {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n };\n } else { // vertical\n if (isFieldDef(xDef)) {\n if (!sizeDef && isBinScale(xScale.type)) {\n return mixins.binnedPosition('x', model, config.bar.binSpacing);\n } else if (xScale.type === ScaleType.BAND) {\n return mixins.bandPosition('x', model);\n }\n }\n // sized bin, normal point-ordinal axis, quantitative x-axis, or no x\n\n return mixins.centeredBandPosition('x', model,\n {...ref.midX(config), offset: 1}, // TODO: config.singleBarOffset,\n defaultSizeRef(xScaleName, model.scale(X), config)\n );\n }\n}\n\nfunction y(model: UnitModel, stack: StackProperties) {\n const {config, encoding} = model;\n const orient = model.markDef.orient;\n const sizeDef = encoding.size;\n\n const yDef = encoding.y;\n const yScaleName = model.scaleName(Y);\n const yScale = model.scale(Y);\n // y, y2 & height -- we must specify two of these in all conditions\n if (orient === 'vertical') {\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMin'),\n };\n } else {\n if (isFieldDef(yDef)) {\n if (yDef.bin && !sizeDef) {\n return mixins.binnedPosition('y', model, config.bar.binSpacing);\n } else if (yScale.type === ScaleType.BAND) {\n return mixins.bandPosition('y', model);\n }\n }\n return mixins.centeredBandPosition('y', model, ref.midY(config), defaultSizeRef(yScaleName, model.scale(Y), config));\n }\n}\n\nfunction defaultSizeRef(scaleName: string, scale: Scale, config: Config): VgValueRef {\n if (config.bar.discreteBandSize) {\n return {value: config.bar.discreteBandSize};\n }\n\n if (scale) {\n if (scale.type === ScaleType.POINT) {\n if (scale.rangeStep !== null) {\n return {value: scale.rangeStep - 1};\n }\n log.warn(log.message.BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL);\n } else if (scale.type === ScaleType.BAND) {\n return ref.band(scaleName);\n } else { // non-ordinal scale\n return {value: config.bar.continuousBandSize};\n }\n }\n if (config.scale.rangeStep && config.scale.rangeStep !== null) {\n return {value: config.scale.rangeStep - 1};\n }\n // TODO: this should depends on cell's width / height?\n return {value: 20};\n}\n\n","import {Mark, MarkDef, isMarkDef, BAR, AREA, POINT, LINE, TICK, CIRCLE, SQUARE, RECT, RULE, TEXT, Orient} from '../../mark';\nimport {Encoding, isAggregate, channelHasField} from '../../encoding';\nimport * as log from '../../log';\nimport {Dict, contains} from '../../util';\nimport {Scale, hasDiscreteDomain} from '../../scale';\nimport {isFieldDef, FieldDef, isContinuous} from '../../fielddef';\nimport {TEMPORAL} from '../../type';\nimport {Config} from '../../config';\nimport {getMarkConfig} from '../common';\nimport {StackProperties} from '../../stack';\n\nexport function initMarkDef(mark: Mark | MarkDef, encoding: Encoding, scale: Dict, config: Config): MarkDef & {filled: boolean} {\n const markDef = isMarkDef(mark) ? mark : {type: mark};\n\n const specifiedOrient = markDef.orient || getMarkConfig('orient', markDef.type, config);\n markDef.orient = orient(markDef.type, encoding, scale, specifiedOrient);\n if (specifiedOrient !== undefined && specifiedOrient !== markDef.orient) {\n log.warn(log.message.orientOverridden(markDef.orient,specifiedOrient));\n }\n\n return {\n ...markDef,\n\n // TODO: filled could be injected to encoding too, but we don't have filled channel yet.\n // Thus we inject it here for now.\n filled: filled(markDef.type, config)\n };\n}\n\n/**\n * Initialize encoding's value with some special default values\n */\nexport function initEncoding(mark: Mark, encoding: Encoding, stacked: StackProperties, config: Config): Encoding {\n const opacityConfig = getMarkConfig('opacity', mark, config);\n if (!encoding.opacity && opacityConfig === undefined) {\n const opacity = defaultOpacity(mark, encoding, stacked);\n if (opacity !== undefined) {\n encoding.opacity = {value: opacity};\n }\n }\n return encoding;\n}\n\n\nfunction defaultOpacity(mark: Mark, encoding: Encoding, stacked: StackProperties) {\n if (contains([POINT, TICK, CIRCLE, SQUARE], mark)) {\n // point-based marks\n if (!isAggregate(encoding) || channelHasField(encoding, 'detail')) {\n return 0.7;\n }\n }\n if (mark === BAR && !stacked) {\n if (channelHasField(encoding, 'color') || channelHasField(encoding, 'detail') || channelHasField(encoding, 'size')) {\n return 0.7;\n }\n }\n if (mark === AREA) {\n return 0.7; // inspired by Tableau\n }\n return undefined;\n}\n\nfunction filled(mark: Mark, config: Config) {\n const filledConfig = getMarkConfig('filled', mark, config);\n return filledConfig !== undefined ? filledConfig : mark !== POINT && mark !== LINE && mark !== RULE;\n}\n\nfunction orient(mark: Mark, encoding: Encoding, scale: Dict, specifiedOrient: Orient): Orient {\n switch (mark) {\n case POINT:\n case CIRCLE:\n case SQUARE:\n case TEXT:\n case RECT:\n // orient is meaningless for these marks.\n return undefined;\n }\n\n const yIsRange = encoding.y && encoding.y2;\n const xIsRange = encoding.x && encoding.x2;\n\n switch (mark) {\n case TICK:\n const xScaleType = scale['x'] ? scale['x'].type : null;\n const yScaleType = scale['y'] ? scale['y'].type : null;\n\n // Tick is opposite to bar, line, area and never have ranged mark.\n if (!hasDiscreteDomain(xScaleType) && (\n !encoding.y ||\n hasDiscreteDomain(yScaleType) ||\n (isFieldDef(encoding.y) && encoding.y.bin)\n )) {\n return 'vertical';\n }\n // y:Q or Ambiguous case, return horizontal\n return 'horizontal';\n\n case RULE:\n case BAR:\n case AREA:\n // If there are range for both x and y, y (vertical) has higher precedence.\n if (yIsRange) {\n return 'vertical';\n } else if (xIsRange) {\n return 'horizontal';\n } else if (mark === RULE) {\n if (encoding.x && !encoding.y) {\n return 'vertical';\n } else if (encoding.y && !encoding.x) {\n return 'horizontal';\n }\n }\n\n /* tslint:disable */\n case LINE: // intentional fall through\n /* tslint:enable */\n const xIsContinuous = isFieldDef(encoding.x) && isContinuous(encoding.x);\n const yIsContinuous = isFieldDef(encoding.y) && isContinuous(encoding.y);\n if (xIsContinuous && !yIsContinuous) {\n return 'horizontal';\n } else if (!xIsContinuous && yIsContinuous) {\n return 'vertical';\n } else if (xIsContinuous && yIsContinuous) {\n const xDef = encoding.x as FieldDef; // we can cast here since they are surely fieldDef\n const yDef = encoding.y as FieldDef;\n\n const xIsTemporal = xDef.type === TEMPORAL;\n const yIsTemporal = yDef.type === TEMPORAL;\n\n // temporal without timeUnit is considered continuous, but better serves as dimension\n if (xIsTemporal && !yIsTemporal) {\n return 'vertical';\n } else if (!xIsTemporal && yIsTemporal) {\n return 'horizontal';\n }\n\n if (!xDef.aggregate && !!yDef.aggregate) {\n return 'vertical';\n } else if (!!xDef.aggregate && !yDef.aggregate) {\n return 'horizontal';\n }\n\n if (specifiedOrient) {\n // When ambiguous, use user specified one.\n return specifiedOrient;\n }\n\n if (!(mark === LINE && encoding.order)) {\n // Except for connected scatterplot, we should log warning for unclear orientation of QxQ plots.\n log.warn(log.message.unclearOrientContinuous(mark));\n }\n return 'vertical';\n } else {\n // For Discrete x Discrete case, return undefined.\n log.warn(log.message.unclearOrientDiscreteOrEmpty(mark));\n return undefined;\n }\n }\n return 'vertical';\n}\n","import * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\n\nexport const line: MarkCompiler = {\n vgMark: 'line',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's line size is strokeWidth\n }),\n ...mixins.markDefProperties(model.markDef, ['interpolate', 'tension'])\n };\n }\n};\n","import {NONSPATIAL_CHANNELS, Channel} from '../../channel';\nimport {AREA, LINE} from '../../mark';\nimport {contains, without} from '../../util';\n\nimport {MarkCompiler} from './base';\nimport {area} from './area';\nimport {bar} from './bar';\nimport {line} from './line';\nimport {point, circle, square} from './point';\nimport {rect} from './rect';\nimport {rule} from './rule';\nimport {text} from './text';\nimport {tick} from './tick';\n\nimport {FacetModel} from '../facet';\nimport {UnitModel} from '../unit';\n\nconst markCompiler: {[type: string]: MarkCompiler} = {\n area: area,\n bar: bar,\n line: line,\n point: point,\n text: text,\n tick: tick,\n rect: rect,\n rule: rule,\n circle: circle,\n square: square\n};\n\nexport function parseMark(model: UnitModel): any[] {\n if (contains([LINE, AREA], model.mark())) {\n return parsePathMark(model);\n } else {\n return parseNonPathMark(model);\n }\n}\n\n// FIXME: maybe this should not be here. Need re-think and refactor, esp. after having all composition in.\nfunction dataFrom(model: UnitModel): string {\n const parent = model.parent;\n if (parent && parent.isFacet()) {\n return (parent as FacetModel).facetedTable();\n }\n if (model.stack) {\n return model.dataName('stacked');\n }\n return model.dataTable();\n}\n\nconst FACETED_PATH_PREFIX = 'faceted-path-';\n\nfunction parsePathMark(model: UnitModel) {\n const mark = model.mark();\n // FIXME: replace this with more general case for composition\n const details = detailFields(model);\n\n let pathMarks: any = [\n {\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n // If has subfacet for line/area group, need to use faceted data from below.\n // FIXME: support sorting path order (in connected scatterplot)\n from: {data: (details.length > 0 ? FACETED_PATH_PREFIX : '') + dataFrom(model)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n }\n ];\n\n if (details.length > 0) { // have level of details - need to facet line into subgroups\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n return [{\n name: model.getName('pathgroup'),\n type: 'group',\n from: {\n facet: {\n name: FACETED_PATH_PREFIX + dataFrom(model),\n data: dataFrom(model),\n groupby: details,\n }\n },\n encode: {\n update: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}}\n }\n },\n marks: pathMarks\n }];\n } else {\n return pathMarks;\n }\n}\n\nfunction parseNonPathMark(model: UnitModel) {\n const mark = model.mark();\n\n const role = markCompiler[mark].role;\n\n let marks: any[] = []; // TODO: vgMarks\n\n // TODO: for non-stacked plot, map order to zindex. (Maybe rename order for layer to zindex?)\n\n marks.push({\n name: model.getName('marks'),\n type: markCompiler[mark].vgMark,\n ...(role? {role} : {}),\n from: {data: dataFrom(model)},\n encode: {update: markCompiler[mark].encodeEntry(model)}\n });\n\n return marks;\n}\n\nconst NONSPATIAL_CHANNELS_EXCEPT_ORDER = without(NONSPATIAL_CHANNELS, ['order'] as Channel[]);\n\n/**\n * Returns list of detail (group-by) fields\n * that the model's spec contains.\n */\nfunction detailFields(model: UnitModel): string[] {\n return NONSPATIAL_CHANNELS_EXCEPT_ORDER.reduce(function(details, channel) {\n if (model.channelHasField(channel) && !model.fieldDef(channel).aggregate) {\n details.push(model.field(channel));\n }\n return details;\n }, []);\n}\n","import {MarkDef} from '../../mark';\nimport * as util from '../../util';\nimport {VgEncodeEntry, VgValueRef} from '../../vega.schema';\nimport {getMarkConfig} from '../common';\nimport {UnitModel} from '../unit';\n\nimport * as ref from './valueref';\n\nimport {NONSPATIAL_SCALE_CHANNELS} from '../../channel';\nimport {Condition} from '../../fielddef';\nimport {predicate} from '../selection/selection';\n\nexport function color(model: UnitModel) {\n const config = model.config;\n const filled = model.markDef.filled;\n\n let e = nonPosition('color', model, {\n vgChannel: filled ? 'fill' : 'stroke',\n defaultValue: getMarkConfig('color', model.mark(), config) as string\n });\n\n // If there is no fill, always fill symbols\n // with transparent fills https://github.com/vega/vega-lite/issues/1316\n if (!e.fill && util.contains(['bar', 'point', 'circle', 'square'], model.mark())) {\n e.fill = {value: 'transparent'};\n }\n return e;\n}\n\nexport function markDefProperties(mark: MarkDef, props: (keyof MarkDef)[]) {\n return props.reduce((m, prop) => {\n if (mark[prop]) {\n m[prop] = {value: mark[prop]};\n }\n return m;\n }, {});\n}\n\nexport function valueIfDefined(prop: string, value: VgValueRef): VgEncodeEntry {\n if (value !== undefined) {\n return {[prop]: {value: value}};\n }\n return undefined;\n}\n\n/**\n * Return mixins for non-positional channels with scales. (Text doesn't have scale.)\n */\nexport function nonPosition(channel: typeof NONSPATIAL_SCALE_CHANNELS[0], model: UnitModel, opt: {defaultValue?: number | string | boolean, vgChannel?: string, defaultRef?: VgValueRef} = {}): VgEncodeEntry {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {defaultValue, vgChannel} = opt;\n const defaultRef = opt.defaultRef || (defaultValue !== undefined ? {value: defaultValue} : undefined);\n\n const channelDef = model.encoding[channel];\n const valueRef = ref.midPoint(channel, channelDef, model.scaleName(channel), model.scale(channel), defaultRef);\n\n return wrapCondition(model, channelDef && channelDef.condition, vgChannel || channel, valueRef);\n}\n\n/**\n * Return a mixin that include a Vega production rule for a Vega-Lite conditional channel definition.\n * or a simple mixin if channel def has no condition.\n */\nfunction wrapCondition(model: UnitModel, condition: Condition, vgChannel: string, valueRef: VgValueRef): VgEncodeEntry {\n if (condition) {\n const {selection, value} = condition;\n return {\n [vgChannel]: [\n {test: selectionTest(model, selection), value},\n ...(valueRef !== undefined ? [valueRef] : [])\n ]\n };\n } else {\n return valueRef !== undefined ? {[vgChannel]: valueRef} : {};\n }\n}\n\nfunction selectionTest(model: UnitModel, selectionName: string) {\n const negate = selectionName.charAt(0) === '!',\n name = negate ? selectionName.slice(1) : selectionName;\n return (negate ? '!' : '') + predicate(model.component.selection[name]);\n}\n\nexport function text(model: UnitModel) {\n const channelDef = model.encoding.text;\n return wrapCondition(model, channelDef && channelDef.condition, 'text', ref.text(channelDef, model.config));\n}\n\nexport function bandPosition(channel: 'x'|'y', model: UnitModel) {\n // TODO: band scale doesn't support size yet\n const fieldDef = model.encoding[channel];\n const scaleName = model.scaleName(channel);\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n [channel]: ref.fieldRef(fieldDef, scaleName, {}),\n [sizeChannel]: ref.band(scaleName)\n };\n}\n\nexport function centeredBandPosition(channel: 'x' | 'y', model: UnitModel, defaultPosRef: VgValueRef, defaultSizeRef: VgValueRef) {\n const centerChannel: 'xc' | 'yc' = channel === 'x' ? 'xc' : 'yc';\n const sizeChannel = channel === 'x' ? 'width' : 'height';\n return {\n ...pointPosition(channel, model, defaultPosRef, centerChannel),\n ...nonPosition('size', model, {defaultRef: defaultSizeRef, vgChannel: sizeChannel})\n };\n}\n\nexport function binnedPosition(channel: 'x'|'y', model: UnitModel, spacing: number) {\n const fieldDef = model.encoding[channel];\n const scaleName = model.scaleName(channel);\n if (channel === 'x') {\n return {\n x2: ref.bin(fieldDef, scaleName, 'start', spacing),\n x: ref.bin(fieldDef, scaleName, 'end')\n };\n } else {\n return {\n y2: ref.bin(fieldDef, scaleName, 'start'),\n y: ref.bin(fieldDef, scaleName, 'end', spacing)\n };\n }\n}\n\n/**\n * Return mixins for point (non-band) position channels.\n */\nexport function pointPosition(channel: 'x'|'y', model: UnitModel, defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax', vgChannel?: 'x'|'y'|'xc'|'yc') {\n // TODO: refactor how refer to scale as discussed in https://github.com/vega/vega-lite/pull/1613\n\n const {encoding, stack} = model;\n const valueRef = ref.stackable(channel, encoding[channel], model.scaleName(channel), model.scale(channel), stack, defaultRef);\n\n return {\n [vgChannel || channel]: valueRef\n };\n}\n\n/**\n * Return mixins for x2, y2.\n * If channel is not specified, return one channel based on orientation.\n */\nexport function pointPosition2(model: UnitModel, defaultRef: 'zeroOrMin' | 'zeroOrMax', channel?: 'x2' | 'y2') {\n const {encoding, markDef, stack} = model;\n channel = channel || (markDef.orient === 'horizontal' ? 'x2' : 'y2');\n const baseChannel = channel === 'x2' ? 'x' : 'y';\n\n const valueRef = ref.stackable2(channel, encoding[baseChannel], encoding[channel], model.scaleName(baseChannel), model.scale(baseChannel), stack, defaultRef);\n return {[channel]: valueRef};\n}\n","\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\nimport {getMarkConfig} from '../common';\nimport {Config} from '../../config';\n\nfunction encodeEntry(model: UnitModel, fixedShape?: 'circle' | 'square') {\n const {config} = model;\n\n return {\n ...mixins.pointPosition('x', model, ref.midX(config)),\n ...mixins.pointPosition('y', model, ref.midY(config)),\n\n ...mixins.color(model),\n ...mixins.nonPosition('size', model),\n ...shapeMixins(model, config, fixedShape),\n ...mixins.nonPosition('opacity', model)\n };\n}\n\nexport function shapeMixins(model: UnitModel, config: Config, fixedShape?: 'circle' | 'square') {\n if (fixedShape) {\n return {shape: {value: fixedShape}};\n }\n return mixins.nonPosition('shape', model, {defaultValue: getMarkConfig('shape', 'point', config) as string});\n}\n\nexport const point: MarkCompiler = {\n vgMark: 'symbol',\n role: 'point',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model);\n }\n};\n\nexport const circle: MarkCompiler = {\n vgMark: 'symbol',\n role: 'circle',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'circle');\n }\n};\n\nexport const square: MarkCompiler = {\n vgMark: 'symbol',\n role: 'square',\n encodeEntry: (model: UnitModel) => {\n return encodeEntry(model, 'square');\n }\n};\n","import {X, Y} from '../../channel';\nimport {isFieldDef} from '../../fielddef';\nimport {ScaleType, hasDiscreteDomain} from '../../scale';\nimport {RECT} from '../../mark';\nimport * as log from '../../log';\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\n\nexport const rect: MarkCompiler = {\n vgMark: 'rect',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n return {\n ...x(model),\n ...y(model),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction x(model: UnitModel) {\n const xDef = model.encoding.x;\n const x2Def = model.encoding.x2;\n const xScale = model.scale(X);\n\n if (isFieldDef(xDef) && xDef.bin && !x2Def) {\n return mixins.binnedPosition('x', model, 0);\n } else if (xScale && hasDiscreteDomain(xScale.type)) {\n /* istanbul ignore else */\n if (xScale.type === ScaleType.BAND) {\n return mixins.bandPosition('x', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, xScale.type));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'x2')\n };\n }\n}\n\nfunction y(model: UnitModel) {\n const yDef = model.encoding.y;\n const y2Def = model.encoding.y2;\n const yScale = model.scale(Y);\n\n if (isFieldDef(yDef) && yDef.bin && !y2Def) {\n return mixins.binnedPosition('y', model, 0);\n } else if (yScale && hasDiscreteDomain(yScale.type)) {\n /* istanbul ignore else */\n if (yScale.type === ScaleType.BAND) {\n return mixins.bandPosition('y', model);\n } else {\n // We don't support rect mark with point/ordinal scale\n throw new Error(log.message.scaleTypeNotWorkWithMark(RECT, yScale.type));\n }\n } else { // continuous scale or no scale\n return {\n ...mixins.pointPosition('y', model, 'zeroOrMax'),\n ...mixins.pointPosition2(model, 'zeroOrMin', 'y2')\n };\n }\n}\n","import {UnitModel} from '../unit';\nimport {MarkCompiler} from './base';\nimport * as mixins from './mixins';\n\nexport const rule: MarkCompiler = {\n vgMark: 'rule',\n role: undefined,\n encodeEntry: (model: UnitModel) => {\n return {\n ...mixins.pointPosition('x', model, 'zeroOrMin'),\n ...mixins.pointPosition('y', model, 'zeroOrMin'),\n ...mixins.pointPosition2(model, 'zeroOrMax'),\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'strokeWidth' // VL's rule size is strokeWidth\n })\n };\n }\n};\n","import {X} from '../../channel';\nimport {getMarkConfig} from '../common';\n\nimport * as mixins from './mixins';\nimport {Config} from '../../config';\nimport {ChannelDef, isFieldDef} from '../../fielddef';\nimport {QUANTITATIVE} from '../../type';\nimport {UnitModel} from '../unit';\nimport {VgValueRef} from '../../vega.schema';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\nimport {Encoding, channelHasField} from '../../encoding';\n\nexport const text: MarkCompiler = {\n vgMark: 'text',\n role: undefined,\n\n encodeEntry: (model: UnitModel) => {\n const {config, encoding} = model;\n const textDef = encoding.text;\n\n return {\n ...mixins.pointPosition('x', model, xDefault(config, textDef)),\n ...mixins.pointPosition('y', model, ref.midY(config)),\n ...mixins.text(model),\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n ...mixins.nonPosition('size', model, {\n vgChannel: 'fontSize' // VL's text size is fontSize\n }),\n ...mixins.valueIfDefined('align', align(encoding, config))\n };\n }\n};\n\nfunction xDefault(config: Config, textDef: ChannelDef): VgValueRef {\n if (isFieldDef(textDef) && textDef.type === QUANTITATIVE) {\n return {field: {group: 'width'}, offset: -5};\n }\n // TODO: allow this to fit (Be consistent with ref.midX())\n return {value: config.scale.textXRangeStep / 2};\n}\n\nfunction align(encoding: Encoding, config: Config) {\n const alignConfig = getMarkConfig('align', 'text', config);\n if (alignConfig === undefined) {\n return channelHasField(encoding, X) ? 'center' : 'right';\n }\n // If there is a config, Vega-parser will process this already.\n return undefined;\n}\n","\n\nimport * as mixins from './mixins';\nimport {UnitModel} from '../unit';\n\nimport {MarkCompiler} from './base';\nimport * as ref from './valueref';\n\nexport const tick: MarkCompiler = {\n vgMark: 'rect',\n role: 'tick',\n\n encodeEntry: (model: UnitModel) => {\n const {config, markDef} = model;\n const orient = markDef.orient;\n\n const vgSizeChannel = orient === 'horizontal' ? 'width' : 'height';\n const vgThicknessChannel = orient === 'horizontal' ? 'height' : 'width';\n\n return {\n ...mixins.pointPosition('x', model, ref.midX(config), 'xc'),\n ...mixins.pointPosition('y', model, ref.midY(config), 'yc'),\n\n // size / thickness => width / height\n ...mixins.nonPosition('size', model, {\n defaultValue: defaultSize(model),\n vgChannel: vgSizeChannel\n }),\n [vgThicknessChannel]: {value: config.tick.thickness},\n\n ...mixins.color(model),\n ...mixins.nonPosition('opacity', model),\n };\n }\n};\n\nfunction defaultSize(model: UnitModel): number {\n const {config} = model;\n const orient = model.markDef.orient;\n\n const scaleRangeStep: number | null = (model.scale(orient === 'horizontal' ? 'x' : 'y') || {}).rangeStep;\n\n if (config.tick.bandSize !== undefined) {\n return config.tick.bandSize;\n } else {\n const rangeStep = scaleRangeStep !== undefined ?\n scaleRangeStep :\n config.scale.rangeStep;\n if (typeof rangeStep !== 'number') {\n // FIXME consolidate this log\n throw new Error('Function does not handle non-numeric rangeStep');\n }\n return rangeStep / 1.5;\n }\n}\n","/**\n * Utility files for producing Vega ValueRef for marks\n */\n\nimport {Channel, X, X2, Y, Y2} from '../../channel';\nimport {Config} from '../../config';\nimport {ChannelDef, FieldDef, FieldRefOption, field, isFieldDef, TextFieldDef, ValueDef} from '../../fielddef';\nimport {Scale, ScaleType, hasDiscreteDomain} from '../../scale';\nimport {StackProperties} from '../../stack';\nimport {contains} from '../../util';\nimport {VgValueRef} from '../../vega.schema';\nimport {numberFormat, timeFormatExpression} from '../common';\n\n// TODO: we need to find a way to refactor these so that scaleName is a part of scale\n// but that's complicated. For now, this is a huge step moving forward.\n\n/**\n * @return Vega ValueRef for stackable x or y\n */\nexport function stackable(channel: 'x' | 'y', channelDef: ChannelDef, scaleName: string, scale: Scale,\n stack: StackProperties, defaultRef: VgValueRef): VgValueRef {\n if (channelDef && stack && channel === stack.fieldChannel) {\n // x or y use stack_end so that stacked line's point mark use stack_end too.\n return fieldRef(channelDef, scaleName, {suffix: 'end'});\n }\n return midPoint(channel, channelDef, scaleName, scale, defaultRef);\n}\n\n/**\n * @return Vega ValueRef for stackable x2 or y2\n */\nexport function stackable2(channel: 'x2' | 'y2', aFieldDef: FieldDef, a2fieldDef: FieldDef, scaleName: string, scale: Scale,\n stack: StackProperties, defaultRef: VgValueRef): VgValueRef {\n if (aFieldDef && stack &&\n // If fieldChannel is X and channel is X2 (or Y and Y2)\n channel.charAt(0) === stack.fieldChannel.charAt(0)\n ) {\n return fieldRef(aFieldDef, scaleName, {suffix: 'start'});\n }\n return midPoint(channel, a2fieldDef, scaleName, scale, defaultRef);\n}\n\n/**\n * Value Ref for binned fields\n */\nexport function bin(fieldDef: FieldDef, scaleName: string, side: 'start' | 'end', offset?: number) {\n return fieldRef(fieldDef, scaleName, {binSuffix: side}, offset);\n}\n\nexport function fieldRef(fieldDef: FieldDef, scaleName: string, opt: FieldRefOption, offset?: number | VgValueRef): VgValueRef {\n let ref: VgValueRef = {\n scale: scaleName,\n field: field(fieldDef, opt),\n };\n if (offset) {\n ref.offset = offset;\n }\n return ref;\n}\n\nexport function band(scaleName: string, band: number|boolean = true): VgValueRef {\n return {\n scale: scaleName,\n band: band\n };\n}\n\nfunction binMidSignal(fieldDef: FieldDef, scaleName: string) {\n return {\n signal: `(` +\n `scale(\"${scaleName}\", ${field(fieldDef, {binSuffix: 'start', datum: true})})` +\n ` + ` +\n `scale(\"${scaleName}\", ${field(fieldDef, {binSuffix: 'end', datum: true})})`+\n `)/2`\n };\n}\n\n/**\n * @returns {VgValueRef} Value Ref for xc / yc or mid point for other channels.\n */\nexport function midPoint(channel: Channel, channelDef: ChannelDef, scaleName: string, scale: Scale,\n defaultRef: VgValueRef | 'zeroOrMin' | 'zeroOrMax'): VgValueRef {\n // TODO: datum support\n\n if (channelDef) {\n /* istanbul ignore else */\n if (isFieldDef(channelDef)) {\n if (scale.type === 'bin-linear') {\n return binMidSignal(channelDef, scaleName);\n } else if (scale.type === 'bin-ordinal') {\n return fieldRef(channelDef, scaleName, {binSuffix: 'start'});\n }\n\n if (hasDiscreteDomain(scale.type)) {\n if (scale.type === 'band') {\n // For band, to get mid point, need to offset by half of the band\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'}, band(scaleName, 0.5));\n }\n return fieldRef(channelDef, scaleName, {binSuffix: 'range'});\n } else {\n return fieldRef(channelDef, scaleName, {}); // no need for bin suffix\n }\n } else if (channelDef.value) {\n return {value: channelDef.value};\n } else {\n throw new Error('FieldDef without field or value.'); // FIXME add this to log.message\n }\n }\n\n if (defaultRef === 'zeroOrMin') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMinX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMinY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n } else if (defaultRef === 'zeroOrMax') {\n /* istanbul ignore else */\n if (channel === X || channel === X2) {\n return zeroOrMaxX(scaleName, scale);\n } else if (channel === Y || channel === Y2) {\n return zeroOrMaxY(scaleName, scale);\n } else {\n throw new Error(`Unsupported channel ${channel} for base function`); // FIXME add this to log.message\n }\n }\n return defaultRef;\n}\n\nexport function text(textDef: TextFieldDef | ValueDef, config: Config): VgValueRef {\n // text\n if (textDef) {\n if (isFieldDef(textDef)) {\n if (textDef.type === 'quantitative') {\n // FIXME: what happens if we have bin?\n const format = numberFormat(textDef, textDef.format, config, 'text');\n return {\n signal: `format(${field(textDef, {datum: true})}, '${format}')`\n };\n } else if (textDef.type === 'temporal') {\n return {\n signal: timeFormatExpression(field(textDef, {datum: true}), textDef.timeUnit, textDef.format, config.text.shortTimeLabels, config.timeFormat)\n };\n } else {\n return {field: textDef.field};\n }\n } else if (textDef.value) {\n return {value: textDef.value};\n }\n }\n return {value: config.text.text};\n}\n\nexport function midX(config: Config): VgValueRef {\n\n if (typeof config.scale.rangeStep === 'string') {\n // TODO: For fit-mode, use middle of the width\n throw new Error('midX can not handle string rangeSteps');\n }\n return {value: config.scale.rangeStep / 2};\n}\n\nexport function midY(config: Config): VgValueRef {\n if (typeof config.scale.rangeStep === 'string') {\n // TODO: For fit-mode, use middle of the width\n throw new Error('midX can not handle string rangeSteps');\n }\n return {value: config.scale.rangeStep / 2};\n}\n\nfunction zeroOrMinX(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the x-axis\n return {value: 0};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxX(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n return {field: {group: 'width'}};\n}\n\nfunction zeroOrMinY(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {field: {group: 'height'}};\n}\n\n/**\n * @returns {VgValueRef} base value if scale exists and return max value if scale does not exist\n */\nfunction zeroOrMaxY(scaleName: string, scale: Scale): VgValueRef {\n if (scaleName) {\n // Log / Time / UTC scale do not support zero\n if (!contains([ScaleType.LOG, ScaleType.TIME, ScaleType.UTC], scale.type) &&\n scale.zero !== false) {\n\n return {\n scale: scaleName,\n value: 0\n };\n }\n }\n // Put the mark on the y-axis\n return {value: 0};\n}\n","import * as log from '../log';\n\nimport {Axis} from '../axis';\nimport {Channel, X, COLUMN} from '../channel';\nimport {Config, CellConfig} from '../config';\nimport {Data, DataSourceType, isNamedData, SOURCE} from '../data';\nimport {reduce, forEach} from '../encoding';\nimport {FieldDef, FieldRefOption, field, isFieldDef, ChannelDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Scale, hasDiscreteDomain} from '../scale';\nimport {SortField, SortOrder} from '../sort';\nimport {BaseSpec, Padding} from '../spec';\nimport {Transform} from '../transform';\nimport {extend, flatten, vals, Dict} from '../util';\nimport {VgData, VgEncodeEntry, VgScale, VgAxis, VgLegend} from '../vega.schema';\nimport {Formula} from '../transform';\nimport {OneOfFilter, EqualFilter, RangeFilter} from '../filter';\n\nimport {DataComponent} from './data/data';\nimport {LayoutComponent} from './layout';\nimport {StackProperties} from '../stack';\n\nimport {SelectionComponent} from './selection/selection';\n\n/**\n * Composable Components that are intermediate results of the parsing phase of the\n * compilations. These composable components will be assembled in the last\n * compilation step.\n */\nexport interface Component {\n data: DataComponent;\n layout: LayoutComponent;\n scales: Dict;\n selection: Dict;\n\n /** Dictionary mapping channel to VgAxis definition */\n axes: Dict;\n\n /** Dictionary mapping channel to VgLegend definition */\n legends: Dict;\n\n /** Dictionary mapping channel to axis mark group for facet and concat */\n axisGroups: Dict;\n\n /** Dictionary mapping channel to grid mark group for facet (and concat?) */\n gridGroups: Dict;\n\n mark: VgEncodeEntry[];\n}\n\nexport class NameMap implements NameMapInterface {\n private nameMap: Dict;\n\n constructor() {\n this.nameMap = {};\n }\n\n public rename(oldName: string, newName: string) {\n this.nameMap[oldName] = newName;\n }\n\n\n public has(name: string): boolean {\n return this.nameMap[name] !== undefined;\n }\n\n public get(name: string): string {\n // If the name appears in the _nameMap, we need to read its new name.\n // We have to loop over the dict just in case the new name also gets renamed.\n while (this.nameMap[name]) {\n name = this.nameMap[name];\n }\n\n return name;\n }\n}\n\nexport interface NameMapInterface {\n rename(oldname: string, newName: string): void;\n has(name: string): boolean;\n get(name: string): string;\n}\n\nexport abstract class Model {\n public readonly parent: Model;\n protected readonly name: string;\n public readonly description: string;\n public readonly padding: Padding;\n\n public readonly data: Data;\n\n /** Name map for data sources, which can be renamed by a model's parent. */\n protected dataNameMap: NameMapInterface;\n\n /** Name map for scales, which can be renamed by a model's parent. */\n protected scaleNameMap: NameMapInterface;\n\n /** Name map for size, which can be renamed by a model's parent. */\n protected sizeNameMap: NameMapInterface;\n\n protected readonly transform: Transform;\n protected abstract readonly scales: Dict = {};\n\n protected abstract readonly axes: Dict = {};\n\n protected abstract readonly legends: Dict = {};\n\n public abstract readonly config: Config;\n\n public component: Component;\n\n public abstract readonly children: Model[] = [];\n\n public abstract stack: StackProperties;\n\n constructor(spec: BaseSpec, parent: Model, parentGivenName: string) {\n this.parent = parent;\n\n // If name is not provided, always use parent's givenName to avoid name conflicts.\n this.name = spec.name || parentGivenName;\n\n // Shared name maps\n this.dataNameMap = parent ? parent.dataNameMap : new NameMap();\n this.scaleNameMap = parent ? parent.scaleNameMap : new NameMap();\n this.sizeNameMap = parent ? parent.sizeNameMap : new NameMap();\n\n this.data = spec.data;\n\n this.description = spec.description;\n this.padding = spec.padding;\n this.transform = spec.transform;\n\n if (spec.transform) {\n if (spec.transform.filterInvalid === undefined &&\n spec.transform['filterNull'] !== undefined) {\n spec.transform.filterInvalid = spec.transform['filterNull'];\n log.warn(log.message.DEPRECATED_FILTER_NULL);\n }\n }\n\n this.component = {data: null, layout: null, mark: null, scales: null, axes: null, axisGroups: null, gridGroups: null, legends: null, selection: null};\n }\n\n\n public parse() {\n this.parseData();\n this.parseLayoutData();\n this.parseScale(); // depends on data name\n this.parseSelection();\n this.parseAxis(); // depends on scale name\n this.parseLegend(); // depends on scale name\n this.parseAxisGroup(); // depends on child axis\n this.parseGridGroup();\n this.parseMark(); // depends on data name and scale name, axisGroup, gridGroup and children's scale, axis, legend and mark.\n }\n\n public abstract parseData(): void;\n\n public abstract parseSelection(): void;\n\n public abstract parseLayoutData(): void;\n\n public abstract parseScale(): void;\n\n public abstract parseMark(): void;\n\n public abstract parseAxis(): void;\n\n public abstract parseLegend(): void;\n\n // TODO: revise if these two methods make sense for shared scale concat\n public abstract parseAxisGroup(): void;\n public abstract parseGridGroup(): void;\n\n public abstract assembleSignals(signals: any[]): any[];\n\n public abstract assembleSelectionData(data: VgData[]): VgData[];\n public abstract assembleData(data: VgData[]): VgData[];\n\n public abstract assembleLayout(layoutData: VgData[]): VgData[];\n\n public assembleScales(): VgScale[] {\n // FIXME: write assembleScales() in scale.ts that\n // help assemble scale domains with scale signature as well\n return flatten(vals(this.component.scales).map((scale: VgScale) => {\n let arr = [scale];\n return arr;\n }));\n }\n\n public abstract assembleMarks(): any[]; // TODO: VgMarkGroup[]\n\n public assembleAxes(): VgAxis[] {\n return [].concat.apply([], vals(this.component.axes));\n }\n\n public assembleLegends(): any[] { // TODO: VgLegend[]\n return vals(this.component.legends);\n }\n\n public assembleGroup() {\n let group: VgEncodeEntry = {};\n\n const signals = this.assembleSignals(group.signals || []);\n if (signals.length > 0) {\n group.signals = signals;\n }\n\n // TODO: consider if we want scales to come before marks in the output spec.\n group.marks = this.assembleMarks();\n const scales = this.assembleScales();\n if (scales.length > 0) {\n group.scales = scales;\n }\n\n const axes = this.assembleAxes();\n if (axes.length > 0) {\n group.axes = axes;\n }\n\n const legends = this.assembleLegends();\n if (legends.length > 0) {\n group.legends = legends;\n }\n\n return group;\n }\n\n public abstract assembleParentGroupProperties(cellConfig: CellConfig): VgEncodeEntry;\n\n public abstract channels(): Channel[];\n\n protected abstract getMapping(): {[key: string]: any};\n\n public reduceFieldDef(f: (acc: U, fd: FieldDef, c: Channel) => U, init: T, t?: any) {\n return reduce(this.getMapping(), (acc:U , cd: ChannelDef, c: Channel) => {\n return isFieldDef(cd) ? f(acc, cd, c) : acc;\n }, init, t);\n }\n\n public forEachFieldDef(f: (fd: FieldDef, c: Channel) => void, t?: any) {\n forEach(this.getMapping(), (cd: ChannelDef, c: Channel) => {\n if (isFieldDef(cd)) {\n f(cd, c);\n }\n }, t);\n }\n\n public hasDescendantWithFieldOnChannel(channel: Channel) {\n for (let child of this.children) {\n if (child.isUnit()) {\n if (child.channelHasField(channel)) {\n return true;\n }\n } else {\n if (child.hasDescendantWithFieldOnChannel(channel)) {\n return true;\n }\n }\n }\n return false;\n }\n\n public abstract channelHasField(channel: Channel): boolean;\n\n public getName(text: string, delimiter: string = '_') {\n if (this.data && text === SOURCE && isNamedData(this.data)) {\n return this.data.name;\n }\n return (this.name ? this.name + delimiter : '') + text;\n }\n\n public renameData(oldName: string, newName: string) {\n this.dataNameMap.rename(oldName, newName);\n }\n\n /**\n * Return the data source name for the given data source type.\n *\n * For unit spec, this is always simply the spec.name + '-' + dataSourceType.\n * We already use the name map so that marks and scales use the correct data.\n */\n public dataName(dataSourceType: DataSourceType): string {\n return this.dataNameMap.get(this.getName(String(dataSourceType)));\n }\n\n public renameSize(oldName: string, newName: string) {\n this.sizeNameMap.rename(oldName, newName);\n }\n\n public channelSizeName(channel: Channel): string {\n return this.sizeName(channel === X || channel === COLUMN ? 'width' : 'height');\n }\n\n public sizeName(size: string): string {\n return this.sizeNameMap.get(this.getName(size, '_'));\n }\n\n public abstract dataTable(): string;\n\n // TRANSFORMS\n public calculate(): Formula[] {\n return this.transform ? this.transform.calculate : undefined;\n }\n\n public filterInvalid(): boolean {\n const transform = this.transform || {};\n if (transform.filterInvalid === undefined) {\n return this.parent ? this.parent.filterInvalid() : undefined;\n }\n return transform.filterInvalid;\n }\n\n public filter(): string | OneOfFilter | EqualFilter| RangeFilter | (string | OneOfFilter | EqualFilter| RangeFilter)[] {\n return this.transform ? this.transform.filter : undefined;\n }\n\n /** Get \"field\" reference for vega */\n public field(channel: Channel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (fieldDef.bin) { // bin has default suffix that depends on scaleType\n opt = extend({\n binSuffix: hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start'\n }, opt);\n }\n\n return field(fieldDef, opt);\n }\n\n public abstract fieldDef(channel: Channel): FieldDef;\n\n public scale(channel: Channel): Scale {\n return this.scales[channel];\n }\n\n public hasDiscreteScale(channel: Channel) {\n const scale = this.scale(channel);\n return scale && hasDiscreteDomain(scale.type);\n }\n\n public renameScale(oldName: string, newName: string) {\n this.scaleNameMap.rename(oldName, newName);\n }\n\n\n /**\n * @return scale name for a given channel after the scale has been parsed and named.\n * (DO NOT USE THIS METHOD DURING SCALE PARSING, use model.name() instead)\n */\n public scaleName(this: Model, originalScaleName: Channel|string, parse?: boolean): string {\n if (parse) {\n // During the parse phase always return a value\n // No need to refer to rename map because a scale can't be renamed\n // before it has the original name.\n return this.getName(originalScaleName + '');\n }\n\n // If there is a scale for the channel, it should either\n // be in the _scale mapping or exist in the name map\n if (\n // in the scale map (the scale is not merged by its parent)\n (this.scale && this.scales[originalScaleName]) ||\n // in the scale name map (the the scale get merged by its parent)\n this.scaleNameMap.has(this.getName(originalScaleName + ''))\n ) {\n return this.scaleNameMap.get(this.getName(originalScaleName + ''));\n }\n return undefined;\n }\n\n public sort(channel: Channel): SortField | SortOrder {\n return (this.getMapping()[channel] || {}).sort;\n }\n\n public axis(channel: Channel): Axis {\n return this.axes[channel];\n }\n\n public legend(channel: Channel): Legend {\n return this.legends[channel];\n }\n\n /**\n * Type checks\n */\n public isUnit() {\n return false;\n }\n public isFacet() {\n return false;\n }\n public isLayer() {\n return false;\n }\n}\n","import * as log from '../../log';\n\nimport {SHARED_DOMAIN_OPS} from '../../aggregate';\nimport {Channel} from '../../channel';\nimport {SOURCE} from '../../data';\nimport {DateTime, isDateTime, timestamp} from '../../datetime';\nimport {Domain, hasDiscreteDomain, isBinScale, Scale, ScaleConfig, ScaleType} from '../../scale';\nimport {isSortField} from '../../sort';\nimport {\n FieldRefUnionDomain,\n DataRefUnionDomain,\n isDataRefDomain,\n isDataRefUnionedDomain,\n isFieldRefUnionDomain,\n isSignalRefDomain,\n VgDataRef,\n VgDomain,\n VgSortField\n} from '../../vega.schema';\n\nimport * as util from '../../util';\n\nimport {Model} from '../model';\nimport {FieldDef} from '../../fielddef';\n\nexport function initDomain(domain: Domain, fieldDef: FieldDef, scale: ScaleType, scaleConfig: ScaleConfig) {\n if (domain === 'unaggregated') {\n const {valid, reason} = canUseUnaggregatedDomain(fieldDef, scale);\n if(!valid) {\n log.warn(reason);\n return undefined;\n }\n } else if (domain === undefined && scaleConfig.useUnaggregatedDomain) {\n // Apply config if domain is not specified.\n const {valid} = canUseUnaggregatedDomain(fieldDef, scale);\n if (valid) {\n return 'unaggregated';\n }\n }\n\n return domain;\n}\n\n\nexport function parseDomain(model: Model, channel: Channel): VgDomain {\n const scale = model.scale(channel);\n\n // If channel is either X or Y then union them with X2 & Y2 if they exist\n if (channel === 'x' && model.channelHasField('x2')) {\n if (model.channelHasField('x')) {\n return unionDomains(parseSingleChannelDomain(scale, model, 'x'), parseSingleChannelDomain(scale, model, 'x2'));\n } else {\n return parseSingleChannelDomain(scale, model, 'x2');\n }\n } else if (channel === 'y' && model.channelHasField('y2')) {\n if (model.channelHasField('y')) {\n return unionDomains(parseSingleChannelDomain(scale, model, 'y'), parseSingleChannelDomain(scale, model, 'y2'));\n } else {\n return parseSingleChannelDomain(scale, model, 'y2');\n }\n }\n return parseSingleChannelDomain(scale, model, channel);\n}\n\nfunction parseSingleChannelDomain(scale: Scale, model: Model, channel:Channel): VgDomain {\n const fieldDef = model.fieldDef(channel);\n\n if (scale.domain && scale.domain !== 'unaggregated') { // explicit value\n if (isDateTime(scale.domain[0])) {\n return (scale.domain as DateTime[]).map((dt) => {\n return timestamp(dt, true);\n });\n }\n return scale.domain;\n }\n\n // special case for temporal scale\n if (fieldDef.type === 'temporal') {\n return {\n data: model.dataTable(),\n field: model.field(channel),\n sort: {\n field: model.field(channel),\n op: 'min'\n }\n };\n }\n\n // For stack, use STACKED data.\n const stack = model.stack;\n if (stack && channel === stack.fieldChannel) {\n if(stack.offset === 'normalize') {\n return [0, 1];\n }\n return {\n data: model.dataName('stacked'),\n fields: [\n model.field(channel, {suffix: 'start'}),\n model.field(channel, {suffix: 'end'})\n ]\n };\n }\n\n const sort = domainSort(model, channel, scale.type);\n\n if (scale.domain === 'unaggregated') {\n return {\n data: model.dataTable(),\n fields: [\n model.field(channel, {aggregate: 'min'}),\n model.field(channel, {aggregate: 'max'})\n ]\n };\n } else if (fieldDef.bin) { // bin\n if (isBinScale(scale.type)) {\n const field = model.getName(fieldDef.field + '_bins');\n return {signal: `sequence(${field}.start, ${field}.stop + ${field}.step, ${field}.step)`};\n }\n\n if (hasDiscreteDomain(scale.type)) {\n // ordinal bin scale takes domain from bin_range, ordered by bin_start\n // This is useful for both axis-based scale (x, y, column, and row) and legend-based scale (other channels).\n return {\n data: model.dataTable(),\n field: model.field(channel, {binSuffix: 'range'}),\n sort: {\n field: model.field(channel, {binSuffix: 'start'}),\n op: 'min' // min or max doesn't matter since same _range would have the same _start\n }\n };\n } else { // continuous scales\n if (channel === 'x' || channel === 'y') {\n // X/Y position have to include start and end for non-ordinal scale\n return {\n data: model.dataTable(),\n fields: [\n model.field(channel, {binSuffix: 'start'}),\n model.field(channel, {binSuffix: 'end'})\n ]\n };\n } else {\n // TODO: use bin_mid\n return {\n data: model.dataTable(),\n field: model.field(channel, {binSuffix: 'start'})\n };\n }\n }\n } else if (sort) { // have sort -- only for ordinal\n return {\n // If sort by aggregation of a specified sort field, we need to use SOURCE table,\n // so we can aggregate values for the scale independently from the main aggregation.\n data: util.isBoolean(sort) ? model.dataTable(): SOURCE,\n field: model.field(channel),\n sort: sort\n };\n } else {\n return {\n data: model.dataTable(),\n field: model.field(channel),\n };\n }\n}\n\nexport function domainSort(model: Model, channel: Channel, scaleType: ScaleType): VgSortField {\n if (!hasDiscreteDomain(scaleType)) {\n return undefined;\n }\n\n const sort = model.sort(channel);\n\n // Sorted based on an aggregate calculation over a specified sort field (only for ordinal scale)\n if (isSortField(sort)) {\n return {\n op: sort.op,\n field: sort.field\n };\n }\n\n if (util.contains(['ascending', 'descending', undefined /* default =ascending*/], sort)) {\n return true;\n }\n\n // sort === 'none'\n return undefined;\n}\n\n\n\n/**\n * Determine if a scale can use unaggregated domain.\n * @return {Boolean} Returns true if all of the following conditons applies:\n * 1. `scale.domain` is `unaggregated`\n * 2. Aggregation function is not `count` or `sum`\n * 3. The scale is quantitative or time scale.\n */\nexport function canUseUnaggregatedDomain(fieldDef: FieldDef, scaleType: ScaleType): {valid: boolean, reason?: string} {\n if (!fieldDef.aggregate) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainHasNoEffectForRawField(fieldDef)\n };\n }\n\n if (SHARED_DOMAIN_OPS.indexOf(fieldDef.aggregate) === -1) {\n return {\n valid: false,\n reason: log.message.unaggregateDomainWithNonSharedDomainOp(fieldDef.aggregate)\n };\n }\n\n if (fieldDef.type === 'quantitative') {\n if (scaleType === 'log') {\n return {\n valid: false,\n reason: log.message.unaggregatedDomainWithLogScale(fieldDef)\n };\n }\n }\n\n return {valid: true};\n}\n\n/**\n * Scale domains that we can union. We cannot union signal domains we use for\n * binned data because they have to be exactly the same. Otherwise it doesn't\n * make any sense to union.\n */\ntype UnionableDomain = any[] | VgDataRef | DataRefUnionDomain | FieldRefUnionDomain;\n\n/**\n * Convert the domain to an array of data refs or an array of values. Also, throw\n * away sorting information since we always sort the domain when we union two domains.\n */\nfunction normalizeDomain(domain: UnionableDomain): (any[] | VgDataRef)[] {\n if (util.isArray(domain)) {\n return [domain];\n } else if (isDataRefDomain(domain)) {\n delete domain.sort;\n return [domain];\n } else if(isFieldRefUnionDomain(domain)) {\n return domain.fields.map(d => {\n return {\n data: domain.data,\n field: d\n };\n });\n } else if (isDataRefUnionedDomain(domain)) {\n return domain.fields.map(d => {\n if (util.isArray(d)) {\n return d;\n }\n return {\n field: d.field,\n data: d.data\n };\n });\n }\n /* istanbul ignore next: This should never happen. */\n throw new Error(log.message.INVAID_DOMAIN);\n}\n\n/**\n * Union two data domains. A unioned domain is always sorted.\n */\nexport function unionDomains(domain1: VgDomain, domain2: VgDomain): VgDomain {\n if (isSignalRefDomain(domain1) || isSignalRefDomain(domain2)) {\n if (!isSignalRefDomain(domain1) || !isSignalRefDomain(domain2) || domain1.signal !== domain2.signal) {\n throw new Error(log.message.UNABLE_TO_MERGE_DOMAINS);\n }\n return domain1;\n }\n\n const normalizedDomain1 = normalizeDomain(domain1);\n const normalizedDomain2 = normalizeDomain(domain2);\n\n let domains = normalizedDomain1.concat(normalizedDomain2);\n domains = util.unique(domains, util.hash);\n\n if (domains.length > 1) {\n const allData = domains.map(d => {\n if (isDataRefDomain(d)) {\n return d.data;\n }\n return null;\n });\n\n if (util.unique(allData, x => x).length === 1 && allData[0] !== null) {\n return {\n data: allData[0],\n fields: domains.map(d => (d as VgDataRef).field)\n };\n }\n\n return {fields: domains, sort: true};\n } else {\n return domains[0];\n }\n}\n","import * as log from '../../log';\n\nimport {Config} from '../../config';\nimport {Channel} from '../../channel';\nimport {ScaleFieldDef, FieldDef} from '../../fielddef';\nimport {Mark} from '../../mark';\nimport {Scale, ScaleConfig, scaleTypeSupportProperty, channelScalePropertyIncompatability} from '../../scale';\n\nimport {initDomain} from './domain';\nimport rangeMixins from './range';\nimport * as rules from './rules';\nimport scaleType from './type';\nimport * as util from '../../util';\n\n/**\n * All scale properties except type and all range properties.\n */\nexport const NON_TYPE_RANGE_SCALE_PROPERTIES: (keyof Scale)[] = [\n // general properties\n 'domain', // For domain, we only copy specified value here. Default value is determined during parsing phase.\n 'round',\n // quantitative / time\n 'clamp', 'nice',\n // quantitative\n 'exponent', 'zero', // zero depends on domain\n 'interpolate',\n // ordinal\n 'padding', 'paddingInner', 'paddingOuter' // padding\n];\n\n/**\n * Initialize Vega-Lite Scale's properties\n *\n * Note that we have to apply these rules here because:\n * - many other scale and non-scale properties (including layout, mark) depend on scale type\n * - layout depends on padding\n * - range depends on zero and size (width and height) depends on range\n */\nexport default function init(\n channel: Channel, fieldDef: ScaleFieldDef, config: Config,\n mark: Mark | undefined, topLevelSize: number | undefined, xyRangeSteps: number[]): Scale {\n const specifiedScale = (fieldDef || {}).scale || {};\n\n const scale: Scale = {\n type: scaleType(\n specifiedScale.type, channel, fieldDef, mark, topLevelSize !== undefined,\n specifiedScale.rangeStep, config.scale\n )\n };\n\n // Use specified value if compatible or determine default values for each property\n NON_TYPE_RANGE_SCALE_PROPERTIES.forEach(function(property) {\n const specifiedValue = specifiedScale[property];\n\n const supportedByScaleType = scaleTypeSupportProperty(scale.type, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n\n if (specifiedValue !== undefined) {\n // If there is a specified value, check if it is compatible with scale type and channel\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scale.type, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n }\n }\n if (supportedByScaleType && channelIncompatability === undefined) {\n const value = getValue(specifiedValue, property, scale, channel, fieldDef, config.scale);\n if (value !== undefined) { // use the default value\n scale[property] = value;\n }\n }\n });\n\n return util.extend(\n scale,\n rangeMixins(\n channel, scale.type, fieldDef.type, specifiedScale, config,\n scale.zero, mark, topLevelSize, xyRangeSteps\n )\n );\n}\n\nfunction getValue(specifiedValue: any, property: keyof Scale, scale: Scale, channel: Channel, fieldDef: FieldDef, scaleConfig: ScaleConfig) {\n // For domain, we might override specified value\n if (property === 'domain') {\n return initDomain(specifiedValue, fieldDef, scale.type, scaleConfig);\n }\n\n // Other properties, no overriding default values\n if (specifiedValue !== undefined) {\n return specifiedValue;\n }\n return getDefaultValue(property, scale, channel, fieldDef, scaleConfig);\n}\n\nfunction getDefaultValue(property: keyof Scale, scale: Scale, channel: Channel, fieldDef: FieldDef, scaleConfig: ScaleConfig) {\n\n // If we have default rule-base, determine default value first\n switch (property) {\n case 'nice':\n return rules.nice(scale.type, channel, fieldDef);\n case 'padding':\n return rules.padding(channel, scale.type, scaleConfig);\n case 'paddingInner':\n return rules.paddingInner(scale.padding, channel, scaleConfig);\n case 'paddingOuter':\n return rules.paddingOuter(scale.padding, channel, scale.type, scale.paddingInner, scaleConfig);\n case 'round':\n return rules.round(channel, scaleConfig);\n case 'zero':\n return rules.zero(scale, channel, fieldDef);\n }\n // Otherwise, use scale config\n return scaleConfig[property];\n}\n","import {Channel} from '../../channel';\nimport {Scale} from '../../scale';\nimport {isSortField} from '../../sort';\nimport {Dict} from '../../util';\n\nimport {Model} from '../model';\n\nimport {parseDomain} from './domain';\nimport {parseRange} from './range';\nimport {VgScale} from '../../vega.schema';\n\n/**\n * Parse scales for all channels of a model.\n */\nexport default function parseScaleComponent(model: Model): Dict {\n // TODO: should model.channels() inlcude X2/Y2?\n return model.channels().reduce(function(scaleComponentsIndex: Dict, channel: Channel) {\n const scaleComponents = parseScale(model, channel);\n if (scaleComponents) {\n scaleComponentsIndex[channel] = scaleComponents;\n }\n return scaleComponentsIndex;\n }, {});\n}\n\nexport const NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES: (keyof Scale)[] = [\n 'round',\n // quantitative / time\n 'clamp', 'nice',\n // quantitative\n 'exponent', 'interpolate', 'zero', // zero depends on domain\n // ordinal\n 'padding', 'paddingInner', 'paddingOuter', // padding\n];\n\n/**\n * Parse scales for a single channel of a model.\n */\nexport function parseScale(model: Model, channel: Channel) {\n if (!model.scale(channel)) {\n return null;\n }\n\n const scale = model.scale(channel);\n const sort = model.sort(channel);\n\n let scaleComponent: VgScale = {\n name: model.scaleName(channel + '', true),\n type: scale.type,\n domain: parseDomain(model, channel),\n range: parseRange(scale)\n };\n\n NON_TYPE_DOMAIN_RANGE_VEGA_SCALE_PROPERTIES.forEach((property) => {\n scaleComponent[property] = scale[property];\n });\n\n if (sort && (isSortField(sort) ? sort.order : sort) === 'descending') {\n scaleComponent.reverse = true;\n }\n return scaleComponent;\n}\n","import * as log from '../../log';\n\nimport {COLUMN, ROW, X, Y, SHAPE, SIZE, COLOR, OPACITY, Channel} from '../../channel';\nimport {Config} from '../../config';\nimport {Mark} from '../../mark';\nimport {Scale, ScaleConfig, ScaleType, scaleTypeSupportProperty, Scheme, Range, isExtendedScheme, channelScalePropertyIncompatability} from '../../scale';\nimport {Type} from '../../type';\nimport {VgRange, VgRangeScheme} from '../../vega.schema';\nimport * as util from '../../util';\n\nexport type RangeMixins = {range: Range} | {rangeStep: number} | {scheme: Scheme};\n\nexport function parseRange(scale: Scale): VgRange {\n if (scale.rangeStep) {\n return {step: scale.rangeStep};\n } else if (scale.scheme) {\n const scheme = scale.scheme;\n if (isExtendedScheme(scheme)) {\n let r: VgRangeScheme = {scheme: scheme.name};\n if (scheme.count) {\n r.count = scheme.count;\n }\n if (scheme.extent) {\n r.extent = scheme.extent;\n }\n return r;\n } else {\n return {scheme};\n }\n }\n return scale.range;\n}\n\nexport const RANGE_PROPERTIES: (keyof Scale)[] = ['range', 'rangeStep', 'scheme'];\n\n/**\n * Return mixins that includes one of the range properties (range, rangeStep, scheme).\n */\nexport default function rangeMixins(\n channel: Channel, scaleType: ScaleType, type: Type, specifiedScale: Scale, config: Config,\n zero: boolean, mark: Mark, topLevelSize: number | undefined, xyRangeSteps: number[]): RangeMixins {\n\n let specifiedRangeStepIsNull = false;\n\n // Check if any of the range properties is specified.\n // If so, check if it is compatible and make sure that we only output one of the properties\n for (let property of RANGE_PROPERTIES) {\n if (specifiedScale[property] !== undefined) {\n let supportedByScaleType = scaleTypeSupportProperty(scaleType, property);\n const channelIncompatability = channelScalePropertyIncompatability(channel, property);\n if (!supportedByScaleType) {\n log.warn(log.message.scalePropertyNotWorkWithScaleType(scaleType, property, channel));\n } else if (channelIncompatability) { // channel\n log.warn(channelIncompatability);\n } else {\n switch (property) {\n case 'range':\n return {range: specifiedScale[property]};\n case 'scheme':\n return {scheme: specifiedScale[property]};\n case 'rangeStep':\n if (topLevelSize === undefined) {\n const stepSize = specifiedScale[property];\n if (stepSize !== null) {\n return {rangeStep: stepSize};\n } else {\n specifiedRangeStepIsNull = true;\n }\n } else {\n // If top-level size is specified, we ignore specified rangeStep.\n log.warn(log.message.rangeStepDropped(channel));\n }\n }\n }\n }\n }\n\n switch (channel) {\n // TODO: revise row/column when facetSpec has top-level width/height\n case ROW:\n return {range: 'height'};\n case COLUMN:\n return {range: 'width'};\n case X:\n case Y:\n if (topLevelSize === undefined) {\n if (util.contains(['point', 'band'], scaleType) && !specifiedRangeStepIsNull) { // FIXME isDiscrete blah blah\n if (channel === X && mark === 'text') {\n if (config.scale.textXRangeStep) {\n return {rangeStep: config.scale.textXRangeStep};\n }\n } else {\n if (config.scale.rangeStep) {\n return {rangeStep: config.scale.rangeStep};\n }\n }\n }\n // If specified range step is null or the range step config is null.\n // Use default topLevelSize rule/config\n topLevelSize = channel === X ? config.cell.width : config.cell.height;\n }\n return {range: channel === X ? [0, topLevelSize] : [topLevelSize, 0]};\n\n case SIZE:\n // TODO: support custom rangeMin, rangeMax\n const rangeMin = sizeRangeMin(mark, zero, config);\n const rangeMax = sizeRangeMax(mark, xyRangeSteps, config);\n return {range: [rangeMin, rangeMax]};\n case SHAPE:\n case COLOR:\n return {range: defaultRange(channel, scaleType, type, mark)};\n\n\n case OPACITY:\n // TODO: support custom rangeMin, rangeMax\n return {range: [config.scale.minOpacity, config.scale.maxOpacity]};\n }\n /* istanbul ignore next: should never reach here */\n throw new Error(`Scale range undefined for channel ${channel}`);\n}\n\nfunction defaultRange(channel: 'shape' | 'color', scaleType: ScaleType, type: Type, mark: Mark) {\n switch (channel) {\n case SHAPE:\n return 'symbol';\n case COLOR:\n if (scaleType === 'ordinal') {\n // Only nominal data uses ordinal scale by default\n return type === 'nominal' ? 'category' : 'ordinal';\n }\n return mark === 'rect' ? 'heatmap' : 'ramp';\n }\n}\n\nfunction sizeRangeMin(mark: Mark, zero: boolean, config: Config) {\n if (zero) {\n return 0;\n }\n switch (mark) {\n case 'bar':\n return config.scale.minBandSize !== undefined ? config.scale.minBandSize : config.bar.continuousBandSize;\n case 'tick':\n return config.scale.minBandSize;\n case 'line':\n case 'rule':\n return config.scale.minStrokeWidth;\n case 'text':\n return config.scale.minFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.minSize) {\n return config.scale.minSize;\n }\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMin not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\nfunction sizeRangeMax(mark: Mark, xyRangeSteps: number[], config: Config) {\n const scaleConfig = config.scale;\n // TODO(#1168): make max size scale based on rangeStep / overall plot size\n switch (mark) {\n case 'bar':\n case 'tick':\n if (config.scale.maxBandSize !== undefined) {\n return config.scale.maxBandSize;\n }\n return minXYRangeStep(xyRangeSteps, config.scale) - 1;\n case 'line':\n case 'rule':\n return config.scale.maxStrokeWidth;\n case 'text':\n return config.scale.maxFontSize;\n case 'point':\n case 'square':\n case 'circle':\n if (config.scale.maxSize) {\n return config.scale.maxSize;\n }\n\n // FIXME this case totally should be refactored\n const pointStep = minXYRangeStep(xyRangeSteps, scaleConfig);\n return (pointStep - 2) * (pointStep - 2);\n }\n /* istanbul ignore next: should never reach here */\n // sizeRangeMax not implemented for the mark\n throw new Error(log.message.incompatibleChannel('size', mark));\n}\n\n/**\n * @returns {number} Range step of x or y or minimum between the two if both are ordinal scale.\n */\nfunction minXYRangeStep(xyRangeSteps: number[], scaleConfig: ScaleConfig): number {\n if (xyRangeSteps.length > 0) {\n return Math.min.apply(null, xyRangeSteps);\n }\n if (scaleConfig.rangeStep) {\n return scaleConfig.rangeStep;\n }\n return 21; // FIXME: re-evaluate the default value here.\n}\n","\nimport {X, Y, Channel} from '../../channel';\nimport {FieldDef} from '../../fielddef';\nimport {Scale, ScaleConfig, ScaleType, NiceTime} from '../../scale';\nimport {smallestUnit} from '../../timeunit';\nimport * as util from '../../util';\n\nexport function nice(scaleType: ScaleType, channel: Channel, fieldDef: FieldDef): boolean | NiceTime {\n if (util.contains([ScaleType.TIME, ScaleType.UTC], scaleType)) {\n return smallestUnit(fieldDef.timeUnit) as any;\n }\n return util.contains([X, Y], channel); // return true for quantitative X/Y\n}\n\nexport function padding(channel: Channel, scaleType: ScaleType, scaleConfig: ScaleConfig) {\n if (util.contains([X, Y], channel)) {\n if (scaleType === ScaleType.POINT) {\n return scaleConfig.pointPadding;\n }\n }\n return undefined;\n}\n\nexport function paddingInner(padding: number, channel: Channel, scaleConfig: ScaleConfig) {\n if (padding !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingInner.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n\n // paddingOuter would only be called if it's a band scale, just return the default for bandScale.\n return scaleConfig.bandPaddingInner;\n }\n return undefined;\n}\n\nexport function paddingOuter(padding: number, channel: Channel, scaleType: ScaleType, paddingInner: number, scaleConfig: ScaleConfig) {\n if (padding !== undefined) {\n // If user has already manually specified \"padding\", no need to add default paddingOuter.\n return undefined;\n }\n\n if (util.contains([X, Y], channel)) {\n // Padding is only set for X and Y by default.\n // Basically it doesn't make sense to add padding for color and size.\n if (scaleType === ScaleType.BAND) {\n if (scaleConfig.bandPaddingOuter !== undefined) {\n return scaleConfig.bandPaddingOuter;\n }\n /* By default, paddingOuter is paddingInner / 2. The reason is that\n size (width/height) = step * (cardinality - paddingInner + 2 * paddingOuter).\n and we want the width/height to be integer by default.\n Note that step (by default) and cardinality are integers.) */\n return paddingInner / 2;\n }\n }\n return undefined;\n}\n\nexport function round(channel: Channel, scaleConfig: ScaleConfig) {\n if (util.contains(['x', 'y', 'row', 'column'], channel)) {\n return scaleConfig.round;\n }\n return undefined;\n}\n\nexport function zero(specifiedScale: Scale, channel: Channel, fieldDef: FieldDef) {\n // By default, return true only for the following cases:\n\n // 1) using quantitative field with size\n // While this can be either ratio or interval fields, our assumption is that\n // ratio are more common.\n if (channel === 'size' && fieldDef.type === 'quantitative') {\n return true;\n }\n\n // 2) non-binned, quantitative x-scale or y-scale if no custom domain is provided.\n // (For binning, we should not include zero by default because binning are calculated without zero.\n // Similar, if users explicitly provide a domain range, we should not augment zero as that will be unexpected.)\n if (!specifiedScale.domain && !fieldDef.bin && util.contains([X, Y], channel)) {\n return true;\n }\n return false;\n}\n","import * as log from '../../log';\n\nimport {hasScale, supportScaleType, rangeType, Channel} from '../../channel';\nimport {Mark} from '../../mark';\nimport {ScaleType, ScaleConfig} from '../../scale';\nimport {isDiscreteByDefault} from '../../timeunit';\n\nimport * as util from '../../util';\nimport {FieldDef} from '../../fielddef';\n\nexport type RangeType = 'continuous' | 'discrete' | 'flexible' | undefined;\n\n/**\n * Determine if there is a specified scale type and if it is appropriate,\n * or determine default type if type is unspecified or inappropriate.\n */\n// NOTE: CompassQL uses this method.\nexport default function type(\n specifiedType: ScaleType, channel: Channel, fieldDef: FieldDef, mark: Mark,\n hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType {\n\n const defaultScaleType = defaultType(channel, fieldDef, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n\n if (!hasScale(channel)) {\n // There is no scale for these channels\n return null;\n }\n if (specifiedType !== undefined) {\n // for binned fields we don't allow overriding the default scale\n if (fieldDef.bin) {\n // TODO: generalize this as a method in fieldDef that determines scale type support for a fieldDef (looking at functions and type)\n log.warn(log.message.cannotOverrideBinScaleType(channel, defaultScaleType));\n return defaultScaleType;\n }\n\n // Check if explicitly specified scale type is supported by the channel\n if (supportScaleType(channel, specifiedType)) {\n return specifiedType;\n } else {\n log.warn(log.message.scaleTypeNotWorkWithChannel(channel, specifiedType, defaultScaleType));\n return defaultScaleType;\n }\n }\n\n return defaultScaleType;\n}\n\n/**\n * Determine appropriate default scale type.\n */\nfunction defaultType(channel: Channel, fieldDef: FieldDef, mark: Mark,\n hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType {\n\n if (util.contains(['row', 'column'], channel)) {\n return 'band';\n }\n\n switch (fieldDef.type) {\n case 'nominal':\n if (channel === 'color' || rangeType(channel) === 'discrete') {\n return 'ordinal';\n }\n return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n\n case 'ordinal':\n if (channel === 'color') {\n return 'ordinal';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'ordinal'));\n return 'ordinal';\n }\n return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n\n case 'temporal':\n if (channel === 'color') {\n // Always use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'temporal'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n if (isDiscreteByDefault(fieldDef.timeUnit)) {\n return discreteToContinuousType(channel, mark, hasTopLevelSize, specifiedRangeStep, scaleConfig);\n }\n return 'time';\n\n case 'quantitative':\n if (channel === 'color') {\n if (fieldDef.bin) {\n return 'bin-ordinal';\n }\n // Use `sequential` as the default color scale for continuous data\n // since it supports both array range and scheme range.\n return 'sequential';\n } else if (rangeType(channel) === 'discrete') {\n log.warn(log.message.discreteChannelCannotEncode(channel, 'quantitative'));\n // TODO: consider using quantize (equivalent to binning) once we have it\n return 'ordinal';\n }\n\n if (fieldDef.bin) {\n return 'bin-linear';\n }\n return 'linear';\n }\n\n /* istanbul ignore next: should never reach this */\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\n/**\n * Determines default scale type for nominal/ordinal field.\n * @returns BAND or POINT scale based on channel, mark, and rangeStep\n */\nfunction discreteToContinuousType(\n channel: Channel, mark: Mark, hasTopLevelSize: boolean,\n specifiedRangeStep: number, scaleConfig: ScaleConfig): ScaleType {\n\n if (util.contains(['x', 'y'], channel)) {\n if (mark === 'rect') {\n // The rect mark should fit into a band.\n return 'band';\n }\n if (mark === 'bar') {\n // For bar, use band only if there is no rangeStep since we need to use band for fit mode.\n // However, for non-fit mode, point scale provides better center position.\n if (haveRangeStep(hasTopLevelSize, specifiedRangeStep, scaleConfig)) {\n return 'point';\n }\n return 'band';\n }\n }\n // Otherwise, use ordinal point scale so we can easily get center positions of the marks.\n return 'point';\n}\n\nfunction haveRangeStep(hasTopLevelSize: boolean, specifiedRangeStep: number, scaleConfig: ScaleConfig) {\n if (hasTopLevelSize) {\n // if topLevelSize is provided, rangeStep will be dropped.\n return false;\n }\n if (specifiedRangeStep !== undefined) {\n return specifiedRangeStep !== null;\n }\n return !!scaleConfig.rangeStep;\n}\n","import {SelectionComponent, SelectionCompiler, TUPLE, invert as invertFn, channelSignalName} from './selection';\nimport {X, Y, Channel} from '../../channel';\nimport {UnitModel} from '../unit';\nimport {stringValue, extend} from '../../util';\nimport {warn} from '../../log';\nimport scales from './transforms/scales';\n\nexport const BRUSH = '_brush',\n SIZE = '_size';\n\nconst interval:SelectionCompiler = {\n predicate: 'vlInterval',\n\n signals: function(model, selCmpt) {\n let signals: any[] = [],\n intervals:any[] = [],\n name = selCmpt.name,\n size = name + SIZE;\n\n if (selCmpt.translate && !(scales.has(selCmpt))) {\n events(selCmpt, function(_: any[], evt: any) {\n let filters = evt.between[0].filter || (evt.between[0].filter = []);\n filters.push('!event.item || (event.item && ' +\n `event.item.mark.name !== ${stringValue(name + BRUSH)})`);\n });\n }\n\n selCmpt.project.forEach(function(p) {\n if (p.encoding !== X && p.encoding !== Y) {\n warn('Interval selections only support x and y encoding channels.');\n return;\n }\n\n let cs = channelSignal(model, selCmpt, p.encoding);\n signals.push(cs);\n intervals.push(`{field: ${stringValue(p.field)}, extent: ${cs.name}}`);\n });\n\n signals.push({\n name: size,\n value: [],\n on: events(selCmpt, function(on: any[], evt: any) {\n on.push({\n events: evt.between[0],\n update: '{x: x(unit), y: y(unit), width: 0, height: 0}'\n });\n\n on.push({\n events: evt,\n update: `{x: ${size}.x, y: ${size}.y, ` +\n `width: abs(x(unit) - ${size}.x), height: abs(y(unit) - ${size}.y)}`\n });\n\n return on;\n })\n }, {\n name: name,\n update: `[${intervals.join(', ')}]`\n });\n\n return signals;\n },\n\n tupleExpr: function(model, selCmpt) {\n return `intervals: ${selCmpt.name}`;\n },\n\n modifyExpr: function(model, selCmpt) {\n let tpl = selCmpt.name + TUPLE;\n return `${tpl}, {unit: ${tpl}.unit}`;\n },\n\n marks: function(model, selCmpt, marks) {\n let name = selCmpt.name,\n {x, y} = projections(selCmpt);\n\n // Do not add a brush if we're binding to scales.\n if (scales.has(selCmpt)) {\n return marks;\n }\n\n let update = {\n x: extend({}, x !== null ?\n {scale: model.scaleName(X), signal: `${name}[${x}].extent[0]`} :\n {value: 0}),\n\n x2: extend({}, x !== null ?\n {scale: model.scaleName(X), signal: `${name}[${x}].extent[1]`} :\n {field: {group: 'width'}}),\n\n y: extend({}, y !== null ?\n {scale: model.scaleName(Y), signal: `${name}[${y}].extent[0]`} :\n {value: 0}),\n\n y2: extend({}, y !== null ?\n {scale: model.scaleName(Y), signal: `${name}[${y}].extent[1]`} :\n {field: {group: 'height'}}),\n };\n\n return [{\n name: undefined,\n type: 'rect',\n encode: {\n enter: {fill: {value: '#eee'}},\n update: update\n }\n }].concat(marks, {\n name: name + BRUSH,\n type: 'rect',\n encode: {\n enter: {fill: {value: 'transparent'}},\n update: update\n }\n });\n }\n};\nexport {interval as default};\n\nexport function projections(selCmpt: SelectionComponent) {\n let x:number = null, y:number = null;\n selCmpt.project.forEach(function(p, i) {\n if (p.encoding === X) {\n x = i;\n } else if (p.encoding === Y) {\n y = i;\n }\n });\n return {x: x, y: y};\n}\n\nfunction channelSignal(model: UnitModel, selCmpt: SelectionComponent, channel: Channel): any {\n let name = channelSignalName(selCmpt, channel),\n size = (channel === X ? 'width' : 'height'),\n coord = `${channel}(unit)`,\n invert = invertFn.bind(null, model, selCmpt, channel);\n\n return {\n name: name,\n value: [],\n on: scales.has(selCmpt) ? [] : events(selCmpt, function(on: any[], evt: any) {\n on.push({\n events: evt.between[0],\n update: invert(`[${coord}, ${coord}]`)\n });\n\n on.push({\n events: evt,\n update: `[${name}[0], ` + invert(`clamp(${coord}, 0, ${size})`) + ']'\n });\n\n return on;\n })\n };\n}\n\nfunction events(selCmpt: SelectionComponent, cb: Function) {\n return selCmpt.events.reduce(function(on: any[], evt: any) {\n if (!evt.between) {\n warn(`${evt} is not an ordered event stream for interval selections`);\n return on;\n }\n return cb(on, evt);\n }, []);\n}\n","import {TUPLE, SelectionCompiler} from './selection';\nimport {stringValue} from '../../util';\n\nconst multi:SelectionCompiler = {\n predicate: 'vlPoint',\n\n signals: function(model, selCmpt) {\n let proj = selCmpt.project,\n datum = '(item().isVoronoi ? datum.datum : datum)',\n fields = proj.map((p) => stringValue(p.field)).join(', '),\n values = proj.map((p) => `${datum}[${stringValue(p.field)}]`).join(', ');\n return [{\n name: selCmpt.name,\n value: {},\n on: [{\n events: selCmpt.events,\n update: `{fields: [${fields}], values: [${values}]}`\n }]\n }];\n },\n\n tupleExpr: function(model, selCmpt) {\n let name = selCmpt.name;\n return `fields: ${name}.fields, values: ${name}.values`;\n },\n\n modifyExpr: function(model, selCmpt) {\n return selCmpt.name + TUPLE;\n }\n};\n\nexport {multi as default};\n","import {SelectionDef, SelectionDomain, SelectionResolutions, SelectionTypes} from '../../selection';\nimport {SelectionComponent} from './selection';\nimport {Model} from '../model';\nimport {UnitModel} from '../unit';\nimport {Channel} from '../../channel';\nimport {Dict, extend, stringValue, isString} from '../../util';\nimport {forEachTransform} from './transforms/transforms';\nimport parseSelector from 'vega-parser/src/parsers/event-selector';\nimport {VgData, VgBinding} from '../../vega.schema';\nimport singleCompiler from './single';\nimport multiCompiler from './multi';\nimport intervalCompiler from './interval';\n\nexport const STORE = '_store',\n TUPLE = '_tuple',\n MODIFY = '_modify';\n\nexport interface SelectionComponent {\n name: string;\n type: SelectionTypes;\n domain: SelectionDomain;\n events: any;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n resolve: SelectionResolutions;\n\n // Transforms\n project?: ProjectComponent[];\n scales?: Channel[];\n toggle?: any;\n translate?: any;\n zoom?: any;\n nearest?: any;\n}\n\nexport interface ProjectComponent {\n field?: string;\n encoding?: Channel;\n}\n\nexport interface SelectionCompiler {\n signals: (model: UnitModel, selCmpt: SelectionComponent) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent) => any[];\n tupleExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n modifyExpr: (model: UnitModel, selCmpt: SelectionComponent) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[]) => any[];\n predicate: string; // Vega expr string to determine inclusion in selection.\n}\n\nexport function parseUnitSelection(model: UnitModel, selDefs: Dict) {\n let selCmpts: Dict = {},\n selectionConfig = model.config.selection;\n\n for (let name in selDefs) {\n if (!selDefs.hasOwnProperty(name)) {\n continue;\n }\n\n let selDef = selDefs[name],\n cfg = selectionConfig[selDef.type];\n\n // Set default values from config if a property hasn't been specified,\n // or if it is true. E.g., \"translate\": true should use the default\n // event handlers for translate. However, true may be a valid value for\n // a property (e.g., \"nearest\": true).\n for (let key in cfg) {\n // A selection should contain either `encodings` or `fields`, only use\n // default values for these two values if neither of them is specified.\n if ((key === 'encodings' && selDef.fields) || (key === 'fields' && selDef.encodings)) {\n continue;\n }\n\n if (selDef[key] === undefined || selDef[key] === true) {\n selDef[key] = cfg[key] || selDef[key];\n }\n }\n\n let selCmpt = selCmpts[name] = extend({}, selDef, {\n name: model.getName(name),\n events: isString(selDef.on) ? parseSelector(selDef.on, 'scope') : selDef.on,\n domain: 'data' as SelectionDomain, // TODO: Support def.domain\n resolve: 'union' as SelectionResolutions\n }) as SelectionComponent;\n\n forEachTransform(selCmpt, function(txCompiler) {\n if (txCompiler.parse) {\n txCompiler.parse(model, selDef, selCmpt);\n }\n });\n }\n\n return selCmpts;\n}\n\nexport function assembleUnitSignals(model: UnitModel, signals: any[]) {\n forEachSelection(model, function(selCmpt, selCompiler) {\n let name = selCmpt.name,\n tupleExpr = selCompiler.tupleExpr(model, selCmpt),\n modifyExpr = selCompiler.modifyExpr(model, selCmpt);\n\n signals.push.apply(signals, selCompiler.signals(model, selCmpt));\n\n forEachTransform(selCmpt, function(txCompiler) {\n if (txCompiler.signals) {\n signals = txCompiler.signals(model, selCmpt, signals);\n }\n if (txCompiler.modifyExpr) {\n modifyExpr = txCompiler.modifyExpr(model, selCmpt, modifyExpr);\n }\n });\n\n signals.push({\n name: name + TUPLE,\n on: [{\n events: {signal: name},\n update: `{unit: unit.datum && unit.datum._id, ${tupleExpr}}`\n }]\n }, {\n name: name + MODIFY,\n on: [{\n events: {signal: name},\n update: `modify(${stringValue(name + STORE)}, ${modifyExpr})`\n }]\n });\n });\n\n return signals;\n}\n\nexport function assembleTopLevelSignals(model: Model) {\n let signals:any[] = [{\n name: 'unit',\n value: {},\n on: [{events: 'mousemove', update: 'group()._id ? group() : unit'}]\n }];\n\n forEachSelection(model, function(selCmpt, selCompiler) {\n if (selCompiler.topLevelSignals) {\n signals.push.apply(signals, selCompiler.topLevelSignals(model, selCmpt));\n }\n\n forEachTransform(selCmpt, function(txCompiler) {\n if (txCompiler.topLevelSignals) {\n signals = txCompiler.topLevelSignals(model, selCmpt, signals);\n }\n });\n });\n\n return signals;\n}\n\nexport function assembleUnitData(model: UnitModel, data: VgData[]): VgData[] {\n return data\n .concat(Object.keys(model.component.selection)\n .map(function(k: string) {\n return {name: k + STORE};\n }));\n}\n\nexport function assembleUnitMarks(model: UnitModel, marks: any[]): any[] {\n let clippedGroup = false,\n selMarks = marks;\n forEachSelection(model, function(selCmpt, selCompiler) {\n selMarks = selCompiler.marks ? selCompiler.marks(model, selCmpt, selMarks) : selMarks;\n forEachTransform(selCmpt, function(txCompiler) {\n clippedGroup = clippedGroup || txCompiler.clippedGroup;\n if (txCompiler.marks) {\n selMarks = txCompiler.marks(model, selCmpt, marks, selMarks);\n }\n });\n });\n\n if (clippedGroup) {\n selMarks = [{\n type: 'group',\n encode: {\n enter: {\n width: {field: {group: 'width'}},\n height: {field: {group: 'height'}},\n fill: {value: 'transparent'},\n clip: {value: true}\n }\n },\n marks: selMarks\n }];\n }\n\n return selMarks;\n}\n\nlet PREDICATES_OPS = {\n 'single': '\"intersect\", \"all\"',\n 'independent': '\"intersect\", \"unit\"',\n 'union': '\"union\", \"all\"',\n 'union_others': '\"union\", \"others\"',\n 'intersect': '\"intersect\", \"all\"',\n 'intersect_others': '\"intersect\", \"others'\n};\n\nexport function predicate(selCmpt: SelectionComponent, datum?: string): string {\n const store = stringValue(selCmpt.name + STORE),\n op = PREDICATES_OPS[selCmpt.resolve];\n datum = datum || 'datum';\n return compiler(selCmpt).predicate + `(${store}, parent._id, ${datum}, ${op})`;\n}\n\n// Utility functions\n\nfunction forEachSelection(model: Model, cb: (selCmpt: SelectionComponent, selCompiler: SelectionCompiler) => void) {\n let selections = model.component.selection;\n for (let name in selections) {\n if (selections.hasOwnProperty(name)) {\n let sel = selections[name];\n cb(sel, compiler(sel));\n }\n }\n}\n\nfunction compiler(selCmpt: SelectionComponent): SelectionCompiler {\n switch (selCmpt.type) {\n case 'single':\n return singleCompiler;\n case 'multi':\n return multiCompiler;\n case 'interval':\n return intervalCompiler;\n }\n return null;\n}\n\nexport function invert(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, expr: string) {\n let scale = stringValue(model.scaleName(channel));\n return selCmpt.domain === 'data' ? `invert(${scale}, ${expr})` : expr;\n}\n\nexport function channelSignalName(selCmpt: SelectionComponent, channel: Channel) {\n return selCmpt.name + '_' + channel;\n}\n","import {TUPLE, STORE, SelectionCompiler} from './selection';\nimport multi from './multi';\nimport {stringValue} from '../../util';\n\nconst single:SelectionCompiler = {\n predicate: multi.predicate,\n\n signals: multi.signals,\n\n topLevelSignals: function(model, selCmpt) {\n let name = selCmpt.name;\n return [{\n name: name,\n update: `data(${stringValue(name + STORE)})[0]`\n }];\n },\n\n tupleExpr: function(model, selCmpt) {\n let name = selCmpt.name, values = `${name}.values`;\n return `fields: ${name}.fields, values: ${values}, ` +\n selCmpt.project.map(function(p, i) {\n return `${p.field}: ${values}[${i}]`;\n }).join(', ');\n },\n\n modifyExpr: function(model, selCmpt) {\n return selCmpt.name + TUPLE + ', true';\n }\n};\n\nexport {single as default};\n","import {TransformCompiler} from './transforms';\nimport {stringValue} from '../../../util';\n\nconst inputBindings:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'single' && selCmpt.bind && selCmpt.bind !== 'scales';\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n let name = selCmpt.name,\n proj = selCmpt.project,\n bind = selCmpt.bind,\n datum = '(item().isVoronoi ? datum.datum : datum)';\n\n proj.forEach(function(p) {\n signals.unshift({\n name: name + id(p.field),\n value: '',\n on: [{\n events: selCmpt.events,\n update: `${datum}[${stringValue(p.field)}]`\n }],\n bind: bind[p.field] || bind[p.encoding] || bind\n });\n });\n\n return signals;\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name, proj = selCmpt.project,\n signal = signals.filter((s) => s.name === name)[0],\n fields = proj.map((p) => stringValue(p.field)).join(', '),\n values = proj.map((p) => name + id(p.field)).join(', ');\n\n signal.update = `{fields: [${fields}], values: [${values}]}`;\n delete signal.value;\n delete signal.on;\n\n return signals;\n }\n};\n\nexport {inputBindings as default};\n\nfunction id(str: string) {\n return '_' + str.replace(/\\W/g, '_');\n}\n","import {TransformCompiler} from './transforms';\n\nconst VORONOI = 'voronoi';\n\nconst nearest:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.nearest !== undefined && selCmpt.nearest !== false;\n },\n\n marks: function(model, selCmpt, marks, selMarks) {\n let mark = marks[0],\n index = selMarks.indexOf(mark),\n isPathgroup = mark.name === model.getName('pathgroup'),\n exists = ((m: any) => m.name && m.name.indexOf(VORONOI) >= 0),\n cellDef = {\n name: model.getName(VORONOI),\n type: 'path',\n from: {data: model.getName('marks')},\n encode: {\n enter: {\n fill: {value: 'transparent'},\n strokeWidth: {value: 0.35},\n stroke: {value: 'transparent'},\n isVoronoi: {value: true}\n }\n },\n transform: [{\n type: 'voronoi',\n x: 'datum.x',\n y: 'datum.y',\n size: [{signal: 'width'}, {signal: 'height'}]\n }]\n };\n\n if (isPathgroup && !mark.marks.filter(exists).length) {\n mark.marks.push(cellDef);\n selMarks.splice(index, 1, mark);\n } else if (!isPathgroup && !selMarks.filter(exists).length) {\n selMarks.splice(index + 1, 0, cellDef);\n }\n\n return selMarks;\n }\n};\n\nexport {nearest as default};\n","import {Channel} from '../../../channel';\nimport {SelectionDef} from '../../../selection';\nimport {TransformCompiler} from './transforms';\n\nconst project:TransformCompiler = {\n has: function(selDef: SelectionDef) {\n return selDef.fields !== undefined || selDef.encodings !== undefined;\n },\n\n parse: function(model, selDef, selCmpt) {\n let fields = {};\n // TODO: find a possible channel mapping for these fields.\n (selDef.fields || []).forEach((f) => fields[f] = null);\n (selDef.encodings || []).forEach((e: Channel) => fields[model.field(e)] = e);\n\n let projection = selCmpt.project || (selCmpt.project = []);\n for (let field in fields) {\n if (fields.hasOwnProperty(field)) {\n projection.push({field: field, encoding: fields[field]});\n }\n }\n }\n};\n\nexport {project as default};\n","import {TransformCompiler} from './transforms';\nimport {warn} from '../../../log';\nimport {hasContinuousDomain} from '../../../scale';\nimport {Channel} from '../../../channel';\nimport {TUPLE, MODIFY, channelSignalName} from '../selection';\nimport {UnitModel} from '../../unit';\nimport {SIZE as INTERVAL_SIZE} from '../interval';\nimport {stringValue} from '../../../util';\n\nconst scaleBindings:TransformCompiler = {\n clippedGroup: true,\n\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.bind && selCmpt.bind === 'scales';\n },\n\n parse: function(model, selDef, selCmpt) {\n const scales = model.component.scales;\n const bound:Channel[] = selCmpt.scales = [];\n\n selCmpt.project.forEach(function(p) {\n const channel = p.encoding;\n const scale = scales[channel];\n\n if (!scale || !hasContinuousDomain(scale.type)) {\n warn('Scale bindings are currently only supported for scales with continuous domains.');\n return;\n }\n\n scale.domainRaw = {signal: channelSignalName(selCmpt, channel)};\n bound.push(channel);\n });\n },\n\n topLevelSignals: function(model, selCmpt, signals) {\n return signals.concat(selCmpt.scales.map((channel) => {\n return {name: channelSignalName(selCmpt, channel)};\n }));\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name;\n signals = signals.filter(function(s) {\n return s.name !== name + INTERVAL_SIZE &&\n s.name !== name + TUPLE && s.name !== MODIFY;\n });\n\n selCmpt.scales.forEach(function(channel) {\n let signal = signals.filter((s) => s.name === name + '_' + channel)[0];\n signal.push = 'outer';\n delete signal.value;\n delete signal.update;\n });\n\n return signals;\n }\n};\n\nexport {scaleBindings as default};\n\nexport function domain(model: UnitModel, channel: Channel) {\n let scale = stringValue(model.scaleName(channel));\n return `domain(${scale})`;\n}\n","import {TransformCompiler} from './transforms';\nimport {TUPLE} from '../selection';\n\nconst TOGGLE = '_toggle';\n\nconst toggle:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.toggle !== undefined && selCmpt.toggle !== false;\n },\n\n signals: function(model, selCmpt, signals) {\n return signals.concat({\n name: selCmpt.name + TOGGLE,\n value: false,\n on: [{events: selCmpt.events, update: selCmpt.toggle}]\n });\n },\n\n modifyExpr: function(model, selCmpt, expr) {\n let tpl = selCmpt.name + TUPLE,\n signal = selCmpt.name + TOGGLE;\n\n return `${signal} ? null : ${tpl}, ` +\n `${signal} ? null : true, ` +\n `${signal} ? ${tpl} : null`;\n }\n};\n\nexport {toggle as default};\n","import {Model} from '../../model';\nimport {UnitModel} from '../../unit';\nimport {SelectionDef} from '../../../selection';\nimport {SelectionComponent} from '../selection';\nimport {Dict} from '../../../util';\n\nexport interface TransformCompiler {\n has: (selCmpt: SelectionComponent | SelectionDef) => boolean;\n parse?: (model: UnitModel, def: SelectionDef, selCmpt: SelectionComponent) => void;\n signals?: (model: UnitModel, selCmpt: SelectionComponent, signals: any[]) => any[];\n topLevelSignals?: (model: Model, selCmpt: SelectionComponent, signals: any[]) => any[];\n // tupleExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n modifyExpr?: (model: UnitModel, selCmpt: SelectionComponent, expr: string) => string;\n marks?: (model: UnitModel, selCmpt:SelectionComponent, marks: any[], selMarks: any[]) => any[];\n clippedGroup?: boolean;\n}\n\nimport project from './project';\nimport toggle from './toggle';\nimport translate from './translate';\nimport zoom from './zoom';\nimport scales from './scales';\nimport inputs from './inputs';\nimport nearest from './nearest';\nconst compilers: Dict = {project, toggle, scales,\n translate, zoom, inputs, nearest};\n\nexport function forEachTransform(selCmpt: SelectionComponent, cb: (tx: TransformCompiler) => void) {\n for (let t in compilers) {\n if (compilers[t].has(selCmpt)) {\n cb(compilers[t]);\n }\n }\n}\n","import parseSelector from 'vega-parser/src/parsers/event-selector';\nimport {UnitModel} from './../../unit';\nimport {SelectionComponent} from '../selection';\nimport {X, Y, Channel} from '../../../channel';\nimport {stringValue} from '../../../util';\nimport {TransformCompiler} from './transforms';\nimport {default as scalesCompiler, domain} from './scales';\nimport {projections as intervalProjections, SIZE as INTERVAL_SIZE, BRUSH as INTERVAL_BRUSH} from '../interval';\n\nconst ANCHOR = '_translate_anchor',\n DELTA = '_translate_delta';\n\nconst translate:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.translate !== undefined && selCmpt.translate !== false;\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name,\n scales = scalesCompiler.has(selCmpt),\n size = scales ? 'unit' : name + INTERVAL_SIZE,\n anchor = name + ANCHOR,\n events = parseSelector(selCmpt.translate, 'scope'),\n {x, y} = intervalProjections(selCmpt);\n\n if (!scales) {\n events = events.map((e) => (e.between[0].markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: anchor,\n value: {},\n on: [{\n events: events.map((e) => e.between[0]),\n update: '{x: x(unit), y: y(unit), ' +\n `width: ${size}.width, height: ${size}.height, ` +\n\n (x !== null ? 'extent_x: ' + (scales ? domain(model, X) :\n `slice(${name}_x)`) + ', ' : '') +\n\n (y !== null ? 'extent_y: ' + (scales ? domain(model, Y) :\n `slice(${name}_y)`) + ', ' : '') + '}'\n }]\n }, {\n name: name + DELTA,\n value: {},\n on: [{\n events: events,\n update: `{x: x(unit) - ${anchor}.x, y: y(unit) - ${anchor}.y}`\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, X, 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, Y, 'height', signals);\n }\n\n return signals;\n }\n};\n\nexport {translate as default};\n\nfunction getSign(selCmpt: SelectionComponent, channel: Channel) {\n let s = channel === X ? '+' : '-';\n if (scalesCompiler.has(selCmpt)) {\n s = s === '+' ? '-' : '+';\n }\n return s;\n}\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, size: string, signals: any[]) {\n let name = selCmpt.name,\n signal:any = signals.filter((s:any) => s.name === name + '_' + channel)[0],\n anchor = name + ANCHOR,\n delta = name + DELTA,\n scale = stringValue(model.scaleName(channel)),\n extent = `.extent_${channel}`,\n sign = getSign(selCmpt, channel),\n offset = `${sign} abs(span(${anchor}${extent})) * ` +\n `${delta}.${channel} / ${anchor}.${size}`,\n range = `[${anchor}${extent}[0] ${offset}, ` +\n `${anchor}${extent}[1] ${offset}]`,\n lo = `invert(${scale}` + (channel === X ? ', 0' : `, unit.${size}`) + ')',\n hi = `invert(${scale}` + (channel === X ? `, unit.${size}` : ', 0') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: scalesCompiler.has(selCmpt) ? range : `clampRange(${range}, ${lo}, ${hi})`\n });\n}\n","import parseSelector from 'vega-parser/src/parsers/event-selector';\nimport {UnitModel} from './../../unit';\nimport {SelectionComponent} from '../selection';\nimport {X, Y, Channel} from '../../../channel';\nimport {stringValue} from '../../../util';\nimport {TransformCompiler} from './transforms';\nimport {default as scalesCompiler, domain} from './scales';\nimport {projections as intervalProjections, SIZE as INTERVAL_SIZE, BRUSH as INTERVAL_BRUSH} from '../interval';\n\nconst ANCHOR = '_zoom_anchor',\n DELTA = '_zoom_delta';\n\nconst zoom:TransformCompiler = {\n has: function(selCmpt) {\n return selCmpt.type === 'interval' && selCmpt.zoom !== undefined && selCmpt.zoom !== false;\n },\n\n signals: function(model, selCmpt, signals) {\n let name = selCmpt.name,\n delta = name + DELTA,\n events = parseSelector(selCmpt.zoom, 'scope'),\n {x, y} = intervalProjections(selCmpt),\n sx = stringValue(model.scaleName(X)),\n sy = stringValue(model.scaleName(Y));\n\n if (!scalesCompiler.has(selCmpt)) {\n events = events.map((e) => (e.markname = name + INTERVAL_BRUSH, e));\n }\n\n signals.push({\n name: name + ANCHOR,\n on: [{\n events: events,\n update: `{x: invert(${sx}, x(unit)), y: invert(${sy}, y(unit))}`\n }]\n }, {\n name: delta,\n on: [{\n events: events,\n force: true,\n update: 'pow(1.001, event.deltaY * pow(16, event.deltaMode))'\n }]\n });\n\n if (x !== null) {\n onDelta(model, selCmpt, 'x', 'width', signals);\n }\n\n if (y !== null) {\n onDelta(model, selCmpt, 'y', 'height', signals);\n }\n\n let size = signals.filter((s:any) => s.name === name + INTERVAL_SIZE);\n if (size.length) {\n let sname = size[0].name;\n size[0].on.push({\n events: {signal: delta},\n update: `{x: ${sname}.x, y: ${sname}.y, ` +\n `width: ${sname}.width * ${delta} , ` +\n `height: ${sname}.height * ${delta}}`\n });\n }\n\n return signals;\n }\n};\n\nexport {zoom as default};\n\nfunction onDelta(model: UnitModel, selCmpt: SelectionComponent, channel: Channel, size: string, signals: any[]) {\n let name = selCmpt.name,\n signal:any = signals.filter((s:any) => s.name === name + '_' + channel)[0],\n scales = scalesCompiler.has(selCmpt),\n base = scales ? domain(model, channel) : signal.name,\n anchor = `${name}${ANCHOR}.${channel}`,\n delta = name + DELTA,\n scale = stringValue(model.scaleName(channel)),\n range = `[${anchor} + (${base}[0] - ${anchor}) * ${delta}, ` +\n `${anchor} + (${base}[1] - ${anchor}) * ${delta}]`,\n lo = `invert(${scale}` + (channel === X ? ', 0' : `, unit.${size}`) + ')',\n hi = `invert(${scale}` + (channel === X ? `, unit.${size}` : ', 0') + ')';\n\n signal.on.push({\n events: {signal: delta},\n update: scales ? range : `clampRange(${range}, ${lo}, ${hi})`\n });\n}\n","\n\nimport {Axis, VlOnlyAxisBase, VL_ONLY_AXIS_PROPERTIES} from '../axis';\nimport {X, Y, X2, Y2, Channel, UNIT_CHANNELS, UNIT_SCALE_CHANNELS, NONSPATIAL_SCALE_CHANNELS} from '../channel';\nimport {defaultConfig, Config, CellConfig} from '../config';\nimport {SOURCE, SUMMARY} from '../data';\nimport {Encoding, dropInvalidFieldDefs} from '../encoding';\nimport * as vlEncoding from '../encoding'; // TODO: remove\nimport {FieldDef, FieldRefOption, field, isFieldDef} from '../fielddef';\nimport {Legend} from '../legend';\nimport {Mark, MarkDef, TEXT as TEXT_MARK, FILL_STROKE_CONFIG, isMarkDef} from '../mark';\nimport {Scale, ScaleConfig, hasDiscreteDomain} from '../scale';\nimport {UnitSpec} from '../spec';\nimport {duplicate, extend, mergeDeep, Dict} from '../util';\nimport {VgData} from '../vega.schema';\n\nimport {parseAxisComponent} from './axis/parse';\nimport {applyConfig} from './common';\nimport {assembleData, parseUnitData} from './data/data';\nimport {parseLegendComponent} from './legend/parse';\nimport {assembleLayout, parseUnitLayout} from './layout';\nimport {Model} from './model';\nimport {parseMark} from './mark/mark';\nimport initScale from './scale/init';\nimport parseScaleComponent from './scale/parse';\nimport {stack, StackProperties} from '../stack';\nimport {SelectionDef} from '../selection';\nimport {parseUnitSelection, assembleUnitSignals, assembleUnitData as assembleSelectionData, assembleUnitMarks as assembleSelectionMarks} from './selection/selection';\nimport {initMarkDef, initEncoding} from './mark/init';\n\n/**\n * Internal model of Vega-Lite specification for the compiler.\n */\nexport class UnitModel extends Model {\n /**\n * Fixed width for the unit visualization.\n * If undefined (e.g., for ordinal scale), the width of the\n * visualization will be calculated dynamically.\n */\n public readonly width: number;\n\n /**\n * Fixed height for the unit visualization.\n * If undefined (e.g., for ordinal scale), the height of the\n * visualization will be calculated dynamically.\n */\n public readonly height: number;\n\n public readonly markDef: MarkDef & {filled: boolean};\n public readonly encoding: Encoding;\n\n protected readonly selection: Dict = {};\n protected readonly scales: Dict = {};\n protected readonly axes: Dict = {};\n protected readonly legends: Dict = {};\n public readonly config: Config;\n public readonly stack: StackProperties;\n public children: Model[] = [];\n\n constructor(spec: UnitSpec, parent: Model, parentGivenName: string) {\n super(spec, parent, parentGivenName);\n\n // use top-level width / height or parent's top-level width / height\n\n // FIXME: once facet supports width/height, this is no longer correct!\n const providedWidth = spec.width !== undefined ? spec.width :\n parent ? parent['width'] : undefined; // only exists if parent is layer\n const providedHeight = spec.height !== undefined ? spec.height :\n parent ? parent['height'] : undefined; // only exists if parent is layer\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const encoding = this.encoding = dropInvalidFieldDefs(mark, spec.encoding || {});\n\n // TODO?: ideally we should use config only inside this constructor\n const config = this.config = this.initConfig(spec.config, parent);\n\n // calculate stack properties\n this.stack = stack(mark, encoding, config.stack);\n this.scales = this.initScales(mark, encoding, config, providedWidth, providedHeight);\n\n this.markDef = initMarkDef(spec.mark, encoding, this.scales, config);\n this.encoding = initEncoding(mark, encoding, this.stack, config);\n\n this.axes = this.initAxes(encoding, config);\n this.legends = this.initLegend(encoding, config);\n\n // Selections will be initialized upon parse.\n this.selection = spec.selection;\n\n // width / height\n const {width = this.width, height = this.height} = this.initSize(mark, this.scales,\n providedWidth,\n providedHeight,\n config.cell, config.scale\n );\n this.width = width;\n this.height = height;\n }\n\n\n /**\n * Init config by merging config from parent and, if applicable, from facet config\n */\n private initConfig(specConfig: Config, parent: Model) {\n let config = mergeDeep(duplicate(defaultConfig), parent ? parent.config : {}, specConfig);\n let hasFacetParent = false;\n while (parent !== null) {\n if (parent.isFacet()) {\n hasFacetParent = true;\n break;\n }\n parent = parent.parent;\n }\n\n if (hasFacetParent) {\n config.cell = extend({}, config.cell, config.facet.cell);\n }\n return config;\n }\n\n private initScales(mark: Mark, encoding: Encoding, config: Config, topLevelWidth:number, topLevelHeight: number): Dict {\n const xyRangeSteps: number[] = [];\n\n return UNIT_SCALE_CHANNELS.reduce((scales, channel) => {\n if (vlEncoding.channelHasField(encoding, channel) ||\n (channel === X && vlEncoding.channelHasField(encoding, X2)) ||\n (channel === Y && vlEncoding.channelHasField(encoding, Y2))\n ) {\n const scale = scales[channel] = initScale(\n channel, encoding[channel], config, mark,\n channel === X ? topLevelWidth : channel === Y ? topLevelHeight : undefined,\n xyRangeSteps // for determine point / bar size\n );\n\n if (channel === X || channel === Y) {\n if (scale.rangeStep) {\n xyRangeSteps.push(scale.rangeStep);\n }\n }\n }\n return scales;\n }, {});\n }\n\n // TODO: consolidate this with scale? Current scale range is in parseScale (later),\n // but not in initScale because scale range depends on size,\n // but size depends on scale type and rangeStep\n private initSize(mark: Mark, scale: Dict, width: number, height: number, cellConfig: CellConfig, scaleConfig: ScaleConfig) {\n if (width === undefined) {\n if (scale[X]) {\n if (!hasDiscreteDomain(scale[X].type) || !scale[X].rangeStep) {\n width = cellConfig.width;\n } // else: Do nothing, use dynamic width.\n } else { // No scale X\n if (mark === TEXT_MARK) {\n // for text table without x/y scale we need wider rangeStep\n width = scaleConfig.textXRangeStep;\n } else {\n if (typeof scaleConfig.rangeStep === 'string') {\n throw new Error('_initSize does not handle string rangeSteps');\n }\n width = scaleConfig.rangeStep;\n }\n }\n }\n\n if (height === undefined) {\n if (scale[Y]) {\n if (!hasDiscreteDomain(scale[Y].type) || !scale[Y].rangeStep) {\n height = cellConfig.height;\n } // else: Do nothing, use dynamic height .\n } else {\n if (typeof scaleConfig.rangeStep === 'string') {\n throw new Error('_initSize does not handle string rangeSteps');\n }\n height = scaleConfig.rangeStep;\n }\n }\n\n return {width, height};\n }\n\n private initAxes(encoding: Encoding, config: Config): Dict {\n return [X, Y].reduce(function(_axis, channel) {\n // Position Axis\n\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) ||\n (channel === X && isFieldDef(encoding.x2)) ||\n (channel === Y && isFieldDef(encoding.y2))) {\n\n const axisSpec = isFieldDef(channelDef) ? channelDef.axis : null;\n\n // We no longer support false in the schema, but we keep false here for backward compatability.\n if (axisSpec !== null && axisSpec !== false) {\n let vlOnlyAxisProperties: VlOnlyAxisBase = {};\n VL_ONLY_AXIS_PROPERTIES.forEach(function(property) {\n if (config.axis[property] !== undefined) {\n vlOnlyAxisProperties[property] = config.axis[property];\n }\n });\n _axis[channel] = {\n ...vlOnlyAxisProperties,\n ...axisSpec\n };\n }\n }\n return _axis;\n }, {});\n }\n\n private initLegend(encoding: Encoding, config: Config): Dict {\n return NONSPATIAL_SCALE_CHANNELS.reduce(function(_legend, channel) {\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef)) {\n const legendSpec = channelDef.legend;\n if (legendSpec !== null && legendSpec !== false) {\n _legend[channel] = {...legendSpec};\n }\n }\n return _legend;\n }, {});\n }\n\n public parseData() {\n this.component.data = parseUnitData(this);\n }\n\n public parseSelection() {\n this.component.selection = parseUnitSelection(this, this.selection);\n }\n\n public parseLayoutData() {\n this.component.layout = parseUnitLayout(this);\n }\n\n public parseScale() {\n this.component.scales = parseScaleComponent(this);\n }\n\n public parseMark() {\n this.component.mark = parseMark(this);\n }\n\n public parseAxis() {\n this.component.axes = parseAxisComponent(this, [X, Y]);\n }\n\n public parseAxisGroup(): void {\n return null;\n }\n\n public parseGridGroup(): void {\n return null;\n }\n\n public parseLegend() {\n this.component.legends = parseLegendComponent(this);\n }\n\n public assembleSignals(signals: any[]): any[] {\n return assembleUnitSignals(this, signals);\n }\n\n public assembleSelectionData(data: VgData[]): VgData[] {\n return assembleSelectionData(this, data);\n }\n\n public assembleData(data: VgData[]): VgData[] {\n return assembleData(this, data);\n }\n\n public assembleLayout(layoutData: VgData[]): VgData[] {\n return assembleLayout(this, layoutData);\n }\n\n public assembleMarks() {\n return assembleSelectionMarks(this, this.component.mark);\n }\n\n public assembleParentGroupProperties(cellConfig: CellConfig) {\n return applyConfig({}, cellConfig, FILL_STROKE_CONFIG.concat(['clip']));\n }\n\n public channels() {\n return UNIT_CHANNELS;\n }\n\n protected getMapping() {\n return this.encoding;\n }\n\n public toSpec(excludeConfig?: any, excludeData?: any) {\n const encoding = duplicate(this.encoding);\n let spec: any;\n\n spec = {\n mark: this.markDef,\n encoding: encoding\n };\n\n if (!excludeConfig) {\n spec.config = duplicate(this.config);\n }\n\n if (!excludeData) {\n spec.data = duplicate(this.data);\n }\n\n // remove defaults\n return spec;\n }\n\n public mark(): Mark {\n return this.markDef.type;\n }\n\n public channelHasField(channel: Channel) {\n return vlEncoding.channelHasField(this.encoding, channel);\n }\n\n public fieldDef(channel: Channel): FieldDef {\n // TODO: remove this || {}\n // Currently we have it to prevent null pointer exception.\n return this.encoding[channel] || {};\n }\n\n /** Get \"field\" reference for vega */\n public field(channel: Channel, opt: FieldRefOption = {}) {\n const fieldDef = this.fieldDef(channel);\n\n if (fieldDef.bin) { // bin has default suffix that depends on scaleType\n opt = extend({\n binSuffix: hasDiscreteDomain(this.scale(channel).type) ? 'range' : 'start'\n }, opt);\n }\n\n return field(fieldDef, opt);\n }\n\n public dataTable() {\n return this.dataName(vlEncoding.isAggregate(this.encoding) ? SUMMARY : SOURCE);\n }\n\n public isUnit() {\n return true;\n }\n}\n","import {Encoding} from './encoding';\nimport {MarkDef, isMarkDef} from './mark';\nimport {GenericUnitSpec, LayerSpec} from './spec';\n\nexport const ERRORBAR: 'error-bar' = 'error-bar';\nexport type ERRORBAR = typeof ERRORBAR;\n\nexport type UnitNormalizer = (spec: GenericUnitSpec)=> LayerSpec;\n\n/**\n * Registry index for all composite mark's normalizer\n */\nconst normalizerRegistry: {[mark: string]: UnitNormalizer} = {};\n\nexport function add(mark: string, normalizer: UnitNormalizer) {\n normalizerRegistry[mark] = normalizer;\n}\n\nexport function remove(mark: string) {\n delete normalizerRegistry[mark];\n}\n\n/**\n * Transform a unit spec with composite mark into a normal layer spec.\n */\nexport function normalize(\n // This GenericUnitSpec has any as Encoding because unit specs with composite mark can have additional encoding channels.\n spec: GenericUnitSpec\n ): LayerSpec {\n\n const mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n const normalizer = normalizerRegistry[mark];\n if (normalizer) {\n return normalizer(spec);\n }\n\n throw new Error(`Unregistered composite mark ${mark}`);\n}\n\n\nadd(ERRORBAR, (spec: GenericUnitSpec): LayerSpec => {\n const {mark: _m, encoding: encoding, ...outerSpec} = spec;\n const {size: _s, ...encodingWithoutSize} = encoding;\n const {x2: _x2, y2: _y2, ...encodingWithoutX2Y2} = encoding;\n\n return {\n ...outerSpec,\n layer: [\n {\n mark: 'rule',\n encoding: encodingWithoutSize\n },{ // Lower tick\n mark: 'tick',\n encoding: encodingWithoutX2Y2\n }, { // Upper tick\n mark: 'tick',\n encoding: {\n ...encodingWithoutX2Y2,\n ...(encoding.x2 ? {x: encoding.x2} : {}),\n ...(encoding.y2 ? {y: encoding.y2} : {})\n }\n }\n ]\n };\n});\n","import {AxisConfig, defaultAxisConfig} from './axis';\nimport {LegendConfig, defaultLegendConfig} from './legend';\nimport {MarkConfig, BarConfig, TextConfig, TickConfig} from './mark';\nimport * as mark from './mark';\nimport {ScaleConfig, defaultScaleConfig} from './scale';\nimport {StackOffset} from './stack';\nimport {Padding} from './spec';\nimport {VgRangeScheme} from './vega.schema';\nimport {SelectionConfig, defaultConfig as defaultSelectionConfig} from './selection';\n\nexport interface CellConfig {\n width?: number;\n height?: number;\n\n clip?: boolean;\n\n // FILL_STROKE_CONFIG\n /**\n * The fill color.\n */\n fill?: string;\n\n /** The fill opacity (value between [0,1]). */\n fillOpacity?: number;\n\n /** The stroke color. */\n stroke?: string;\n\n /** The stroke opacity (value between [0,1]). */\n strokeOpacity?: number;\n\n /** The stroke width, in pixels. */\n strokeWidth?: number;\n\n /** An array of alternating stroke, space lengths for creating dashed or dotted lines. */\n strokeDash?: number[];\n\n /** The offset (in pixels) into which to begin drawing with the stroke dash array. */\n strokeDashOffset?: number;\n}\n\nexport const defaultCellConfig: CellConfig = {\n width: 200,\n height: 200,\n fill: 'transparent'\n};\n\nexport const defaultFacetCellConfig: CellConfig = {\n stroke: '#ccc',\n strokeWidth: 1\n};\n\nexport interface FacetConfig {\n /** Facet Axis Config */\n axis?: AxisConfig;\n\n /** Facet Grid Config */\n grid?: FacetGridConfig;\n\n /** Facet Cell Config */\n cell?: CellConfig;\n}\n\nexport interface FacetGridConfig {\n color?: string;\n opacity?: number;\n offset?: number;\n}\n\nconst defaultFacetGridConfig: FacetGridConfig = {\n color: '#000000',\n opacity: 0.4,\n offset: 0\n};\n\nexport const defaultFacetConfig: FacetConfig = {\n axis: {},\n grid: defaultFacetGridConfig,\n cell: defaultFacetCellConfig\n};\n\nexport type AreaOverlay = 'line' | 'linepoint' | 'none';\n\nexport interface OverlayConfig {\n /**\n * Whether to overlay line with point.\n */\n line?: boolean;\n\n /**\n * Type of overlay for area mark (line or linepoint)\n */\n area?: AreaOverlay;\n\n /**\n * Default style for the overlayed point.\n */\n pointStyle?: MarkConfig;\n\n /**\n * Default style for the overlayed point.\n */\n lineStyle?: MarkConfig;\n}\n\nexport const defaultOverlayConfig: OverlayConfig = {\n line: false,\n pointStyle: {filled: true},\n lineStyle: {}\n};\n\nexport type RangeConfig = (number|string)[] | VgRangeScheme | {step: number};\n\nexport interface Config {\n // TODO: add this back once we have top-down layout approach\n // width?: number;\n // height?: number;\n // padding?: number|string;\n /**\n * The width and height of the on-screen viewport, in pixels. If necessary, clipping and scrolling will be applied.\n */\n viewport?: number;\n /**\n * CSS color property to use as background of visualization. Default is `\"transparent\"`.\n */\n background?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. This can be a single number or an object with `\"top\"`, `\"left\"`, `\"right\"`, `\"bottom\"` properties.\n *\n * __Default value__: `5`\n *\n * * @minimum 0\n */\n padding?: Padding;\n\n /**\n * D3 Number format for axis labels and text tables. For example \"s\" for SI units.\n */\n numberFormat?: string;\n\n /**\n * Default datetime format for axis and legend labels. The format can be set directly on each axis and legend.\n */\n timeFormat?: string;\n\n /**\n * Default axis and legend title for count fields.\n * @type {string}\n */\n countTitle?: string;\n\n /** Cell Config */\n cell?: CellConfig;\n\n /** Default stack offset for stackable mark. */\n stack?: StackOffset;\n\n /** Mark Config */\n mark?: MarkConfig;\n\n // MARK-SPECIFIC CONFIGS\n /** Area-Specific Config */\n area?: MarkConfig;\n\n /** Bar-Specific Config */\n bar?: BarConfig;\n\n /** Circle-Specific Config */\n circle?: MarkConfig;\n\n /** Line-Specific Config */\n line?: MarkConfig;\n\n /** Point-Specific Config */\n point?: MarkConfig;\n\n /** Rect-Specific Config */\n rect?: MarkConfig;\n\n /** Rule-Specific Config */\n rule?: MarkConfig;\n\n /** Square-Specific Config */\n square?: MarkConfig;\n\n /** Text-Specific Config */\n text?: TextConfig;\n\n /** Tick-Specific Config */\n tick?: TickConfig;\n\n // OTHER CONFIG\n\n // FIXME: move this to line/area\n /** Mark Overlay Config */\n overlay?: OverlayConfig;\n\n /** Scale Config */\n scale?: ScaleConfig;\n\n /**\n * Scale range config, or properties defining named range arrays\n * that can be used within scale range definitions\n * (such as `{\"type\": \"ordinal\", \"range\": \"category\"}`).\n * For default range that Vega-Lite adopts from Vega, see https://github.com/vega/vega-parser#scale-range-properties.\n */\n range?: {[name: string]: RangeConfig};\n\n /** Axis Config */\n axis?: AxisConfig;\n\n /** Legend Config */\n legend?: LegendConfig;\n\n /** Facet Config */\n facet?: FacetConfig;\n\n /** Selection Config */\n selection?: SelectionConfig;\n}\n\nexport const defaultConfig: Config = {\n padding: 5,\n numberFormat: 's',\n timeFormat: '%b %d, %Y',\n countTitle: 'Number of Records',\n\n cell: defaultCellConfig,\n\n mark: mark.defaultMarkConfig,\n area: {},\n bar: mark.defaultBarConfig,\n circle: {},\n line: {},\n point: {},\n rect: {},\n rule: {},\n square: {},\n text: mark.defaultTextConfig,\n tick: mark.defaultTickConfig,\n\n overlay: defaultOverlayConfig,\n scale: defaultScaleConfig,\n axis: defaultAxisConfig,\n legend: defaultLegendConfig,\n\n facet: defaultFacetConfig,\n\n selection: defaultSelectionConfig\n};\n","/*\n * Constants and utilities for data.\n */\n\nexport interface DataFormat {\n /**\n * Type of input data: `\"json\"`, `\"csv\"`, `\"tsv\"`.\n * The default format type is determined by the extension of the file url.\n * If no extension is detected, `\"json\"` will be used by default.\n */\n type?: DataFormatType;\n\n /**\n * A collection of parsing instructions can be used to define the data types of string-valued attributes in the JSON file. Each instruction is a name-value pair, where the name is the name of the attribute, and the value is the desired data type (one of `\"number\"`, `\"boolean\"` or `\"date\"`). For example, `\"parse\": {\"modified_on\":\"date\"}` ensures that the `modified_on` value in each row of the input data is parsed as a Date value. (See Datalib's [`dl.read.types` method](https://github.com/vega/datalib/wiki/Import#dl_read_types) for more information.)\n */\n parse?: any;\n\n /**\n * JSON only) The JSON property containing the desired data.\n * This parameter can be used when the loaded JSON file may have surrounding structure or meta-data.\n * For example `\"property\": \"values.features\"` is equivalent to retrieving `json.values.features`\n * from the loaded JSON object.\n */\n property?: string;\n\n /**\n * The name of the TopoJSON object set to convert to a GeoJSON feature collection.\n * For example, in a map of the world, there may be an object set named `\"countries\"`.\n * Using the feature property, we can extract this set and generate a GeoJSON feature object for each country.\n */\n feature?: string;\n /**\n * The name of the TopoJSON object set to convert to a mesh.\n * Similar to the `feature` option, `mesh` extracts a named TopoJSON object set.\n * Unlike the `feature` option, the corresponding geo data is returned as a single, unified mesh instance, not as individual GeoJSON features.\n * Extracting a mesh is useful for more efficiently drawing borders or other geographic elements that you do not need to associate with specific regions such as individual countries, states or counties.\n */\n mesh?: string;\n}\n\nexport type DataFormatType = 'json' | 'csv' | 'tsv' | 'topojson';\n\nexport type Data = UrlData | InlineData | NamedData;\n\nexport interface UrlData {\n /**\n * An object that specifies the format for the data file or values.\n */\n format?: DataFormat;\n\n /**\n * A URL from which to load the data set. Use the format.type property\n * to ensure the loaded data is correctly parsed.\n */\n url: string;\n}\n\nexport interface InlineData {\n /**\n * Pass array of objects instead of a url to a file.\n */\n values: any[];\n}\n\nexport interface NamedData {\n /**\n * Provide a placeholder name and bind data at runtime.\n */\n name: string;\n}\n\nexport function isUrlData(data: Data): data is UrlData {\n return !!data['url'];\n}\n\nexport function isInlineData(data: Data): data is InlineData {\n return !!data['values'];\n}\n\nexport function isNamedData(data: Data): data is NamedData {\n return !!data['name'];\n}\n\nexport type DataSourceType = 'source' | 'summary' | 'stacked' | 'layout';\n\nexport const SUMMARY: 'summary' = 'summary';\nexport const SOURCE: 'source' = 'source';\nexport const STACKED: 'stacked' = 'stacked';\nexport const LAYOUT: 'layout' = 'layout';\n","// DateTime definition object\n\nimport {duplicate, keys, isNumber} from './util';\nimport * as log from './log';\n\n/*\n * A designated year that starts on Sunday.\n */\nconst SUNDAY_YEAR = 2006;\n\n/**\n * @minimum 1\n * @maximum 12\n * @TJS-type integer\n */\nexport type Month = number;\n\n/**\n * @minimum 1\n * @maximum 7\n */\nexport type Day = number;\n\n/**\n * Object for defining datetime in Vega-Lite Filter.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n * We accept string for month and day names.\n */\nexport interface DateTime {\n /**\n * Integer value representing the year.\n * @TJS-type integer\n */\n year?: number;\n\n /**\n * Integer value representing the quarter of the year (from 1-4).\n * @minimum 1\n * @maximum 4\n * @TJS-type integer\n */\n quarter?: number;\n\n /** One of: (1) integer value representing the month from `1`-`12`. `1` represents January; (2) case-insensitive month name (e.g., `\"January\"`); (3) case-insensitive, 3-character short month name (e.g., `\"Jan\"`). */\n month?: Month | string;\n\n /**\n * Integer value representing the date from 1-31.\n * @minimum 1\n * @maximum 31\n * @TJS-type integer\n */\n date?: number;\n\n /**\n * Value representing the day of week. This can be one of: (1) integer value -- `1` represents Monday; (2) case-insensitive day name (e.g., `\"Monday\"`); (3) case-insensitive, 3-character short day name (e.g., `\"Mon\"`).
**Warning:** A DateTime definition object with `day`** should not be combined with `year`, `quarter`, `month`, or `date`.\n */\n day?: Day | string;\n\n /**\n * Integer value representing the hour of day from 0-23.\n * @minimum 0\n * @maximum 23\n * @TJS-type integer\n */\n hours?: number;\n\n /**\n * Integer value representing minute segment of a time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n minutes?: number;\n\n /**\n * Integer value representing second segment of a time from 0-59.\n * @minimum 0\n * @maximum 59\n * @TJS-type integer\n */\n seconds?: number;\n\n /**\n * Integer value representing millisecond segment of a time.\n * @minimum 0\n * @maximum 999\n * @TJS-type integer\n */\n milliseconds?: number;\n}\n\n\n/**\n * Internal Object for defining datetime expressions.\n * This is an expression version of DateTime.\n * If both month and quarter are provided, month has higher precedence.\n * `day` cannot be combined with other date.\n */\nexport interface DateTimeExpr {\n year?: string;\n quarter?: string;\n month?: string;\n date?: string;\n day?: string;\n hours?: string;\n minutes?: string;\n seconds?: string;\n milliseconds?: string;\n}\n\nexport function isDateTime(o: any): o is DateTime {\n return !!o && (!!o.year || !!o.quarter || !!o.month || !!o.date || !!o.day ||\n !!o.hours || !!o.minutes || !!o.seconds || !!o.milliseconds);\n}\n\nexport const MONTHS = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];\nexport const SHORT_MONTHS = MONTHS.map((m) => m.substr(0, 3));\n\nexport const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];\nexport const SHORT_DAYS = DAYS.map((d) => d.substr(0,3));\n\nfunction normalizeQuarter(q: number | string) {\n if (isNumber(q)) {\n if (q > 4) {\n log.warn(log.message.invalidTimeUnit('quarter', q));\n }\n // We accept 1-based quarter, so need to readjust to 0-based quarter\n return (q - 1) + '';\n } else {\n // Invalid quarter\n throw new Error(log.message.invalidTimeUnit('quarter', q));\n }\n}\n\nfunction normalizeMonth(m: string | number) {\n if (isNumber(m)) {\n // We accept 1-based month, so need to readjust to 0-based month\n return (m - 1) + '';\n } else {\n const lowerM = m.toLowerCase();\n const monthIndex = MONTHS.indexOf(lowerM);\n if (monthIndex !== -1) {\n return monthIndex + ''; // 0 for january, ...\n }\n const shortM = lowerM.substr(0, 3);\n const shortMonthIndex = SHORT_MONTHS.indexOf(shortM);\n if (shortMonthIndex !== -1) {\n return shortMonthIndex + '';\n }\n // Invalid month\n throw new Error(log.message.invalidTimeUnit('month', m));\n }\n}\n\nfunction normalizeDay(d: string | number) {\n if (isNumber(d)) {\n // mod so that this can be both 0-based where 0 = sunday\n // and 1-based where 7=sunday\n return (d % 7) + '';\n } else {\n const lowerD = d.toLowerCase();\n const dayIndex = DAYS.indexOf(lowerD);\n if (dayIndex !== -1) {\n return dayIndex + ''; // 0 for january, ...\n }\n const shortD = lowerD.substr(0, 3);\n const shortDayIndex = SHORT_DAYS.indexOf(shortD);\n if (shortDayIndex !== -1) {\n return shortDayIndex + '';\n }\n // Invalid day\n throw new Error(log.message.invalidTimeUnit('day', d));\n }\n}\n\nexport function timestamp(d: DateTime, normalize: boolean) {\n const date = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date\n\n // FIXME support UTC\n\n if (d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n } else {\n // Use a year that has 1/1 as Sunday so we can setDate below\n date.setFullYear(SUNDAY_YEAR);\n\n const day = normalize ? normalizeDay(d.day) : d.day;\n date.setDate(+day + 1); // +1 since date start at 1 in JS\n }\n }\n\n if (d.year !== undefined) {\n date.setFullYear(d.year);\n }\n\n if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n date.setMonth(+quarter * 3);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n date.setMonth(+month);\n }\n\n if (d.date !== undefined) {\n date.setDate(d.date);\n }\n\n if (d.hours !== undefined) {\n date.setHours(d.hours);\n }\n\n if (d.minutes !== undefined) {\n date.setMinutes(d.minutes);\n }\n\n if (d.seconds !== undefined) {\n date.setSeconds(d.seconds);\n }\n\n if (d.milliseconds !== undefined) {\n date.setMilliseconds(d.milliseconds);\n }\n\n return date.getTime();\n}\n\n/**\n * Return Vega Expression for a particular date time.\n * @param d\n * @param normalize whether to normalize quarter, month, day.\n */\nexport function dateTimeExpr(d: DateTime | DateTimeExpr, normalize = false) {\n const units: (string | number)[] = [];\n\n if (normalize && d.day !== undefined) {\n if (keys(d).length > 1) {\n log.warn(log.message.droppedDay(d));\n d = duplicate(d);\n delete d.day;\n }\n }\n\n if (d.year !== undefined) {\n units.push(d.year);\n } else if (d.day !== undefined) {\n // Set year to 2006 for working with day since January 1 2006 is a Sunday\n units.push(SUNDAY_YEAR);\n } else {\n units.push(0);\n }\n\n if (d.month !== undefined) {\n const month = normalize ? normalizeMonth(d.month) : d.month;\n units.push(month);\n } else if (d.quarter !== undefined) {\n const quarter = normalize ? normalizeQuarter(d.quarter) : d.quarter;\n units.push(quarter + '*3');\n } else {\n units.push(0); // months start at zero in JS\n }\n\n if (d.date !== undefined) {\n units.push(d.date);\n } else if (d.day !== undefined) {\n // HACK: Day only works as a standalone unit\n // This is only correct because we always set year to 2006 for day\n const day = normalize ? normalizeDay(d.day) : d.day;\n units.push(day + '+1');\n } else {\n units.push(1); // Date starts at 1 in JS\n }\n\n // Note: can't use TimeUnit enum here as importing it will create\n // circular dependency problem!\n for (let timeUnit of ['hours', 'minutes', 'seconds', 'milliseconds']) {\n if (d[timeUnit] !== undefined) {\n units.push(d[timeUnit]);\n } else {\n units.push(0);\n }\n }\n\n return 'datetime(' + units.join(', ') + ')';\n}\n","// utility for encoding mapping\nimport {FieldDef, PositionFieldDef, LegendFieldDef, OrderFieldDef, ValueDef, TextFieldDef, isFieldDef, ChannelDef, isValueDef, normalize, ConditionalValueDef} from './fielddef';\nimport {Channel, CHANNELS, supportMark} from './channel';\nimport {Facet} from './facet';\nimport {isArray, some, duplicate} from './util';\nimport {Mark} from './mark';\nimport * as log from './log';\n\nexport interface Encoding {\n /**\n * X coordinates for `point`, `circle`, `square`,\n * `line`, `rule`, `text`, and `tick`\n * (or to width and height for `bar` and `area` marks).\n */\n x?: PositionFieldDef | ValueDef;\n\n /**\n * Y coordinates for `point`, `circle`, `square`,\n * `line`, `rule`, `text`, and `tick`\n * (or to width and height for `bar` and `area` marks).\n */\n y?: PositionFieldDef | ValueDef;\n\n /**\n * X2 coordinates for ranged `bar`, `rule`, `area`\n */\n x2?: FieldDef | ValueDef;\n\n /**\n * Y2 coordinates for ranged `bar`, `rule`, `area`\n */\n y2?: FieldDef | ValueDef;\n\n /**\n * Color of the marks – either fill or stroke color based on mark type.\n * (By default, fill color for `area`, `bar`, `tick`, `text`, `circle`, and `square` /\n * stroke color for `line` and `point`.)\n */\n color?: LegendFieldDef | ConditionalValueDef;\n\n /**\n * Opacity of the marks – either can be a value or in a range.\n */\n opacity?: LegendFieldDef | ConditionalValueDef;\n\n /**\n * Size of the mark.\n * - For `point`, `square` and `circle`\n * – the symbol size, or pixel area of the mark.\n * - For `bar` and `tick` – the bar and tick's size.\n * - For `text` – the text's font size.\n * - Size is currently unsupported for `line` and `area`.\n */\n size?: LegendFieldDef | ConditionalValueDef;\n\n /**\n * The symbol's shape (only for `point` marks). The supported values are\n * `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`,\n * or `\"triangle-down\"`, or else a custom SVG path string.\n */\n shape?: LegendFieldDef | ConditionalValueDef; // TODO: maybe distinguish ordinal-only\n\n /**\n * Additional levels of detail for grouping data in aggregate views and\n * in line and area marks without mapping data to a specific visual channel.\n */\n detail?: FieldDef | FieldDef[];\n\n /**\n * Text of the `text` mark.\n */\n text?: TextFieldDef | ConditionalValueDef;\n\n /**\n * stack order for stacked marks or order of data points in line marks.\n */\n order?: OrderFieldDef | OrderFieldDef[];\n}\n\nexport interface EncodingWithFacet extends Encoding, Facet {}\n\nexport function channelHasField(encoding: EncodingWithFacet, channel: Channel): boolean {\n const channelDef = encoding && encoding[channel];\n if (channelDef) {\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.field);\n } else {\n return isFieldDef(channelDef);\n }\n }\n return false;\n}\n\nexport function isAggregate(encoding: EncodingWithFacet) {\n return some(CHANNELS, (channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n if (isArray(channelDef)) {\n return some(channelDef, (fieldDef) => !!fieldDef.aggregate);\n } else {\n return isFieldDef(channelDef) && !!channelDef.aggregate;\n }\n }\n return false;\n });\n}\n\nexport function dropInvalidFieldDefs(mark: Mark, encoding: Encoding): Encoding {\n\n // clone to prevent side effect to the original spec\n encoding = duplicate(encoding);\n\n Object.keys(encoding).forEach((channel: Channel) => {\n if (!supportMark(channel, mark)) {\n // Drop unsupported channel\n\n log.warn(log.message.incompatibleChannel(channel, mark));\n delete encoding[channel];\n return;\n }\n\n // Drop line's size if the field is aggregated.\n if (channel === 'size' && mark === 'line') {\n const channelDef = encoding[channel];\n if (isFieldDef(channelDef) && channelDef.aggregate) {\n log.warn(log.message.incompatibleChannel(channel, mark, 'when the field is aggregated.'));\n delete encoding[channel];\n }\n return;\n }\n\n if (isArray(encoding[channel])) {\n // Array of fieldDefs for detail channel (or production rule)\n encoding[channel] = encoding[channel].reduce((channelDefs: ChannelDef[], channelDef: ChannelDef) => {\n if (!isFieldDef(channelDef) && !isValueDef(channelDef)) { // TODO: datum\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n } else {\n channelDefs.push(normalize(channelDef, channel));\n }\n return channelDefs;\n }, []);\n } else {\n const channelDef = encoding[channel];\n if (!isFieldDef(channelDef) && !isValueDef(channelDef)) { // TODO: datum\n log.warn(log.message.emptyFieldDef(channelDef, channel));\n delete encoding[channel];\n return;\n }\n normalize(channelDef, channel);\n }\n });\n return encoding;\n}\n\n\nexport function isRanged(encoding: EncodingWithFacet) {\n return encoding && ((!!encoding.x && !!encoding.x2) || (!!encoding.y && !!encoding.y2));\n}\n\nexport function fieldDefs(encoding: EncodingWithFacet): FieldDef[] {\n let arr: FieldDef[] = [];\n CHANNELS.forEach(function(channel) {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n arr.push(fieldDef);\n });\n }\n });\n return arr;\n};\n\nexport function forEach(mapping: any,\n f: (fd: FieldDef, c: Channel) => void,\n thisArg?: any) {\n if (!mapping) {\n return;\n }\n\n Object.keys(mapping).forEach((c: any) => {\n const channel: Channel = c;\n if (isArray(mapping[channel])) {\n mapping[channel].forEach(function(channelDef: ChannelDef) {\n f.call(thisArg, channelDef, channel);\n });\n } else {\n f.call(thisArg, mapping[channel], channel);\n }\n });\n}\n\nexport function reduce(mapping: U,\n f: (acc: any, fd: FieldDef, c: Channel) => U,\n init: T, thisArg?: any) {\n if (!mapping) {\n return init;\n }\n\n return Object.keys(mapping).reduce((r: T, c: any) => {\n const channel: Channel = c;\n if (isArray(mapping[channel])) {\n return mapping[channel].reduce(function(r1: T, channelDef: ChannelDef) {\n return f.call(thisArg, r1, channelDef, channel);\n }, r);\n } else {\n return f.call(thisArg, r, mapping[channel], channel);\n }\n }, init);\n}\n","// utility for a field definition object\n\nimport {AggregateOp} from './aggregate';\nimport {Axis} from './axis';\nimport {Bin} from './bin';\nimport {Channel, rangeType} from './channel';\nimport {Config} from './config';\nimport {Legend} from './legend';\nimport * as log from './log';\nimport {Scale} from './scale';\nimport {StackOffset} from './stack';\nimport {SortField, SortOrder} from './sort';\nimport {TimeUnit, isDiscreteByDefault} from './timeunit';\nimport {Type, getFullName} from './type';\n\n/**\n * Definition object for a constant value of an encoding channel.\n */\nexport interface ValueDef {\n /**\n * A constant value in visual domain.\n */\n value?: T;\n}\n\nexport interface ConditionalValueDef extends ValueDef {\n condition?: Condition;\n}\n\n/**\n * Definition object for a data field, its type and transformation of an encoding channel.\n */\nexport interface FieldDef {\n /**\n * Name of the field from which to pull a data value.\n */\n field?: string;\n\n /**\n * The encoded field's type of measurement. This can be either a full type\n * name (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, and `\"nominal\"`)\n * or an initial character of the type name (`\"Q\"`, `\"T\"`, `\"O\"`, `\"N\"`).\n * This property is case insensitive.\n */\n type?: Type;\n\n\n // function\n\n /**\n * Time unit for a `temporal` field (e.g., `year`, `yearmonth`, `month`, `hour`).\n */\n timeUnit?: TimeUnit;\n\n /**\n * Flag for binning a `quantitative` field, or a bin property object\n * for binning parameters.\n */\n bin?: boolean | Bin;\n\n /**\n * Aggregation function for the field\n * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).\n */\n aggregate?: AggregateOp;\n\n /**\n * Title for axis or legend.\n */\n title?: string;\n}\n\nexport interface Condition {\n selection: string;\n value: T;\n}\n\nexport interface ScaleFieldDef extends FieldDef {\n scale?: Scale;\n sort?: SortField | SortOrder;\n}\n\nexport interface PositionFieldDef extends ScaleFieldDef {\n /**\n * @nullable\n */\n axis?: Axis;\n\n /**\n * Type of stacking offset if the field should be stacked.\n * \"none\" or null, if the field should not be stacked.\n */\n stack?: StackOffset;\n}\nexport interface LegendFieldDef extends ScaleFieldDef {\n /**\n * @nullable\n */\n legend?: Legend;\n\n condition?: Condition;\n}\n\n// Detail\n\n// Order Path have no scale\n\nexport interface OrderFieldDef extends FieldDef {\n sort?: SortOrder;\n}\n\nexport interface TextFieldDef extends FieldDef {\n // FIXME: add more reference to Vega's format pattern or d3's format pattern.\n /**\n * The formatting pattern for text value. If not defined, this will be determined automatically.\n */\n format?: string;\n\n condition?: Condition;\n};\n\nexport type ChannelDef = FieldDef | ValueDef;\n\nexport function isFieldDef(channelDef: ChannelDef): channelDef is FieldDef | PositionFieldDef | LegendFieldDef | OrderFieldDef | TextFieldDef {\n return channelDef && (!!channelDef['field'] || channelDef['aggregate'] === 'count');\n}\n\nexport function isValueDef(channelDef: ChannelDef): channelDef is ValueDef {\n return channelDef && 'value' in channelDef && channelDef['value'] !== undefined;\n}\n\n// TODO: consider if we want to distinguish ordinalOnlyScale from scale\nexport type FacetFieldDef = PositionFieldDef;\n\nexport interface FieldRefOption {\n /** exclude bin, aggregate, timeUnit */\n nofn?: boolean;\n /** Wrap the field inside datum[...] per Vega convention */\n datum?: boolean;\n /** prepend fn with custom function prefix */\n prefix?: string;\n /** append suffix to the field ref for bin (default='start') */\n binSuffix?: 'start' | 'end' | 'range';\n /** append suffix to the field ref (general) */\n suffix?: string;\n /** Overrride which aggregate to use. Needed for unaggregated domain. */\n aggregate?: AggregateOp;\n}\n\nexport function field(fieldDef: FieldDef, opt: FieldRefOption = {}) {\n let field = fieldDef.field;\n let prefix = opt.prefix;\n let suffix = opt.suffix;\n\n if (isCount(fieldDef)) {\n field = 'count_*';\n } else {\n let fn: string = undefined;\n\n if (!opt.nofn) {\n if (fieldDef.bin) {\n fn = 'bin';\n suffix = opt.binSuffix;\n } else if (fieldDef.aggregate) {\n fn = String(opt.aggregate || fieldDef.aggregate);\n } else if (fieldDef.timeUnit) {\n fn = String(fieldDef.timeUnit);\n }\n }\n\n if (!!fn) {\n field = `${fn}_${field}`;\n }\n }\n\n if (!!suffix) {\n field = `${field}_${suffix}`;\n }\n\n if (!!prefix) {\n field = `${prefix}_${field}`;\n }\n\n if (opt.datum) {\n field = `datum[\"${field}\"]`;\n }\n\n return field;\n}\n\nexport function isDiscrete(fieldDef: FieldDef) {\n switch (fieldDef.type) {\n case 'nominal':\n case 'ordinal':\n return true;\n case 'quantitative':\n return !!fieldDef.bin;\n case 'temporal':\n // TODO: deal with custom scale type case.\n return isDiscreteByDefault(fieldDef.timeUnit);\n }\n throw new Error(log.message.invalidFieldType(fieldDef.type));\n}\n\nexport function isContinuous(fieldDef: FieldDef) {\n return !isDiscrete(fieldDef);\n}\n\nexport function isCount(fieldDef: FieldDef) {\n return fieldDef.aggregate === 'count';\n}\n\nexport function title(fieldDef: FieldDef, config: Config) {\n if (fieldDef.title != null) {\n return fieldDef.title;\n }\n if (isCount(fieldDef)) {\n return config.countTitle;\n }\n const fn = fieldDef.aggregate || fieldDef.timeUnit || (fieldDef.bin && 'bin');\n if (fn) {\n return fn.toString().toUpperCase() + '(' + fieldDef.field + ')';\n } else {\n return fieldDef.field;\n }\n}\n\nexport function defaultType(fieldDef: FieldDef, channel: Channel): Type {\n if (!!fieldDef.timeUnit) {\n return 'temporal';\n }\n if (!!fieldDef.bin) {\n return 'quantitative';\n }\n switch (rangeType(channel)) {\n case 'continuous':\n return 'quantitative';\n case 'discrete':\n return 'nominal';\n case 'flexible': // color\n return 'nominal';\n default:\n return 'quantitative';\n }\n}\n\n/**\n * Convert type to full, lowercase type, or augment the fieldDef with a default type if missing.\n */\nexport function normalize(fieldDef: ChannelDef, channel: Channel) {\n // If a fieldDef contains a field, we need type.\n if (isFieldDef(fieldDef)) { // TODO: or datum\n // convert short type to full type\n const fullType = getFullName(fieldDef.type);\n if (fullType) {\n fieldDef.type = fullType;\n } else {\n // If type is empty / invalid, then augment with default type\n const newType = defaultType(fieldDef, channel);\n log.warn(log.message.emptyOrInvalidFieldType(fieldDef.type, channel, newType));\n fieldDef.type = newType;\n }\n\n const {compatible, warning} = channelCompatibility(fieldDef, channel);\n if (!compatible) {\n log.warn(warning);\n }\n }\n return fieldDef;\n}\n\nconst COMPATIBLE = {compatible: true};\nexport function channelCompatibility(fieldDef: FieldDef, channel: Channel): {compatible: boolean; warning?: string;} {\n switch (channel) {\n case 'row':\n case 'column':\n if (isContinuous(fieldDef) && !fieldDef.timeUnit) {\n // TODO:(https://github.com/vega/vega-lite/issues/2011):\n // with timeUnit it's not always strictly continuous\n return {\n compatible: false,\n warning: log.message.facetChannelShouldBeDiscrete(channel)\n };\n }\n return COMPATIBLE;\n\n case 'x':\n case 'y':\n case 'color':\n case 'text':\n case 'detail':\n return COMPATIBLE;\n\n case 'opacity':\n case 'size':\n case 'x2':\n case 'y2':\n if (isDiscrete(fieldDef) && !fieldDef.bin) {\n return {\n compatible: false,\n warning: `Channel ${channel} should not be used with discrete field.`\n };\n }\n return COMPATIBLE;\n\n case 'shape':\n if (fieldDef.type !== 'nominal') {\n return {\n compatible: false,\n warning: 'Shape channel should be used with nominal data only'\n };\n } else {\n return COMPATIBLE;\n }\n\n case 'order':\n if (fieldDef.type === 'nominal') {\n return {\n compatible: false,\n warning: `Channel order is inappropriate for nominal field, which has no inherent order.`\n };\n }\n return COMPATIBLE;\n }\n throw new Error('channelCompatability not implemented for channel ' + channel);\n}\n","import {DateTime, dateTimeExpr, isDateTime} from './datetime';\nimport {field} from './fielddef';\nimport {TimeUnit, fieldExpr as timeUnitFieldExpr, isSingleTimeUnit} from './timeunit';\nimport {isArray, isString} from './util';\n\nexport type Filter = EqualFilter | RangeFilter | OneOfFilter ;\n\n\nexport interface EqualFilter {\n // TODO: support aggregate\n\n /**\n * Time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered.\n */\n field: string;\n\n /**\n * Value that the field should be equal to.\n */\n equal: string | number | boolean | DateTime;\n\n}\n\nexport function isEqualFilter(filter: any): filter is EqualFilter {\n return filter && !!filter.field && filter.equal!==undefined;\n}\n\nexport interface RangeFilter {\n // TODO: support aggregate\n\n /**\n * time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered\n */\n field: string;\n\n /**\n * Array of inclusive minimum and maximum values\n * for a field value of a data item to be included in the filtered data.\n * @maxItems 2\n * @minItems 2\n */\n range: (number|DateTime)[];\n\n}\n\nexport function isRangeFilter(filter: any): filter is RangeFilter {\n if (filter && !!filter.field) {\n if (isArray(filter.range) && filter.range.length === 2) {\n return true;\n }\n }\n return false;\n}\n\nexport interface OneOfFilter {\n // TODO: support aggregate\n\n /**\n * time unit for the field to be filtered.\n */\n timeUnit?: TimeUnit;\n\n /**\n * Field to be filtered\n */\n field: string;\n\n /**\n * A set of values that the `field`'s value should be a member of,\n * for a data item included in the filtered data.\n */\n oneOf: (string|number|boolean|DateTime)[];\n\n}\n\nexport function isOneOfFilter(filter: any): filter is OneOfFilter {\n return filter && !!filter.field && (\n isArray(filter.oneOf) ||\n isArray(filter.in) // backward compatibility\n );\n}\n\nexport function expression(filter: Filter | string) {\n if (isString(filter)) {\n return filter as string;\n } else { // Filter Object\n const fieldExpr = filter.timeUnit ?\n // For timeUnit, cast into integer with time() so we can use ===, inrange, indexOf to compare values directly.\n // TODO: We calculate timeUnit on the fly here. Consider if we would like to consolidate this with timeUnit pipeline\n // TODO: support utc\n ('time(' + timeUnitFieldExpr(filter.timeUnit, filter.field) + ')') :\n field(filter, {datum: true});\n\n if (isEqualFilter(filter)) {\n return fieldExpr + '===' + valueExpr(filter.equal, filter.timeUnit);\n } else if (isOneOfFilter(filter)) {\n // \"oneOf\" was formerly \"in\" -- so we need to add backward compatibility\n const oneOf: OneOfFilter[] = filter.oneOf || filter['in'];\n return 'indexof([' +\n oneOf.map((v) => valueExpr(v, filter.timeUnit)).join(',') +\n '], ' + fieldExpr + ') !== -1';\n } else if (isRangeFilter(filter)) {\n const lower = filter.range[0];\n const upper = filter.range[1];\n\n if (lower !== null && upper !== null) {\n return 'inrange(' + fieldExpr + ', ' +\n valueExpr(lower, filter.timeUnit) + ', ' +\n valueExpr(upper, filter.timeUnit) + ')';\n } else if (lower !== null) {\n return fieldExpr + ' >= ' + lower;\n } else if (upper !== null) {\n return fieldExpr + ' <= ' + upper;\n }\n }\n }\n return undefined;\n}\n\nfunction valueExpr(v: any, timeUnit: TimeUnit) {\n if (isDateTime(v)) {\n const expr = dateTimeExpr(v, true);\n return 'time(' + expr + ')';\n }\n if (isSingleTimeUnit(timeUnit)) {\n const datetime: DateTime = {};\n datetime[timeUnit] = v;\n const expr = dateTimeExpr(datetime, true);\n return 'time(' + expr + ')';\n }\n return JSON.stringify(v);\n}\n","import {DateTime} from './datetime';\nimport {VgLegendEncode, VgLegendBase, VgLegendConfig} from './vega.schema';\n\nexport interface LegendConfig extends VgLegendConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\n/**\n * Properties of a legend or boolean flag for determining whether to show it.\n */\nexport interface Legend extends VgLegendBase {\n /**\n * Optional mark definitions for custom legend encoding.\n */\n encode?: VgLegendEncode;\n\n /**\n * An optional formatting pattern for legend labels. Vega uses D3\\'s format pattern.\n */\n format?: string;\n\n /**\n * The desired number of tick values for quantitative legends.\n */\n tickCount?: number;\n\n /**\n * A title for the legend. (Shows field name and its function by default.)\n */\n title?: string;\n /**\n * Explicitly set the visible legend values.\n */\n values?: number[] | string[] | DateTime[];\n\n /**\n * The name of a scale that maps to a shape value.\n */\n shape?: string;\n\n /**\n * The type of the legend. Use `symbol` to create a discrete legend and `gradient` for a continuous color gradient.\n */\n type?: 'symbol' | 'gradient';\n\n /**\n * A non-positive integer indicating z-index of the legend.\n * If zindex is 0, legend should be drawn behind all chart elements.\n * To put them in front, use zindex = 1.\n * @TJS-type integer\n * @minimum 0\n */\n zindex?: number;\n}\n\nexport const defaultLegendConfig: LegendConfig = {\n orient: undefined, // implicitly \"right\"\n};\n\nexport const LEGEND_PROPERTIES:(keyof Legend)[] = ['entryPadding', 'format', 'offset', 'orient', 'tickCount', 'title', 'type', 'values' ,'zindex'];\n","///\n\n/**\n * Vega-Lite's singleton logger utility.\n */\n\nimport {logger, LoggerInterface, Warn} from 'vega-util';\n\nimport {AggregateOp} from './aggregate';\nimport {Channel} from './channel';\nimport {DateTime, DateTimeExpr} from './datetime';\nimport {FieldDef} from './fielddef';\nimport {Mark} from './mark';\nimport {TimeUnit} from './timeunit';\nimport {Type} from './type';\nimport {ScaleType} from './scale';\n\nexport {LoggerInterface} from 'vega-util';\n\n/**\n * Main (default) Vega Logger instance for Vega-Lite\n */\nconst main = logger(Warn);\nlet current: LoggerInterface = main;\n\n/**\n * Logger tool for checking if the code throws correct warning\n */\nexport class LocalLogger implements LoggerInterface {\n public warns: any[] = [];\n public infos: any[] = [];\n public debugs: any[] = [];\n\n public level() {\n return this;\n }\n\n public warn(...args: any[]) {\n this.warns.push(...args);\n return this;\n }\n\n public info(...args: any[]) {\n this.infos.push(...args);\n return this;\n }\n\n public debug(...args: any[]) {\n this.debugs.push(...args);\n return this;\n }\n}\n\nexport function runLocalLogger(f: (localLogger: LocalLogger) => void) {\n const localLogger = current = new LocalLogger();\n f(localLogger);\n reset();\n}\n\nexport function wrap(f: (logger: LocalLogger) => void) {\n return () => {\n const logger = current = new LocalLogger();\n f(logger);\n reset();\n };\n}\n\n/**\n * Set the singleton logger to be a custom logger\n */\nexport function set(logger: LoggerInterface) {\n current = logger;\n return current;\n}\n\n/**\n * Reset the main logger to use the default Vega Logger\n */\nexport function reset() {\n current = main;\n return current;\n}\n\nexport function warn(..._: any[]) {\n current.warn.apply(current, arguments);\n}\n\nexport function info(..._: any[]) {\n current.info.apply(current, arguments);\n}\n\nexport function debug(..._: any[]) {\n current.debug.apply(current, arguments);\n}\n\n/**\n * Collection of all Vega-Lite Error Messages\n */\nexport namespace message {\n export const INVALID_SPEC = 'Invalid spec';\n\n // DATA\n export const DEPRECATED_FILTER_NULL = 'filterNull is deprecated. Please use filterInvalid instead.';\n\n // ENCODING & FACET\n export function invalidFieldType(type: Type) {\n return `Invalid field type \"${type}\"`;\n }\n\n export function emptyOrInvalidFieldType(type: Type | string, channel: Channel, newType: Type) {\n return `Invalid field type (${type}) for channel ${channel}, using ${newType} instead.`;\n }\n\n export function emptyFieldDef(fieldDef: FieldDef, channel: Channel) {\n return `Dropping ${JSON.stringify(fieldDef)} from channel ${channel} since it does not contain data field or value.`;\n }\n\n export function incompatibleChannel(channel: Channel, markOrFacet: Mark | 'facet', when?: string) {\n return `${channel} dropped as it is incompatible with ${markOrFacet}` +\n when ? `when ${when}` : '';\n }\n\n export function facetChannelShouldBeDiscrete(channel: string) {\n return `${channel} encoding should be discrete (ordinal / nominal / binned).`;\n }\n\n export function discreteChannelCannotEncode(channel: Channel, type: Type) {\n return `Using discrete channel ${channel} to encode ${type} field can be misleading as it does not encode ${type === 'ordinal' ? 'order' : 'magnitude'}.`;\n }\n\n // Mark\n export const BAR_WITH_POINT_SCALE_AND_RANGESTEP_NULL = 'Bar mark should not be used with point scale when rangeStep is null. Please use band scale instead.';\n\n export function unclearOrientContinuous(mark: Mark) {\n return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode continous fields. In this case, we use vertical by default';\n }\n\n export function unclearOrientDiscreteOrEmpty(mark: Mark) {\n return 'Cannot clearly determine orientation for ' + mark + ' since both x and y channel encode discrete or empty fields.';\n }\n\n export function orientOverridden(original: string, actual: string) {\n return `Specified orient ${original} overridden with ${actual}`;\n }\n\n // SCALE\n export const CANNOT_UNION_CUSTOM_DOMAIN_WITH_FIELD_DOMAIN = 'custom domain scale cannot be unioned with default field-based domain';\n\n export function cannotUseScalePropertyWithNonColor(prop: string) {\n return `Cannot use ${prop} with non-color channel.`;\n }\n\n export function unaggregateDomainHasNoEffectForRawField(fieldDef: FieldDef) {\n return `Using unaggregated domain with raw field has no effect (${JSON.stringify(fieldDef)}).`;\n }\n\n export function unaggregateDomainWithNonSharedDomainOp(aggregate: AggregateOp) {\n return `Unaggregated domain not applicable for ${aggregate} since it produces values outside the origin domain of the source data.`;\n }\n\n export function unaggregatedDomainWithLogScale(fieldDef: FieldDef) {\n return `Unaggregated domain is currently unsupported for log scale (${JSON.stringify(fieldDef)}).`;\n }\n\n export const CANNOT_USE_RANGE_WITH_POSITION =\n 'Cannot use custom range with x or y channel. Please customize width, height, padding, or rangeStep instead.';\n\n export const CANNOT_USE_PADDING_WITH_FACET = 'Cannot use padding with facet\\'s scale. Please use spacing instead.';\n\n export function cannotUseRangePropertyWithFacet(propName: string) {\n return `Cannot use custom ${propName} with row or column channel. Please use width, height, or spacing instead.`;\n }\n\n export function rangeStepDropped(channel: Channel) {\n return `rangeStep for ${channel} is dropped as top-level ${\n channel === 'x' ? 'width' : 'height'} is provided.`;\n }\n\n export function cannotOverrideBinScaleType(channel: Channel, defaultScaleType: ScaleType) {\n return `Cannot override scale type for binned channel ${channel}. We are using ${defaultScaleType} scale instead.`;\n }\n\n export function scaleTypeNotWorkWithChannel(channel: Channel, scaleType: ScaleType, defaultScaleType: ScaleType) {\n return `Channel ${channel} does not work with ${scaleType} scale. We are using ${defaultScaleType} scale instead.`;\n }\n\n export function scalePropertyNotWorkWithScaleType(scaleType: ScaleType, propName: string, channel: Channel) {\n return `${channel}-scale's \"${propName}\" is dropped as it does not work with ${scaleType} scale.`;\n }\n\n export function scaleTypeNotWorkWithMark(mark: Mark, scaleType: ScaleType) {\n return `Scale type \"${scaleType}\" does not work with mark ${mark}.`;\n }\n\n export const INVAID_DOMAIN = 'Invalid scale domain';\n\n export const UNABLE_TO_MERGE_DOMAINS = 'Unable to merge domains';\n\n // AXIS\n export const INVALID_CHANNEL_FOR_AXIS = 'Invalid channel for axis.';\n\n // STACK\n export function cannotStackRangedMark(channel: Channel) {\n return `Cannot stack ${channel} if there is already ${channel}2`;\n }\n\n export function cannotStackNonLinearScale(scaleType: ScaleType) {\n return `Cannot stack non-linear scale (${scaleType})`;\n }\n\n export function cannotStackNonSummativeAggregate(aggregate: AggregateOp) {\n return `Cannot stack when the aggregate function is non-summative (${aggregate})`;\n }\n\n // TIMEUNIT\n export function invalidTimeUnit(unitName: string, value: string | number) {\n return `Invalid ${unitName}: ${value}`;\n }\n\n export function dayReplacedWithDate(fullTimeUnit: TimeUnit) {\n return `Time unit \"${fullTimeUnit}\" is not supported. We are replacing it with ` +\n (fullTimeUnit+'').replace('day', 'date') + '.';\n }\n\n export function droppedDay(d: DateTime | DateTimeExpr) {\n return 'Dropping day from datetime ' + JSON.stringify(d) +\n ' as day cannot be combined with other units.';\n }\n}\n\n","import {toSet} from './util';\nimport {Orient, Interpolate, VgMarkConfig} from './vega.schema';\nexport {Orient} from './vega.schema';\n\nexport namespace Mark {\n export const AREA: 'area' = 'area';\n export const BAR: 'bar' = 'bar';\n export const LINE: 'line' = 'line';\n export const POINT: 'point' = 'point';\n export const RECT: 'rect' = 'rect';\n export const RULE: 'rule' = 'rule';\n export const TEXT: 'text' = 'text';\n export const TICK: 'tick' = 'tick';\n export const CIRCLE: 'circle' = 'circle';\n export const SQUARE: 'square' = 'square';\n}\n\n/**\n * All types of primitive marks.\n */\nexport type Mark = typeof Mark.AREA | typeof Mark.BAR | typeof Mark.LINE | typeof Mark.POINT | typeof Mark.TEXT | typeof Mark.TICK | typeof Mark.RECT | typeof Mark.RULE | typeof Mark.CIRCLE | typeof Mark.SQUARE;\n\n\nexport const AREA = Mark.AREA;\nexport const BAR = Mark.BAR;\nexport const LINE = Mark.LINE;\nexport const POINT = Mark.POINT;\nexport const TEXT = Mark.TEXT;\nexport const TICK = Mark.TICK;\nexport const RECT = Mark.RECT;\nexport const RULE = Mark.RULE;\n\nexport const CIRCLE = Mark.CIRCLE;\nexport const SQUARE = Mark.SQUARE;\n\nexport const PRIMITIVE_MARKS = [AREA, BAR, LINE, POINT, TEXT, TICK, RECT, RULE, CIRCLE, SQUARE];\n\nexport interface MarkDef {\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, and `\"text\"`.\n */\n type: Mark;\n\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n}\n\nexport function isMarkDef(mark: string | MarkDef): mark is MarkDef {\n return mark['type'];\n}\n\nconst PRIMITIVE_MARK_INDEX = toSet(PRIMITIVE_MARKS);\n\nexport function isPrimitiveMark(mark: string | MarkDef): mark is Mark {\n const markType = isMarkDef(mark) ? mark.type : mark;\n return markType in PRIMITIVE_MARK_INDEX;\n}\n\nexport const STROKE_CONFIG = ['stroke', 'strokeWidth',\n 'strokeDash', 'strokeDashOffset', 'strokeOpacity'];\n\nexport const FILL_CONFIG = ['fill', 'fillOpacity'];\n\nexport const FILL_STROKE_CONFIG = [].concat(STROKE_CONFIG, FILL_CONFIG);\n\nexport interface MarkConfig extends VgMarkConfig {\n\n // ---------- Color ----------\n /**\n * Whether the shape\\'s color should be used as fill color instead of stroke color.\n * This is only applicable for \"bar\", \"point\", and \"area\".\n * All marks except \"point\", \"line\", and \"rule\" are filled by default.\n */\n filled?: boolean;\n\n // TODO: remove this once we correctly integrate theme\n /**\n * Default color.\n */\n color?: string;\n}\n\nexport const defaultMarkConfig: MarkConfig = {\n color: '#4c78a8',\n};\n\nexport interface BarConfig extends MarkConfig {\n /**\n * Offset between bar for binned field. Ideal value for this is either 0 (Preferred by statisticians) or 1 (Vega-Lite Default, D3 example style).\n * @minimum 0\n */\n binSpacing?: number;\n /**\n * Default size of the bars on continuous scales.\n * @minimum 0\n */\n continuousBandSize?: number;\n\n /**\n * The size of the bars. If unspecified, the default size is `bandSize-1`,\n * which provides 1 pixel offset between bars.\n * @minimum 0\n */\n discreteBandSize?: number;\n}\n\nexport const defaultBarConfig: BarConfig = {\n binSpacing: 1,\n continuousBandSize: 2\n};\n\nexport interface TextConfig extends MarkConfig {\n /**\n * Whether month names and weekday names should be abbreviated.\n */\n shortTimeLabels?: boolean;\n}\n\nexport const defaultTextConfig: TextConfig = {\n baseline: 'middle',\n};\n\nexport interface TickConfig extends MarkConfig {\n /**\n * The width of the ticks.\n * If this value is undefined (by default,), we use 2/3 of rangeStep by default.\n * @minimum 0\n */\n bandSize?: number;\n\n /**\n * Thickness of the tick mark.\n * @minimum 0\n */\n thickness?: number;\n}\n\nexport const defaultTickConfig: TickConfig = {\n thickness: 1\n};\n","import * as log from './log';\nimport {Channel} from './channel';\nimport {DateTime} from './datetime';\nimport {contains, toSet} from './util';\n\nexport namespace ScaleType {\n // Continuous - Quantitative\n export const LINEAR: 'linear' = 'linear';\n export const BIN_LINEAR: 'bin-linear' = 'bin-linear';\n export const LOG: 'log' = 'log';\n export const POW: 'pow' = 'pow';\n export const SQRT: 'sqrt' = 'sqrt';\n // Continuous - Time\n export const TIME: 'time' = 'time';\n export const UTC: 'utc' = 'utc';\n // sequential\n export const SEQUENTIAL: 'sequential' = 'sequential';\n\n // Quantile, Quantize, threshold\n export const QUANTILE: 'quantile' = 'quantile';\n export const QUANTIZE: 'quantize' = 'quantize';\n export const THRESHOLD: 'threshold' = 'threshold';\n\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const BIN_ORDINAL: 'bin-ordinal' = 'bin-ordinal';\n export const POINT: 'point' = 'point';\n export const BAND: 'band' = 'band';\n}\n\nexport type ScaleType = typeof ScaleType.LINEAR | typeof ScaleType.BIN_LINEAR |\n typeof ScaleType.LOG | typeof ScaleType.POW | typeof ScaleType.SQRT |\n typeof ScaleType.TIME | typeof ScaleType.UTC |\n // TODO: add 'quantize', 'quantile', 'threshold' back when we really support them\n typeof ScaleType.SEQUENTIAL | // typeof ScaleType.QUANTILE | typeof ScaleType.QUANTIZE | typeof ScaleType.THRESHOLD |\n typeof ScaleType.ORDINAL | typeof ScaleType.BIN_ORDINAL | typeof ScaleType.POINT | typeof ScaleType.BAND;\n\nexport const SCALE_TYPES: ScaleType[] = [\n // Continuous - Quantitative\n 'linear', 'bin-linear', 'log', 'pow', 'sqrt',\n // Continuous - Time\n 'time', 'utc',\n // Sequential\n 'sequential', // TODO: add 'quantile', 'quantize' when we really support them\n // Discrete\n 'ordinal', 'bin-ordinal', 'point', 'band',\n];\n\nexport const CONTINUOUS_TO_CONTINUOUS_SCALES: ScaleType[] = ['linear', 'bin-linear', 'log', 'pow', 'sqrt', 'time', 'utc'];\nconst CONTINUOUS_TO_CONTINUOUS_INDEX = toSet(CONTINUOUS_TO_CONTINUOUS_SCALES);\n\nexport const CONTINUOUS_DOMAIN_SCALES: ScaleType[] = CONTINUOUS_TO_CONTINUOUS_SCALES.concat(['sequential' /* TODO add 'quantile', 'quantize', 'threshold'*/]);\nconst CONTINUOUS_DOMAIN_INDEX = toSet(CONTINUOUS_DOMAIN_SCALES);\n\nexport const DISCRETE_DOMAIN_SCALES: ScaleType[] = ['ordinal', 'bin-ordinal', 'point', 'band'];\nconst DISCRETE_DOMAIN_INDEX = toSet(DISCRETE_DOMAIN_SCALES);\n\nconst BIN_SCALES_INDEX = toSet(['bin-linear', 'bin-ordinal']);\n\nexport const TIME_SCALE_TYPES: ScaleType[] = ['time', 'utc'];\n\nexport function hasDiscreteDomain(type: ScaleType): type is 'ordinal' | 'bin-ordinal' | 'point' | 'band' {\n return type in DISCRETE_DOMAIN_INDEX;\n}\n\nexport function isBinScale(type: ScaleType): type is 'bin-linear' | 'bin-ordinal' {\n return type in BIN_SCALES_INDEX;\n}\n\nexport function hasContinuousDomain(type: ScaleType):\n type is 'linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc'|\n 'sequential' /* TODO add | 'quantile' | 'quantize' | 'threshold' */ {\n return type in CONTINUOUS_DOMAIN_INDEX;\n}\n\nexport function isContinuousToContinuous(type: ScaleType): type is 'linear' | 'bin-linear' | 'log' | 'pow' | 'sqrt' | 'time' | 'utc' {\n return type in CONTINUOUS_TO_CONTINUOUS_INDEX;\n}\n\nexport type NiceTime = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';\n\nexport interface ScaleConfig {\n /**\n * If true, rounds numeric output values to integers.\n * This can be helpful for snapping to the pixel grid.\n * (Only available for `x`, `y`, `size`, `row`, and `column` scales.)\n */\n round?: boolean;\n\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * Default range step for `x` ordinal scale when is mark is `text`.\n * @minimum 0\n */\n textXRangeStep?: number; // FIXME: consider if we will rename this \"tableColumnWidth\"\n /**\n * Default range step for (1) `y` ordinal scale,\n * and (2) `x` ordinal scale when the mark is not `text`.\n *\n * @minimum 0\n * @nullable\n */\n rangeStep?: number | null;\n\n /**\n * Default inner padding for `x` and `y` band-ordinal scales.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingInner?: number;\n\n /**\n * Default outer padding for `x` and `y` band-ordinal scales.\n * If not specified, by default, band scale's paddingOuter is paddingInner/2.\n * @minimum 0\n * @maximum 1\n */\n bandPaddingOuter?: number;\n\n /**\n * Default outer padding for `x` and `y` point-ordinal scales.\n * @minimum 0\n * @maximum 1\n */\n pointPadding?: number;\n\n /**\n * Default spacing between faceted plots.\n * @TJS-type integer\n * @minimum 0\n */\n facetSpacing?: number;\n\n /**\n * Use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n */\n useUnaggregatedDomain?: boolean;\n\n // nice should depends on type (quantitative or temporal), so\n // let's not make a config.\n\n // Configs for Range\n\n\n /**\n * The default max value for mapping quantitative fields to bar's size/bandSize.\n * If undefined (default), we will use bandSize - 1.\n * @minimum 0\n */\n maxBandSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to bar and tick's size/bandSize scale with zero=false\n * If undefined (default), we will use the `continuousBandSize` value for bar and 3 for ticks.\n * @minimum 0\n */\n minBandSize?: number;\n\n /**\n * The default max value for mapping quantitative fields to text's size/fontSize.\n * If undefined (default), we will use bandSize - 1.\n * @minimum 0\n */\n maxFontSize?: number;\n\n /**\n * The default min value for mapping quantitative fields to tick's size/fontSize scale with zero=false\n * @minimum 0\n */\n minFontSize?: number;\n\n /**\n * Default minimum opacity for mapping a field to opacity.\n * @minimum 0\n * @maximum 1\n */\n minOpacity?: number;\n\n /**\n * Default max opacity for mapping a field to opacity.\n * @minimum 0\n * @maximum 1\n */\n maxOpacity?: number;\n\n\n /**\n * Default minimum value for point size scale with zero=false.\n * @minimum 0\n */\n minSize?: number;\n\n /**\n * Default max value for point size scale.\n * @minimum 0\n */\n maxSize?: number;\n\n /**\n * Default minimum strokeWidth for strokeWidth (or rule/line's size) scale with zero=false.\n * @minimum 0\n */\n minStrokeWidth?: number;\n\n /**\n * Default max strokeWidth for strokeWidth (or rule/line's size) scale.\n * @minimum 0\n */\n maxStrokeWidth?: number;\n\n /**\n * The default collection of symbol shapes for mapping nominal fields to shapes of point marks (i.e., range of a `shape` scale).\n * Each value should be one of: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n */\n shapes?: string[];\n}\n\nexport const defaultScaleConfig = {\n round: true,\n textXRangeStep: 90,\n rangeStep: 21,\n pointPadding: 0.5,\n bandPaddingInner: 0.1,\n facetSpacing: 16,\n\n minFontSize: 8,\n maxFontSize: 40,\n\n minOpacity: 0.3,\n maxOpacity: 0.8,\n\n // FIXME: revise if these *can* become ratios of rangeStep\n minSize: 9, // Point size is area. For square point, 9 = 3 pixel ^ 2, not too small!\n\n minStrokeWidth: 1,\n maxStrokeWidth: 4,\n\n shapes: ['circle', 'square', 'cross', 'diamond', 'triangle-up', 'triangle-down']\n};\n\nexport interface ExtendedScheme {\n /**\n * Color scheme that determines output color of an ordinal/sequential color scale.\n */\n name: string;\n\n // TODO: add docs\n extent?: number[];\n\n // TODO: add docs\n count?: number;\n}\n\nexport type Domain = number[] | string[] | DateTime[] | 'unaggregated';\nexport type Scheme = string | ExtendedScheme;\n\nexport type Range = number[] | string[] | string;\n\nexport function isExtendedScheme(scheme: string | ExtendedScheme): scheme is ExtendedScheme {\n return scheme && !!scheme['name'];\n}\n\nexport interface Scale {\n type?: ScaleType;\n /**\n * The domain of the scale, representing the set of data values. For quantitative data, this can take the form of a two-element array with minimum and maximum values. For ordinal/categorical data, this may be an array of valid input values.\n *\n * If the domain is 'unaggregated', we use the source data range before aggregation as scale domain instead of aggregated data for aggregate axis.\n * This property only works with aggregate functions that produce values within the raw data domain (`\"mean\"`, `\"average\"`, `\"median\"`, `\"q1\"`, `\"q3\"`, `\"min\"`, `\"max\"`). For other aggregations that produce values outside of the raw data domain (e.g. `\"count\"`, `\"sum\"`), this property is ignored.\n */\n domain?: Domain;\n\n /**\n * The range of the scale, representing the set of visual values. For numeric values, the range can take the form of a two-element array with minimum and maximum values. For ordinal or quantized data, the range may by an array of desired output values, which are mapped to elements in the specified domain.\n */\n range?: Range;\n\n /**\n * If true, rounds numeric output values to integers. This can be helpful for snapping to the pixel grid.\n *\n * __Default Rule:__ `true` for `\"x\"`, `\"y\"`, `\"row\"`, `\"column\"` channels if scale config's `round` is `true`; `false` otherwise.\n */\n round?: boolean;\n\n // ordinal\n /**\n * The distance between the starts of adjacent bands or points in band or point scales.\n * If this value is `null`, this will be determined to fit width (for x) or height (for y) of the plot.\n * If both width and x-scale's rangeStep is provided, rangeStep will be dropped. (The same rule is applied for height and y-scale's rangeStep.)\n *\n * __Default Rule:__ for `x` ordinal scale of a `text` mark, derived from [scale config](config.html#scale-config)'s `textXRangeStep`. Otherwise, derived from [scale config](config.html#scale-config)'s `rangeStep`.\n * __Warning:__ If the cardinality of the scale domain is too high, the rangeStep might become less than one pixel and the mark might not appear correctly.\n * @minimum 0\n * @nullable\n */\n rangeStep?: number | null;\n\n /**\n * Range scheme (e.g., color schemes such as \"category10\" or \"viridis\").\n */\n scheme?: Scheme;\n\n /**\n * (For `row` and `column` only) A pixel value for padding between cells in the trellis plots.\n * @TJS-type integer\n */\n spacing?: number;\n\n /**\n * Applies spacing among ordinal elements in the scale range. The actual effect depends on how the scale is configured. If the __points__ parameter is `true`, the padding value is interpreted as a multiple of the spacing between points. A reasonable value is 1.0, such that the first and last point will be offset from the minimum and maximum value by half the distance between points. Otherwise, padding is typically in the range [0, 1] and corresponds to the fraction of space in the range interval to allocate to padding. A value of 0.5 means that the band size will be equal to the padding width. For more, see the [D3 ordinal scale documentation](https://github.com/mbostock/d3/wiki/Ordinal-Scales).\n * A convenience property for setting the inner and outer padding to the same value.\n * @minimum 0\n * @maximum 1\n */\n padding?: number;\n\n /**\n * The inner padding of a band scale determines the ratio of the range that is reserved for blank space between bands. (For point scale, this property is ignored.)\n * @minimum 0\n * @maximum 1\n */\n paddingInner?: number;\n\n /**\n * The outer padding determines the ratio of the range that is reserved for blank space before the first and after the last bands/points.\n * @minimum 0\n * @maximum 1\n */\n paddingOuter?: number;\n\n // typical\n /**\n * If true, values that exceed the data domain are clamped to either the minimum or maximum range value\n */\n clamp?: boolean;\n /**\n * If specified, modifies the scale domain to use a more human-friendly value range. If specified as a true boolean, modifies the scale domain to use a more human-friendly number range (e.g., 7 instead of 6.96). If specified as a string, modifies the scale domain to use a more human-friendly value range. For time and utc scale types only, the nice value should be a string indicating the desired time interval.\n */\n nice?: boolean | NiceTime;\n /**\n * Sets the exponent of the scale transformation. For pow scale types only, otherwise ignored.\n */\n exponent?: number;\n /**\n * If `true`, ensures that a zero baseline value is included in the scale domain.\n * Default value: `true` for `x` and `y` channel if the quantitative field is not binned\n * and no custom `domain` is provided; `false` otherwise.\n */\n zero?: boolean;\n\n // FIXME: Add description\n interpolate?: 'rgb'| 'lab' | 'hcl' | 'hsl' | 'hsl-long' | 'hcl-long' | 'cubehelix' | 'cubehelix-long';\n}\n\nexport const SCALE_PROPERTIES:(keyof Scale)[]= [\n 'type', 'domain', 'range', 'round', 'rangeStep', 'scheme', 'padding', 'paddingInner', 'paddingOuter', 'clamp', 'nice',\n 'exponent', 'zero', 'interpolate'\n];\n\nexport function scaleTypeSupportProperty(scaleType: ScaleType, propName: keyof Scale) {\n switch (propName) {\n case 'type':\n case 'domain':\n case 'range':\n case 'scheme':\n return true;\n case 'interpolate':\n return scaleType === 'linear' || scaleType === 'bin-linear';\n case 'round':\n return isContinuousToContinuous(scaleType) || scaleType === 'band' || scaleType === 'point';\n case 'rangeStep':\n case 'padding':\n case 'paddingOuter':\n return contains(['point', 'band'], scaleType);\n case 'paddingInner':\n return scaleType === 'band';\n case 'clamp':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential';\n case 'nice':\n return isContinuousToContinuous(scaleType) || scaleType === 'sequential' || scaleType as any === 'quantize';\n case 'exponent':\n return scaleType === 'pow' || scaleType === 'log';\n case 'zero':\n // TODO: what about quantize, threshold?\n return scaleType === 'bin-ordinal' || (!hasDiscreteDomain(scaleType) && !contains(['log', 'time', 'utc'], scaleType));\n }\n /* istanbul ignore next: should never reach here*/\n throw new Error(`Invalid scale property ${propName}.`);\n}\n\n/**\n * Returns undefined if the input channel supports the input scale property name\n */\nexport function channelScalePropertyIncompatability(channel: Channel, propName: keyof Scale): string {\n switch (propName) {\n case 'range':\n // User should not customize range for position and facet channel directly.\n if (channel === 'x' || channel === 'y') {\n return log.message.CANNOT_USE_RANGE_WITH_POSITION;\n }\n if (channel === 'row' || channel === 'column') {\n return log.message.cannotUseRangePropertyWithFacet('range');\n }\n return undefined; // GOOD!\n // band / point\n case 'rangeStep':\n if (channel === 'row' || channel === 'column') {\n return log.message.cannotUseRangePropertyWithFacet('rangeStep');\n }\n return undefined; // GOOD!\n case 'padding':\n case 'paddingInner':\n case 'paddingOuter':\n if (channel === 'row' || channel === 'column') {\n /*\n * We do not use d3 scale's padding for row/column because padding there\n * is a ratio ([0, 1]) and it causes the padding to be decimals.\n * Therefore, we manually calculate \"spacing\" in the layout by ourselves.\n */\n return log.message.CANNOT_USE_PADDING_WITH_FACET;\n }\n return undefined; // GOOD!\n case 'interpolate':\n case 'scheme':\n if (channel !== 'color') {\n return log.message.cannotUseScalePropertyWithNonColor(channel);\n }\n return undefined;\n case 'type':\n case 'domain':\n case 'round':\n case 'clamp':\n case 'exponent':\n case 'nice':\n case 'zero':\n // These channel do not have strict requirement\n return undefined; // GOOD!\n }\n /* istanbul ignore next: it should never reach here */\n throw new Error('Invalid scale property \"${propName}\".');\n}\n","import {VgBinding} from './vega.schema';\n\nexport type SelectionTypes = 'single' | 'multi' | 'interval';\nexport type SelectionDomain = 'data' | 'visual';\nexport type SelectionResolutions = 'single' | 'independent' | 'union' |\n 'union_others' | 'intersect' | 'intersect_others';\n\nexport interface BaseSelectionDef {\n // domain?: SelectionDomain;\n on?: any;\n // predicate?: string;\n bind?: 'scales' | VgBinding | {[key: string]: VgBinding};\n\n // Transforms\n fields?: string[];\n encodings?: string[];\n toggle?: string | boolean;\n translate?: string | boolean;\n zoom?: string | boolean;\n nearest?: boolean;\n}\n\nexport interface SelectionDef extends BaseSelectionDef {\n type: SelectionTypes;\n}\n\nexport interface SelectionConfig {\n single: BaseSelectionDef;\n multi: BaseSelectionDef;\n interval: BaseSelectionDef;\n}\n\nexport const defaultConfig:SelectionConfig = {\n single: {on: 'click', fields: ['_id']},\n multi: {on: 'click', fields: ['_id'], toggle: 'event.shiftKey'},\n interval: {\n on: '[mousedown, window:mouseup] > window:mousemove!',\n encodings: ['x', 'y'],\n translate: '[mousedown, window:mouseup] > window:mousemove!',\n zoom: 'wheel'\n }\n};\n","import {AggregateOp} from './aggregate';\n\nexport type SortOrder = 'ascending' | 'descending' | null;\n\nexport interface SortField {\n /**\n * The field name to aggregate over.\n */\n field: string;\n /**\n * The sort aggregation operator\n */\n op: AggregateOp;\n\n order?: SortOrder;\n}\n\nexport function isSortField(sort: SortOrder | SortField): sort is SortField {\n return !!sort && !!sort['field'] && !!sort['op'];\n}\n","/* Package of defining Vega-lite Specification's json schema at its utility functions */\n\nimport {Config, defaultOverlayConfig} from './config';\nimport * as compositeMark from './compositemark';\nimport {Data} from './data';\nimport {EncodingWithFacet, Encoding, channelHasField, isRanged} from './encoding';\nimport {Facet} from './facet';\nimport {FieldDef} from './fielddef';\n\nimport * as log from './log';\nimport {Mark, MarkDef, AREA, LINE, POINT, isPrimitiveMark} from './mark';\nimport {stack} from './stack';\nimport {Transform} from './transform';\nimport {ROW, COLUMN, X, Y, X2, Y2} from './channel';\nimport * as vlEncoding from './encoding';\nimport {contains, duplicate, extend, hash, keys, omit, pick, vals} from './util';\nimport {SelectionDef} from './selection';\n\nexport type Padding = number | {top?: number, bottom?: number, left?: number, right?: number};\n\nexport interface BaseSpec {\n /**\n * URL to JSON schema for this Vega-Lite specification.\n * @format uri\n */\n $schema?: string;\n\n /**\n * Name of the visualization for later reference.\n */\n name?: string;\n\n /**\n * An optional description of this mark for commenting purpose.\n * This property has no effect on the output visualization.\n */\n description?: string;\n\n /**\n * The default visualization padding, in pixels, from the edge of the visualization canvas to the data rectangle. This can be a single number or an object with `\"top\"`, `\"left\"`, `\"right\"`, `\"bottom\"` properties.\n *\n * __Default value__: `5`\n *\n * @minimum 0\n */\n padding?: Padding;\n\n /**\n * An object describing the data source\n */\n data?: Data;\n\n /**\n * An object describing filter and new field calculation.\n */\n transform?: Transform;\n\n /**\n * Configuration object\n */\n config?: Config;\n}\n\nexport interface GenericUnitSpec extends BaseSpec {\n // FIXME description for top-level width\n width?: number;\n\n // FIXME description for top-level width\n height?: number;\n\n /**\n * The mark type.\n * One of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`,\n * `\"area\"`, `\"point\"`, `\"rule\"`, and `\"text\"`.\n */\n mark: M;\n\n /**\n * A key-value mapping between encoding channels and definition of fields.\n */\n encoding: E;\n\n /**\n * A key-value mapping between selection names and definitions.\n */\n selection?: {[name: string]: SelectionDef};\n}\n\nexport type UnitSpec = GenericUnitSpec;\n\nexport type LayeredUnitSpec = GenericUnitSpec;\n\nexport type FacetedUnitSpec = GenericUnitSpec;\n\nexport interface GenericLayerSpec> extends BaseSpec {\n // FIXME description for top-level width\n width?: number;\n\n // FIXME description for top-level width\n height?: number;\n\n /**\n * Unit specs that will be layered.\n */\n // TODO: support layer of layer\n layer: (GenericLayerSpec | U)[];\n}\n\nexport type LayerSpec = GenericLayerSpec;\n\nexport interface GenericFacetSpec> extends BaseSpec {\n facet: Facet;\n\n // TODO: support facet of facet\n spec: GenericLayerSpec | U;\n}\n\nexport type FacetSpec = GenericFacetSpec;\nexport type ExtendedFacetSpec = GenericFacetSpec;\n\nexport type GenericSpec> = U | GenericLayerSpec | GenericFacetSpec;\n\nexport type ExtendedSpec = GenericSpec;\n\nexport type Spec = GenericSpec;\n\n/* Custom type guards */\n\n\nexport function isFacetSpec(spec: GenericSpec>): spec is GenericFacetSpec> {\n return spec['facet'] !== undefined;\n}\n\nexport function isFacetedUnitSpec(spec: ExtendedSpec): spec is FacetedUnitSpec {\n if (isUnitSpec(spec)) {\n const hasRow = channelHasField(spec.encoding, ROW);\n const hasColumn = channelHasField(spec.encoding, COLUMN);\n\n return hasRow || hasColumn;\n }\n\n return false;\n}\n\nexport function isUnitSpec(spec: ExtendedSpec | Spec): spec is FacetedUnitSpec | UnitSpec {\n return !!spec['mark'];\n}\n\nexport function isLayerSpec(spec: ExtendedSpec | Spec): spec is GenericLayerSpec> {\n return spec['layer'] !== undefined;\n}\n\n/**\n * Decompose extended unit specs into composition of pure unit specs.\n */\n// TODO: consider moving this to another file. Maybe vl.spec.normalize or vl.normalize\nexport function normalize(spec: ExtendedSpec): Spec {\n if (isFacetSpec(spec)) {\n return normalizeFacet(spec);\n }\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec);\n }\n if (isFacetedUnitSpec(spec)) {\n return normalizeFacetedUnit(spec);\n }\n if (isUnitSpec(spec)) {\n return normalizeNonFacetUnit(spec);\n }\n throw new Error(log.message.INVALID_SPEC);\n}\n\nfunction normalizeNonFacet(spec: GenericLayerSpec | LayeredUnitSpec) {\n if (isLayerSpec(spec)) {\n return normalizeLayer(spec);\n }\n return normalizeNonFacetUnit(spec);\n}\n\nfunction normalizeFacet(spec: GenericFacetSpec): FacetSpec {\n const {spec: subspec, ...rest} = spec;\n return {\n ...rest,\n spec: normalizeNonFacet(subspec)\n };\n}\n\nfunction normalizeLayer(spec: GenericLayerSpec): LayerSpec {\n const {layer: layer, ...rest} = spec;\n return {\n ...rest,\n layer: layer.map(normalizeNonFacet)\n };\n}\n\nfunction normalizeFacetedUnit(spec: FacetedUnitSpec): FacetSpec {\n // New encoding in the inside spec should not contain row / column\n // as row/column should be moved to facet\n const {row: row, column: column, ...encoding} = spec.encoding;\n\n // Mark and encoding should be moved into the inner spec\n const {mark: mark, encoding: _, ...outerSpec} = spec;\n\n return {\n ...outerSpec,\n facet: {\n ...(row ? {row} : {}),\n ...(column ? {column}: {}),\n },\n spec: normalizeNonFacetUnit({\n mark,\n encoding\n })\n };\n}\n\nfunction isNonFacetUnitSpecWithPrimitiveMark(spec: GenericUnitSpec):\n spec is GenericUnitSpec {\n return isPrimitiveMark(spec.mark);\n}\n\nfunction normalizeNonFacetUnit(spec: GenericUnitSpec) {\n const config = spec.config;\n const overlayConfig = config && config.overlay;\n const overlayWithLine = overlayConfig && spec.mark === AREA &&\n contains(['linepoint', 'line'], overlayConfig.area);\n const overlayWithPoint = overlayConfig && (\n (overlayConfig.line && spec.mark === LINE) ||\n (overlayConfig.area === 'linepoint' && spec.mark === AREA)\n );\n\n if (isNonFacetUnitSpecWithPrimitiveMark(spec)) {\n // TODO: thoroughly test\n if (isRanged(spec.encoding)) {\n return normalizeRangedUnit(spec);\n }\n\n // TODO: consider moving this to become another case of compositeMark\n if (overlayWithPoint || overlayWithLine) {\n return normalizeOverlay(spec, overlayWithPoint, overlayWithLine);\n }\n\n return spec; // Nothing to normalize\n } else {\n return compositeMark.normalize(spec);\n }\n}\n\nfunction normalizeRangedUnit(spec: UnitSpec) {\n const hasX = channelHasField(spec.encoding, X);\n const hasY = channelHasField(spec.encoding, Y);\n const hasX2 = channelHasField(spec.encoding, X2);\n const hasY2 = channelHasField(spec.encoding, Y2);\n if ((hasX2 && !hasX) || (hasY2 && !hasY)) {\n let normalizedSpec = duplicate(spec);\n if (hasX2 && !hasX) {\n normalizedSpec.encoding.x = normalizedSpec.encoding.x2;\n delete normalizedSpec.encoding.x2;\n }\n if (hasY2 && !hasY) {\n normalizedSpec.encoding.y = normalizedSpec.encoding.y2;\n delete normalizedSpec.encoding.y2;\n }\n\n return normalizedSpec;\n }\n return spec;\n}\n\n\n// FIXME(#1804): rewrite this\nfunction normalizeOverlay(spec: UnitSpec, overlayWithPoint: boolean, overlayWithLine: boolean): LayerSpec {\n let outerProps = ['name', 'description', 'data', 'transform'];\n let baseSpec = omit(spec, outerProps.concat('config'));\n\n let baseConfig = duplicate(spec.config);\n delete baseConfig.overlay;\n // TODO: remove shape, size\n\n // Need to copy stack config to overlayed layer\n const stacked = stack(spec.mark,\n spec.encoding,\n spec.config ? spec.config.stack : undefined\n );\n\n const layerSpec = {\n ...pick(spec, outerProps),\n layer: [baseSpec],\n ...(keys(baseConfig).length > 0 ? {config: baseConfig} : {})\n };\n\n if (overlayWithLine) {\n // TODO: add name with suffix\n let lineSpec = duplicate(baseSpec);\n lineSpec.mark = LINE;\n // TODO: remove shape, size\n let markConfig = extend({},\n defaultOverlayConfig.lineStyle,\n spec.config.overlay.lineStyle,\n stacked ? {stacked: stacked.offset} : null\n );\n if (keys(markConfig).length > 0) {\n lineSpec.config = {mark: markConfig};\n }\n\n layerSpec.layer.push(lineSpec);\n }\n\n if (overlayWithPoint) {\n // TODO: add name with suffix\n let pointSpec = duplicate(baseSpec);\n pointSpec.mark = POINT;\n\n let markConfig = extend({},\n defaultOverlayConfig.pointStyle,\n spec.config.overlay.pointStyle,\n stacked ? {stacked: stacked.offset} : null\n );\n if (keys(markConfig).length > 0) {\n pointSpec.config = {mark: markConfig};\n }\n layerSpec.layer.push(pointSpec);\n }\n return layerSpec;\n}\n\n// TODO: add vl.spec.validate & move stuff from vl.validate to here\n\n/* Accumulate non-duplicate fieldDefs in a dictionary */\nfunction accumulate(dict: any, fieldDefs: FieldDef[]): any {\n fieldDefs.forEach(function(fieldDef) {\n // Consider only pure fieldDef properties (ignoring scale, axis, legend)\n const pureFieldDef = ['field', 'type', 'value', 'timeUnit', 'bin', 'aggregate'].reduce((f, key) => {\n if (fieldDef[key] !== undefined) {\n f[key] = fieldDef[key];\n }\n return f;\n }, {});\n let key = hash(pureFieldDef);\n dict[key] = dict[key] || fieldDef;\n });\n return dict;\n}\n\n/* Recursively get fieldDefs from a spec, returns a dictionary of fieldDefs */\nfunction fieldDefIndex(spec: ExtendedSpec | ExtendedFacetSpec, dict: any = {}): any {\n // TODO: Support repeat and concat\n if (isLayerSpec(spec)) {\n spec.layer.forEach(function(layer) {\n if (isUnitSpec(layer)) {\n accumulate(dict, vlEncoding.fieldDefs(layer.encoding));\n } else {\n fieldDefIndex(layer, dict);\n }\n });\n } else if (isFacetSpec(spec)) {\n accumulate(dict, vlEncoding.fieldDefs(spec.facet));\n fieldDefIndex(spec.spec, dict);\n } else { // Unit Spec\n accumulate(dict, vlEncoding.fieldDefs(spec.encoding));\n }\n return dict;\n}\n\n/* Returns all non-duplicate fieldDefs in a spec in a flat array */\nexport function fieldDefs(spec: ExtendedSpec | ExtendedFacetSpec): FieldDef[] {\n return vals(fieldDefIndex(spec));\n};\n\nexport function isStacked(spec: FacetedUnitSpec): boolean {\n if (isPrimitiveMark(spec.mark)) {\n return stack(spec.mark, spec.encoding,\n spec.config ? spec.config.stack : undefined\n ) !== null;\n }\n return false;\n}\n","import * as log from './log';\n\nimport {SUM_OPS} from './aggregate';\nimport {Channel, STACK_GROUP_CHANNELS, X, Y, X2, Y2} from './channel';\nimport {Encoding, channelHasField, isAggregate} from './encoding';\nimport {FieldDef, PositionFieldDef, isFieldDef} from './fielddef';\nimport {Mark, BAR, AREA, POINT, CIRCLE, SQUARE, LINE, RULE, TEXT, TICK, MarkDef, isMarkDef} from './mark';\nimport {ScaleType} from './scale';\nimport {contains, isArray} from './util';\n\n\n\nexport type StackOffset = 'zero' | 'center' | 'normalize' | 'none';\n\nexport interface StackProperties {\n /** Dimension axis of the stack ('x' or 'y'). */\n groupbyChannel: Channel;\n\n /** Measure axis of the stack ('x' or 'y'). */\n fieldChannel: Channel;\n\n /** Stack-by fields e.g., color, detail */\n stackBy: {\n fieldDef: FieldDef,\n channel: Channel\n }[];\n\n /**\n * Modes for stacking marks:\n * - `zero`: stacking with baseline offset at zero value of the scale (for creating typical stacked [bar](mark.html#stacked-bar-chart) and [area](mark.html#stacked-area-chart) chart).\n * - `normalize` - stacking with normalized domain (for creating normalized stacked [bar](mark.html#normalized-stacked-bar-chart) and [area](mark.html#normalized-stacked-area-chart) chart).
\n * -`center` - stacking with center baseline (for [streamgraph](mark.html#streamgraph)).\n * - `none` - No-stacking. This will produce layered [bar](mark.html#layered-bar-chart) and area chart.\n *\n * __Default value:__ `zero` for plots with all of the following conditions: (1) `bar` or `area` marks (2) `color`, `opacity`, `size`, or `detail` channel mapped to a group-by field (3) One ordinal or nominal axis, and (4) one quantitative axis with linear scale and summative aggregation function (e.g., `sum`, `count`).\n */\n offset: StackOffset;\n}\n\nexport const STACKABLE_MARKS = [BAR, AREA, RULE, POINT, CIRCLE, SQUARE, LINE, TEXT, TICK];\nexport const STACK_BY_DEFAULT_MARKS = [BAR, AREA];\n\n// Note: CompassQL uses this method and only pass in required properties of each argument object.\n// If required properties change, make sure to update CompassQL.\n\nexport function stack(m: Mark | MarkDef, encoding: Encoding, stackConfig: StackOffset): StackProperties {\n const mark = isMarkDef(m) ? m.type : m;\n // Should have stackable mark\n if (!contains(STACKABLE_MARKS, mark)) {\n return null;\n }\n\n // Should be aggregate plot\n if (!isAggregate(encoding)) {\n return null;\n }\n\n // Should have grouping level of detail\n const stackBy = STACK_GROUP_CHANNELS.reduce((sc, channel) => {\n if (channelHasField(encoding, channel)) {\n const channelDef = encoding[channel];\n (isArray(channelDef) ? channelDef : [channelDef]).forEach((fieldDef) => {\n if (isFieldDef(fieldDef) && !fieldDef.aggregate) {\n sc.push({\n channel: channel,\n fieldDef: fieldDef\n });\n }\n });\n }\n return sc;\n }, []);\n\n if (stackBy.length === 0) {\n return null;\n }\n\n // Has only one aggregate axis\n const hasXField = isFieldDef(encoding.x);\n const hasYField = isFieldDef(encoding.y);\n const xIsAggregate = isFieldDef(encoding.x) && !!encoding.x.aggregate;\n const yIsAggregate = isFieldDef(encoding.y) && !!encoding.y.aggregate;\n\n if (xIsAggregate !== yIsAggregate) {\n const fieldChannel = xIsAggregate ? X : Y;\n const fieldDef = encoding[fieldChannel] as PositionFieldDef;\n const fieldChannelAggregate = fieldDef.aggregate;\n const fieldChannelScale = fieldDef.scale;\n\n let stackOffset: StackOffset = null;\n if (fieldDef.stack !== undefined) {\n stackOffset = fieldDef.stack;\n } else if (contains(STACK_BY_DEFAULT_MARKS, mark)) {\n // Bar and Area with sum ops are automatically stacked by default\n stackOffset = stackConfig === undefined ? 'zero' : stackConfig;\n } else {\n stackOffset = stackConfig;\n }\n\n if (!stackOffset || stackOffset === 'none') {\n return null;\n }\n\n // If stacked, check if it qualifies for stacking (and log warning if not qualified.)\n if (fieldChannelScale && fieldChannelScale.type && fieldChannelScale.type !== ScaleType.LINEAR) {\n log.warn(log.message.cannotStackNonLinearScale(fieldChannelScale.type));\n return null;\n }\n\n if (channelHasField(encoding, fieldChannel === X ? X2 : Y2)) {\n log.warn(log.message.cannotStackRangedMark(fieldChannel));\n return null;\n }\n\n if (!contains(SUM_OPS, fieldChannelAggregate)) {\n log.warn(log.message.cannotStackNonSummativeAggregate(fieldChannelAggregate));\n return null;\n }\n\n return {\n groupbyChannel: xIsAggregate ? (hasYField ? Y : null) : (hasXField ? X : null),\n fieldChannel: fieldChannel,\n stackBy: stackBy,\n offset: stackOffset\n };\n }\n return null;\n}\n","import {DateTimeExpr, dateTimeExpr} from './datetime';\nimport {Dict, keys} from './util';\nimport * as log from './log';\n\nexport namespace TimeUnit {\n export const YEAR: 'year' = 'year';\n export const MONTH: 'month' = 'month';\n export const DAY: 'day' = 'day';\n export const DATE: 'date' = 'date';\n export const HOURS: 'hours' = 'hours';\n export const MINUTES: 'minutes' = 'minutes';\n export const SECONDS: 'seconds' = 'seconds';\n export const MILLISECONDS: 'milliseconds' = 'milliseconds';\n export const YEARMONTH: 'yearmonth' = 'yearmonth';\n export const YEARMONTHDATE: 'yearmonthdate' = 'yearmonthdate';\n export const YEARMONTHDATEHOURS: 'yearmonthdatehours' = 'yearmonthdatehours';\n export const YEARMONTHDATEHOURSMINUTES: 'yearmonthdatehoursminutes' = 'yearmonthdatehoursminutes';\n export const YEARMONTHDATEHOURSMINUTESSECONDS: 'yearmonthdatehoursminutesseconds' = 'yearmonthdatehoursminutesseconds';\n\n // MONTHDATE always include 29 February since we use year 0th (which is a leap year);\n export const MONTHDATE: 'monthdate' = 'monthdate';\n export const HOURSMINUTES: 'hoursminutes' = 'hoursminutes';\n export const HOURSMINUTESSECONDS: 'hoursminutesseconds' = 'hoursminutesseconds';\n export const MINUTESSECONDS: 'minutesseconds' = 'minutesseconds';\n export const SECONDSMILLISECONDS: 'secondsmilliseconds' = 'secondsmilliseconds';\n export const QUARTER: 'quarter' = 'quarter';\n export const YEARQUARTER: 'yearquarter' = 'yearquarter';\n export const QUARTERMONTH: 'quartermonth' = 'quartermonth';\n export const YEARQUARTERMONTH: 'yearquartermonth' = 'yearquartermonth';\n}\n\nexport type TimeUnit = typeof TimeUnit.YEAR | typeof TimeUnit.MONTH | typeof TimeUnit.DAY | typeof TimeUnit.DATE | typeof TimeUnit.HOURS\n | typeof TimeUnit.MINUTES | typeof TimeUnit.SECONDS | typeof TimeUnit.MILLISECONDS | typeof TimeUnit.YEARMONTH\n | typeof TimeUnit.YEARMONTHDATE | typeof TimeUnit.YEARMONTHDATEHOURS | typeof TimeUnit.YEARMONTHDATEHOURSMINUTES\n | typeof TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS | typeof TimeUnit.MONTHDATE | typeof TimeUnit.HOURSMINUTES\n | typeof TimeUnit.HOURSMINUTESSECONDS | typeof TimeUnit.MINUTESSECONDS | typeof TimeUnit.SECONDSMILLISECONDS\n | typeof TimeUnit.QUARTER | typeof TimeUnit.YEARQUARTER | typeof TimeUnit.QUARTERMONTH | typeof TimeUnit.YEARQUARTERMONTH;\n\n/** Time Unit that only corresponds to only one part of Date objects. */\nexport const SINGLE_TIMEUNITS = [\n TimeUnit.YEAR,\n TimeUnit.QUARTER,\n TimeUnit.MONTH,\n TimeUnit.DAY,\n TimeUnit.DATE,\n TimeUnit.HOURS,\n TimeUnit.MINUTES,\n TimeUnit.SECONDS,\n TimeUnit.MILLISECONDS,\n];\n\nconst SINGLE_TIMEUNIT_INDEX: Dict = SINGLE_TIMEUNITS.reduce((d, timeUnit) => {\n d[timeUnit] = true;\n return d;\n}, {});\n\nexport function isSingleTimeUnit(timeUnit: TimeUnit) {\n return !!SINGLE_TIMEUNIT_INDEX[timeUnit];\n}\n\n/**\n * Converts a date to only have the measurements relevant to the specified unit\n * i.e. ('yearmonth', '2000-12-04 07:58:14') -> '2000-12-01 00:00:00'\n * Note: the base date is Jan 01 1900 00:00:00\n */\nexport function convert(unit: TimeUnit, date: Date): Date {\n const result: Date = new Date(0, 0, 1, 0, 0, 0, 0); // start with uniform date\n SINGLE_TIMEUNITS.forEach(function(singleUnit) {\n if (containsTimeUnit(unit, singleUnit)) {\n switch (singleUnit) {\n case TimeUnit.DAY:\n throw new Error('Cannot convert to TimeUnits containing \\'day\\'');\n case TimeUnit.YEAR:\n result.setFullYear(date.getFullYear());\n break;\n case TimeUnit.QUARTER:\n // indicate quarter by setting month to be the first of the quarter i.e. may (4) -> april (3)\n result.setMonth((Math.floor(date.getMonth() / 3)) * 3);\n break;\n case TimeUnit.MONTH:\n result.setMonth(date.getMonth());\n break;\n case TimeUnit.DATE:\n result.setDate(date.getDate());\n break;\n case TimeUnit.HOURS:\n result.setHours(date.getHours());\n break;\n case TimeUnit.MINUTES:\n result.setMinutes(date.getMinutes());\n break;\n case TimeUnit.SECONDS:\n result.setSeconds(date.getSeconds());\n break;\n case TimeUnit.MILLISECONDS:\n result.setMilliseconds(date.getMilliseconds());\n break;\n }\n }\n });\n\n return result;\n}\n\nexport const MULTI_TIMEUNITS = [\n TimeUnit.YEARQUARTER,\n TimeUnit.YEARQUARTERMONTH,\n TimeUnit.YEARMONTH,\n TimeUnit.YEARMONTHDATE,\n TimeUnit.YEARMONTHDATEHOURS,\n TimeUnit.YEARMONTHDATEHOURSMINUTES,\n TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS,\n TimeUnit.QUARTERMONTH,\n TimeUnit.HOURSMINUTES,\n TimeUnit.HOURSMINUTESSECONDS,\n TimeUnit.MINUTESSECONDS,\n TimeUnit.SECONDSMILLISECONDS,\n];\n\nconst MULTI_TIMEUNIT_INDEX: Dict = MULTI_TIMEUNITS.reduce((d, timeUnit) => {\n d[timeUnit] = true;\n return d;\n}, {});\n\nexport function isMultiTimeUnit(timeUnit: TimeUnit) {\n return !!MULTI_TIMEUNIT_INDEX[timeUnit];\n}\n\nexport const TIMEUNITS = [\n TimeUnit.YEAR,\n TimeUnit.QUARTER,\n TimeUnit.MONTH,\n TimeUnit.DAY,\n TimeUnit.DATE,\n TimeUnit.HOURS,\n TimeUnit.MINUTES,\n TimeUnit.SECONDS,\n TimeUnit.MILLISECONDS,\n TimeUnit.YEARQUARTER,\n TimeUnit.YEARQUARTERMONTH,\n TimeUnit.YEARMONTH,\n TimeUnit.YEARMONTHDATE,\n TimeUnit.YEARMONTHDATEHOURS,\n TimeUnit.YEARMONTHDATEHOURSMINUTES,\n TimeUnit.YEARMONTHDATEHOURSMINUTESSECONDS,\n TimeUnit.QUARTERMONTH,\n TimeUnit.HOURSMINUTES,\n TimeUnit.HOURSMINUTESSECONDS,\n TimeUnit.MINUTESSECONDS,\n TimeUnit.SECONDSMILLISECONDS\n];\n\n/** Returns true if fullTimeUnit contains the timeUnit, false otherwise. */\nexport function containsTimeUnit(fullTimeUnit: TimeUnit, timeUnit: TimeUnit) {\n let fullTimeUnitStr = fullTimeUnit.toString();\n let timeUnitStr = timeUnit.toString();\n const index = fullTimeUnitStr.indexOf(timeUnitStr);\n return index > -1 &&\n (\n timeUnit !== TimeUnit.SECONDS ||\n index === 0 ||\n fullTimeUnitStr.charAt(index-1) !== 'i' // exclude milliseconds\n );\n}\n\n/**\n * Returns Vega expresssion for a given timeUnit and fieldRef\n */\nexport function fieldExpr(fullTimeUnit: TimeUnit, field: string): string {\n const fieldRef = `datum[\"${field}\"]`;\n\n function func(timeUnit: TimeUnit) {\n if (timeUnit === TimeUnit.QUARTER) {\n // quarter starting at 0 (0,3,6,9).\n return `(quarter(${fieldRef})-1)`;\n } else {\n return `${timeUnit}(${fieldRef})`;\n }\n }\n\n let d = SINGLE_TIMEUNITS.reduce((_d: DateTimeExpr, tu: TimeUnit) => {\n if (containsTimeUnit(fullTimeUnit, tu)) {\n _d[tu] = func(tu);\n }\n return _d;\n }, {});\n\n if (d.day && keys(d).length > 1) {\n log.warn(log.message.dayReplacedWithDate(fullTimeUnit));\n delete d.day;\n d.date = func(TimeUnit.DATE);\n }\n\n return dateTimeExpr(d);\n}\n\n/** returns the smallest nice unit for scale.nice */\nexport function smallestUnit(timeUnit: TimeUnit): string {\n if (!timeUnit) {\n return undefined;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n return 'second';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n return 'minute';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n return 'hour';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY) ||\n containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n return 'day';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n return 'month';\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.YEAR)) {\n return 'year';\n }\n return undefined;\n}\n\n/** returns the signal expression used for axis labels for a time unit */\nexport function formatExpression(timeUnit: TimeUnit, field: string, shortTimeLabels: boolean): string {\n if (!timeUnit) {\n return undefined;\n }\n\n let dateComponents: string[] = [];\n let expression = '';\n const hasYear = containsTimeUnit(timeUnit, TimeUnit.YEAR);\n\n if (containsTimeUnit(timeUnit, TimeUnit.QUARTER)) {\n // special expression for quarter as prefix\n expression = `'Q' + quarter(${field})`;\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.MONTH)) {\n // By default use short month name\n dateComponents.push(shortTimeLabels !== false ? '%b' : '%B');\n }\n\n if (containsTimeUnit(timeUnit, TimeUnit.DAY)) {\n dateComponents.push(shortTimeLabels ? '%a' : '%A');\n } else if (containsTimeUnit(timeUnit, TimeUnit.DATE)) {\n dateComponents.push('%d' + (hasYear ? ',' : '')); // add comma if there is year\n }\n\n if (hasYear) {\n dateComponents.push(shortTimeLabels ? '%y' : '%Y');\n }\n\n let timeComponents: string[] = [];\n\n if (containsTimeUnit(timeUnit, TimeUnit.HOURS)) {\n timeComponents.push('%H');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MINUTES)) {\n timeComponents.push('%M');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.SECONDS)) {\n timeComponents.push('%S');\n }\n if (containsTimeUnit(timeUnit, TimeUnit.MILLISECONDS)) {\n timeComponents.push('%L');\n }\n\n let dateTimeComponents: string[] = [];\n if (dateComponents.length > 0) {\n dateTimeComponents.push(dateComponents.join(' '));\n }\n if (timeComponents.length > 0) {\n dateTimeComponents.push(timeComponents.join(':'));\n }\n\n if (dateTimeComponents.length > 0) {\n if (expression) {\n // Add space between quarter and main time format\n expression += ` + ' ' + `;\n }\n expression += `timeFormat(${field}, '${dateTimeComponents.join(' ')}')`;\n }\n\n // If expression is still an empty string, return undefined instead.\n return expression || undefined;\n}\n\nexport function isDiscreteByDefault(timeUnit: TimeUnit) {\n switch (timeUnit) {\n // These time unit use discrete scale by default\n case 'hours':\n case 'day':\n case 'month':\n case 'quarter':\n return true;\n }\n return false;\n}\n","/** Constants and utilities for data type */\n/** Data type based on level of measurement */\n\nexport namespace Type {\n export const QUANTITATIVE: 'quantitative' = 'quantitative';\n export const ORDINAL: 'ordinal' = 'ordinal';\n export const TEMPORAL: 'temporal' = 'temporal';\n export const NOMINAL: 'nominal' = 'nominal';\n}\nexport type Type = typeof Type.QUANTITATIVE | typeof Type.ORDINAL | typeof Type.TEMPORAL | typeof Type.NOMINAL;\n\nexport const QUANTITATIVE = Type.QUANTITATIVE;\nexport const ORDINAL = Type.ORDINAL;\nexport const TEMPORAL = Type.TEMPORAL;\nexport const NOMINAL = Type.NOMINAL;\n\n/**\n * Get full, lowercase type name for a given type.\n * @param type\n * @return Full type name.\n */\nexport function getFullName(type: Type|string): Type {\n if (type) {\n type = type.toLowerCase();\n switch (type) {\n case 'q':\n case QUANTITATIVE:\n return 'quantitative';\n case 't':\n case TEMPORAL:\n return 'temporal';\n case 'o':\n case ORDINAL:\n return 'ordinal';\n case 'n':\n case NOMINAL:\n return 'nominal';\n }\n }\n // If we get invalid input, return undefined type.\n return undefined;\n}\n","import * as stringify from 'json-stable-stringify';\nexport {extend, isArray, isObject, isNumber, isString, truncate, toSet, stringValue} from 'vega-util';\nimport {isNumber, isString, isArray} from 'vega-util';\n\n/**\n * Creates an object composed of the picked object properties.\n *\n * Example: (from lodash)\n *\n * var object = {'a': 1, 'b': '2', 'c': 3};\n * pick(object, ['a', 'c']);\n * // → {'a': 1, 'c': 3}\n *\n */\nexport function pick(obj: any, props: string[]) {\n const copy = {};\n props.forEach((prop) => {\n if (obj.hasOwnProperty(prop)) {\n copy[prop] = obj[prop];\n }\n });\n return copy;\n}\n\n/**\n * The opposite of _.pick; this method creates an object composed of the own\n * and inherited enumerable string keyed properties of object that are not omitted.\n */\nexport function omit(obj: any, props: string[]) {\n const copy = duplicate(obj);\n props.forEach((prop) => {\n delete copy[prop];\n });\n return copy;\n}\n\nexport function hash(a: any) {\n if (isString(a) || isNumber(a) || isBoolean(a)) {\n return String(a);\n }\n return stringify(a);\n}\n\nexport function contains(array: Array, item: T) {\n return array.indexOf(item) > -1;\n}\n\n/** Returns the array without the elements in item */\nexport function without(array: Array, excludedItems: Array) {\n return array.filter(item => !contains(excludedItems, item));\n}\n\nexport function union(array: Array, other: Array) {\n return array.concat(without(other, array));\n}\n\nexport function reduce(obj: any, f: (a: any, i: any, d: any, k: any, o: any) => any, init: any, thisArg?: any) {\n if (obj.reduce) {\n return obj.reduce.call(thisArg, f, init);\n } else {\n for (const k in obj) {\n if (obj.hasOwnProperty(k)) {\n init = f.call(thisArg, init, obj[k], k, obj);\n }\n }\n return init;\n }\n}\n\n/**\n * Returns true if any item returns true.\n */\nexport function some(arr: Array, f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(arr: Array, f: (d: T, k?: any, i?: any) => boolean) {\n let i = 0;\n for (let k = 0; k(values: T[], f: (item: T) => string): T[] {\n const results: any[] = [];\n const u = {};\n let v: string;\n for (const val of values) {\n v = f(val);\n if (v in u) {\n continue;\n }\n u[v] = 1;\n results.push(val);\n }\n return results;\n};\n\nexport interface Dict {\n [key: string]: T;\n}\n\nexport type StringSet = Dict;\n\n/**\n * Returns true if the two dictionaries disagree. Applies only to defined values.\n */\nexport function differ(dict: Dict, other: Dict) {\n for (const key in dict) {\n if (dict.hasOwnProperty(key)) {\n if (other[key] && dict[key] && other[key] !== dict[key]) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport const keys = Object.keys;\n\nexport function vals(x: any) {\n const _vals: any[] = [];\n for (const k in x) {\n if (x.hasOwnProperty(k)) {\n _vals.push(x[k]);\n }\n }\n return _vals;\n};\n\nexport function duplicate(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n};\n\nexport function isBoolean(b: any): b is boolean {\n return b === true || b === false;\n}\n","import {FacetedUnitSpec} from './spec';\nimport {isMarkDef} from './mark';\n\n// TODO: move to vl.spec.validator?\n\nimport {toSet} from './util';\nimport {BAR} from './mark';\n\nexport interface RequiredChannelMap {\n [mark: string]: Array;\n}\n\n/**\n * Required Encoding Channels for each mark type\n * @type {Object}\n */\nexport const DEFAULT_REQUIRED_CHANNEL_MAP: RequiredChannelMap = {\n text: ['text'],\n line: ['x', 'y'],\n area: ['x', 'y']\n};\n\nexport interface SupportedChannelMap {\n [mark: string]: {\n [channel: string]: number\n };\n}\n\n/**\n * Supported Encoding Channel for each mark type\n */\nexport const DEFAULT_SUPPORTED_CHANNEL_TYPE: SupportedChannelMap = {\n bar: toSet(['row', 'column', 'x', 'y', 'size', 'color', 'detail']),\n line: toSet(['row', 'column', 'x', 'y', 'color', 'detail']), // TODO: add size when Vega supports\n area: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n tick: toSet(['row', 'column', 'x', 'y', 'color', 'detail']),\n circle: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n square: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail']),\n point: toSet(['row', 'column', 'x', 'y', 'color', 'size', 'detail', 'shape']),\n text: toSet(['row', 'column', 'size', 'color', 'text']) // TODO(#724) revise\n};\n\n// TODO: consider if we should add validate method and\n// requires ZSchema in the main vega-lite repo\n\n/**\n * Further check if encoding mapping of a spec is invalid and\n * return error if it is invalid.\n *\n * This checks if\n * (1) all the required encoding channels for the mark type are specified\n * (2) all the specified encoding channels are supported by the mark type\n * @param {[type]} spec [description]\n * @param {RequiredChannelMap = DefaultRequiredChannelMap} requiredChannelMap\n * @param {SupportedChannelMap = DefaultSupportedChannelMap} supportedChannelMap\n * @return {String} Return one reason why the encoding is invalid,\n * or null if the encoding is valid.\n */\nexport function getEncodingMappingError(spec: FacetedUnitSpec,\n requiredChannelMap: RequiredChannelMap = DEFAULT_REQUIRED_CHANNEL_MAP,\n supportedChannelMap: SupportedChannelMap = DEFAULT_SUPPORTED_CHANNEL_TYPE\n ) {\n let mark = isMarkDef(spec.mark) ? spec.mark.type : spec.mark;\n let encoding = spec.encoding;\n let requiredChannels = requiredChannelMap[mark];\n let supportedChannels = supportedChannelMap[mark];\n\n for (let i in requiredChannels) { // all required channels are in encoding`\n if (!(requiredChannels[i] in encoding)) {\n return 'Missing encoding channel \\\"' + requiredChannels[i] +\n '\\\" for mark \\\"' + mark + '\\\"';\n }\n }\n\n for (let channel in encoding) { // all channels in encoding are supported\n if (!supportedChannels[channel]) {\n return 'Encoding channel \\\"' + channel +\n '\\\" is not supported by mark type \\\"' + mark + '\\\"';\n }\n }\n\n if (mark === BAR && !encoding.x && !encoding.y) {\n return 'Missing both x and y for bar';\n }\n\n return null;\n}\n","import {StackOffset} from './stack';\nimport {ScaleType, NiceTime} from './scale';\nimport {isArray} from './util';\n\nexport interface VgData {\n name: string;\n source?: string;\n values?: any;\n format?: any;\n url?: any;\n transform?: any;\n}\n\n\nexport type VgParentRef = {\n parent: string\n};\n\nexport type VgFieldRef = string | VgParentRef | VgParentRef[];\n\nexport type VgSortField = boolean | {\n field: VgFieldRef,\n op: string\n};\n\nexport type VgDataRef = {\n data: string,\n field: VgFieldRef,\n sort?: VgSortField\n};\n\nexport type VgSignalRef = {\n signal: string\n};\n\n// TODO: add type of value (Make it VgValueRef {value?:T ...})\nexport type VgValueRef = {\n value?: number | string | boolean,\n field?: string | {\n datum?: string,\n group?: string,\n parent?: string\n },\n signal?: string;\n scale?: string, // TODO: object\n mult?: number,\n offset?: number | VgValueRef,\n band?: boolean | number\n};\n\n// TODO: add vg prefix\nexport type DataRefUnionDomain = {\n fields: (any[] | VgDataRef)[],\n sort?: boolean | {\n op: 'count'\n }\n};\n\n// TODO: add vg prefix\nexport type FieldRefUnionDomain = {\n data: string,\n fields: VgFieldRef[],\n sort?: boolean | {\n op: 'count'\n }\n};\n\nexport type VgRangeScheme = {scheme: string, extent?: number[], count?: number};\nexport type VgRange = string | VgDataRef | (number|string|VgDataRef)[] | VgRangeScheme | {step: number};\n\nexport type VgDomain = any[] | VgDataRef | DataRefUnionDomain | FieldRefUnionDomain | VgSignalRef;\n\nexport type VgScale = {\n name: string,\n type: ScaleType,\n domain: VgDomain,\n domainRaw?: VgSignalRef,\n range: VgRange,\n\n clamp?: boolean,\n exponent?: number,\n nice?: boolean | NiceTime,\n padding?: number,\n paddingInner?: number,\n paddingOuter?: number,\n reverse?: boolean,\n round?: boolean,\n zero?: boolean\n};\n\nexport function isDataRefUnionedDomain(domain: VgDomain): domain is DataRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && !('data' in domain);\n }\n return false;\n}\n\nexport function isFieldRefUnionDomain(domain: VgDomain): domain is FieldRefUnionDomain {\n if (!isArray(domain)) {\n return 'fields' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isDataRefDomain(domain: VgDomain): domain is VgDataRef {\n if (!isArray(domain)) {\n return 'field' in domain && 'data' in domain;\n }\n return false;\n}\n\nexport function isSignalRefDomain(domain: VgDomain): domain is VgSignalRef {\n if (!isArray(domain)) {\n return 'signal' in domain;\n }\n return false;\n}\n\nexport type VgEncodeEntry = any;\n// TODO: make export interface VgEncodeEntry {\n// x?: VgValueRef\n// y?: VgValueRef\n// ...\n// color?: VgValueRef\n// ...\n// }\n\nexport type VgAxis = any;\nexport type VgLegend = any;\n\nexport interface VgBinTransform {\n type: 'bin';\n field: string;\n as: string;\n extent?: {signal: string};\n // TODO: add other properties\n}\n\nexport interface VgExtentTransform {\n type: 'extent';\n field: string;\n signal: string;\n}\n\nexport interface VgFormulaTransform {\n type: 'formula';\n as: string;\n expr: string;\n}\n\nexport interface VgAxisEncode {\n ticks?: VgGuideEncode;\n labels?: VgGuideEncode;\n title?: VgGuideEncode;\n grid?: VgGuideEncode;\n domain?: VgGuideEncode;\n}\n\nexport interface VgLegendEncode {\n title?: VgGuideEncode;\n labels?: VgGuideEncode;\n legend?: VgGuideEncode;\n symbols?: VgGuideEncode;\n gradient?: VgGuideEncode;\n}\n\nexport type VgGuideEncode = any; // TODO: replace this (See guideEncode in Vega Schema)\n\nexport type VgTransform = VgBinTransform | VgExtentTransform | VgFormulaTransform | any;\n\nexport interface VgStackTransform {\n type: 'stack';\n offset?: StackOffset;\n groupby: string[];\n field: string;\n sort: VgSort;\n as: string[];\n}\n\nexport type VgSort = {\n field: string;\n order: 'ascending' | 'descending';\n} | {\n field: string[];\n order: ('ascending' | 'descending')[];\n};\n\nexport interface VgImputeTransform {\n type: 'impute';\n groupby?: string[];\n field: string;\n orderby?: string[];\n method?: 'value' | 'median' | 'max' | 'min' | 'mean';\n value?: any;\n};\n\nexport type VgCheckboxBinding = {\n input: 'checkbox';\n element?: string;\n};\n\nexport type VgRadioBinding = {\n input: 'radio';\n options: string[];\n element?: string;\n};\n\nexport type VgSelectBinding = {\n input: 'select';\n options: string[];\n element?: string;\n};\n\nexport type VgRangeBinding = {\n input: 'range';\n min?: number;\n max?: number;\n step?: number;\n element?: string;\n};\n\nexport type VgGenericBinding = {\n input: string;\n element?: string;\n};\n\nexport type VgBinding = VgCheckboxBinding | VgRadioBinding |\n VgSelectBinding | VgRangeBinding | VgGenericBinding;\n\n\n/**\n * Base object for Vega's Axis and Axis Config.\n * All of these properties are both properties of Vega's Axis and Axis Config.\n */\nexport interface VgAxisBase {\n /**\n * A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis (default true).\n */\n domain?: boolean;\n\n /**\n * A flag indicate if gridlines should be created in addition to ticks. If `grid` is unspecified, the default value is `true` for ROW and COL. For X and Y, the default value is `true` for quantitative and time fields and `false` otherwise.\n */\n grid?: boolean;\n\n /**\n * A boolean flag indicating if labels should be included as part of the axis (default true).\n */\n labels?: boolean;\n\n /**\n * The rotation angle of the axis labels.\n * @minimum 0\n * @maximum 360\n */\n labelAngle?: number;\n\n /**\n * Whether the axis should include ticks.\n */\n ticks?: boolean;\n\n /**\n * The size, in pixels, of major, minor and end ticks.\n * @minimum 0\n */\n tickSize?: number;\n\n /**\n * Max length for axis title if the title is automatically generated from the field's description. By default, this is automatically based on cell size and characterWidth property.\n * @minimum 0\n * @TJS-type integer\n */\n titleMaxLength?: number;\n\n /**\n * The padding, in pixels, between title and axis.\n */\n titlePadding?: number;\n\n /**\n * The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n */\n minExtent?: number;\n\n /**\n * The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n */\n maxExtent?: number;\n}\n\nexport interface VgAxisConfig extends VgAxisBase {\n // ---------- Axis ----------\n /**\n * Stroke width of axis domain line\n */\n domainWidth?: number;\n\n /**\n * Color of axis domain line.\n */\n domainColor?: string;\n\n // ---------- Grid ----------\n /**\n * Color of gridlines.\n */\n gridColor?: string;\n\n /**\n * The offset (in pixels) into which to begin drawing with the grid dash array.\n * @minimum 0\n */\n gridDash?: number[];\n\n /**\n * The stroke opacity of grid (value between [0,1])\n * @minimum 0\n * @maximum 1\n */\n gridOpacity?: number;\n\n /**\n * The grid width, in pixels.\n * @minimum 0\n */\n gridWidth?: number;\n\n // ---------- Ticks ----------\n /**\n * The color of the axis's tick.\n */\n tickColor?: string;\n\n /**\n * The color of the tick label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the tick label.\n */\n labelFont?: string;\n\n /**\n * The font size of label, in pixels.\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The width, in pixels, of ticks.\n * @minimum 0\n */\n tickWidth?: number;\n\n // ---------- Title ----------\n /**\n * Color of the title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * Font of the title.\n */\n titleFont?: string;\n\n /**\n * Font size of the title.\n * @minimum 0\n */\n titleFontSize?: number;\n\n /**\n * Font weight of the title.\n */\n titleFontWeight?: string | number;\n}\n\nexport interface VgLegendBase {\n /**\n * Padding (in pixels) between legend entries in a symbol legend.\n */\n entryPadding?: number;\n\n /**\n * The orientation of the legend. One of \"left\" or \"right\". This determines how the legend is positioned within the scene. The default is \"right\".\n */\n orient?: string;\n\n /**\n * The offset, in pixels, by which to displace the legend from the edge of the enclosing group or data rectangle.\n */\n offset?: number;\n\n /**\n * The padding, in pixels, between the legend and axis.\n */\n padding?: number;\n}\n\nexport interface VgLegendConfig extends VgLegendBase {\n // ---------- Gradient ----------\n /**\n * The color of the gradient stroke, can be in hex color code or regular color name.\n */\n gradientStrokeColor?: string;\n\n /**\n * The width of the gradient stroke, in pixels.\n * @minimum 0\n */\n gradientStrokeWidth?: number;\n\n /**\n * The height of the gradient, in pixels.\n * @minimum 0\n */\n gradientHeight?: number;\n\n /**\n * The width of the gradient, in pixels.\n * @minimum 0\n */\n gradientWidth?: number;\n\n // ---------- Label ----------\n /**\n * The alignment of the legend label, can be left, middle or right.\n */\n labelAlign?: string;\n\n /**\n * The position of the baseline of legend label, can be top, middle or bottom.\n */\n labelBaseline?: string;\n\n /**\n * The color of the legend label, can be in hex color code or regular color name.\n */\n labelColor?: string;\n\n /**\n * The font of the legend label.\n */\n labelFont?: string;\n\n /**\n * The font size of legend label.\n * @minimum 0\n */\n labelFontSize?: number;\n\n /**\n * The offset of the legend label.\n * @minimum 0\n */\n labelOffset?: number;\n\n // ---------- Symbols ----------\n /**\n * The color of the legend symbol,\n */\n symbolColor?: string;\n\n /**\n * Default shape type (such as \"circle\") for legend symbols.\n */\n symbolType?: string;\n\n /**\n * The size of the legend symbol, in pixels.\n * @minimum 0\n */\n symbolSize?: number;\n\n /**\n * The width of the symbol's stroke.\n * @minimum 0\n */\n symbolStrokeWidth?: number;\n\n // ---------- Title ----------\n /**\n * Optional mark property definitions for custom legend styling.\n */\n /**\n * The color of the legend title, can be in hex color code or regular color name.\n */\n titleColor?: string;\n\n /**\n * The font of the legend title.\n */\n titleFont?: string;\n\n /**\n * The font size of the legend title.\n */\n titleFontSize?: number;\n\n /**\n * The font weight of the legend title.\n */\n titleFontWeight?: string | number;\n\n /**\n * The padding, in pixels, between title and legend.\n */\n titlePadding?: number;\n}\n\nexport type FontStyle = 'normal' | 'italic';\nexport type FontWeight = 'normal' | 'bold';\n/**\n * @TJS-type integer\n * @minimum 100\n * @maximum 900\n */\nexport type FontWeightNumber = number;\nexport type HorizontalAlign = 'left' | 'right' | 'center';\nexport type Interpolate = 'linear' | 'linear-closed' |\n 'step' | 'step-before' | 'step-after' |\n 'basis' | 'basis-open' | 'basis-closed' |\n 'cardinal' | 'cardinal-open' | 'cardinal-closed' |\n 'bundle' | 'monotone';\nexport type Orient = 'horizontal' | 'vertical';\nexport type VerticalAlign = 'top' | 'middle' | 'bottom';\n\nexport interface VgMarkConfig {\n\n /**\n * Default Fill Color. This has higher precedence than config.color\n */\n fill?: string;\n\n /**\n * Default Stroke Color. This has higher precedence than config.color\n */\n stroke?: string;\n\n // ---------- Opacity ----------\n /**\n * @minimum 0\n * @maximum 1\n */\n opacity?: number;\n\n\n /**\n * @minimum 0\n * @maximum 1\n */\n fillOpacity?: number;\n\n /**\n * @minimum 0\n * @maximum 1\n */\n strokeOpacity?: number;\n\n // ---------- Stroke Style ----------\n /**\n * @minimum 0\n */\n strokeWidth?: number;\n\n /**\n * An array of alternating stroke, space lengths for creating dashed or dotted lines.\n */\n strokeDash?: number[];\n\n /**\n * The offset (in pixels) into which to begin drawing with the stroke dash array.\n */\n strokeDashOffset?: number;\n\n // ---------- Orientation: Bar, Tick, Line, Area ----------\n /**\n * The orientation of a non-stacked bar, tick, area, and line charts.\n * The value is either horizontal (default) or vertical.\n * - For bar, rule and tick, this determines whether the size of the bar and tick\n * should be applied to x or y dimension.\n * - For area, this property determines the orient property of the Vega output.\n * - For line, this property determines the sort order of the points in the line\n * if `config.sortLineBy` is not specified.\n * For stacked charts, this is always determined by the orientation of the stack;\n * therefore explicitly specified value will be ignored.\n */\n orient?: Orient;\n\n // ---------- Interpolation: Line / area ----------\n /**\n * The line interpolation method to use for line and area marks. One of the following:\n * - `\"linear\"`: piecewise linear segments, as in a polyline.\n * - `\"linear-closed\"`: close the linear segments to form a polygon.\n * - `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n * - `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n * - `\"basis\"`: a B-spline, with control point duplication on the ends.\n * - `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n * - `\"basis-closed\"`: a closed B-spline, as in a loop.\n * - `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n * - `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n * - `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n * - `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n * - `\"monotone\"`: cubic interpolation that preserves monotonicity in y.\n */\n interpolate?: Interpolate;\n /**\n * Depending on the interpolation type, sets the tension parameter (for line and area marks).\n * @minimum 0\n * @maximum 1\n */\n tension?: number;\n\n /**\n * The default symbol shape to use. One of: `\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, or `\"triangle-down\"`, or a custom SVG path.\n */\n shape?: string;\n\n /**\n * The pixel area each the point/circle/square.\n * For example: in the case of circles, the radius is determined in part by the square root of the size value.\n * @minimum 0\n */\n size?: number;\n\n // Text / Label Mark Config\n\n /**\n * The horizontal alignment of the text. One of left, right, center.\n */\n align?: HorizontalAlign;\n\n /**\n * The rotation angle of the text, in degrees.\n * @minimum 0\n * @maximum 360\n */\n angle?: number;\n\n /**\n * The vertical alignment of the text. One of top, middle, bottom.\n */\n baseline?: VerticalAlign;\n\n /**\n * The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property.\n */\n dx?: number;\n\n /**\n * The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the angle property.\n */\n dy?: number;\n\n /**\n * Polar coordinate radial offset, in pixels, of the text label from the origin determined by the x and y properties.\n * @minimum 0\n */\n radius?: number;\n\n /**\n * Polar coordinate angle, in radians, of the text label from the origin determined by the x and y properties. Values for theta follow the same convention of arc mark startAngle and endAngle properties: angles are measured in radians, with 0 indicating \"north\".\n */\n theta?: number;\n\n /**\n * The typeface to set the text in (e.g., Helvetica Neue).\n * @minimum 0\n */\n font?: string;\n\n /**\n * The font size, in pixels.\n * @minimum 0\n */\n fontSize?: number;\n\n /**\n * The font style (e.g., italic).\n */\n fontStyle?: FontStyle;\n /**\n * The font weight (e.g., `\"normal\"`, `\"bold\"`, `900`).\n */\n fontWeight?: FontWeight | FontWeightNumber;\n\n /**\n * Placeholder Text\n */\n text?: string;\n}\n","export import axis = require('./axis');\nexport import aggregate = require('./aggregate');\nexport import bin = require('./bin');\nexport import channel = require('./channel');\nexport import compositeMark = require('./compositemark');\nexport {compile} from './compile/compile';\nexport import config = require('./config');\nexport import data = require('./data');\nexport import datetime = require('./datetime');\nexport import encoding = require('./encoding');\nexport import facet = require('./facet');\nexport import fieldDef = require('./fielddef');\nexport import legend = require('./legend');\nexport import mark = require('./mark');\nexport import scale = require('./scale');\nexport import sort = require('./sort');\nexport import spec = require('./spec');\nexport import stack = require('./stack');\nexport import timeUnit = require('./timeunit');\nexport import transform = require('./transform');\nexport import type = require('./type');\nexport import util = require('./util');\nexport import validate = require('./validate');\n\nexport const version: string = require('../package.json').version;\n"]} \ No newline at end of file