hvega 0.3.0.1 → 0.4.0.0
raw patch · 513 files changed
+51684/−4627 lines, 513 filesdep +aeson-prettydep +bytestringdep +containersdep ~aesondep ~basedep ~textnew-component:exe:playtutorialbinary-addedPVP ok
version bump matches the API change (PVP)
Dependencies added: aeson-pretty, bytestring, containers, directory, filepath, hvega, tasty, tasty-golden, unordered-containers
Dependency ranges changed: aeson, base, text
API changes (from Hackage documentation)
This diff is very large; some files are shown as “too large to diff”. Download the raw patch for the complete diff.
Files
- CHANGELOG.md +358/−0
- default.nix +2/−10
- hvega.cabal +178/−7
- hvega.nix +19/−0
- images/example.png binary
- images/vl/baseplot.png binary
- images/vl/bindscales.png binary
- images/vl/combinedplot-selected.png binary
- images/vl/combinedplot.png binary
- images/vl/comparingerrors.png binary
- images/vl/concatenatedplot.png binary
- images/vl/concatenatedplot2.png binary
- images/vl/contextandfocus.png binary
- images/vl/coordinatedviews.png binary
- images/vl/coordinatedviews2.png binary
- images/vl/crossfilter.png binary
- images/vl/errorauto.png binary
- images/vl/errorband.png binary
- images/vl/errorbars.png binary
- images/vl/errorbox.png binary
- images/vl/errormanual-zoomed.png binary
- images/vl/errormanual.png binary
- images/vl/eventselection.png binary
- images/vl/gmaghistogram.png binary
- images/vl/gmaghistogramwithcolor.png binary
- images/vl/gmaglinewithcolor.png binary
- images/vl/intervalselection.png binary
- images/vl/intervalselectiony.png binary
- images/vl/layereddiversion.png binary
- images/vl/layeredplot.png binary
- images/vl/multiselection.png binary
- images/vl/nearestselection.png binary
- images/vl/parallaxhistogram.png binary
- images/vl/pointplot.png binary
- images/vl/posplot.png binary
- images/vl/repeatplot.png binary
- images/vl/singleselection.png binary
- images/vl/skyplot.png binary
- images/vl/smallmultiples.png binary
- images/vl/smallmultiples2.png binary
- images/vl/splomplot.png binary
- images/vl/stripplot.png binary
- images/vl/stripplotwithbackground.png binary
- images/vl/stripplotwithcolor.png binary
- images/vl/stripplotwithcolorordinal.png binary
- images/vl/stripploty.png binary
- images/vl/transformselection.png binary
- images/vl/widgetselection.png binary
- images/vl/yhistogram.png binary
- images/vl/yloghistogram.png binary
- images/zindex.png binary
- shell.nix +2/−0
- src/Graphics/Vega/Tutorials/VegaLite.hs +3528/−0
- src/Graphics/Vega/VegaLite.hs +10328/−4609
- stack.yaml +1/−1
- tests/AxisTests.hs +193/−0
- tests/ColorTests.hs +253/−0
- tests/CompositeTests.hs +203/−0
- tests/ConditionalTests.hs +269/−0
- tests/ConfigTests.hs +229/−0
- tests/DataTests.hs +626/−0
- tests/FillStrokeTests.hs +107/−0
- tests/Gallery/Advanced.hs +448/−0
- tests/Gallery/Area.hs +263/−0
- tests/Gallery/Bar.hs +447/−0
- tests/Gallery/Dist.hs +243/−0
- tests/Gallery/Error.hs +198/−0
- tests/Gallery/Facet.hs +206/−0
- tests/Gallery/Geo.hs +385/−0
- tests/Gallery/Interaction.hs +483/−0
- tests/Gallery/Label.hs +330/−0
- tests/Gallery/Layer.hs +433/−0
- tests/Gallery/Line.hs +370/−0
- tests/Gallery/Multi.hs +467/−0
- tests/Gallery/Repeat.hs +232/−0
- tests/Gallery/Scatter.hs +279/−0
- tests/Gallery/Table.hs +170/−0
- tests/GeoTests.hs +653/−0
- tests/HyperlinkTests.hs +86/−0
- tests/InteractionTests.hs +172/−0
- tests/LegendTests.hs +118/−0
- tests/NullTests.hs +192/−0
- tests/PositionTests.hs +125/−0
- tests/ProjectionTests.hs +161/−0
- tests/ScaleTests.hs +228/−0
- tests/ShapeTests.hs +318/−0
- tests/SortTests.hs +103/−0
- tests/Test.hs +159/−0
- tests/TextFormatTests.hs +83/−0
- tests/TimeTests.hs +168/−0
- tests/TooltipTests.hs +48/−0
- tests/TrailTests.hs +52/−0
- tests/ViewCompositionTests.hs +250/−0
- tests/WindowTransformTests.hs +281/−0
- tests/specs/axis/axis1.vl +521/−0
- tests/specs/axis/axis2.vl +521/−0
- tests/specs/axis/axis3.vl +521/−0
- tests/specs/axis/axis4.vl +529/−0
- tests/specs/axis/axis5.vl +530/−0
- tests/specs/axis/axis6.vl +88/−0
- tests/specs/axis/zorder.vl +54/−0
- tests/specs/color/customContinuous.vl +40/−0
- tests/specs/color/customDiscrete.vl +41/−0
- tests/specs/color/defContinuous.vl +34/−0
- tests/specs/color/defNominal.vl +34/−0
- tests/specs/color/defOrdinal.vl +34/−0
- tests/specs/color/gamma1.vl +45/−0
- tests/specs/color/gamma2.vl +45/−0
- tests/specs/color/gamma3.vl +45/−0
- tests/specs/color/gamma4.vl +45/−0
- tests/specs/color/gamma5.vl +45/−0
- tests/specs/color/interp1.vl +44/−0
- tests/specs/color/interp2.vl +44/−0
- tests/specs/color/interp3.vl +44/−0
- tests/specs/color/interp4.vl +44/−0
- tests/specs/color/interp5.vl +44/−0
- tests/specs/color/interp6.vl +45/−0
- tests/specs/color/interp7.vl +45/−0
- tests/specs/color/namedContinuous1.vl +37/−0
- tests/specs/color/namedContinuous2.vl +43/−0
- tests/specs/color/namedContinuous3.vl +38/−0
- tests/specs/color/namedContinuous4.vl +44/−0
- tests/specs/color/scale1.vl +41/−0
- tests/specs/color/scale3.vl +41/−0
- tests/specs/color/scale4.vl +42/−0
- tests/specs/color/scale5.vl +41/−0
- tests/specs/color/scale6.vl +41/−0
- tests/specs/color/scale7.vl +41/−0
- tests/specs/color/scale8.vl +42/−0
- tests/specs/composite/boxplot1.vl +23/−0
- tests/specs/composite/boxplot2.vl +23/−0
- tests/specs/composite/boxplot3.vl +42/−0
- tests/specs/composite/errorband1.vl +27/−0
- tests/specs/composite/errorband2.vl +27/−0
- tests/specs/composite/errorbar1.vl +26/−0
- tests/specs/composite/errorbar2.vl +26/−0
- tests/specs/composite/errorbar3.vl +49/−0
- tests/specs/conditional/bindScales1.vl +25/−0
- tests/specs/conditional/bindScales2.vl +26/−0
- tests/specs/conditional/markCondition1.vl +32/−0
- tests/specs/conditional/markCondition2.vl +53/−0
- tests/specs/conditional/selectionCondition1.vl +42/−0
- tests/specs/conditional/selectionCondition2.vl +51/−0
- tests/specs/conditional/selectionCondition3.vl +63/−0
- tests/specs/conditional/selectionCondition4.vl +37/−0
- tests/specs/conditional/selectionCondition5.vl +38/−0
- tests/specs/config/axisCfg1.vl +40/−0
- tests/specs/config/dark.vl +111/−0
- tests/specs/config/default.vl +85/−0
- tests/specs/config/mark1.vl +89/−0
- tests/specs/config/mark2.vl +102/−0
- tests/specs/config/padding.vl +42/−0
- tests/specs/config/vbTest.vl +120/−0
- tests/specs/data/annotate1.vl +49/−0
- tests/specs/data/bin1.vl +65/−0
- tests/specs/data/bin2.vl +110/−0
- tests/specs/data/bin3.vl +235/−0
- tests/specs/data/data1.vl +30/−0
- tests/specs/data/data10.vl +61/−0
- tests/specs/data/data2.vl +30/−0
- tests/specs/data/data3.vl +30/−0
- tests/specs/data/data4.vl +17/−0
- tests/specs/data/data5.vl +17/−0
- tests/specs/data/data6.vl +21/−0
- tests/specs/data/data7.vl +17/−0
- tests/specs/data/data8.vl +61/−0
- tests/specs/data/data9.vl +61/−0
- tests/specs/data/filter1.vl +59/−0
- tests/specs/data/filter2.vl +78/−0
- tests/specs/data/flatten1.vl +57/−0
- tests/specs/data/fold1.vl +48/−0
- tests/specs/data/geodata1.vl +24/−0
- tests/specs/data/geodata2.vl +100/−0
- tests/specs/data/impute1.vl +70/−0
- tests/specs/data/impute2.vl +74/−0
- tests/specs/data/impute3.vl +75/−0
- tests/specs/data/impute4.vl +63/−0
- tests/specs/data/impute5.vl +63/−0
- tests/specs/data/impute6.vl +67/−0
- tests/specs/data/impute7.vl +66/−0
- tests/specs/data/impute8.vl +68/−0
- tests/specs/data/namedData1.vl +55/−0
- tests/specs/data/namedData2.vl +18/−0
- tests/specs/data/namedData3.vl +18/−0
- tests/specs/data/null1.vl +49/−0
- tests/specs/data/sample1.vl +39/−0
- tests/specs/data/sequence1.vl +27/−0
- tests/specs/data/sequence2.vl +28/−0
- tests/specs/fillstroke/combined1.vl +56/−0
- tests/specs/fillstroke/combined2.vl +61/−0
- tests/specs/fillstroke/combined3.vl +61/−0
- tests/specs/fillstroke/default.vl +54/−0
- tests/specs/fillstroke/fill1.vl +55/−0
- tests/specs/fillstroke/fill2.vl +58/−0
- tests/specs/fillstroke/fill3.vl +57/−0
- tests/specs/fillstroke/geo1.vl +63/−0
- tests/specs/fillstroke/geo2.vl +69/−0
- tests/specs/fillstroke/stroke1.vl +55/−0
- tests/specs/fillstroke/stroke2.vl +58/−0
- tests/specs/fillstroke/stroke3.vl +57/−0
- tests/specs/gallery/advanced/advanced1.vl +64/−0
- tests/specs/gallery/advanced/advanced2.vl +59/−0
- tests/specs/gallery/advanced/advanced3.vl +78/−0
- tests/specs/gallery/advanced/advanced4.vl +58/−0
- tests/specs/gallery/advanced/advanced5.vl +140/−0
- tests/specs/gallery/advanced/advanced6.vl +233/−0
- tests/specs/gallery/advanced/advanced7.vl +34/−0
- tests/specs/gallery/advanced/advanced8.vl +198/−0
- tests/specs/gallery/advanced/advanced9.vl +21/−0
- tests/specs/gallery/area/area1.vl +28/−0
- tests/specs/gallery/area/area2.vl +30/−0
- tests/specs/gallery/area/area3.vl +30/−0
- tests/specs/gallery/area/area4.vl +35/−0
- tests/specs/gallery/area/area5.vl +35/−0
- tests/specs/gallery/area/area6.vl +159/−0
- tests/specs/gallery/area/area7.vl +247/−0
- tests/specs/gallery/bar/bar1.vl +55/−0
- tests/specs/gallery/bar/bar10.vl +48/−0
- tests/specs/gallery/bar/bar11.vl +376/−0
- tests/specs/gallery/bar/bar12.vl +56/−0
- tests/specs/gallery/bar/bar13.vl +267/−0
- tests/specs/gallery/bar/bar14.vl +249/−0
- tests/specs/gallery/bar/bar2.vl +22/−0
- tests/specs/gallery/bar/bar3.vl +31/−0
- tests/specs/gallery/bar/bar4.vl +60/−0
- tests/specs/gallery/bar/bar5.vl +45/−0
- tests/specs/gallery/bar/bar6.vl +23/−0
- tests/specs/gallery/bar/bar7.vl +45/−0
- tests/specs/gallery/bar/bar8.vl +37/−0
- tests/specs/gallery/bar/bar9.vl +36/−0
- tests/specs/gallery/dist/dist1.vl +22/−0
- tests/specs/gallery/dist/dist2.vl +39/−0
- tests/specs/gallery/dist/dist3.vl +87/−0
- tests/specs/gallery/dist/dist4.vl +118/−0
- tests/specs/gallery/dist/dist5.vl +120/−0
- tests/specs/gallery/error/error1.vl +51/−0
- tests/specs/gallery/error/error2.vl +75/−0
- tests/specs/gallery/error/error3.vl +46/−0
- tests/specs/gallery/error/error4.vl +75/−0
- tests/specs/gallery/facet/facet1.vl +48/−0
- tests/specs/gallery/facet/facet2.vl +27/−0
- tests/specs/gallery/facet/facet3.vl +22/−0
- tests/specs/gallery/facet/facet4.vl +25/−0
- tests/specs/gallery/facet/facet5.vl +31/−0
- tests/specs/gallery/facet/facet6.vl +47/−0
- tests/specs/gallery/facet/facet7.vl +52/−0
- tests/specs/gallery/geo/geo1.vl +42/−0
- tests/specs/gallery/geo/geo2.vl +41/−0
- tests/specs/gallery/geo/geo3.vl +53/−0
- tests/specs/gallery/geo/geo4.vl +125/−0
- tests/specs/gallery/geo/geo5.vl +61/−0
- tests/specs/gallery/geo/geo6.vl +51/−0
- tests/specs/gallery/geo/geo7.vl +125/−0
- tests/specs/gallery/geo/geo8.vl +49/−0
- tests/specs/gallery/geo/geo9.vl +119/−0
- tests/specs/gallery/interaction/interaction1.vl +102/−0
- tests/specs/gallery/interaction/interaction10.vl +80/−0
- tests/specs/gallery/interaction/interaction11a.vl +32/−0
- tests/specs/gallery/interaction/interaction11b.vl +37/−0
- tests/specs/gallery/interaction/interaction11c.vl +37/−0
- tests/specs/gallery/interaction/interaction11d.vl +41/−0
- tests/specs/gallery/interaction/interaction2.vl +36/−0
- tests/specs/gallery/interaction/interaction3.vl +31/−0
- tests/specs/gallery/interaction/interaction4.vl +45/−0
- tests/specs/gallery/interaction/interaction5.vl +32/−0
- tests/specs/gallery/interaction/interaction6.vl +40/−0
- tests/specs/gallery/interaction/interaction7.vl +86/−0
- tests/specs/gallery/interaction/interaction8.vl +59/−0
- tests/specs/gallery/interaction/interaction9.vl +109/−0
- tests/specs/gallery/label/label1.vl +56/−0
- tests/specs/gallery/label/label2.vl +51/−0
- tests/specs/gallery/label/label3.vl +157/−0
- tests/specs/gallery/label/label4.vl +166/−0
- tests/specs/gallery/label/label5.vl +40/−0
- tests/specs/gallery/label/label6.vl +40/−0
- tests/specs/gallery/label/label7.vl +247/−0
- tests/specs/gallery/layer/layer1.vl +289/−0
- tests/specs/gallery/layer/layer2.vl +99/−0
- tests/specs/gallery/layer/layer3.vl +187/−0
- tests/specs/gallery/layer/layer4.vl +53/−0
- tests/specs/gallery/layer/layer5.vl +159/−0
- tests/specs/gallery/layer/layer6.vl +181/−0
- tests/specs/gallery/layer/layer7.vl +66/−0
- tests/specs/gallery/line/line1.vl +26/−0
- tests/specs/gallery/line/line10.vl +157/−0
- tests/specs/gallery/line/line11.vl +135/−0
- tests/specs/gallery/line/line12.vl +59/−0
- tests/specs/gallery/line/line2.vl +32/−0
- tests/specs/gallery/line/line3.vl +25/−0
- tests/specs/gallery/line/line4.vl +27/−0
- tests/specs/gallery/line/line5.vl +29/−0
- tests/specs/gallery/line/line6.vl +29/−0
- tests/specs/gallery/line/line7.vl +31/−0
- tests/specs/gallery/line/line8.vl +29/−0
- tests/specs/gallery/line/line9.vl +50/−0
- tests/specs/gallery/multi/multi1.vl +61/−0
- tests/specs/gallery/multi/multi2.vl +70/−0
- tests/specs/gallery/multi/multi3.vl +60/−0
- tests/specs/gallery/multi/multi4.vl +110/−0
- tests/specs/gallery/multi/multi5.vl +142/−0
- tests/specs/gallery/multi/multi6.vl +163/−0
- tests/specs/gallery/multi/multi7.vl +178/−0
- tests/specs/gallery/repeat/repeat1.vl +68/−0
- tests/specs/gallery/repeat/repeat2.vl +48/−0
- tests/specs/gallery/repeat/repeat3.vl +34/−0
- tests/specs/gallery/repeat/repeat4.vl +60/−0
- tests/specs/gallery/repeat/repeat5.vl +96/−0
- tests/specs/gallery/scatter/scatter1.vl +23/−0
- tests/specs/gallery/scatter/scatter10.vl +54/−0
- tests/specs/gallery/scatter/scatter11.vl +32/−0
- tests/specs/gallery/scatter/scatter2.vl +14/−0
- tests/specs/gallery/scatter/scatter3.vl +18/−0
- tests/specs/gallery/scatter/scatter4.vl +26/−0
- tests/specs/gallery/scatter/scatter5.vl +28/−0
- tests/specs/gallery/scatter/scatter6.vl +22/−0
- tests/specs/gallery/scatter/scatter7.vl +28/−0
- tests/specs/gallery/scatter/scatter8.vl +18/−0
- tests/specs/gallery/scatter/scatter9.vl +39/−0
- tests/specs/gallery/table/table1.vl +23/−0
- tests/specs/gallery/table/table2.vl +47/−0
- tests/specs/gallery/table/table3.vl +56/−0
- tests/specs/gallery/table/table4.vl +25/−0
- tests/specs/gallery/table/table5.vl +51/−0
- tests/specs/geo/choropleth1.vl +27/−0
- tests/specs/geo/choropleth2.vl +134/−0
- tests/specs/geo/defaultSize1.vl +20/−0
- tests/specs/geo/defaultSize2.vl +26/−0
- tests/specs/geo/dotMap1.vl +36/−0
- tests/specs/geo/graticule1.vl +34/−0
- tests/specs/geo/graticule2.vl +50/−0
- tests/specs/geo/graticule3.vl +59/−0
- tests/specs/geo/graticule4.vl +39/−0
- tests/specs/geo/linear1.vl +22/−0
- tests/specs/geo/linear2.vl +62/−0
- tests/specs/geo/linear3.vl +118/−0
- tests/specs/geo/map1d.vl +67/−0
- tests/specs/geo/mapComp1.vl +59/−0
- tests/specs/geo/mapComp2.vl +124/−0
- tests/specs/geo/mapComp3.vl +172/−0
- tests/specs/geo/mapComp4.vl +166/−0
- tests/specs/geo/scale1.vl +39/−0
- tests/specs/geo/scribbleMap1.vl +57/−0
- tests/specs/geo/scribbleMap2.vl +63/−0
- tests/specs/geo/sphere1.vl +19/−0
- tests/specs/geo/sphere2.vl +32/−0
- tests/specs/geo/translate1.vl +42/−0
- tests/specs/hyperlink/hyperlink1.vl +62/−0
- tests/specs/hyperlink/hyperlink2.vl +23/−0
- tests/specs/hyperlink/hyperlink3.vl +34/−0
- tests/specs/interaction/interaction1.vl +58/−0
- tests/specs/interaction/interaction2.vl +58/−0
- tests/specs/interaction/interaction3.vl +62/−0
- tests/specs/interaction/interaction4.vl +62/−0
- tests/specs/interaction/interaction5.vl +62/−0
- tests/specs/interaction/interaction6.vl +59/−0
- tests/specs/interaction/interaction7.vl +75/−0
- tests/specs/interaction/interaction8.vl +76/−0
- tests/specs/legend/legend1.vl +34/−0
- tests/specs/legend/legend10.vl +28/−0
- tests/specs/legend/legend11.vl +48/−0
- tests/specs/legend/legend2.vl +40/−0
- tests/specs/legend/legend3.vl +40/−0
- tests/specs/legend/legend4.vl +40/−0
- tests/specs/legend/legend5.vl +40/−0
- tests/specs/legend/legend6.vl +40/−0
- tests/specs/legend/legend7.vl +40/−0
- tests/specs/legend/legend8.vl +40/−0
- tests/specs/legend/legend9.vl +40/−0
- tests/specs/null/axis1.vl +54/−0
- tests/specs/null/filter1.vl +27/−0
- tests/specs/null/filter2.vl +41/−0
- tests/specs/null/scale0.vl +92/−0
- tests/specs/null/scale1.vl +93/−0
- tests/specs/null/scale2.vl +93/−0
- tests/specs/null/scale3.vl +93/−0
- tests/specs/null/scale4.vl +93/−0
- tests/specs/null/scale5.vl +93/−0
- tests/specs/position/position1.vl +16/−0
- tests/specs/position/position10.vl +44/−0
- tests/specs/position/position11.vl +44/−0
- tests/specs/position/position12.vl +44/−0
- tests/specs/position/position2.vl +15/−0
- tests/specs/position/position3.vl +16/−0
- tests/specs/position/position4.vl +16/−0
- tests/specs/position/position5.vl +17/−0
- tests/specs/position/position6.vl +43/−0
- tests/specs/position/position7.vl +43/−0
- tests/specs/position/position8.vl +44/−0
- tests/specs/position/position9.vl +44/−0
- tests/specs/projection/Albers.vl +23/−0
- tests/specs/projection/AzimuthalEqualArea.vl +23/−0
- tests/specs/projection/AzimuthalEquidistant.vl +23/−0
- tests/specs/projection/ConicConformal.vl +24/−0
- tests/specs/projection/ConicEqualArea.vl +23/−0
- tests/specs/projection/ConicEquidistant.vl +23/−0
- tests/specs/projection/Equirectangular.vl +23/−0
- tests/specs/projection/Gnomonic.vl +23/−0
- tests/specs/projection/Identity.vl +23/−0
- tests/specs/projection/Mercator.vl +23/−0
- tests/specs/projection/Orthographic.vl +23/−0
- tests/specs/projection/Stereographic.vl too large to diff
- tests/specs/projection/TransverseMercator.vl too large to diff
- tests/specs/projection/airy.vl too large to diff
- tests/specs/projection/aitoff.vl too large to diff
- tests/specs/projection/armadillo.vl too large to diff
- tests/specs/projection/august.vl too large to diff
- tests/specs/projection/baker.vl too large to diff
- tests/specs/projection/berghaus.vl too large to diff
- tests/specs/projection/bertin1953.vl too large to diff
- tests/specs/projection/boggs.vl too large to diff
- tests/specs/projection/bonne.vl too large to diff
- tests/specs/projection/bottomley.vl too large to diff
- tests/specs/projection/collignon.vl too large to diff
- tests/specs/projection/configExample.vl too large to diff
- tests/specs/projection/craig.vl too large to diff
- tests/specs/projection/craster.vl too large to diff
- tests/specs/projection/cylindricalequalarea.vl too large to diff
- tests/specs/projection/cylindricalstereographic.vl too large to diff
- tests/specs/projection/eckert1.vl too large to diff
- tests/specs/projection/eckert2.vl too large to diff
- tests/specs/projection/eckert3.vl too large to diff
- tests/specs/projection/eckert4.vl too large to diff
- tests/specs/projection/eckert5.vl too large to diff
- tests/specs/projection/eckert6.vl too large to diff
- tests/specs/projection/eisenlohr.vl too large to diff
- tests/specs/projection/fahey.vl too large to diff
- tests/specs/projection/foucaut.vl too large to diff
- tests/specs/projection/gingery.vl too large to diff
- tests/specs/projection/identityExample.vl too large to diff
- tests/specs/projection/reflectXExample.vl too large to diff
- tests/specs/projection/reflectXYExample.vl too large to diff
- tests/specs/projection/reflectYExample.vl too large to diff
- tests/specs/projection/winkel3.vl too large to diff
- tests/specs/scale/scale1.vl too large to diff
- tests/specs/scale/scale2.vl too large to diff
- tests/specs/scale/scale3.vl too large to diff
- tests/specs/scale/scale4.vl too large to diff
- tests/specs/scale/scale5.vl too large to diff
- tests/specs/scale/scale6.vl too large to diff
- tests/specs/scale/scale7.vl too large to diff
- tests/specs/scale/scale8.vl too large to diff
- tests/specs/scale/scale9.vl too large to diff
- tests/specs/shape/custom1.vl too large to diff
- tests/specs/shape/custom2.vl too large to diff
- tests/specs/shape/custom3.vl too large to diff
- tests/specs/shape/custom4.vl too large to diff
- tests/specs/shape/defNominal.vl too large to diff
- tests/specs/shape/defOrdinal.vl too large to diff
- tests/specs/shape/isotype1.vl too large to diff
- tests/specs/shape/multi1.vl too large to diff
- tests/specs/shape/multi2.vl too large to diff
- tests/specs/shape/multi3.vl too large to diff
- tests/specs/shape/multi4.vl too large to diff
- tests/specs/shape/multi5.vl too large to diff
- tests/specs/shape/multi6.vl too large to diff
- tests/specs/shape/point1.vl too large to diff
- tests/specs/shape/point2.vl too large to diff
- tests/specs/shape/point3.vl too large to diff
- tests/specs/shape/point4.vl too large to diff
- tests/specs/shape/point5.vl too large to diff
- tests/specs/shape/point6.vl too large to diff
- tests/specs/shape/point7.vl too large to diff
- tests/specs/shape/size1.vl too large to diff
- tests/specs/shape/size2.vl too large to diff
- tests/specs/shape/size3.vl too large to diff
- tests/specs/sort/ascending.vl too large to diff
- tests/specs/sort/custom.vl too large to diff
- tests/specs/sort/descending.vl too large to diff
- tests/specs/sort/stack1.vl too large to diff
- tests/specs/sort/weighted.vl too large to diff
- tests/specs/textformat/textFormat1.vl too large to diff
- tests/specs/textformat/textFormat2.vl too large to diff
- tests/specs/time/localTime.vl too large to diff
- tests/specs/time/timeDate.vl too large to diff
- tests/specs/time/timeDay.vl too large to diff
- tests/specs/time/timeHours.vl too large to diff
- tests/specs/time/timeHoursMinutes.vl too large to diff
- tests/specs/time/timeHoursMinutesSeconds.vl too large to diff
- tests/specs/time/timeMinutes.vl too large to diff
- tests/specs/time/timeMinutesSeconds.vl too large to diff
- tests/specs/time/timeMonth.vl too large to diff
- tests/specs/time/timeMonthDate.vl too large to diff
- tests/specs/time/timeQuarter.vl too large to diff
- tests/specs/time/timeQuarterMonth.vl too large to diff
- tests/specs/time/timeYear.vl too large to diff
- tests/specs/time/timeYearMonthDateHours.vl too large to diff
- tests/specs/time/timeYearMonthDateHoursMinutes.vl too large to diff
- tests/specs/time/timeYearMonthDateHoursMinutesSeconds.vl too large to diff
- tests/specs/time/utcTime.vl too large to diff
- tests/specs/tooltip/tooltip1.vl too large to diff
- tests/specs/tooltip/tooltip2.vl too large to diff
- tests/specs/trail/trail1.vl too large to diff
- tests/specs/trail/trail2.vl too large to diff
- tests/specs/viewcomposition/columns1.vl too large to diff
- tests/specs/viewcomposition/columns2.vl too large to diff
- tests/specs/viewcomposition/columns3.vl too large to diff
- tests/specs/viewcomposition/columns4.vl too large to diff
- tests/specs/viewcomposition/grid1.vl too large to diff
- tests/specs/viewcomposition/grid2.vl too large to diff
- tests/specs/viewcomposition/grid3.vl too large to diff
- tests/specs/viewcomposition/grid4.vl too large to diff
- tests/specs/viewcomposition/grid5.vl too large to diff
- tests/specs/windowtransform/joinAggregate1.vl too large to diff
- tests/specs/windowtransform/joinAggregate2.vl too large to diff
- tests/specs/windowtransform/joinAggregate3.vl too large to diff
- tests/specs/windowtransform/window1.vl too large to diff
- tests/specs/windowtransform/window2.vl too large to diff
- tests/specs/windowtransform/window3.vl too large to diff
- tests/specs/windowtransform/window4.vl too large to diff
- tests/specs/windowtransform/window5.vl too large to diff
- tests/specs/windowtransform/window6.vl too large to diff
- tests/specs/windowtransform/window7.vl too large to diff
- tools/PlayTutorial.hs too large to diff
@@ -1,6 +1,364 @@ For the latest version of this document, please see [https://github.com/DougBurke/hvega/blob/master/hvega/CHANGELOG.md](https://github.com/DougBurke/hvega/blob/master/hvega/CHANGELOG.md). +## 0.4.0.0++Thanks to (in no order): Matthew Pickering (mpickering),+Adam Conner-Sax (adamConnerSax), and Jo Wood (jwoLondon).++This is a large release, in that it greatly-improves the functionality+of hvega (more-closely aligning it with version 3.4.0 of the Vega-Lite+specification), but does provide a number of **breaking changes** (a+number of functions and constructors have either been removed or had+some combination of being renamed, argument types have changed, or the+number of arguments has been changed). The documentation has also+seen a number of additions and improvements.++A large number of functions, data types, and constructors for data+types have been added, based on version 1.12.0 (and the development+version of the next release) of the elm-vegalite module. Thanks to Jo+Wood for doing all the work! The Haddock documentation indicates new+symbols with the `since 0.4.0.0` label.++### Bug fixes++Corrected the serialization of the `datasets` function, reported by+Matthew Pickering as [issue+29](https://github.com/DougBurke/hvega/issues/17).++Improved the output to better-match the Vega Lite 3.4.0 specification.+Note that hvega does not guarantee that it always creates valid output,+in part because this would complicate the API, but also because the+Vega-Lite specification is changing (e.g. I reported several issues with+version 3.3.0 of the specification during development of this release,+some of which have been addressed in the 3.4.0 version).++### New functions, symbols, and types++The error-related types and functions discussed below are based on+changes provided by Adam Conner-Sax.++`toVegaLiteSchema` has been added to allow you to specify a different+Vega-Lite schema. `toVegaLite` uses version 3 but version 4 is being+worked on as I type this. The `vlSchema` function has been added,+along with `vlSchema4`, `vlSchema3`, and `vlSchema2` values. The+`toHtmlWith` and `toHtmlFileWith` functions have been added to support+more control over the embedding of the Vega-Lite visualizations, and+the versions of the required Javascript libraries used by the+`toHtmlXXX` routines has been updated.++The `VLProperty` type now exports its constructors, to support users+who may need to tweak or augment the JSON Vega-Lite specification+created by `hvega` (see [issue+17](https://github.com/DougBurke/hvega/issues/17)). It has also gained+several new constructors and associated functions, which are given in+brackets after the constructor: `VLAlign` (`align`); `VLBounds`+(`bounds`); `VLCenter` (`center`, `centerRC`); `VLColumns`+(`columns`); `VLConcat` (`vlConcat`); `VLSpacing` (`alignRC`,+`spacing`, `spacingRC`); `VLUserMetadata` (`usermetadata`); and+`VLViewBackground` (`viewBackground`). It is expected that you will be+using the functions rather the constructors!++The `ZIndex` type has been added: this provides constructors for the+common options - `ZFront` and `ZBack` - and a fall-through (`ZValue`)+as a protection against future changes to the Vega-Lite specification.++Four new type aliases have been added: `Angle`, `Color`, `Opacity`,+and `ZIndex`. These do not provide any new functionality but do+document intent.++The `noData` function has been added to let compositions define the+source of the data (whether it is from the parent or not), and data+sources can be named with `dataName`. Data can be created with+`dataSequence`, `dataSequenceAs`, and `sphere`. Graticules can be+created with `graticule`. The `NullValue` type has been added to+`DataValue` to support data sources that are missing elements, but for+more-complex cases it is suggested that you create your data as an+Aeson Value and then use `dataFromJson`. Support for data imputation+(creating new values based on existing data) has been added, as+discussed below.++The alignment, size, and composition of plots can be defined and+changed with `align`, `alignRC`, `bounds`, `center`, `centerRC`,+`columns`, `spacing`, and `spacingRC`.++Plots can be combined and arranged with: `facet`, `facetFlow`,+`repeat`, `repeatFlow`, and `vlConcat`++New functions for use in a `transform`: `flatten`, `flattenAs`,+`fold`, `foldAs`, `impute`, and `stack`.++New functions for use with `encoding`: `fillOpacity`, `strokeOpacity`,+`strokeWidth`,++The ability to arrange specifications has added the "flow" option+(aka "repeat"). This is seen in the addition of the `Flow` constructor+to the `Arrangement` type - which is used with `ByRepeatOp`,+`HRepeat`, `MRepeat`, `ORepeat`, `PRepeat`, and `TRepeat`.++The `Mark` type has gained `Boxplot`, `ErrorBar`, `ErrorBand`, and+`Trail` constructors. The `MarkProperty` type has gained `MBorders`,+`MBox`, `MExtent`, `MHeight`, `MHRef`, `MLine`, `MMedian`, `MOrder`,+`MOutliers`, `MNoOutliers`, `MPoint`, `MRule`, `MStrokeCap`, `MStrokeJoin`,+`MStrokeMiterLimit`, `MTicks`, `MTooltip`, `MWidth`, `MX`, `MX2`,+`MXOffset`, `MX2Offset`, `MY`, `MY2`, `MYOffset`, and `MY2Offset`+constructors.++The `Position` type has added `XError`, `XError2`, `YError`, and+`YError2` constructors.++The `MarkErrorExtent` type was added.++The `BooleanOp` type has gained the `FilterOp` and `FilterOpTrans`+constructors which lets you use `Filter` expressions as part of a+boolean operation. The `Filter` type has also gained expresiveness,+with the `FLessThan`, `FLessThanEq`, `FGreaterThan`, `FGreaterThanEq`,+and `FValid`.++The `Format` type has gained the `DSV` constructor, which allow you+to specify the separator character for column data.++The MarkChannel type has been expanded to include: `MBinned`, `MSort`,+`MTitle`, and `MNoTitle`. The PositionChannel type has added+`PHeight`, `PWidth`, `PNumber`, `PBinned`, `PImpute`, `PTitle`, and+`PNoTitle` constructors.++The LineMarker and PointMarker types have been added for use with+`MLine` and `MPoint` respectively (both from `MarkProperty`).++The ability to define the binning property with +`binAs`, `DBin`, `FBin`, `HBin`, `MBin`, `OBin`, `PBin`, and `TBin` has+been expanded by adding the `AlreadyBinned` and `BinAnchor`+constructors to `BinProperty`, as well as changing the `Divide`+constructor (as described below).++The `StrokeCap` and `StrokeJoin` types has been added. These are used+with `MStrokeCap`, `VBStrokeCap`, and `ViewStrokeCap` and+`MStrokeJoin`, `VBStrokeJoin`, and `ViewStrokeJoin` respectively.++The `StackProperty` constructor has been added with the `StOffset`+and `StSort` constructors. As discussed below this is a breaking change+since the old StackProperty type has been renamed to `StackOffset`.++The `ScaleProperty` type has seen significant enhancement, by adding+the constructors: `SAlign`, `SBase`, `SBins`, `SConstant` and+`SExponent`. THe `Scale` tye has added `ScSymLog` `ScQuantile`,+`ScQuantize`, and `ScThreshold`.++The `SortProperty` type has new constructors: `CustomSort`,+`ByRepeatOp`, `ByFieldOp`, and `ByChannel`. See the breaking-changes+section below for the constructors that were removed.++The `AxisProperty` type has seen significant additions, including:+`AxBandPosition`, `AxDomainColor`, `AxDomainDash`,+`AxDomainDashOffset`, `AxDomainOpacity`, `AxDomainWidth`,+`AxFormatAsNum`, `AxFormatAsTemporal`, `AxGridColor`, `AxGridDash`,+`AxGridDashOffset`, `AxGridOpacity`, `AxGridWidth`, `AxLabelAlign`,+`AxLabelBaseline`, `AxLabelNoBound`, `AxLabelBound`,+`AxLabelBoundValue`, `AxLabelColor`, `AxLabelNoFlush`, `AxLabelFlush`,+`AxLabelFlushValue`, `AxLabelFlushOffset`, `AxLabelFont`,+`AxLabelFontSize`, `AxLabelFontStyle`, `AxLabelFontWeight`,+`AxLabelLimit`, `AxLabelOpacity`, `AxLabelSeparation`, `AxTickColor`,+`AxTickDash`, `AxTickDashOffset`, `AxTickExtra`, `AxTickMinStep`,+`AxTickOffset`, `AxTickOpacity`, `AxTickRound`, `AxTickWidth`,+`AxNoTitle`, `AxTitleAnchor`, `AxTitleBaseline`, `AxTitleColor`,+`AxTitleFont`, `AxTitleFontSize`, `AxTitleFontStyle`,+`AxTitleFontWeight`, `AxTitleLimit`, `AxTitleOpacity`, `AxTitleX`, and+`AxTitleY`.++The `AxisConfig` has seen a similar enhancement, and looks similar+to the above apart from the constructors do not start with 'Ax'.++The `LegendConfig` type has been significantly expanded and, as+discussed in the Breaking Changes section, changed. It has gained:+`LeClipHeight`, `LeColumnPadding`, `LeColumns`, `LeGradientDirection`,+`LeGradientHorizontalMaxLength`, `LeGradientHorizontalMinLength`,+`LeGradientLength`, `LeGradientOpacity`, `LeGradientThickness`,+`LeGradientVerticalMaxLength`, `LeGradientVerticalMinLength`,+`LeGridAlign`, `LeLabelFontStyle`, `LeLabelFontWeight`,+`LeLabelOpacity`, `LeLabelOverlap`, `LeLabelPadding`,+`LeLabelSeparation`, `LeLayout`, `LeLeX`, `LeLeY`, `LeRowPadding`,+`LeSymbolBaseFillColor`, `LeSymbolBaseStrokeColor`, `LeSymbolDash`,+`LeSymbolDashOffset`, `LeSymbolDirection`, `LeSymbolFillColor`,+`LeSymbolOffset`, `LeSymbolOpacity`, `LeSymbolStrokeColor`, `LeTitle`,+`LeNoTitle`, `LeTitleAnchor`, `LeTitleFontStyle`, `LeTitleOpacity`,+and `LeTitleOrient`.++The `LegendOrientation` type has gained `LOTop` and `LOBottom`.++The `LegendLayout` and `BaseLegendLayout` types are new, and used+with `LeLayout` to define the legent orient group.++The `LegendProperty` type gained: `LClipHeight`, `LColumnPadding`,+`LColumns`, `LCornerRadius`, `LDirection`, `LFillColor`,+`LFormatAsNum`, `LFormatAsTemporal`, `LGradientLength`,+`LGradientOpacity`, `LGradientStrokeColor`, `LGradientStrokeWidth`,+`LGradientThickness`, `LGridAlign`, `LLabelAlign`, `LLabelBaseline`,+`LLabelColor`, `LLabelFont`, `LLabelFontSize`, `LLabelFontStyle`,+`LLabelFontWeight`, `LLabelLimit`, `LLabelOffset`, `LLabelOpacity`,+`LLabelOverlap`, `LLabelPadding`, `LLabelSeparation`, `LRowPadding`,+`LStrokeColor`, `LSymbolDash`, `LSymbolDashOffset`,+`LSymbolFillColor`, `LSymbolOffset`, `LSymbolOpacity`, `LSymbolSize`,+`LSymbolStrokeColor`, `LSymbolStrokeWidth`, `LSymbolType`,+`LTickMinStep`, `LNoTitle`, `LTitleAlign`, `LTitleAnchor`,+`LTitleBaseline`, `LTitleColor`, `LTitleFont`, `LTitleFontSize`,+`LTitleFontStyle`, `LTitleFontWeight`, `LTitleLimit`, `LTitleOpacity`,+`LTitleOrient`, `LTitlePadding`, `LeX`, and `LeY`.++`Projection` has gained the `Identity` constructor. The+`ProjectionProperty` type has gained `PrScale`, `PrTranslate`,+`PrReflectX`, and `PrReflectY`. The `GraticuleProperty` type was+added to configure the appearance of graticules created with+`graticule`.++The `CompositionAlignment` type was added and is used with `align`,+`alignRC`, `LeGridAlign`, and `LGridAlign`.++The `Bounds` type was added for use with `bounds`.++The `ImputeProperty` and `ImMethod` types were added for use with+`impute` and `PImpute`.++The `ScaleConfig` type has gained `SCBarBandPaddingInner`,+`SCBarBandPaddingOuter`, `SCRectBandPaddingInner`, and+`SCRectBandPaddingOuter`.++The `SelectionProperty` type has gained `Clear`, `SInit`, and+`SInitInterval`.++The Channel type has gained: `ChLongitude`, `ChLongitude2`,+`ChLatitude`, `ChLatitude2`, `ChFill`, `ChFillOpacity`, `ChHref`,+`ChKey`, `ChStroke`, `ChStrokeOpacity`. `ChStrokeWidth`, `ChText`,+and `ChTooltip`.++The `TitleConfig` type has gained: `TFontStyle`, `TFrame`, `TStyle`,+and `TZIndex`.++The `TitleFrame` type is new and used with `TFrame` from `TitleConfig`.++The `ViewBackground` type is new and used with `viewBackground`.++The `ViewConfig` type has gained `ViewCornerRadius`, `ViewOpacity`,+`ViewStrokeCap`, `ViewStrokeJoin`, and `ViewStrokeMiterLimit`.++The `ConfigurationProperty` type, used with `configuration`, has+gained `ConcatStyle`, `FacetStyle`, `GeoshapeStyle`, `HeaderStyle`,+`NamedStyles`, and `TrailStyle` constructors.++The `ConcatConfig` type was added for use with the `ConcatStyle`,+and the `FacetConfig` type for the `FacetStyle`+configuration settings.++The `HeaderProperty` type has gained: `HFormatAsNum`,+`HFormatAsTemporal`, `HNoTitle`, `HLabelAlign`, `HLabelAnchor`,+`HLabelAngle`, `HLabelColor`, `HLabelFont`, `HLabelFontSize`,+`HLabelLimit`, `HLabelOrient`, `HLabelPadding`, `HTitleAlign`,+`HTitleAnchor`, `HTitleAngle`, `HTitleBaseline`, `HTitleColor`,+`HTitleFont`, `HTitleFontSize`, `HTitleFontWeight`, `HTitleLimit`,+`HTitleOrient`, and `HTitlePadding`.++The `HyperlinkChannel` type has gained `HBinned`.++The `FacetChannel` type has gained `FSort`, `FTitle`, and `FNoTitle`.++The `TextChannel` type has gained `TBinned`, `TFormatAsNum`,+`TFormatAsTemporal`, `TTitle`, and `TNoTitle`.++The `TooltipContent` type was added, for use with `MTooltip`.++The `Symbol` type has gained: `SymArrow`, `SymStroke`, `SymTriangle`,+`SymTriangleLeft`, `SymTriangleRight`, and `SymWedge`.++### Breaking Changes++Some of these are repeated from above.++The `title` function now takes a second argument, a list of `TitleConfig`+values for configuring the appearance of the title.++The `SReverse` construtor was removed from `ScaleProperty` as it+represented a Vega, rather than Vega-Lite, property. The `xSort`+constructors are used to change the order of an item (e.g. `PSort`,+`MSort`).++The `ScSequential` constructor was removed from `Scale` as+`ScLinear` should be used.++The `SortProperty` type has had a number of changes: the `Op`,+`ByField`, and `ByRepeat` constructors have been removed, and+`ByRepeatOp`, `ByFieldOp`, and `ByChannel` constructors have been+added.++The `AxTitleMaxLength` and `TitleMaxLength` constructors have been+removed (from `AxisProperty` and `AxisConfig` respectively) as they+are invalid. The `AxTitleLimit` (new in this release) and+`TitleLimit` constructors should be used instead.++`AxisProperty`: the `AxValues` constructor has been changed from+accepting a list of doubles to `DataValues`. The `AxDates`+constructor has been deprecated and `AxValues` should be used+instead.++There have been significant changes to the `LegendConfig` type: the+`EntryPadding`, `GradientHeight`, `GradientLabelBaseline`,+`GradientWIdth`, and `SymbolColor` constructors have been removed;+the renaming constructors have been renamed so they all begin with+`Le` (e.g. `Orient` is now `LeOrient`, and `Orient` has been added+to `AxisConfig`); and new constructors have been added.++The `StackProperty` type has been renamed to `StackOffset` and its+constructors have changed, and a new `StackProperty`+type has been added (that references the `StackOffset` type).++The `Average` constructor of `Operation` was removed, and `Mean`+should be used instead.++The `LEntryPadding` constructor of `LegendProperty` was removed.++The arguments to the `MDataCondition`, `TDataCondition`, and+`HDataCondition` constructors - of `MarkChannel`, `TextChannel`,+and `HyperlinkChannel` respectively - have changed to support+accepting multiple expressions.++The `MarkOrientation` type has been renamed `Orientation`.++The constructors of the `ViewConfig` type have been renamed so they+all begin with `View` (to match `ViewWidth` and `ViewHeight`).++The constructors of the `ProjectionProperty` type have been renamed+so that they begin with `Pr` rather than `P` (to avoid conflicts+with the `PositionChannel` type).++The `Divide` constructor of `BinProperty` now takes a list of+Doubles rather than two.++The `TitleConfig` type has gained the following constructors:+`TFontStyle`, `TFrame`, `TStyle`, and `TZIndex`. The `TitleFrame`+type was added for use with `TFrame`.++The `ArgMax` and `ArgMin` constructors of `Operation` now take an+optional field name, to allow them to be used as part of an encoding+aggregation (e.g. with `PAggregate`).++The "z index" value has changed from an 'Int' to the 'ZIndex' type.++The constructors for the `Symbol` type now all start with `Sym`, so+`Cross`, `Diamond`, `TriangleUp`, `TriangleDown`, and `Path` have been+renamed to `SymCross`, `SymDiamond`, `SymTriangleUp`,+`SymTriangleDown`, and `SymPath`, respectively.++The `Legend` type has been renamed `LegendType` and its constructors+have been renamed 'GradientLegend' and 'SymbolLegend'.++### Improved testing++Added a test suite based on the Elm Vega-Lite tests (based entirely on+the work of Jo Wood).++The IPython notebooks have been expanded to cover recent changes in the+[Vega-Lite gallery](https://vega.github.io/vega-lite/examples/), and+include validation of the output (to check against the expected output).+ ## 0.3.0.1 The minimum base version has been bumped from 4.7 to 4.9, which
@@ -1,10 +1,2 @@-{ mkDerivation, aeson, base, stdenv, text, vector }:-mkDerivation {- pname = "hvega";- version = "0.3.0.0";- src = ./.;- libraryHaskellDepends = [ aeson base text vector ];- homepage = "https://github.com/DougBurke/hvega";- description = "Create Vega-Lite visualizations in Haskell";- license = stdenv.lib.licenses.bsd3;-}+{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc865" }:+nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./hvega.nix { }
@@ -1,9 +1,9 @@ name: hvega-version: 0.3.0.1+version: 0.4.0.0 synopsis: Create Vega-Lite visualizations (version 3) in Haskell.-description: This is an almost-direct port of elm-vega- (<http://package.elm-lang.org/packages/gicentre/elm-vega/2.2.1>)- to Haskell.+description: This is based on the elm-vegalite package+ (<http://package.elm-lang.org/packages/gicentre/elm-vegalite/latest>)+ by Jo Wood of the giCentre at the City University of London. homepage: https://github.com/DougBurke/hvega bug-reports: https://github.com/DougBurke/hvega/issues license: BSD3@@ -17,21 +17,192 @@ CHANGELOG.md stack.yaml default.nix+ shell.nix+ hvega.nix+ tests/specs/axis/*.vl+ tests/specs/color/*.vl+ tests/specs/composite/*.vl+ tests/specs/conditional/*.vl+ tests/specs/config/*.vl+ tests/specs/data/*.vl+ tests/specs/fillstroke/*.vl+ tests/specs/geo/*.vl+ tests/specs/hyperlink/*.vl+ tests/specs/interaction/*.vl+ tests/specs/legend/*.vl+ tests/specs/null/*.vl+ tests/specs/position/*.vl+ tests/specs/projection/*.vl+ tests/specs/scale/*.vl+ tests/specs/shape/*.vl+ tests/specs/sort/*.vl+ tests/specs/textformat/*.vl+ tests/specs/time/*.vl+ tests/specs/tooltip/*.vl+ tests/specs/trail/*.vl+ tests/specs/viewcomposition/*.vl+ tests/specs/windowtransform/*.vl+ tests/specs/gallery/advanced/*.vl+ tests/specs/gallery/area/*.vl+ tests/specs/gallery/bar/*.vl+ tests/specs/gallery/dist/*.vl+ tests/specs/gallery/error/*.vl+ tests/specs/gallery/facet/*.vl+ tests/specs/gallery/geo/*.vl+ tests/specs/gallery/interaction/*.vl+ tests/specs/gallery/label/*.vl+ tests/specs/gallery/layer/*.vl+ tests/specs/gallery/line/*.vl+ tests/specs/gallery/multi/*.vl+ tests/specs/gallery/repeat/*.vl+ tests/specs/gallery/scatter/*.vl+ tests/specs/gallery/table/*.vl+ extra-doc-files: images/example.png images/intro.png+ images/zindex.png+ images/vl/stripplot.png+ images/vl/stripplotwithbackground.png+ images/vl/stripploty.png+ images/vl/stripplotwithcolor.png+ images/vl/stripplotwithcolorordinal.png+ images/vl/parallaxhistogram.png+ images/vl/gmaghistogram.png+ images/vl/yloghistogram.png+ images/vl/gmaghistogramwithcolor.png+ images/vl/gmaglinewithcolor.png+ images/vl/yhistogram.png+ images/vl/pointplot.png+ images/vl/posplot.png+ images/vl/skyplot.png+ images/vl/smallmultiples.png+ images/vl/smallmultiples2.png+ images/vl/baseplot.png+ images/vl/layeredplot.png+ images/vl/layereddiversion.png+ images/vl/concatenatedplot.png+ images/vl/concatenatedplot2.png+ images/vl/repeatplot.png+ images/vl/splomplot.png+ images/vl/singleselection.png+ images/vl/nearestselection.png+ images/vl/multiselection.png+ images/vl/eventselection.png+ images/vl/intervalselection.png+ images/vl/intervalselectiony.png+ images/vl/transformselection.png+ images/vl/widgetselection.png+ images/vl/bindscales.png+ images/vl/coordinatedviews.png+ images/vl/coordinatedviews2.png+ images/vl/contextandfocus.png+ images/vl/crossfilter.png+ images/vl/errormanual.png+ images/vl/errormanual-zoomed.png+ images/vl/errorauto.png+ images/vl/errorbars.png+ images/vl/errorband.png+ images/vl/errorbox.png+ images/vl/comparingerrors.png+ images/vl/combinedplot.png+ images/vl/combinedplot-selected.png+ cabal-version: 1.18 +source-repository head+ type: git+ location: https://github.com/DougBurke/hvega++flag tools+ description: Build associated tools (in general you won't need this)+ default: False+ library hs-source-dirs: src exposed-modules: Graphics.Vega.VegaLite+ Graphics.Vega.Tutorials.VegaLite build-depends: base >= 4.9 && < 5 , aeson >= 0.11 && < 1.5 , text == 1.2.*+ , unordered-containers == 0.2.* , vector >= 0.11 && < 0.13 default-language: Haskell2010 ghc-options: -Wall -source-repository head- type: git- location: https://github.com/DougBurke/hvega+test-suite test+ type: exitcode-stdio-1.0+ hs-source-dirs: tests/+ main-is: Test.hs+ other-modules: AxisTests+ ColorTests+ CompositeTests+ ConditionalTests+ ConfigTests+ DataTests+ FillStrokeTests+ GeoTests+ HyperlinkTests+ InteractionTests+ LegendTests+ NullTests+ PositionTests+ ProjectionTests+ ScaleTests+ ShapeTests+ SortTests+ TextFormatTests+ TimeTests+ TooltipTests+ TrailTests+ ViewCompositionTests+ WindowTransformTests+ Gallery.Advanced+ Gallery.Area+ Gallery.Bar+ Gallery.Dist+ Gallery.Error+ Gallery.Facet+ Gallery.Geo+ Gallery.Interaction+ Gallery.Label+ Gallery.Layer+ Gallery.Line+ Gallery.Multi+ Gallery.Repeat+ Gallery.Scatter+ Gallery.Table++ build-depends: aeson >= 0.11 && < 1.5+ , aeson-pretty == 0.8.*+ , base >= 4 && < 5+ , bytestring == 0.10.*+ , containers >= 0.5.8 && < 0.7+ , filepath+ , tasty+ , tasty-golden >= 2.2 && < 2.4+ , text == 1.2.*+ , hvega++ default-language: Haskell2010+ ghc-options: -Wall+++executable playtutorial+ hs-source-dirs: tools/+ main-is: PlayTutorial.hs++ if flag(tools)+ build-depends: aeson+ , aeson-pretty == 0.8.*+ , base+ , bytestring+ , directory+ , filepath+ , hvega+ , text+ else+ buildable: False++ default-language: Haskell2010+ ghc-options: -Wall
@@ -0,0 +1,19 @@+{ mkDerivation, aeson, aeson-pretty, base, bytestring, containers+, filepath, stdenv, tasty, tasty-golden, text, unordered-containers+, vector+}:+mkDerivation {+ pname = "hvega";+ version = "0.4.0.0";+ src = ./.;+ libraryHaskellDepends = [+ aeson base text unordered-containers vector+ ];+ testHaskellDepends = [+ aeson aeson-pretty base bytestring containers filepath tasty+ tasty-golden text+ ];+ homepage = "https://github.com/DougBurke/hvega";+ description = "Create Vega-Lite visualizations (version 3) in Haskell";+ license = stdenv.lib.licenses.bsd3;+}
binary file changed (6122 → 5854 bytes)
binary file changed (absent → 5831 bytes)
binary file changed (absent → 26734 bytes)
binary file changed (absent → 95352 bytes)
binary file changed (absent → 133399 bytes)
binary file changed (absent → 27031 bytes)
binary file changed (absent → 11664 bytes)
binary file changed (absent → 8867 bytes)
binary file changed (absent → 105361 bytes)
binary file changed (absent → 81701 bytes)
binary file changed (absent → 92136 bytes)
binary file changed (absent → 20674 bytes)
binary file changed (absent → 8304 bytes)
binary file changed (absent → 24122 bytes)
binary file changed (absent → 10175 bytes)
binary file changed (absent → 18724 bytes)
binary file changed (absent → 10406 bytes)
binary file changed (absent → 14452 bytes)
binary file changed (absent → 31074 bytes)
binary file changed (absent → 5452 bytes)
binary file changed (absent → 15160 bytes)
binary file changed (absent → 41983 bytes)
binary file changed (absent → 31999 bytes)
binary file changed (absent → 33507 bytes)
binary file changed (absent → 9526 bytes)
binary file changed (absent → 5836 bytes)
binary file changed (absent → 30752 bytes)
binary file changed (absent → 29410 bytes)
binary file changed (absent → 4878 bytes)
binary file changed (absent → 113079 bytes)
binary file changed (absent → 26189 bytes)
binary file changed (absent → 24791 bytes)
binary file changed (absent → 29255 bytes)
binary file changed (absent → 10899 bytes)
binary file changed (absent → 19622 bytes)
binary file changed (absent → 25518 bytes)
binary file changed (absent → 290152 bytes)
binary file changed (absent → 1994 bytes)
binary file changed (absent → 2072 bytes)
binary file changed (absent → 6518 bytes)
binary file changed (absent → 6569 bytes)
binary file changed (absent → 2667 bytes)
binary file changed (absent → 35362 bytes)
binary file changed (absent → 40611 bytes)
binary file changed (absent → 6472 bytes)
binary file changed (absent → 7492 bytes)
binary file changed (absent → 6047 bytes)
@@ -0,0 +1,2 @@+{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc865" }:+(import ./default.nix { inherit nixpkgs compiler; }).env
@@ -0,0 +1,3528 @@+{-# LANGUAGE OverloadedStrings #-}++{-|+Module : Graphics.Vega.Tutorials.VegaLite+Copyright : (c) Douglas Burke, 2019+License : BSD3++Maintainer : dburke.gw@gmail.com++This tutorial is inspired by - in that it starts off as a close copy of - the+<https://github.com/gicentre/elm-vegalite/tree/master/docs/walkthrough Elm Vega-Lite walkthrough>+created by Jo Wood, and+converted as necessary for the differences between @hvega@ and+<https://package.elm-lang.org/packages/gicentre/elm-vegalite/latest elm-vegalite>.+The Elm tutorial is based on the talk given by+<https://youtu.be/9uaHRWj04D4 Wongsuphasawat et al at the 2017 Open Vis Conf>.++The tutorial targets version 3 of the Vega-Lite specification and+the functionality provided in version @0.4.0.0@ of hvega.++-}++module Graphics.Vega.Tutorials.VegaLite (++ -- * A Grammar of Graphics+ --+ -- $intro++ -- ** How many Haskell extensions do you need?+ --+ -- $intro-extensions++ -- ** A note on type safety+ --+ -- $intro-type-safety++ -- ** Comparing hvega to Elm Vega-Lite+ --+ -- $compare-to-elm+ + -- * What data are we using?+ --+ -- $datasource++ -- * Creating the Vega-Lite visualization+ --+ -- $output+ + -- * A Strip Plot+ --+ -- $singleview-stripplot++ -- ** Our first hvega plot+ --+ stripPlot++ -- ** Backgrounds+ --+ -- $background-note++ , stripPlotWithBackground+ + -- ** Challenging the primacy of the x axis+ --+ , stripPlotY++ -- ** Data sources+ --+ + , gaiaData++ -- ** Adding color as an encoding++ , stripPlotWithColor++ -- ** Comparing Ordinal with Nominal data types+ --+ -- $stripplot-mmtype++ , stripPlotWithColorOrdinal+ + -- * Adding an axis and summing up data+ --+ -- $singleview-histogram+ + , simpleHistogram++ -- ** Histograms+ + , parallaxHistogram+ , gmagHistogram+ + -- ** Changing the scale of an axis+ --+ -- $ylog-histogram+ + , ylogHistogram++ -- ** Stacked Histogram++ , gmagHistogramWithColor+ , gmagLineWithColor++ -- ** You don't have to just count+ --+ -- $histogramChoice+ + , yHistogram++ -- ** Plotting with points+ --+ -- $intro-points++ , pointPlot++ -- * Making a map+ --+ -- $intro-map+ + , posPlot++ , skyPlot++ -- * Layered and Multi-View Compositions+ --+ -- $intro-layered++ , smallMultiples+ , smallMultiples2++ -- ** One plot, two plot, red plot, blue plot+ --+ -- $intro-multiplot++ , basePlot++ -- ** Composing layers+ + , layeredPlot+ , layeredDiversion++ -- ** Concatenating views++ , concatenatedPlot+ , concatenatedPlot2++ -- ** Repeated views+ --+ -- $intro-repeat+ + , repeatPlot+ , splomPlot++ -- * Interactivity+ --+ -- $intro-interactivity++ , selectionProperties+ , singleSelection+ , nearestSelection+ , multiSelection+ , eventSelection+ , intervalSelection+ , intervalSelectionY++ -- ** Selection Transformations+ --+ -- $intro-selection-transforms++ , transformSelection++ -- *** Selection and bindings+ --+ -- $intro-selection-binding++ , widgetSelection+ , bindScales++ -- *** Multiple Coordinated Views+ --+ -- $intro-coordinated-views+ + , coordinatedViews+ , coordinatedViews2++ , contextAndFocus++ -- *** Cross-filtering+ --+ -- $intro-crossfilter+ + , crossFilter++ -- * Errors: lines, bars, bands, and boxes+ --+ -- $intro-error+ + , errorManual+ , errorAuto+ + , errorBars+ , errorBand+ , errorBox++ , comparingErrors++ -- * Dashboard-esque+ --+ -- $intro-dashboard+ + , combinedPlot+ + ) where++import qualified Data.Text as T++import Prelude hiding (filter, lookup, repeat)++import Graphics.Vega.VegaLite++-- $intro+-- hvega is a wrapper for the [Vega-Lite visualization+-- grammar](https://vega.github.io/) which itself is based on Leland+-- Wilkinson's [Grammar of+-- Graphics](http://www.springer.com/gb/book/9780387245447). The+-- grammar provides an expressive way to define how data are+-- represented graphically. The seven key elements of the grammar as+-- represented in hvega and Vega-Lite are:+--+-- [@Data@]: The input to visualize. Example functions: 'dataFromUrl', 'dataFromColumns', and 'dataFromRows'.+--+-- [@Transform@]: Functions to change the data before they are visualized. Example functions: 'filter', 'calculateAs', and 'binAs'. These functions are combined with 'transform'.+--+-- [@Projection@]: The mapping of 3d global geospatial locations onto a 2d plane . Example function: 'projection'.+--+-- [@Mark@]: The visual symbol, or symbols, that represent the data. Example types, used with 'mark': 'Line', 'Circle', 'Bar', 'Text', and 'Geoshape'. There are also ways to specify the shape to use for the 'Point' type, using the 'MShape' setting and the 'Symbol' type.+--+-- [@Encoding@]: The specification of which data elements are mapped to which mark characteristics (commonly known as channels). Example functions: 'position', 'shape', 'size', and 'color'. These encodings are combined with 'encoding'.+--+-- [@Scale@]: Descriptions of the way encoded marks represent the data. Example settings: 'SDomain', 'SPadding', and 'SInterpolate'.+--+-- [@Guides@]: Supplementary visual elements that support interpreting the visualization. Example setings: 'AxDomain' (for position encodings) and 'LeTitle' (for legend color, size, and shape encodings).+--+-- In common with other languages that build upon a grammar of graphics+-- such as D3 and Vega, this grammar allows fine grain control of+-- visualization design. Unlike those languages, Vega-Lite - and+-- hvega in turn - provide practical default specifications for most of the+-- grammar, allowing for a much more compact high-level form of+-- expression.+--+-- The [Vega-Lite Example Gallery](https://vega.github.io/vega-lite/examples/)+-- provides a large-number of example visualizations that show off+-- the capabilities of Vega-Lite. Hopefully, by the end of this+-- tutorial, you will be able to create most of them.++-- $intro-extensions+-- The 'Graphics.Vega.VegaLite' module is long, but does not use any+-- complex type machinery, and so it can be loaded without any extensions,+-- although the extensive use of the 'Data.Text.Text' type means that+-- using the @OverloadedStrings@ extension is __strongly__ advised.+--+-- The module does export several types that conflict with the Prelude,+-- so one suggestion is to use+--+-- > import Prelude hiding (filter, lookup, repeat)++-- $intro-type-safety+-- The interface provided by @hvega@ provides __limited__ type safety. Various+-- fields such as 'PmType' are limited by the type of the argument (in this+-- case 'Measurement'), but there's no support to check that the type makes+-- sense for the particular column (as @hvega@ itself does not inspect the+-- data source). Similarly, @hvega@ does not stop you from defining+-- properties that are not valid for a given situation - for instance+-- you can say @'toVegaLite' []@ even though the output is not a+-- valid Vega-Lite specification (i.e. it does not validate against+-- the [Vega-Lite schema](https://github.com/vega/schema)).++-- $compare-to-elm+-- @hvega@ started out as a direct copy of +-- [elm-vegalite](https://package.elm-lang.org/packages/gicentre/elm-vegalite/latest),+-- and has been updated to try and match the functionality of that package.+-- However, @hvega@ has not (yet?) followed @elm-vegalite@ into using+-- functions rather than data structures to define the options: for+-- example, @elm-vegalite@ provides @pQuant n@ which in @hvega@ is the+-- combination of @'PName' n@ and @'PmType' 'Quantitative'@ in @hvega@.+-- The top-level functions - such as 'dataFromUrl', 'encoding', and+-- 'filter' - are generally the same.++-- $datasource+-- Rather than use the Seattle weather dataset, used in the Elm walkthrough+-- (if you go through the [Vega-Lite Example Gallery](https://vega.github.io/vega-lite/examples/)+-- you may also want to look at different data ;-), I am going to use a+-- small datset from the [Gaia satellite](http://sci.esa.int/gaia/),+-- which has - and still is, as of Summer 2019 - radically-improved our knowledge+-- of our Galaxy. The data itself is from the paper+-- \"Gaia Data Release 2: Observational Hertzsprung-Russell diagrams\"+-- [preprint on arXiV](https://arxiv.org/abs/1804.09378)+-- [NASA ADS link](https://ui.adsabs.harvard.edu/#abs/arXiv:1804.09378).+-- We are going to use Table 1a, which was downloaded from the+-- [VizieR archive](http://vizier.u-strasbg.fr/viz-bin/VizieR-3?-source=J/A%2bA/616/A10/tablea1a)+-- as a tab-separated file (aka 'TSV' format).+--+-- The file contains basic measurements for a number of stars in+-- nine open clusters that all lie within 250 parsecs of the Earth+-- (please note, a parsec is a measure of distance, not time, no matter+-- what [some ruggedly-handsome ex-carpenter](https://en.wikipedia.org/wiki/Han_Solo)+-- might claim). The downloaded file is called+-- @gaia-aa-616-a10-table1a.no-header.tsv@, although I have+-- manually edited it to a \"more standard\" TSV form (we Astronomers like+-- our metadata, and tend to stick it in inappropriate places, such as the+-- start of comma- and tab-separated files, which really mucks up+-- other-people's parsing code). The first few rows in the file are:+--+--+-- +-------------------+---------+-----------+-----------+--------+--------+-------++-- | Source | Cluster | RA_ICRS | DE_ICRS | Gmag | plx | e_plx |+-- +===================+=========+===========+===========+========+========+=======++-- | 49520255665123328 | Hyades | 064.87461 | +21.75372 | 12.861 | 20.866 | 0.033 |+-- +-------------------+---------+-----------+-----------+--------+--------+-------++-- | 49729231594420096 | Hyades | 060.20378 | +18.19388 | 5.790 | 21.789 | 0.045 |+-- +-------------------+---------+-----------+-----------+--------+--------+-------++-- | 51383893515451392 | Hyades | 059.80696 | +20.42805 | 12.570 | 22.737 | 0.006 |+-- +-------------------+---------+-----------+-----------+--------+--------+-------++-- | ... | ... | ... | ... | ... | ... | ... |+-- +-------------------+---------+-----------+-----------+--------+--------+-------++--+-- The @Source@ column is a numeric identifier for the star in the Gaia database,+-- in this particular case the [\"DR2\" release](https://www.cosmos.esa.int/web/gaia/dr2),+-- the @Cluster@ column tells us which [Star Cluster](https://en.wikipedia.org/wiki/Star_cluster)+-- the star belongs to, @RA_ICRS@ and @DE_ICRS@+-- [locate the star on the sky](https://en.wikipedia.org/wiki/Celestial_coordinate_system)+-- and use the [Equatorial coordinate system](https://en.wikipedia.org/wiki/Equatorial_coordinate_system)+-- (the @ICRS@ term has a meaning too, but it isn't important for our+-- purposes),+-- @Gmag@ measues the "brightness" of the star (as in most-things Astronomical,+-- this is not as obvious as you might think, as I'll go into below),+-- and the @plx@ and @e_plx@ columns give the measured+-- [parallax of the star](https://en.wikipedia.org/wiki/Equatorial_coordinate_system)+-- and its error value, in units of+-- milli [arcseconds](https://en.wikipedia.org/wiki/Minute_and_second_of_arc).+-- And yes, I do realise after complaining about popular-culture references+-- confusing distances and time, I am now measuring distances with angles.+-- I think I've already mentioned that Astronomy is confusing...++-- $output+-- The function 'toVegaLite' takes a list of grammar specifications,+-- as will be shown in the examples below, and creates a single JSON object+-- that encodes the entire design. As of @hvega-0.4.0.0@ this targets+-- version 3 of the Vega-Lite schema, but this can be over-ridden with+-- 'toVegaLiteSchema' if needed.+--+-- There is no concept of ordering to these specification lists, in that+-- @[ dataFromUrl ..., encoding ..., mark ...]@;+-- @[ encoding ..., dataFromUrl ..., mark ... ]@;+-- and+-- @[ encoding ..., mark ..., dataFromUrl ... ]@+-- would all result in the same visualization.+--+-- The output of 'toVegaLite' can be sent to the Vega-Lite runtime to+-- generate the Canvas or SVG output. @hvega@ contains the helper+-- routines:+--+-- * 'fromVL', which is used to extract the JSON contents from 'VegaLite'+-- and create an Aeson 'Data.Aeson.Value';+--+-- * 'toHtml', which creates a HTML page which uses the+-- <https://github.com/vega/vega-embed Vega Embed> Javascript+-- library to display the Vega-Lite visualization;+--+-- * and 'toHtmlFile', which is like 'toHtml' but writes the output+-- to a file.++-- $singleview-stripplot+-- In this section we shall concentrate on creating a single+-- plot. Later on we shall try combining plots, after branching+-- out to explore some of the different ways to visualize+-- multi-dimensional data sets. +--+-- In the examples I link to symbols that have not been used in+-- previous visualizations, to make it easier to see the use+-- of new functionality.++{-|++We could encode one of the numeric data fields as a strip plot where+the horizontal position of a tick mark is determined by the value+of the data item. In this case I am going to pick the "@plx@" column:++<<images/vl/stripplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAXAlgY2QGnCgBNZ1ZUxQIJIBXeAGwsgAt10AHAZxQHpf4sAO4A6AOaZ0LWgCNaXAKbxsAewB26BRpGrovACIraYgEL1EC3iwBuCsbF5wum+Fdv3eJMr3uZYAWlgAgDYARmDA0IAGfzIZBgVQ2BE1FX8WBVgiJRF0LmtIAmooADMVeDh0CmBIdABPDgVmPIKAX0JWoqgAEi5sDLhmNk4efndkiSlZEUwVXj6Bh3H-BklLawBmEQArLnVCwkgtVSJMNTFqyAAPS5LMBQYiZg4GG7wMBqa0SABHWlgNJJSJhbJBWp1Dqo1HcLmhgO1WkA Open this visualization in the Vega Editor>++@+'toVegaLite'+ [ 'dataFromUrl' "https:\/\/raw.githubusercontent.com\/DougBurke\/hvega\/master\/hvega\/data\/gaia-aa-616-a10-table1a.no-header.tsv" ['TSV']+ , 'mark' 'Tick' []+ , 'encoding' ('position' 'X' [ 'PName' "plx", 'PmType' 'Quantitative' ] [])+ ]+@++Notice how there is __no explicit definition__ of the axis details,+color choice or size. These can be customised, as shown in examples+below, but the default values are designed to follow good practice in+visualization design.++Three grammar elements are represented by the three functions+'dataFromUrl', 'mark', and 'encoding'.++The 'encoding' function takes as a single parameter, a list of+specifications that are themselves generated by other functions. In+this case we use the function 'position' to provide an encoding of the+@\"plx\"@ field as the x-position in our plot. The precise way in which+the data value (parallax) is mapped to the x-position will depend on the type of+data we are encoding. We can provide a hint by delcaring the+measurement type of the data field, here 'Quantitative' indicating a+numeric measurement type. The final parameter of position is a list of+any additional encodings in our specification. Here, with only one+encoding, we provide an empty list.++As we build up more complex visualizations we will use many more+encodings. To keep the coding clear, the idiomatic way to do this with+hvega is to chain encoding functions using point-free+style. The example above coded in this way would be++@+let enc = encoding+ . position X [ PName "plx", PmType Quantitative ]++in toVegaLite+ [ dataFromUrl "https:\/\/raw.githubusercontent.com\/DougBurke\/hvega\/master\/hvega\/data\/gaia-aa-616-a10-table1a.no-header.tsv" [TSV]+ , mark Tick []+ , enc []+ ]+@++-}++stripPlot :: VegaLite+stripPlot = toVegaLite+ [ dataFromUrl "https://raw.githubusercontent.com/DougBurke/hvega/master/hvega/data/gaia-aa-616-a10-table1a.no-header.tsv" [TSV]+ , mark Tick []+ , encoding (position X [ PName "plx", PmType Quantitative ] [])+ ]++-- $background-note+-- The default background color for the visualization, at least in the+-- Vega-Embed PNG and SVG output, is transparent. In many cases this is+-- perfectly fine, but an explicit color can be specified using the+-- 'Background' configuration option.++{-|++The 'configure' function allows a large number of configuration+options to be configured, each one introduced by the+'configuration' function. Here I set the color to be a light gray+(actually a very-transparent black; the 'Color' type describes the+various supported color specifications, but it is generally safe to assume+that if you can use it in HTML then you can use it here).++<<images/vl/stripplotwithbackground.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEDGD2B2AzAlgc0gLjMSAjAhtANaoBOsArvACaZSmoEAUADADRjuccsB0AjAEpIAXzbgoAW3ykidSABdkxSOIiRq+BfjqgI6iqQA28gBYKFABwDOGAPR3S+AO69UyBaYq4K1gKakcPAKfsG8cJJ2ACKUqABChkR+dqYAbn6o+HbS1iGkKemZdpradpnI+AC0+FUAbPy11fwsldq4Rn78+LzwsJWmfvjUAbwK1qmqEuqIsKTSCrqKAJ6WfvJjEyISYhKQACTW0APSZhY29naF3e6e3rzIsHaHx1lXlUYeyakAzLwAVtYEJN1KE4NRkPB0FgcAAPRYoPxGWhYSCWIxwjjLVbyACOFHwwQ8WmQ6VEWxEQA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"plx\", PmType Quantitative ]++ conf = 'configure'+ . 'configuration' ('Background' "rgba(0, 0, 0, 0.1)")++in toVegaLite+ [ dataFromUrl \"https:\/\/raw.githubusercontent.com\/DougBurke\/hvega\/master\/hvega\/data\/gaia-aa-616-a10-table1a.no-header.tsv\" [TSV]+ , mark Tick []+ , enc []+ , conf []+ ]+@++-}++stripPlotWithBackground :: VegaLite+stripPlotWithBackground = toVegaLite+ [ dataFromUrl "https://raw.githubusercontent.com/DougBurke/hvega/master/hvega/data/gaia-aa-616-a10-table1a.no-header.tsv" [TSV]+ , mark Tick []+ , encoding (position X [ PName "plx", PmType Quantitative ] [])+ , configure (configuration (Background "rgba(0, 0, 0, 0.1)") [])+ ]+++{-|+There is nothing that forces us to use the x axis, so let's+try a vertical strip plot. To do so requires changing only+__one__ character in the specifiction, that is the first argument to+'position' is now 'Y' rather than 'X':++<<images/vl/stripploty.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAXAlgY2QGnCgBNZ1ZUxQIJIBXeAGwsgAt10AHAZxQHpf4sAO4A6AOaZ0LWgCNaXAKbxsAewB26BRpGrovACIraYgEL1EC3iwBuCsbF5wum+Fdv3eJMr3uZYAWlgAgDYARmDA0IAGfzIZBgVQ2BE1FX8WBVgiJRF0LmtIAmooADMVeDh0CmBIdABPDgVmPIKAX0JWoqgAEi5sDLhmNk4efndkiSlZEUwVXj6Bh3H-BklLawBmEQArLnVCwkgtVSJMNTFqyDrLkswFBiJmDgYAD0KMBqa0SABHWlgNJJSJhbJBWp1Dqo1LcLmhgO1WkA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position 'Y' [ PName "plx", PmType Quantitative ]++in toVegaLite+ [ dataFromUrl \"https:\/\/raw.githubusercontent.com\/DougBurke\/hvega\/master\/hvega\/data\/gaia-aa-616-a10-table1a.no-header.tsv\" [TSV]+ , mark Tick []+ , enc []+ ]+@+-}+stripPlotY :: VegaLite+stripPlotY = toVegaLite+ [ dataFromUrl "https://raw.githubusercontent.com/DougBurke/hvega/master/hvega/data/gaia-aa-616-a10-table1a.no-header.tsv" [TSV]+ , mark Tick []+ , encoding (position Y [ PName "plx", PmType Quantitative ] [])+ ]+++{-|+Since we are going to be using the same data source, let's define it here:++@+gaiaData =+ let addFormat n = (n, 'FoNumber')+ cols = [ \"RA_ICRS\", \"DE_ICRS\", \"Gmag\", \"plx\", \"e_plx\" ]+ opts = [ 'Parse' (map addFormat cols) ]++ in dataFromUrl "https:\/\/raw.githubusercontent.com\/DougBurke\/hvega\/master\/hvega\/data\/gaia-aa-616-a10-table1a.no-header.tsv" opts+@++The list argument to 'dataFromUrl' allows for some customisation of+the input data. Previously I used @['TSV']@ to specify the data is in+tab-separated format, but it isn't actually needed here (since the+file name ends in \".tsv\"). However, I have now explicitly defined how+to parse the numeric columns using 'Parse': this is because the columns+are read in as strings for this file by default, which actually doesn't+cause any problems in most cases, but did cause me significant problems+at one point during the development of the tutorial! There is limited+to no feedback from the visualizer for cases like this (perhaps I should+have used the Javascript console), and I only realised the problem thanks+to the @Data Viewer@ tab in the+<https://vega.github.io/editor/#/ Vega Editor>+(after a+<https://twitter.com/pkgw/status/1167127390880968707 suggestion from a colleague>).++Although not used in this tutorial, data+can also be defined algorithmically - using 'dataSequence' and+'dataSequenceAs' - or inline - with 'dataFromColumns' or+'dataFromRows' - or directly from JSON (as a 'Data.Aeson.Value') using+'dataFromJson'.++-}++gaiaData :: Data+gaiaData =+ let addFormat n = (n, FoNumber)+ cols = [ "Gmag", "plx", "e_plx" ]+ opts = [ Parse (map addFormat cols) ]++ in dataFromUrl "https://raw.githubusercontent.com/DougBurke/hvega/master/hvega/data/gaia-aa-616-a10-table1a.no-header.tsv" opts+++{-|++One question would be how the parallaxes vary by cluster: as parallax is measuring distance,+then are the clusters similar distances away from us, or are there a range of values? A+first look is to use another \"channel\" to represent (i.e. encode) the cluster:++<<images/vl/stripplotwithcolor.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAXAlgY2QGnCgBNZ1ZUxQIJIBXeAGwsgAt10AHAZxQHpf4sAO4A6AOaZ0LWgCNaXAKbxsAewB26BRpGrovACIraYgEL1EC3iwBuCsbF5wum+Fdv3eJMr3uZYAWlgAgDYARmDA0IAGfzIZBgVQ2BE1FX8WBVgiJRF0LmtIAmooADMVeDh0CmBIDgRFasgAcTgxZjVaaBklQqgOBgAPds7u+F7IBQB9fqG0SA6unoBfJcIloqgAEi5sDLhmNk4efndkiSlZEUwVXh29h1P-BklLawBmEQArLnVCwgm1KoiJg1G00FRqJBVAxyo0SpgFAwiMwAMIMeQucboACeHAU7RU0BBsCY60INFmlHJkPhiORcxmf2KNBxeOYAEdaLANJJSJhbEzmZBYANMFxGlh0AlmAAFBAkhgisAACicAEpIKtilqwGSaKo1PCwZRVksgA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"plx\", PmType Quantitative, 'PAxis' [ 'AxTitle' \"Parallax (mas)\" ] ]+ . 'color' [ 'MName' \"Cluster\", MmType 'Nominal' ]++in toVegaLite+ [ gaiaData+ , mark Tick []+ , enc []+ ]+@++Now each tick mark is colored by the cluster, and a legend is automatically+added to indicate this mapping. Fortunately the number of clusters in the+sample is small enough to make this readable! The 'color' function has+added this mapping, just by giving the column to use (with 'MName') and+its type ('MmType'). The constructors generally begin with @P@ for+position and @M@ for mark, and as we'll see there are other property+types such as facet and text.++Vega-Lite supports several data types, represented+by the 'Measurement' type. We have already seen 'Quantitative', which+is used for numeric data, and here we use 'Nominal' for the clusters,+since they have no obvious ordering.++The labelling for the X axis has been tweaked using 'PAxis', in this+case the default value for the label (the column name) has been+over-ridden by an explicit value.++-}++stripPlotWithColor :: VegaLite+stripPlotWithColor =+ let enc = encoding+ . position X [ PName "plx", PmType Quantitative, PAxis [ AxTitle "Parallax (mas)" ] ]+ . color [ MName "Cluster", MmType Nominal ]++ in toVegaLite+ [ gaiaData+ , mark Tick []+ , enc []+ ]+++-- $stripplot-mmtype+-- It is instructive to see what happens if we change the mark type for+-- the color encoding from 'Nominal' to 'Ordinal'.++{-|++<<images/vl/stripplotwithcolorordinal.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAXAlgY2QGnCgBNZ1ZUxQIJIBXeAGwsgAt10AHAZxQHpf4sAO4A6AOaZ0LWgCNaXAKbxsAewB26BRpGrovACIraYgEL1EC3iwBuCsbF5wum+Fdv3eJMr3uZYAWlgAgDYARmDA0IAGfzIZBgVQ2BE1FX8WBVgiJRF0LmtIAmooADMVeDh0CmBIDgRFasgAcTgxZjVaaBklQqgOBgAPds7u+F7IBQB9fqG0SA6unoBfJcIloqgAEi5sDLhmNk4efndkiSlZEUwVXh29h1P-BklLawBmEQArLnVCwgm1KoiJg1G00FRqJBVAxyo0SpgFAwiMwAMIMeQucboACeHAUzHKwLUsCY60INFmlHJkPhiORcxmf2KNBxeOYAEdaLANJJSJhbEzmZBYANMFxGlh0AlmAAFBAkhgisAACicAEpIKtilqwGSaKo1PCwZRVksgA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"plx\", PmType Quantitative, PAxis [ AxTitle \"Parallax (mas)\" ] ]+ . color [ MName \"Cluster\", MmType 'Ordinal' ]++in toVegaLite+ [ gaiaData+ , mark Tick []+ , enc []+ ]+@++As can be seen, the choice of color scale has changed to one more+appropriate for an ordered set of values.+-}+stripPlotWithColorOrdinal :: VegaLite+stripPlotWithColorOrdinal =+ let enc = encoding+ . position X [ PName "plx", PmType Quantitative, PAxis [ AxTitle "Parallax (mas)" ] ]+ . color [ MName "Cluster", MmType Ordinal ]++ in toVegaLite+ [ gaiaData+ , mark Tick []+ , enc []+ ]++-- $singleview-histogram+-- While the strip plot shows the range of parallaxes, it is hard to+-- make out the distribution of values, since the ticks overlap. Even+-- changing the opacity of the ticks - by adding an encoding channel+-- like @'opacity' [ 'MNumber' 0.6 ]@, or by setting the 'MOpacity'+-- property of the 'mark' - only helps so much. So, we+-- would like to bin up the parallax values, and report the number+-- of stars in each bin (i.e. aggregate the data). That is, create+-- a histogram of the data.++{-|++Since sensible (hopefully) defaults are provided for unspecified settings, it+is relatively easy to write generic representations of a particular+visualization. The following function expands upon the previous+specifications by:++ * taking a field name, rather than hard coding it;++ * the use of @'PBin' []@ to ask for the x-axis values to be binned;++ * the addition of a second axis ('Y') which is used for the+ aggregated value ('Count', which means that no column has+ to be specified with @PName@);++ * and the change from 'Tick' to 'Bar' for the 'mark'.++Note that we did not have to specify how we wanted the histogram+calculation to proceed - e.g. the number of bins, the bin widths,+or edges - although we could have added this, by using a non-empty+list of 'BinProperty' values with 'PBin', if the defaults are not+sufficient.++@+simpleHistogram field =+ let enc = encoding+ . position X [ PName field, PmType Quantitative, 'PBin' [] ]+ . position Y [ 'PAggregate' 'Count', PmType Quantitative ]++ in toVegaLite+ [ gaiaData+ , mark 'Bar' []+ , enc []+ ]+@++-}++simpleHistogram :: T.Text -> VegaLite+simpleHistogram field =+ let enc = encoding+ . position X [ PName field, PmType Quantitative, PBin [] ]+ . position Y [ PAggregate Count, PmType Quantitative ]++ in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ ] ++{-|++With 'simpleHistogram' it becomes easy to get a histogram of the parallax+values:++<<images/vl/parallaxhistogram.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAjBkA04oBNYAXWVMUCCSAV3gBszIALIogBwGcUB6b+WAO4A6AOYBLIk2rpqHAKbwAxgHsAdkTnqhK6NwAiy6iIBCtRHO5MAbnJGxucDhviWbd7oRLc7Y2AFpYfwA2AEYggJCABj8SdDo5ENghVWU-JjlYfAUhIg4rHDwqADNleDgiMmBINgR5SsgAcTgRRlVqaHQFHCg2OgAPVvbO+G7IOQB9XoG0SDaOroBfBbwF3CoAEg5FdLhGFnYuXjck8UlpITFlbi2d+2O-OgkLKwBmIQArDjUCqk0VfDEqhaaAolEg03IkCKYjkdHwjCmo3QgLIRHg1Dk2CgRAAnmw5IwAI7UWDqCTEMQ2SCrQpQHH1WAiETwWzEAkzFTUdSjXH4okkskkIiUgnLCA0qgqVTQ4HkZYLIA Open this visualization in the Vega Editor>++@parallaxHistogram = 'simpleHistogram' \"plx\"@++We can see that although parallaxes around 20 to 25 milli-arcseconds+dominated the earlier visualizations, such as 'stripPlotWithColor',+__most__ of the stars have a much-smalled parallax, with values+in the range 5 to 10.++-}++-- TODO XXX explain parallax++parallaxHistogram :: VegaLite+parallaxHistogram = simpleHistogram "plx"++{-|++A different column (or field) of the input data can be viewed,+just by changing the name in the specification:++<<images/vl/gmaghistogram.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAjBkA04oBNYAXWVMUCCSAV3gBszIALIogBwGcUB6b+WAO4A6AOYBLIk2rpqHAKbwAxgHsAdkTnqhK6NwAiy6iIBCtRHO5MAbnJGxucDhviWbd7oRLc7Y2AFpYfwA2AEYggJCABj8SdDo5ENghVWU-JjlYfAUhIg4rHDwqADNleDgiMmBINgR5SsgAcTgRRlVqaHQFHCg2OgAPVvbO+G7IOQB9XoG0SDaOroBfBbwF3CoAEg5FdLhGFnYuXjck8UlpITFlbi2d+2O-OgkLKwBmIQArDjUCqk0VfDEqhaaAolEg03IkCKYjkdHwjCasBa2AwgLIRHg1DkKMgRAAnmw5IwAI7UWDqCTEMQ2SCrQpQPH1JEieC2YhEmYqajqUb4wkkskUkhEalE5YQOlUFSqaHA8jLBZAA Open this visualization in the Vega Editor>++@gmagHistogram = simpleHistogram \"Gmag\"@++Here we can see that the number of stars with a given magnitude+rises up until a value of around 18, and then drops off.++-}++-- TODO XXX explain magnitudes++gmagHistogram :: VegaLite+gmagHistogram = simpleHistogram "Gmag"++++-- $ylog-histogram+-- In the case of 'parallaxHistogram', the data is __dominated__ by+-- stars with small parallaxes. Changing the scale of the+-- Y axis to use a logarithmic, rather than linear, scale /might/+-- provide more information:++{-|++<<images/vl/yloghistogram.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFALYCGATgNYZjCQDOK5A9pbDZIuaQJ6T5QAZvAA2Ijs24A7ROwGQUPAA7tMkAEYVIAX0IRIAE1IpSNUBH0BXcuLWoUS+ugD0z7gHcAdIngpol9Ut6WHIAY2YpFFhIz3DiZwARZktEACFrNmdoADdYRFJnMkYQrNz85yMTZ3z4UgBaUnqANgBGJoaWnDqTdRFYFtJPKWY6uFIDEM8Uemz+In1BSTI0TDolCmCzSABxMkQOKUtidRD+KCURAA8Do5PyM8hYAH0L67VD49PtbSJdIkgACT0UJwMgceyOFzOMqDHx+AKeeDMZzA0EFGF1ES+WDQrCeABW9Aic30KF8fQ421ItTAAAUKKQxKRLrB6CSoNFwgZ4DIzPMoG9aPyFvBYCIDBxXuyLFB1DyaExLLA9DKoIoVBwAI6WUiRXzGeC5aUWSDM+Bs1YKcmqKD07hMy5gAAURQAlDp+X8ZZA+KthVBgYybXR1TbICJmPsvarTYguHljGHwpZIsbScow9rdWSTGSjZ7firIOEpMJ9qsftogA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName "plx", PmType Quantitative, PBin [], PAxis [ AxTitle "Parallax (mas)" ] ]+ . position Y [ PAggregate Count, PmType Quantitative, 'PScale' [ 'SType' 'ScLog' ] ]++in toVegaLite+ [ gaiaData+ , mark Bar [ 'MFill' "orange", 'MStroke' "gray" ]+ , enc []+ , 'height' 300+ , 'title' "Gaia Parallaxes" []+ ] +@++There are four new changes to the visualization created by 'simpleHistogram' (since 'PAxis'+has been used above):++ 1. an explicit choice of scaling for the Y channel (using 'PScale');++ 2. the fill ('MFill') and edge ('MStroke') colors of the histogram bars are different;++ 3. the height of the overall visualization has been increased;++ 4. and a title has been added.++If you view this in the Vega Editor you will see the following warning:++@+A log scale is used to encode bar's y. This can be misleading as the height of the bar can be arbitrary based on the scale domain. You may want to use point mark instead.+@++-}+ylogHistogram :: VegaLite+ylogHistogram =+ let enc = encoding+ . position X [ PName "plx", PmType Quantitative, PBin [], PAxis [ AxTitle "Parallax (mas)" ] ]+ . position Y [ PAggregate Count, PmType Quantitative, PScale [ SType ScLog ] ]++ in toVegaLite+ [ gaiaData+ , mark Bar [ MFill "orange", MStroke "gray" ]+ , enc []+ , height 300+ , title "Gaia Parallaxes" []+ ] +++{-|++A color encoding can also be added. When used with the 'Tick' mark -+'stripPlotWithColor' - the result was that each tick mark was colored+by the \"Cluster\" field, but for the 'Bar' mark the result is that+the bars are stacked together. I have also taken the opportunity to+widen the plot ('width'); define the binning scheme used, with @'Step'+1@; and configure the location of the x axis tick marks, using+'AxValues'.++<<images/vl/gmaghistogramwithcolor.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFALYCGATgNYZQBGFkhEkAJqSqTaBMwK7kAbGjBQoADgGd0AemnlSAdwB0ieCmi9avCbHIBjAPYA7FLBNLDxaQBEDvRACF+lWNOgA3WIlLSyE0+Runt7SbBzS3vCkALSkMQBsAIzxsYk40Ry0ArCJpEpGBtFwpCy6SigS7oxEzABmBuRkaJjAkGIUOlyQAOJkiMJGvMS0uoxQYgIAHgNDI+RjkLAA+hPTmJCDw6MAvttE20xQCvAs6jQALHiHkAAkEnpwZMKo4lKywXmq6ppK8AbS90ePg+0QEalc7iwSgAVhJjNVmGZDCx4EZ+i0alBDAIGl1avBYAIWMIAMICbQBBYoACeYlgAwMxFRpCEB0xkDWYG4PDqBKJwl6pH6hx5kFoqK6-lgYhoiTZPOYNLpwgAjrxSCY1Ox4J4EQrIKRJvAJF13CzeLATZgANoEMAAVnwYDSTsSjrAACYcABdPY8+U8SDUrpCxDkLzsenrQy8ExU2lRqBqjUoLWp3V+sAByCGIz49FcvbbIA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, binning, axis ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color [ MName \"Cluster\", MmType Nominal ]++ binning = PBin [ 'Step' 1 ]+ axis = PAxis [ 'AxValues' ('Numbers' [ 0, 5 .. 20 ]) ]+ +in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ , height 300+ , 'width' 400+ ] +@++Note that @hvega@ will allow you to combine a 'color' encoding with a 'ScLog'+scale, even though a Vega-Lite viewer will not display the+resulting Vega-Lite specification, saying++@Cannot stack non-linear scale (log)@++-}+gmagHistogramWithColor :: VegaLite+gmagHistogramWithColor =+ let enc = encoding+ . position X [ PName "Gmag", PmType Quantitative, binning, axis ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color [ MName "Cluster", MmType Nominal ]++ binning = PBin [ Step 1 ]+ axis = PAxis [ AxValues (Numbers [ 0, 5 .. 20 ]) ]+ + in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ , height 300+ , width 400+ ] ++{-|++Notice how we never needed to state explicitly that we wished our bars+to be stacked. This was reasoned directly by Vega-Lite based on the+combination of bar marks and color channel encoding. If we were to+change just the mark function from 'Bar' to 'Line', Vega-Lite produces an+unstacked series of lines, which makes sense because unlike bars,+lines do not occlude one another to the same extent.++<<images/vl/gmaglinewithcolor.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFALYCGATgNYZQA28AdrJIRJACakqk2gRsBXcrRowUKAA4BndAHpZ5UgHcAdIngpoAgEYCpscgGMA9gxSwzKk8VkARYwMQAhIZVizoAN1iJSsslLm5B7evrKc3LK+8KQAtKRxAGwAjInxyTix3Nq0sMmkKgzGsXCk7AYqKFKeLERsAGbG5GRomMCQEhT6vJAA4mSIogwCxNoGLFAStAAeQyNj5BOQsAD6U7OYkMOj4wC+u0S7rFBK8OyaNAAseMeQACRShnBkoqiSMvKhBeqaOirwxlkj2efi+sXo5lkniwKgAVlJTLU2BYTOxGIM2nUoCZaE0evV4LBaOxRABhWh6IJLFAATwkzE2RWIjFIIiOWMgGzAfH4DUJxNE-VIg2OvMg2kYPUCsAkNGS7N5bFp9NEAEcBKQzBouPBvEjFZBSNN4FIep5WQJYKbMABtAhgACs+DAGWdySdYAATDgALoHXkK-iQGk9YWIcg+LgM7EOMzUunRyDqzUobWpvX+sCByAmBgEjHcg67IA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, binning, axis ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color [ MName \"Cluster\", MmType Nominal ]++ binning = PBin [ Step 1 ]+ axis = PAxis [ AxValues (Numbers [ 0, 5 .. 20 ]) ]+ +in toVegaLite+ [ gaiaData+ , mark 'Line' []+ , enc []+ , height 300+ , width 400+ ] +@++-}++gmagLineWithColor :: VegaLite+gmagLineWithColor =+ let enc = encoding+ . position X [ PName "Gmag", PmType Quantitative, binning, axis ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color [ MName "Cluster", MmType Nominal ]++ binning = PBin [ Step 1 ]+ axis = PAxis [ AxValues (Numbers [ 0, 5 .. 20 ]) ]+ + in toVegaLite+ [ gaiaData+ , mark Line []+ , enc []+ , height 300+ , width 400+ ] +++-- $histogramChoice+-- The previous histogram visualizations have taken advantage of Vega-Lite's+-- ability to bin up ('Count') a field, but there are a number of aggregation+-- properties (as defined by the 'Operation' type). For example, there+-- are a number of measures of the \"spread\" of a population, such as+-- the sample standard deviation ('Stdev').++{-|+The aim for this visualization is to show the spread in the @Gmag@ field+for each cluster, so we now swap the axis on which the aggregate is+being applied (so that the cluster names appear on the y axis),+and hide the legend that is applied (using @'MLegend' []@) since+we can read off the color mapping from the y axis.++<<images/vl/yhistogram.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuMxIHsAOsDGAlgC4CeqYADAHQBsANFKdgKbmQBGCkAvneFABNYRWOVAQIkAK7wANmwAWRItgDOKAPQb4sAO5UA5sQVT2U1c3h5MAOyLM7Va9A0ARTFIMAhGYmYaFADdmA1gNOFV7eADg0I0hEQ1QglgAWlg0mgBGGnSsilSRdllmLNgqG0xUhWZYAUsqIlVAyD4JKAAzTHg4IjFIXHgLfoBxOAM2GylodktWqGxZAA9J6dn4echmAH1FlbRIKZm57m5+Xn5IABJVPBq4RWU1TQ1Y8qMiE3YqAkwNW-uYTeqVkxH8gQAzFQAFaqWytS4OawCAg2CZocQSSDWWTdfodAjMWQCNgAYVk5iimyYrAOlWgqNg8gYkBKBgcJLQU1ksgu7Ug+3QkAJRM5UDGsAmLMlBngIWEtKgkXqLRZNLYAEcpLA7MRhARgjw2liyBjhYTiWSKZE5mqSCxJpgGTYmTxzsbsbYCej0GduEA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, PAggregate 'Stdev' ]+ . position Y [ PName \"Cluster\", PmType Nominal ]+ . color [ MName \"Cluster\", MmType Nominal, 'MLegend' [] ]++in toVegaLite+ [ gaiaData+ , mark Bar [ 'MOpacity' 0.6 ]+ , enc []+ ] +@++The bar opacity is reduced slightly with 'MOpacity 0.6' so that the+x-axis grid lines are visible. An alternative would be to change the+'AxZIndex' value for the 'X' encoding so that it is drawn on top of+the bars.++-}++yHistogram :: VegaLite+yHistogram =+ let enc = encoding+ . position X [ PName "Gmag", PmType Quantitative, PAggregate Stdev ]+ . position Y [ PName "Cluster", PmType Nominal ]+ . color [ MName "Cluster", MmType Nominal, MLegend [] ]++ in toVegaLite+ [ gaiaData+ , mark Bar [ MOpacity 0.6 ]+ , enc []+ ] + +++-- $intro-points+-- At this point we make a signifiant detour from the Elm Vega-Lite+-- walkthtough, and look at the 'Point' mark, rather than creating+-- small-multiple plots. Don't worry, we'll get to them later.++{-|++Here I use the 'Point' mark to display the individual+@Gmag, plx@ pairs, encoding by __both__ 'color' and 'shape.+Since the encoding uses the same field of the data (the @Cluster@+name), Vega-Lite is smart enough to only display one legend,+which contains the point shape and color used for each cluster.++Since the parallax values are bunched together at low values,+a logarithmic scale ('ScLog') is used for the y axis, along with+commands to define the actual axis domain - by turning off the+'IsNice' support and listing the minimum and maximum values+for the axis with 'SDomain'.++<<images/vl/pointplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMAWADDgNOFALYCGATgNYZQAOA9vAHZqESQAmpKpNoE7AK7kANjRgoUtAM7oA9HPKkA7gDpE8FNEEAjQdNjkAxvRawWqk8TkAReoMQAhYZVhzoAN1iJScstJRDdy8fOS4eOR94UgBaUliANgBGBLiknBieHRFYJNJVJnoYuFIOQ1UUaQ9INgFIADN6cjI0TGBIWgoDPkgAcTJEcSZBYh1DGroRAA8hkbHyCchYAH1aadnR8YBfLaIt2shleA4tGlwCIkgAEmkjODJxVClZBRD8jS1dVXh6OVv73xvGIiTRuDwAZlUACtpKYapdzCYOMxBm0iOwTCImj16vBYCIOOIAMIifSBBb4KAoACetFgQ3oxGYpDE+3RUGk0FIdJxeIJxNJAXGlMgNJ5mEghSZTBZkDZAigMzaDT5hIl-VIgxFYvpEoAjoJSCxNNx4F45bV2NS+Oz2Lj8WrJjNLXVbizdWB2hxGaRmDQANqQgCslPBACYALra2keyBYrVQJjwIwe+osgzyhVUmPiA1GlAmgvm9m7CCZyAmJi41Ge3ZbIA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative ]+ . position Y [ PName \"plx\", PmType Quantitative, PScale scaleOpts ]+ . color cluster+ . shape cluster++ scaleOpts = [ SType ScLog, 'SDomain' ('DNumbers' [3.5, 32]), 'SNice' ('IsNice' False) ]+ cluster = [ MName \"Cluster\", MmType Nominal ]++in toVegaLite [ gaiaData+ , mark 'Point' []+ , enc []+ , width 400+ , height 400+ ]+@++We can see that each cluster appears to have a separate parallax+value, and that it doesn't really vary with Gmag. What this is telling+us is that for these star clusters, the distance to each member star+is similar, and that they are generally at different distances+from us. However, it's a bit hard to tell exactly what is going+on around 5 to 6 milli arcseconds, as the clusters overlap here.++This line of thinking leads us nicely to map making, but before we+try some cartography, I wanted to briefly provide some context for+these plots. The+<https://lco.global/spacebook/distance/parallax-and-distance-measurement/ parallax of a star>+is a measure of its distance from us, but it is an inverse relationship,+so that nearer stars have a larger parallax than those further from us.+The @Gmag@ column measures the apparent brightness of the star, with the+@G@ part indicating what+<https://www.cosmos.esa.int/web/gaia/iow_20180316 part of the spectrum>+is used (for Gaia, the @G@ band is pretty broad, covering much of+the visible spectrum), and the @mag@ part is because optical Astronomy+tends to use++ * <https://www.skyandtelescope.com/astronomy-resources/the-stellar-magnitude-system/ the logarithm of the measured flux>++ * and then subtract this from a constant++so that larger values mean fainter sources. These are also+<https://en.wikipedia.org/wiki/Apparent_magnitude apparent magnitues>,+so that they measure the flux of the star as measured at Earth,+rather than its intrinsic luminosity (often defined as an object's+<https://en.wikipedia.org/wiki/Absolute_magnitude absolute magnitude>).++We can see that the further the cluster is from us - that is, as we+move down this graph to smaller parallax values - then the+smallest stellar magnitude we can see in a cluster tends to increase,+but that there are stars up to the maximum value (20) in each cluster.+This information can be used to look at the+distribution of absolute magnitudes of stars in a cluster, which+tells us about its evolutionary state - such as is it newly formed or old -+amongst other things. However, this is straying far from the+aim of this tutorial, so lets get back to plotting things.++-}++pointPlot :: VegaLite+pointPlot =+ let enc = encoding+ . position X [ PName "Gmag", PmType Quantitative ]+ . position Y [ PName "plx", PmType Quantitative, PScale scaleOpts ]+ . shape cluster+ . color cluster++ scaleOpts = [ SType ScLog, SDomain (DNumbers [3.5, 32]), SNice (IsNice False) ]+ cluster = [ MName "Cluster", MmType Nominal ]+ + in toVegaLite [ gaiaData+ , mark Point []+ , enc []+ , width 400+ , height 400+ ]++-- $intro-map+-- We have some hint that the different clusters are distinct objects+-- in space, in that they appear to be different distances from us,+-- but where does the \"cluster\" in the name \"Stellar Cluster\"+-- come from? Well, we can try plotting up the position of each star+-- on the sky - using the @RA_ICRS@ and @DE_ICRS@ fields - to find out.++{-|++The following specification should only contain one new feature - other+than sneakily switching from 'Point' to 'Circle' type for the mark - and+that is displaying the x axis (namely Right Ascension) in reverse (using+@'PSort' [ 'Descending' ]@. This is needed because Right Ascension+is measured from right to left. I like to explain it by talking about+oranges, and how we are at the center of an orange looking out at its+skin, and so have the direction reversed to if you were outside, looking+in. You can see that we also have one cluster that straddles the+0 and 360 degrees Right Ascension barrier, which will lead to some+fun later.++<<images/vl/posplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFALYCGATgNYZQDG85tANrJIRJACakqk2gQOAV3JMaMFCgAOAZ3QB6eeVIB3AHSJ4KaEIBGQmbEYB7AHYpY5tbWPF5AEWNDEAIRGVY86ADdYiUvJkMhbkXr7+8ty88v7wpAC0pAkAbACMyYmpOPG8uiyppGqmxvFwpJxGaigy3mxEHABmxuRkaJjAkFIUhvyQAOJkiOKmQsS6RmxQUkwAHsOj4+STkLAA+tNzmJAjYxMAvntEe+xQKvCc2jQALHgnkAAkMrRwZOKo0nKK4YWa2npq8GM8ieLwC33iTC0nm8WDUACsZGY6hxLDZOPBTEN2vU6MYmM1eg14LAmJxxABhJgGELLFAATykrC2xWIGNIYmOOMgmzAAkEjWJpPEACUAIKrACS5OFAGVkfyoE92UzeVxbKQMTQANoEbDJHAAXXwUFM8FoKoa7MMnIViuabSgFSelnRmPl-Mg9MZ4gAjkJSOYtDx4L53YJIKQZvAZL0UFoWCKkKgwKLnaYZIDTGAABQVRAASkgh35NvDdP4OIFJLJW3sAFFJdK5ScPUqE+01WRNZgtfEAJy6gdGk1mi1W2Clj1elWQP0BuO8OOhlvhyPR2Pxmf2WDMNlxsw5vOF4uCE+lyA2UxErG8w57IA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X (axOpts \"RA_ICRS\" \"Right Ascension (deg)\" ++ [ raScale, 'PSort' [ 'Descending' ] ])+ . position Y (axOpts \"DE_ICRS\" \"Declination (deg)\" ++ [ decScale ])+ . color [ MName \"Cluster\", MmType Nominal ]+ + axOpts field lbl = [ PName field, PmType Quantitative, PAxis [ AxTitle lbl ]]+ + scaleOpts minVal maxVal = [ SDomain (DNumbers [ minVal, maxVal ]), SNice (IsNice False) ]+ raScale = PScale (scaleOpts 0 360)+ decScale = PScale (scaleOpts (-90) 90)+ +in toVegaLite [ gaiaData+ , mark 'Circle' []+ , enc []+ , width 400+ , height 300+ ]+@++We can see that these clusters are indeed localised on the sky,+with <https://en.wikipedia.org/wiki/Hyades_(star_cluster) Hyades>+looking like it covers the largest area. However, we should be+careful and __not forget__ either +<https://www.youtube.com/watch?v=E9IuXEwpU7U Grover's hard work>+or+<https://www.youtube.com/watch?v=MMiKyfd6hA0 Father Ted's explanation to Father Dougal>,+since these clusters are different distances from us, which+makes size a tricky thing to measure from this plot.++There is also the fact that I have used possibly the worst+way of displaying the Right Ascension and Declination data. Although+the night sky is not the same as the Earth's surface, the issues+when trying to display the Globe on a flat surface also apply to+displaying up the sky. For this plot the distortions near the+pole are huge, although fortunately we don't have any clusters+too close to either pole.++-}++posPlot :: VegaLite+posPlot =+ let enc = encoding+ . position X (axOpts "RA_ICRS" "Right Ascension (deg)" ++ [ raScale, PSort [ Descending ] ])+ . position Y (axOpts "DE_ICRS" "Declination (deg)" ++ [ decScale ])+ . color [ MName "Cluster", MmType Nominal ]+ + axOpts field lbl = [ PName field, PmType Quantitative, PAxis [ AxTitle lbl ]]+ + scaleOpts minVal maxVal = [ SDomain (DNumbers [ minVal, maxVal ]), SNice (IsNice False) ]+ raScale = PScale (scaleOpts 0 360)+ decScale = PScale (scaleOpts (-90) 90)+ + in toVegaLite [ gaiaData+ , mark Circle []+ , enc []+ , width 400+ , height 300+ ]+++{-|+Vega-Lite supports a large number of projections - via the+'Projection' type - which we use below to create+a similar visualization to 'posPlot'. Here I use the+'Longitude' and 'Latitude' channels, along with a+'Mercator' 'projection', to display the data.++The trick in this case is that longitude runs from -180 to 180+degrees, but the data has Right Ascension going from 0+to 360 degrees. We can take advantage of Vega Lite's+__data transformation__ capabilities and create a new+column - which I call @fakeLongitude@ - and is+defined as "180 - Right Ascension". The "expression" support+is essentially a sub-set of Javascript, and the @datum@+object refers to the current row. The new data column+can then be used with the 'Longitude' channel.++<<images/vl/skyplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJ5k8pV4BrAUwBl1EBzAS2gFcATGyAGigDG8ADYD2w+NB75IARgAcABjABaMJ0nssAOgBKAQQD6ASQDCugMqQAvgF1e4KFniwq5SAJawBwng4iQGtDw5KAQAeywwu4AFtDQAA7IuAD0KQgA7tqs0DHsAEbsyDTejFKI0NoC6FgpACLo7EwAQpG0KTEAbjRM8CnOyFKwHd29KUF9vSzwKvAzAGyy87OyiirB+b6y8NqI6CoxNPDcsNrQyJ18jgEY2JKhkAkuxQ8A4s5M7oha+SV8UAlhAAPL4-P78SA0QyAkEyb5YX6wGzWRzWfxQAAkyAEh2csXiSVSKVGOxyeXy2hY6BS2NxfRJKmEbBoxIAzNoAFbIRhXAIJWDoDk0ATQKmIB7QACeCWkThKQmgmBs6MhiGqnBYzFC10E6GESvwYXCNxYNGEnHcMN5xqg2JEsuItJoWFlkE6XhYGrIEKlMvc+s+aJ1AV9roAjuwkKLgqLupAdUHjZAJNGuA7IKhTeb3HUAKImcxWH3S8ORipsSQsOOJ8IwdB60UJB6Zs0WmSmYRFIb-GAlr41TUiZU65OMHJp5tZtsUaj0MdsCfFv0yCNRiuxngoiA1jyMTOfQ0o6xAA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position 'Longitude' (axOpts "fakeLongitude")+ . position 'Latitude' (axOpts \"DE_ICRS\")+ . color [ MName \"plx\"+ , MmType Quantitative+ , 'MScale' [ SType ScLog+ , 'SScheme' \"viridis\" []+ ]+ ]+ . 'tooltip' [ 'TName' \"Cluster\", 'TmType' Nominal ]+ + axOpts field = [ PName field, PmType Quantitative ]+ + trans = 'transform'+ . 'calculateAs' "180 - datum.RA_ICRS" "fakeLongitude"+ +in toVegaLite [ 'projection' [ 'PrType' 'Mercator' ]+ , gaiaData+ , trans []+ , mark Circle []+ , enc []+ ]+@++The other major change made to 'posPlot' is that the stars are now+color-encoded by the log of their parallax value+rather than cluster membership,+and the color scheme has been changed to use the \"viridis\" color+scale.+Since parallax is a numeric value, with ordering (i.e. 'Quantitative'),+the legend has changed from a list of symbols to a gradient bar.+To account for this lost of information, I have added a 'tooltip'+encoding so that when the pointer is moved over a star its cluster+name will be displayed (this replaces the default behavior when+all the encoded channels, so in this case the position and parallax+values, would be displayed, and it is only visible in \"interactive\"+versions of the visualization).++From this visualization we can see that the apparent size of the cluster+(if we approximate each cluster as a circle, then we can think of the radius+of the circle as a measure of size) depends on parallax, with larger+sizes having larger parallaxes. This is because the distance to a star+is inversely-dependent on its parallax, so larger parallaxes mean the+star is closer to us. However, there is no reason that the intrinsic+size - that is its actual radius - of each cluster is the same.+We can see that although the Hyades and Pleiades clusters overlap+on the sky, they have significantly-different parallaxes (as can+be seen in 'pointPlot' for example), with Hyades being the closer+of the two.++It is possible to add graticules - with the aptly-named+'graticule' function - but this appears to need to be done+as a layer, which we haven't covered yet. I may get to it+below, but am having teensy problems with getting it+working in the Vega Lite viewer I use (the one provided with+Jupyter notebook, which defaults to an earlier version+of Vega-Lite support, which doesn't seem to like the more-recent+capabilities of Vega Lite).++-}++skyPlot :: VegaLite+skyPlot =+ let enc = encoding+ . position Longitude (axOpts "fakeLongitude")+ . position Latitude (axOpts "DE_ICRS")+ . color [ MName "plx"+ , MmType Quantitative+ , MScale [ SType ScLog+ , SScheme "viridis" []+ ]+ ]+ . tooltip [ TName "Cluster", TmType Nominal ]+ + axOpts field = [ PName field, PmType Quantitative ]+ + trans = transform+ . calculateAs "180 - datum.RA_ICRS" "fakeLongitude"+ + in toVegaLite [ projection [ PrType Mercator ]+ , gaiaData+ , trans []+ , mark Circle []+ , enc []+ ]++-- $intro-layered+-- The Stacked-Histogram plot - created by 'gmagHistogramWithColor' - showed+-- the distribution of the \"Gmag\" field by cluster, but it was hard to+-- compare them. A common approach in this situation is to split up+-- the data into multiple plots -+-- the <https://en.wikipedia.org/wiki/Small_multiple small multiple>+-- approach (also known as trellis plots) - which we can easily achieve in+-- Vega Lite. It also gets us back on track with the Elm walkthrough.++{-|++Our first attempt is with the 'column' function, which tells+Vega-Lite to create a plot for each @Cluster@ field (and introduces+us to the @F@ family of 'FacetChannel' constructors).++The legend has been turned off with @'MLegend' []@, since it doesn't+add anything to this visulization (as the individual plots, labelled+by the cluster name, provide the same information).++<<images/vl/smallmultiples.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAjBkA04oBNYAXWVMUCCSAV3gBszIALIogBwGcUB6b+WAO4A6AOYBLIk2rpqHAKbwAxgHsAdkTnqhK6NwAiy6iIBCtRHO5MAbnJGxucDhviWbd7oRLc7Y2AFpYfwA2AEYggJCABj8SdDo5ENghVWU-JjlYfAUhIg4rHDwqADNleDgiMmBINgR5SsgAcTgRRlVqaHQFHCg2OgAPVvbO+G7IOQB9XoG0SDaOroBfBbwF3CoAEg5FdLhGFnYuXjck8UlpITFlbi2d+2O-OgkLKwBmIQArDjUCqk0VfDEqhaaAolEgKjopXqRTEcjo+EYAGE6LJnKMiABPNhyVrKaCA2AMbBQeIiTQItBtOh0VaFKDTciQGFwilQJqwFrEyDoQFkIjwahyLmY7GMACO1Fg6gkxDENkgtMoUAh7VU0Nh8KRKKcXWFWJxMxS+NUhIVazBGMqdKoHJE8FsxANysM6h+SqgIqdkAlUqIMr98vNSsgsD6Yg49T9RHijAAckMFGBlEUwABlEjwCPLJXZsCK52qGHA8jLBZAA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, PBin [] ]+ . position Y yAxis+ . color [ MName \"Cluster\", MmType Nominal, MLegend [] ]+ . 'column' [ 'FName' \"Cluster\", 'FmType' Nominal ]++ yAxis = [ PAggregate Count+ , PmType Quantitative+ , PAxis [ AxTitle \"Number of Stars\" ]+ ]+ +in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ ]+@++Since we have nine clusters in the sample, the overall visualization is+too wide, unless you have a very-large monitor. Can we do better?++-}++smallMultiples :: VegaLite+smallMultiples =+ let enc = encoding+ . position X [ PName "Gmag", PmType Quantitative, PBin [] ]+ . position Y yAxis+ . color [ MName "Cluster", MmType Nominal, MLegend [] ]+ . column [ FName "Cluster", FmType Nominal ]++ yAxis = [ PAggregate Count+ , PmType Quantitative+ , PAxis [ AxTitle "Number of Stars" ]+ ]+ + in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ ]+++{-|++The number of columns used in small-multiple can be defined using the+'columns' function. However, this requires us to:++ * move the facet definition out from the encoding and into the top-level,+ with the 'facetFlow' function;++ * and define the plot as a separate specification, and apply it+ with 'specification' and 'asSpec'.++The actual syntactic changes to 'smallMultiples' are actually+fairly minor:++@+let enc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, PBin [] ]+ . position Y yAxis+ . color [ MName \"Cluster\", MmType Nominal, MLegend [] ]++ yAxis = [ PAggregate Count+ , PmType Quantitative+ , PAxis [ AxTitle \"Number of Stars\" ]+ ]+ +in toVegaLite+ [ gaiaData+ , 'columns' 4+ , 'facetFlow' [ FName \"Cluster\", FmType Nominal ]+ , 'specification' ('asSpec' [ mark Bar [], enc [] ])+ ]+@++<<images/vl/smallmultiples2.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAmCGAutIC4yghSBXATgGxSgAt54AHAZ2QHpqdYB3AOgHMBLeIrAIywoFMcAYwD2AO3j8JTUQFtqAERFYWAIVwBrftSIA3fi1jVZsCpJw79h6nETVDbWAFpYzgGwBGNy48AGJ4jcePwesExiIk5E-LDQgkzwFLqQADTgGJAAZiI4JvCEwJBksDgCBZAA4iYshJBiWLLcgqlQZHgAHrX1jc0pUPwA+m2dqHUNTTiQAL5T6VNpmBRk-EIF6ZgmOBq13CWp6-1iotBsYjWo6BiYong55Zls-HjQtQDCeHzmLZDwAJ7LXREslOsAIfUgwRYUheqHqeDw8wOmBGaCyj2etSqsBq4O4p0I8BwWH44L+ANGAEcsLAJBwEGx9NMFlcoL81iyMtiWDgDAh+LVRFgJPsOZgyfzKdTaYh4Az+cyOZBYO02BRyrL4MFagA5caCMAiTJgADKiFK0yRYFmV2tVuZkAAJBQhNETLUSOQqLQrGF2JweEw2CJqM7XUYfU48BxtLoAMxMABWFHEIqgNwaYjVqAALPbMrAhPx8hc0U8YVB3p9elBxYDgWJQUz0pBRGIHuc0LMpkA Open this visualization in the Vega Editor>++Note that Vega Lite does support a @\"facet\"@ field in its encodings,+but hvega follows Elm VegaLite and requires you to use this+<https://github.com/gicentre/elm-vegalite/issues/5#issuecomment-514501218 wrapped facet> approach.++-}++smallMultiples2 :: VegaLite+smallMultiples2 =+ let enc = encoding+ . position X [ PName "Gmag", PmType Quantitative, PBin [] ]+ . position Y yAxis+ . color [ MName "Cluster", MmType Nominal, MLegend [] ]++ yAxis = [ PAggregate Count+ , PmType Quantitative+ , PAxis [ AxTitle "Number of Stars" ]+ ]+ + in toVegaLite+ [ gaiaData+ , columns 4+ , facetFlow [ FName "Cluster", FmType Nominal ]+ , specification (asSpec [ mark Bar [], enc [] ])+ ]+++-- $intro-multiplot+-- There are four ways in which multiple views may be combined:+--+-- * The __facet operator__ takes subsets of a dataset (facets) and+-- separately applies the same view specification to each of+-- those facets (as seen with the 'column' function above).+-- Available functions to create faceted views:+-- 'column', 'row', 'facet', 'facetFlow', and 'specification'.+--+-- * The __layer operator__ creates different views of the data but+-- each is layered (superposed) on the same same space; for example+-- a trend line layered on top of a scatterplot.+-- Available functions to create a layered view: 'layer' and 'asSpec'.+--+-- * The __concatenation operator__ allows arbitrary views (potentially+-- with different datasets) to be assembled in rows or columns.+-- This allows \'dashboards\' to be built.+-- Available functions to create concatenated views:+-- 'vConcat', 'hConcat', and 'asSpec'.+--+-- * The __repeat operator__ is a concise way of combining multiple views+-- with only small data-driven differences in each view.+-- Available functions for repeated views: 'repeat' and 'specification'.+++{-|++We start with a \"basic\" plot for the dataset: the median value+of the parallax of the stars in each cluster.++<<images/vl/baseplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuKAjBkA04oBNYAXWVMUCCSAV3gBszIALIogBwGcUB6b+WAO4A6AOYBLIk2rpqHAKbwAxgHsAdkTnqhK6NwAiy6iIBCtRHO5MAbnJGxucDhviWbd7oRLc7Y2AFpYfwA2AEYggJCABj8SdDo5ENghVWU-JjlYfAUhIg4rHDwqADNleDgiMmBINgR5SsgAcTgRRlVqaHQFHCg2OgAPVvbO+G7IOQB9XoG0SDaOroBfBbwF3CoAEg5FdLhGFnYuXjck8UlpITFlbi2d+2O-OgkLKwBmIQArDjUCqk0VfDEqhaaAolEg03IkCKYjkdHwjAAwnRZM5RkQAJ5sOStZTQQGwBirQpQdH1aGw+EzKajWAiETwWzEbEzaByAGwVRozHMqAAR2oHKIEmIYhskGWECJVBUqmhwPIywWQA Open this visualization in the Vega Editor>++@+let plx = position Y [ PName \"plx\", PmType Quantitative, PAggregate 'Median' ]+ cluster = position X [ PName \"Cluster\", PmType Nominal ]+ enc = encoding . cluster . plx+ +in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ ]+@+-}++basePlot :: VegaLite+basePlot =+ let plx = position Y [ PName "plx", PmType Quantitative, PAggregate Median ]+ cluster = position X [ PName "Cluster", PmType Nominal ]+ enc = encoding . cluster . plx+ + in toVegaLite+ [ gaiaData+ , mark Bar []+ , enc []+ ]+++{-|++We start our exploration by combining two visualizations, layering+one on top of the other. The base plot shows the same data as+'basePlot', and then on top we will show a horizontal line that+indicates the median parallax for all the stars in the sample.++<<images/vl/layeredplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAmCGAutIC4yghSBXATgGxSgAt54AHAZ2QHpqdYB3AOgHMBLeIrAIywoFMcAYwD2AO3j8JTUQFtqAERFYWAIVwBrftSIA3fi1jVZsCpJw79h6nETVDbWAFpYzgGwBGNy48AGJ4jcePwesExiIk5E-LDQgkzwFLqQADTgGJAAZiI4JvCEwJBksDgCBZAA4iYshJBiWLLcgqlQZHgAHrX1jc0pUPwA+m2dqHUNTTiQAL5T6VNpmAAkFELRJrUk5FS0VmHsnDxMbCLUK2tGu054HNq6AMxMAFYU4qnpkHiwAJ7NqADa6QghRMOA0tW4JRakCkomgbDENVQhRGaCybH4eGgtQAwng+OYofAvmR+F0RLJ4bACDN5oDUSCwaMcFhgtN0gBdBb9MSw+GItB0yBfcqZdGY2rDKGwFgsHAGBCk0ayfhw2BiQnExVQACOWDV8A4CDY+jZEFpmFEYlF-OAsymQA Open this visualization in the Vega Editor>++@+let plx = position Y [ PName \"plx\", PmType Quantitative, PAggregate Median ]+ cluster = position X [ PName \"Cluster\", PmType Nominal ]+ + perCluster = [ mark Bar [], encoding (cluster []) ]+ allClusters = [ mark 'Rule' [] ]+ +in toVegaLite+ [ gaiaData+ , encoding (plx [])+ , 'layer' (map 'asSpec' [perCluster, allClusters])+ ]+@++For this visualization, the specification starts with the data+source and an encoding, but __only__ for the y axis (which means+that all layered plots use the same encoding for the axis). The+'layer' function introduces the different visualizations that+will be combined, each as there own \"specification\" (hence+the need to apply 'asSpec' to both @perCluster@ and @allClusters@).+Note that there is no x-axis encoding for the 'Rule', since the+data applies to all clusters (i.e. it should span the+whole visualization).++-}+layeredPlot :: VegaLite+layeredPlot =+ let plx = position Y [ PName "plx", PmType Quantitative, PAggregate Median ]+ cluster = position X [ PName "Cluster", PmType Nominal ]+ + perCluster = [ mark Bar [], encoding (cluster []) ]+ allClusters = [ mark Rule [] ]+ + in toVegaLite+ [ gaiaData+ , encoding (plx [])+ , layer (map asSpec [perCluster, allClusters])+ ]+ ++{-|++This example is similar to 'layeredPlot' but includes an x-axis+encoding for the second layer. We use this to show the range of the+data - so the minimum to maximum parallax range of each cluster - with+the 'Rule' type. The difference to the previous plot is that an+extra positional encoding is added ('Y2') to define the end point+of each line ('Y' is used as the start point).++<<images/vl/layereddiversion.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFACYCGKpGYoEEkArgE4A2VMKKADgM7oD0fRqQDuAOkTwU0egCN63WIwDGAewB2KWBtGqAtnwAiK+ogBCTANaw+0AG6xEpPrtLdNjG-cd8yFPo-hSAFpSYIA2AEYwkIicIIoZZlgI0lE1FSC4UmJFURRuW0hCWigAMxVGFzRMYEhOUkYFKlqAcRdENjV6XRlFIqhOZgAPTu7exn7IWAB9QZHMSC6evoBfFaIV4qhheGIpKlwCIkgAEm4lOBc2VC5eAS9UiSlZUXgVPnPLpweg5klrWxYUQAK246iKx2YpAAnn1MABtIgQGglKAuRgWZqQbjwABesCoACYCFAUNDOASFkp4MokpBNkjaFM1KpiPA1B0aoySpBoVjSvBYMxiGw5pNSIhEIwHORKWjYGzSGpJmSKWwAI70JUoSTkeD2encsDrEoMkoonnozELRj0OlbHlaVnsznUI10aGE-mC4Wi4biyXSxyaNguEZm1Ee71CkULMX4KASqUykMLXTslXkuWQTXa3U6g0m1FFiBFgC6W2Zzo5WPm1EgApjbAAwsx5O5M2qFul02pSKw1pXVGoBa7gOsVkA Open this visualization in the Vega Editor>++@+let plx op = position Y [ PName \"plx\", PmType Quantitative, PAggregate op ]+ cluster = position X [ PName \"Cluster\", PmType Nominal ]+ + median = [ mark Circle [ 'MSize' 20 ]+ , encoding (plx Median [])+ ]+ range = [ mark Rule [ ]+ , encoding+ . plx 'Min'+ . position 'Y2' [ PName "plx", PAggregate 'Max' ]+ $ []+ ]+ +in toVegaLite+ [ gaiaData+ , encoding (cluster [])+ , layer (map asSpec [ median, range ])+ , width 300+ , height 300+ ]+@++The 'MSize' option is used to change the size of the circles so that they+do not drown out the lines (the size value indicates the area of the mark,+and so for circles the radius is proportional to the square root of this+size value; in practical terms I adjusted the value until I got something+that looked sensible).++Note that the y axis is automatically labelled with the different+operation types that were applied - median, minimum, and maximum -+although there is no indication of what marks map to these operations.++-}+layeredDiversion :: VegaLite+layeredDiversion = + let plx op = position Y [ PName "plx", PmType Quantitative, PAggregate op ]+ cluster = position X [ PName "Cluster", PmType Nominal ]+ + median = [ mark Circle [ MSize 20 ], encoding ( plx Median []) ]+ range = [ mark Rule [ ], encoding . plx Min . position Y2 [ PName "plx", PAggregate Max ] $ [] ]+ + in toVegaLite+ [ gaiaData+ , encoding (cluster [])+ , layer (map asSpec [ median, range ])+ , width 300+ , height 300+ ]+++{-|++Instead of layering one view on top of another (superposition), we can+place them side by side in a row or column (juxtaposition). In+Vega-Lite this is referred to as /concatenation/:++<<images/vl/concatenatedplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAmCGAutIC4yghSBXATgGxSgAt54AHAZ2QHpqdYB3AOgHMBLeIrAIywoFMcAYwD2AO3j8JTUQFtqAERFYWAIVwBrftSIA3fi1jVZsCpJw79h6nETVDbWAFpYzgGwBGNy48AGJ4jcePwesExiIk5E-LDQgkzwFLqQADTgGJAAZiI4JvCEwJBksDgCBZAA4iYshJBiWLLcgqlQZHgAHrX1jc0pUPwA+m2dqHUNTTiQAL5T6VNpmLqiYkIIhADa6RDoGJgmOBq13CWpWxlSotBsYjWoO7uYI2hZbPx40LUAwnh85i2Q8AAnmR+F0RLJrrACPMzrtIIDyplXu9asN-rAWCwcAYEKDRrJ+FdYGJ-kCQbUAI5YYnwDgINj6aawsCzXYw3b3DL7Q6jY6TBYPSAXERXG4FZmPRHIj6jb6-XpQMl4qARCFiKHTAUPKAIu4vN4yqBVDHozHYwySWoEokkvoA4HKyBUml02mM1kPD0QD0AXQFkAAJBQhNETLUSOQqLQrGF2JweEw2CJqMHQ0YY048BxtLoAMxMABWFHEp0wyyRtzQsymQA Open this visualization in the Vega Editor>++@+let enc field = encoding+ . position X [ PName \"Cluster\", PmType Nominal ]+ . position Y [ PName field, PmType Quantitative, PAggregate Median ]+ + parallaxes = [ mark Bar [], enc \"plx\" [] ]+ magnitudes = [ mark Bar [], enc \"Gmag\" [] ]+ + specs = map asSpec [ parallaxes, magnitudes ]+ +in toVegaLite+ [ gaiaData+ , 'vConcat' specs+ ]+@++The 'hConcat' function would align the two plots horizontally,+rather than vertically (and is used in 'combinedPlot').++Note that as the axes are identical apart from the field for the y axis,+the encoding has been moved into a function to enforce this constraint+(this ensures the x axis is the same, which makes it easier to visually+compare the two plots). However, there is no requirement that the+two plots be "compatible" (they could use different data sources).++-}+++concatenatedPlot :: VegaLite+concatenatedPlot = + let enc field = encoding+ . position X [ PName "Cluster", PmType Nominal ]+ . position Y [ PName field, PmType Quantitative, PAggregate Median ]+ + parallaxes = [ mark Bar [], enc "plx" [] ]+ magnitudes = [ mark Bar [], enc "Gmag" [] ]+ + specs = map asSpec [ parallaxes, magnitudes ]+ + in toVegaLite+ [ gaiaData+ , vConcat specs+ ]+++{-|++The alignment of the plots can be adjusted with 'spacing', which we+use here to remove the vertical gap between the two plots (the+example is written so that we can see the only difference between+the two plot specifications is the addition of @'PAxis' []@ to the+parallax plot).++<<images/vl/concatenatedplot2.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAmCGAutIC4yghSBXATgGxSgAt54AHAZ2QHpqdYB3AOgHMBLeIrAIywoFMcAYwD2AO3j8JTUQFtqAERFYWAIVwBrftSIA3fi1jVZsCpJw79h6nETVDbWAFpYzgGwBGNy48AGJ4jcePwesExiIk5E-LDQgkzwFLqQADTgGJAAZiI4JvCEwJBksDgCBZAA4iYshJBiWLLcgqlQZHgAHrX1jc0pUPwA+m2dqHUNTTiQAL5T6VNpmLqiYkIIhADa6RDoGJgmOBq13CWpWxlSotBsYjWoO7uYI2hZbPx40LUAwnh85i2Q8AAnmR+F0RLJrrACH1ILB2mwKIR6ng8PMzrtIIDyplXu9asN-rAWCwcAYEKDRrJ+FdYGJ-kCQbUAI5YWnwDgINj6abosCzXZo3b3DL7Q6jY6TBYPSAXERXG4FXmPbG4j6jb6-XpQBkUqARCFiKHTKUPKBYu4vN5qqBVImE4mkwySWpUml0mE65msiQc9nc-kPAMQAMAXSlkAAJBQhNETLUSOQqLQrGF2JweEw2CJqNHY0YU048BxtLoAMxMABWFHEp0wFGKQmutzAvnDyxxzeAsymQA Open this visualization in the Vega Editor>++@+let enc field flag = encoding+ . position X ([ PName \"Cluster\", PmType Nominal ] +++ if flag then [ PAxis [] ] else [])+ . position Y [ PName field, PmType Quantitative, PAggregate Median ]+ + parallaxes = [ mark Bar [], enc \"plx\" True [] ]+ magnitudes = [ mark Bar [], enc \"Gmag\" False [] ]+ + specs = map asSpec [ parallaxes, magnitudes ]+ +in toVegaLite+ [ gaiaData+ , 'spacing' 0+ , vConcat specs+ ]+@++Even though we set 'spacing' to @0@ there is still a small gap between+the plots: this can be removed by using @'bounds' 'Flush'@, but we'll+leave using that until the grand finale.++-}++concatenatedPlot2 :: VegaLite+concatenatedPlot2 = + let enc field flag = encoding+ . position X ([ PName "Cluster", PmType Nominal ] +++ if flag then [ PAxis [] ] else [])+ . position Y [ PName field, PmType Quantitative, PAggregate Median ]+ + parallaxes = [ mark Bar [], enc "plx" True [] ]+ magnitudes = [ mark Bar [], enc "Gmag" False [] ]+ + specs = map asSpec [ parallaxes, magnitudes ]+ + in toVegaLite+ [ gaiaData+ , spacing 0+ , vConcat specs+ ]+++-- $intro-repeat+-- Creating the same plot but with a different field is common-enough+-- that Vega-Lite provides the 'repeat' operator.+++{-|++The 'concatenatedPlot' example can be extended to view the+distribution of several fields - in this case Right Ascension,+Declination, parallax, and magnitude:++<<images/vl/repeatplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEBOCmAOsCGAXSAuMwYHsDuGYA2pAEoCCA+gJIDCpAypADRQAiAojfU65PABsAHiygBxALZIA5pAC6AX2bgoAZ0QBjQqAgRIU6AGtCkAEZJoLFXoAmqJNuu7IAV2gCTACxQp4q9AD0AdBIeAB00gCWKJ4upi6qsNAaOAB2KLDpYSkSAWw4LtIAQm6GsAGeAG6w0kgBUqoZ0BXVtQF2KHW1kUgAtEh9AGwAjIP9wwAMvZ2mArDDSGGpOL2eyDZJYSiqlVa6zgBmONBSaJg6+87wFonakJIyJqkuEqZJovzCTy9vlnywlEEIkwkGer3eCicEEh+yUTkgmRSNkiqVk5yhUGBWEgB0isAENhMtAECSaHxQAE9EE8cBIUUgPHDLlAKY5mXpcfjCecYAhkGcoNB8JAmezIDJpHBahkTBJYMikKk9mLKdSQQBHFyKlDRVCRaqQDEw3TG0WQAAkqg0aykXh8fkCAVaiyiMTiYUiOACVptdWdvQE0XKlQAzGEAFaqNLKyApVK4tFYSEKIA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PName \"Cluster\", PmType Nominal ]+ . position Y [ 'PRepeat' 'Row', PmType Quantitative, PAggregate Median ]+ + spec = asSpec [ gaiaData+ , mark Bar []+ , enc [] ]+ + rows = [ \"RA_ICRS\", \"DE_ICRS\", \"plx\", \"Gmag\" ]+ +in toVegaLite+ [ 'repeat' [ 'RowFields' rows ]+ , 'specification' spec+ ]+@+++This more compact specification replaces the data field name+(for example @'PName' \"plx\"@) with a reference to the repeating field+('PRepeat') either as a 'Row' or 'Column' depending on the desired+layout. We then compose the specifications by providing a set of+'RowFields' (or 'ColumnFields') containing a list of the fields to which+we wish to apply the specification (identified with the function+'specification' which should follow the repeat function provided to+toVegaLite).++-}++repeatPlot :: VegaLite+repeatPlot =+ let enc = encoding+ . position X [ PName "Cluster", PmType Nominal ]+ . position Y [ PRepeat Row, PmType Quantitative, PAggregate Median ]+ + spec = asSpec [ gaiaData+ , mark Bar []+ , enc [] ]+ + rows = [ "RA_ICRS", "DE_ICRS", "plx", "Gmag" ]+ + in toVegaLite+ [ repeat [ RowFields rows ]+ , specification spec+ ]+++{-|++We can combine repeated rows and columns to create a grid of+views, such as a scatterplot matrix, adding in color+encoding to separate out the clusters:++<<images/vl/splomplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEBOCmAOsCGAXSAuMoIRgewHcMwBtSAJQEEB9ASQGFyBlSAGigBEBROxl9yPAA2ADzZQA4gFskAc0gBdVuByQAxniEBXKQDtiZKr2bjI3Y-yjCxA6XMUqAvstwBnRGuLZVM6AGsvSFcASwAvWGIAVgEUAE9EYkE8YN00ZxVcABNUJC8M1S1oIUSACxQUeFd0AHpq6CQCADpZYJQSrQAjLVdYaA1U2FTGjSlqjjwtWQAhQr9YapKAN1hZJGqZVxReheXV6uyUNdXgpABaJDOANgBGS-PrgAZTw46hWGukRt08U5LkTN6jRQrkWbHyuAAZnhoDI0JhvDhVPAkNAeoE7PJMJBdDoOr1TNZEjipHjoKZYNRCVjiaTII5wWB6Yj0ojIIMNJkUpisAz1JpoYEIcFYEJMol6NpNviYvEItS8FIUkhiizEVAxPDIEKRWLNXBEKhEhptHo6TKEliAI5aJCpVqoYLLM282KC4WiwL65BwqDQQhmqBxC1Qa22lD28NOpk4aOqyAAElcaj+MlK5UqNWqu0+LTanUawTw1STKbW2dOQla80WAGZGgArVx4fQuKD9IXc4D0xxAA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PRepeat 'Column', PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color [ MName \"Cluster\", MmType Nominal ]+ + spec = asSpec [ gaiaData+ , mark Point [ MSize 5 ]+ , enc [] ]+ + fields = [ \"RA_ICRS\", \"DE_ICRS\", \"plx\", \"Gmag\" ]+ +in toVegaLite+ [ repeat [ RowFields fields, 'ColumnFields' fields ]+ , specification spec+ ] +@++To be honest, this is not the best dataset to use here, as+there is no direct correlation between location (the @RA_ICRS@+and @DE_ICRS@ fields) and the other columns, but it's the+dataset I chose, so we are stuck with it.++Once you have sub-plots as a specification, you can combine+them horizontally and vertically to make a dashboard style+visualization. Interested parties should check out the+<https://github.com/gicentre/elm-vegalite/tree/master/docs/walkthrough#building-a-dashboard-1240 Building a Dashboard> section of the+Elm Vega-Lite Walkthrough for more details.++-}++splomPlot :: VegaLite+splomPlot =+ let enc = encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color [ MName "Cluster", MmType Nominal ]+ + spec = asSpec [ gaiaData+ , mark Point [ MSize 5 ]+ , enc [] ]+ + fields = [ "RA_ICRS", "DE_ICRS", "plx", "Gmag" ]+ + in toVegaLite+ [ repeat [ RowFields fields, ColumnFields fields ]+ , specification spec+ ] +++-- $intro-interactivity+-- Interaction is enabled by creating /selections/ that may be combined with+-- the kinds of specifications already described. Selections involve three+-- components:+--+-- * __Events__ are those actions that trigger the interaction such as+-- clicking at a location on screen or pressing a key.+--+-- * __Points of interest__ are the elements of the visualization with+-- which the interaction occurs, such as the set of points selected+-- on a scatterplot.+--+-- * __Predicates__ (i.e. Boolean functions) identify whether or not+-- something is included in the selection. These need not be limited+-- to only those parts of the visualization directly selected through+-- interaction.++{-|++The next several plots show different types of selection -+select a single point, a range of plots, or follow the mouse - and+all have the same basic structure. To avoid repetition, and mistakes,+I am going to introduce a helper function which creates the+plot structure but without the selection definition, and then+use that to build up the plots.++The helper function, 'selectionProperties', takes two arguments, which are +the selection name and the plot title. The selection name is used+to identify the selection, as a visualization can support multiple+selections, and the plot title has been added mainly to show some+minor customization (the use of 'TOrient' to move the title to the+bottom).++The definition of this helper function is:++@+selectionProps selName label =+ let posOpts field = [ PName field+ , PmType Quantitative+ , PScale [ 'SZero' False ]+ ]++ enc = encoding+ . position X (posOpts \"Gmag\")+ . position Y (posOpts \"plx\")+ + . color [ 'MSelectionCondition' ('SelectionName' selName)+ [ MName \"Cluster\", MmType Nominal ]+ [ 'MString' "grey" ]+ ]+ + . 'opacity' [ MSelectionCondition (SelectionName selName)+ [ 'MNumber' 1.0 ]+ [ MNumber 0.3 ]+ ]++ . 'size' [ MSelectionCondition (SelectionName selName)+ [ MNumber 40 ]+ [ MNumber 5 ]+ ]+ + trans = transform+ . 'filter' ('FExpr' \"datum.DE_ICRS < -20\")+ + in [ gaiaData+ , trans []+ , mark Point []+ , enc []+ , title label [ TOrient SBottom ]+ ]+@++The three non-selection-related features added here are that+'SZero' is used to tell Vega Lite that we do not need 0 displayed+on either axis, which leads to a \"tight\" bounding box around+the data, a 'filter' is used to select a subset of rows, namely+only those with a declination less than -20 (via 'FExpr'),+and the plot title is moved to the bottom with 'TOrient'.++The main change is that the selection is used in the encoding section,+identified by name, using 'SelectionName' and the supplied+argument. It is used as a filter for the encoding section, where+'MSelectionCondition' defines the properties to use+when the selection occurs (the first list of properties) +and when it does not (the second list). This is used for+three different encodings:++ - 'color', where the selected star is labelled by its+ cluster color, and all the other are grey;++ - 'opacity', so that the selected star is fully opaque+ whereas un-selected stars are partially transparent;++ - and 'size', so that the selected star is much bigger+ than the others.++When no selection has been made - such as when the visualization+is first created - then all points are encoded with the+\"selected\" case (so colorful, fully opaque, and large in this+case).++-}++selectionProperties ::+ T.Text+ -- ^ The selection name+ -> T.Text+ -- ^ The title for the plot+ -> [PropertySpec]+selectionProperties selName label =+ let posOpts field = [ PName field+ , PmType Quantitative+ , PScale [ SZero False ]+ ]++ enc = encoding+ . position X (posOpts "Gmag")+ . position Y (posOpts "plx")+ + . color [ MSelectionCondition (SelectionName selName)+ [ MName "Cluster", MmType Nominal ]+ [ MString "grey" ]+ ]+ + . opacity [ MSelectionCondition (SelectionName selName)+ [ MNumber 1.0 ]+ [ MNumber 0.3 ]+ ]++ . size [ MSelectionCondition (SelectionName selName)+ [ MNumber 40 ]+ [ MNumber 5 ]+ ]+ + trans = transform+ . filter (FExpr "datum.DE_ICRS < -20")+ + in [ gaiaData+ , trans []+ , mark Point []+ , enc []+ , title label [ TOrient SBottom ]+ ]+++{-|++The actual plot just requires the selection information to be+defined and then added to the plot properties:++<<images/vl/singleselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEDsDKQ4gV6DtoABPAxUfTIEzBUZKIEaGBhQX4YjUW5mT4iKg06BgeBgIwmMzPSCYUjJGVQSLoDzoHDCyzJBL0fl2dZQBLkTBWhwOSDFeDkZg8z7BWBUDmUx02xIWukUiXWx0kbXkNmfARu6pPMNO6lUWn0-RMllUNnA-1QTnc05GkyuyCJgGOk1J0gALw9YGILrddYArBqEogg2mJc7Xe66AAWOQa5OpkPXZmsoU5qDoAzwOJhX3dxt9-ByNiEtuBsJd+s9pt0brD+Up4MMz4Zyf-aeQD57sjy6NQI7wE7DuKuuvEWuwdB0VCurEQJ5lydaQAAjswSB0jYdKlEoN5LvekZPoYdxXJA4KfjsP5-vgAHkEBGr5mBkHQWETCkPB5ZgJWkDtmQJwSgCihAA Open this visualization in the Vega Editor>++@+let selLabel = "picked"+ sel = 'selection'+ . 'select' selLabel 'Single' []+ +in toVegaLite (sel [] : 'selectionProperties' selLabel "Select a point")+@++The 'selection' function is used to define the selection, via one or+more applications of the 'select' function. The form of 'select' is+that the selection is named, in this case we use @\"picked\"@, and the+type is given (a 'Single' click), and then options, which in our case+there aren't any, so an empty list is used.++Note that @hvega@ does not track the selection names, and will allow+you to use a name that you have not defined.++-}++singleSelection :: VegaLite+singleSelection =+ let selLabel = "picked"++ sel = selection+ . select selLabel Single []+ + in toVegaLite (sel [] : selectionProperties selLabel "Select a point")+++{-|++The only change here is to add a property to the selection - that+is @'Nearest' True@ - which means that the nearest point to the+click will be highlighted.++<<images/vl/nearestselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEDsDKQ4gV6DtEHNYFRqnQ4MwqM8YABPAxUfTIEzBUZKIEaGBhaX4YjUW5mT4iKg06BgDnabnaowmMyCzCkZJqqCRdAedA4WWWZIJeiSuzrKAJciYV0OByQYrwcj8-TBLlCyk+92JZ10ilKt0+khm8hsz4CQPVJ7x33Uqi0+n6Jksqhs4ERqDQEViz5TLAmAOQLMAn327OkABeVbAxH9gc7AFZBQlENH80q-QGg-gACxyQU5vOx67M1ky0tQdAGeBxMJhsc9ydgORsQmDqNhUdd8e9ujdOea3MxhmfQsr-5ryAfS9kTUpqBHeAnHOcQBp2xAdrA6B0KgAaxEC5aVvoACOzBIHSNh0qUSjvruX5Jr+hh3FckDgiBOzgZB+DQeQsGChWopIShphhEwpCYU2YAtpAQ5kCcSoAooQA Open this visualization in the Vega Editor>++@+let selLabel = "picked"+ sel = selection+ . select selLabel Single [ 'Nearest' True ]+ +in toVegaLite (sel [] : selectionProperties selLabel "Select nearest point")+@++One consequence of this change is that once a point has been selected you+can not remove this (i.e. un-select the point). This is in contrast to+'singleSelection', where clicking on an area with no stars would remove the+previous selection. The 'Clear' property can be added to the list+to define a way to clear the selection.++-}++nearestSelection :: VegaLite+nearestSelection =+ let selLabel = "picked"++ sel = selection+ . select selLabel Single [ Nearest True ]+ + in toVegaLite (sel [] : selectionProperties selLabel "Select nearest point")+++{-|++The selection can easily be changed to allow multiple stars+to be selected, using shift-click, by swapping from 'Single' to 'Multi'.++<<images/vl/multiselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEDtwqRkGBmWASTFoGB4GByPALi58MRoABPAxUfRYZiUUhKIEaGBhUaMqi3MyfESuUioLlxPFxHRgaDoMDUqi0sBGEzLK6QTCkZLqqCRdAedA4eWWZIJegmE5C9ZQBLkTB2QOWYrwcjMCWfYKwKgiykOSwJRC+ukUgMplMkB3kej6ATR6pPcMOSBm2n0-RMllsjnVbm8-lUFzAnNQUXi07ukxRyDlgEpz0V5CkABesbA9hzkEj0enAFYOxW0xma0L51GY3QACxyZ6VtvmzMMz511ksxtcnl8gVKQOjyzoAzwOJhJPZucL3f4ORsISq6pokG5ZjO26LnQ3RHlWZ61lq9bXpyzb3m2j4jqukAfBBZBtoWnxHPAJywXEUbTsQU6wOgdCoFGsRAl2YrTpAACOzBIHSNh0qUShYV+uH5gR1x3La4LkTsVE0fgdHkAxR7dix7GcWETCkLxw5gKOkBpmQ-ozgCihAA Open this visualization in the Vega Editor>++@+let selLabel = "this is just a label"+ sel = selection+ . select selLabel 'Multi' []+ +in toVegaLite (sel [] : selectionProperties selLabel "Shift click to select points")+@++-}++multiSelection :: VegaLite+multiSelection =+ let selLabel = "this is just a label"++ sel = selection+ . select selLabel Multi []+ + in toVegaLite (sel [] : selectionProperties selLabel "Shift click to select points")+++{-|++We can take advantage of browser event by using 'On' to define which+event to use, such as mouse movement over points:++<<images/vl/eventselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEDsDKQ4gV6DtoABPAxUfRYZiUUhXSAUz5YLKxdClP5AjQwMKjdlUW5mT4AWUlVDA4U1RhMNS16DA1KotLA8DAutMQswpGSKqgkXQHnQOBllmSCXoJhO+HsDkgCXImDs639xXg5GYPM+wVgVA5lIclgSiC9dJFYD9SY2tvIbM+Akj1SeoaTkGNtPp+iZLKobOB2agnO5pxdJgjkFLYABSbd-uQpAAXtHM5Bw5GRwBWZ4BxJpqu+scRqN0AAschnFfTDM+NdZSj7lnQBngcTCCcX45X+DkbEJM5T84zxCvI+6m6oNO31eZ+-+DagD5RzIT98ygI54BOTc4gjEdiGHWB0DoVAI1iIEmy5EdIAAR2YJA6RsOlSiUADIAvYDczAww7iFcFYJ2BCkPwFDyDQmdmyw3D8LCJhSGIntu2BWdEDIH1MwBRQgA Open this visualization in the Vega Editor>++@+let selLabel = "picked"+ sel = selection+ . select selLabel Multi [ 'On' "mouseover" ]+ +in toVegaLite (sel [] : selectionProperties selLabel "Move the pointer to select a point")+@++The supported list of events is described in the+<https://vega.github.io/vega/docs/event-streams/#selector Vega Event-Stream Selectors> documentation.++The addition of @Nearest True@ to the list of properties+sent to 'select' would avoid the flickering, as the mouse moves+between the stars.++-}+eventSelection :: VegaLite+eventSelection =+ let selLabel = "picked"++ sel = selection+ . select selLabel Multi [ On "mouseover" ]+ + in toVegaLite (sel [] : selectionProperties selLabel "Move the pointer to select a point")+++{-|++The final 'Selection' value is 'Interval',+which lets you drag a rectangle to select the interior points:++<<images/vl/intervalselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEDtEPAsCZgmBSMgwK5tPQdtAAJ4GKj6Ew1YrwFz-YEwMKjPlUW5mT4cBBs+BgWBUWlIYKjMDQdBgala6BgIyi5BXSCYUjJJVQSLoDzoHBAjSQZIJeisuzrKAJciYX0OByQcXkZjCz7BTX8ykh-2Jb10in4ewJja28i8z4CCPVJ5+kOQY20+mnZms9mc7mwXnAjMwQVRqBTFlMlxFsAAkNu4vIUgALxb6eL4cjdAArA3QwlEMny2mwxKJ-gACxyZ4lqg0lMMz5M9tsjlcnlKP190PoAzwOJhONprvLiMtuRsQkzyxzhepsDEcctt0W6lnuFZHtWp51uevYzpAHx-iQWY5lARzwCcwFxBKI6QMOsDoHQqASrEQJQAKQr6AAjswSB0jYdKlEosEPghZA7shhh3Fa4JYTsuH4fghHkMRW5kS2kBUTRYRMKQDE9t20pzmQJxpgCihAA Open this visualization in the Vega Editor>++@+let selLabel = "naming is hard"+ sel = selection+ . select selLabel 'Interval' [ ]+ +in toVegaLite (sel [] : selectionProperties selLabel "Drag a rectangle to select points")+@++-}++intervalSelection :: VegaLite+intervalSelection =+ let selLabel = "naming is hard"++ sel = selection+ . select selLabel Interval [ ]+ + in toVegaLite (sel [] : selectionProperties selLabel "Drag a rectangle to select points")+++{-|++The default interval option is to select a rectangle, but it can be restricted -+such as to select all items within a range along a given axis+using 'Encodings':++<<images/vl/intervalselectiony.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEHZ1lBEPAsCZgmBSMgwNUKOQwK5tPQdskEvR2cg6ARIABPSBqKDQGUGKj6Ew1YrwFwAiBAjQwMKjHbUW5mT4cBAc6DoHlUGnQMBGdXcyIyx3aLXkeD3Z6QTCkZJmqCRdAedA4PWWUXocWIE74ewOSAJciYRkOJOa8jMVWfYKwKhy4EZ5OJcV0ikJpklsh24WfATZ6pPatJ6lUWn006s9mc7m88j8wWwYXFjOK5W55nhkxayCtnUOSNt0gALyniZLWZzdAArGPLAlEOWuwnINupwAWOS+9udyvMntxvs8umDgVCpRM5eWdAGeBxGEcpVuOUAXnQchsISB5QEeJ4PsQ4H4N0t52h2FYMp8LJss+XKvnyH4jl+GY-lAHxgMQtbkPWUBHPAJy3nEWobpA66wOgdCoFqsRAhOKr6AAjswSB0jYdKlEoY6yjsVE0YYdxXJA4LMTsbEcfgXHkDxvpKvxnxCSJYRMKQEmLsupaIGQ8YUQCihAA Open this visualization in the Vega Editor>++@+let selLabel = "naming is still hard"+ sel = selection+ . select selLabel Interval [ 'Encodings' [ 'ChY' ] ]+ +in toVegaLite (sel [] : selectionProperties selLabel "Drag to select points by parallax")+@++We'll come back to further things to do with interval selections+when we get to interactive plots below (see 'bindScales').++-}+++intervalSelectionY :: VegaLite+intervalSelectionY =+ let selLabel = "naming is still hard"++ sel = selection+ . select selLabel Interval [ Encodings [ ChY ] ]+ + in toVegaLite (sel [] : selectionProperties selLabel "Drag to select points by parallax")+++-- $intro-selection-transforms+-- Simple selections as described above create sets of selected data marks+-- based directly on what was interacted with by the user. Selection+-- transformations allow us to /project/ that direct selection onto other+-- parts of our dataset.++{-|++For example, we can adjust the visualization to select all stars in the+same cluster, which is useful in this case since the Blanco1 and+IC2391 clusters occupy the same space in the magnitude-parallax+plane.++This is invoked simply by adding the 'Fields' constructor to the select+parameters naming the fields onto which we wish to project our selection.+Additionally, we have set the default selection with 'Empty' so that if+nothing is selected, the selection is empty+(as we have previously seen, without this the default selection is the+entire encoded dataset).++<<images/vl/transformselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEHZ1tdSHE9Ph7A5LIg5rAqNU6HBmFRgZzIFQsAZoABPU6JKiUzlQaUGeWfZAmYKjBWishUcj0ZB0AiQATkGI1SDKJkAiBAjQwMJa9kwKi3MyfER6qi0sDwMBGEzQZ7U73QX1gOJm6pPKCYUjJd1QSLoDzoHB2yzJBL0DWM0UJciYPOKyDFeBm1VQYK8mUihyQBKIHN0inO3X6-Sm80xyAh2n0-QGFl6Z4wKUq2VYEzlpTWuu90gAL0rxDLFboAFZR43mwPnWuhXQACxyUd9lsMz5D1lKDP19AGeBxMIy-flw-4ORsQnbxK71tgKu76Vt0Z5ev2AGGMOt7zh8gEkPGHafEc8AnGecTliukDLrA6B0Kg5axECSrjpWkAAI7MEgdI2HSpRKPOr7we29CDncVy9hhTrwTheH4AR5BEaOypkZR1FhEwpD0TaYB3g2iRkCc7IAooQA Open this visualization in the Vega Editor>++@+let sel = selection+ . select "pick" Single [ 'Fields' [ \"Cluster\" ]+ , 'Empty'+ , Nearest True+ ]+ +in toVegaLite (sel [] : selectionProperties "pick" "Select a point, select a cluster")+@++-}++transformSelection :: VegaLite+transformSelection =+ let sel = selection+ . select "pick" Single [ Fields [ "Cluster" ]+ , Empty+ , Nearest True+ ]+ + in toVegaLite (sel [] : selectionProperties "pick" "Select a point, select a cluster")++-- $intro-selection-binding+-- Selection need not be limited to direct interaction with the+-- visualization marks. We can also /bind/ the selection to other+-- user-interface components.++{-|++The Elm Vega-Lite walkthrough uses a dataset which has a+column for which a range-slider makes sense. The dataset I'm+using is less rich, and so I am going to use a HTML select+widget - a drop-down list of values - instead. This lets+the user select all stars from a given cluster, and is+introduced with the 'Bind' and 'ISelect' constructors.++The 'InOptions' list is given the values of the Cluster column that+can be selected: I start with a value not in the list (@none@) just to+indicate that no values are selected, and then the list of clusters in+this sub-sample (remembering that 'selectionProperties' applies a+declination cut off). Eagle-eyed readers will note that the cluster+names in this list (the @clusters@ variable) end in spaces: this is+because the input data file has the cluster names stored in an+eight-character field, even though it is a tab-separated file.+This surprised me when I first tried this visualization, and+using the value \"Blanco1\" did not select anything! Isn't working+with data so much fun!++<<images/vl/widgetselection.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoAY3SIyAczrEARvE0BrPbHTNE9OpCNVSeqkvURIWeLDP2ADuikiNCQ7gxM8IYaHsyw5PYAFtDQfsi4APTpCADubHqk0AnMRszINNrBVMFs2ljpHNZ6AEKxZlTpCQBuVHrw6V7I1LAd3b3pjNB9vaTwUvCzAGwAjAtzS3JSk0bkVEvwbIjoUglU8PQ0bNDInaHRUBjYTIaQft5lzwDiXgb4kIisjloqigfnIAA97P8sIDQlAqDxQRDflCYYpFBpFGFIAASZCaE5eRLJVIZdKjfb5QrFNikdDpPEEvrkqTkArtToAZjYACtkDpbh4yjtNNBaYgohAPH5SOYqHZ8KBJZLIFQsH5oABPSE6VxhJUOILysCKpXKgTkUpDCWm-VBPzMEK-IVUEUCm3K9DqsXIOgEP462GQJrkJDaJZQYGQQQyDkATnDEag0YWchkHkjADkPgIZAAWACs4cgyjuSvRNsxpagmr8ridQT0Ozd+rIVHI9B9+D95stNGLd3LYErHlF0CbCpgVDBjqgAAUdvAymBnSKwPAwJoLYM+5HMKQqjOHOhkugcMO4YhtPQG9aPNpyJhb8rOvALXWoJYqFq9cqKtfRfyCpVh4rbtvYPbbkCwFQCuAHir80qynYP76jW77+lgQSvpAVaDhA56CqQABe77EC+b50PmkZ-gUYrPORzDvrmciRrBdEITKbR2GiP6QJ6pgFFqE4Me+chsBy1E6P+7HGpAIl0EsrFti6cH+JxcpKARUBIrJoFGpAXzwAYrGaK+pGQCRVh0Kgr5lJi1YarW9gAI7MEgo5MKQ3RuHckBCbp+5gQh4KBniZnPJZ6DWbZVD2TAjnoa57kFJ53mDuiihAA Open this visualization in the Vega Editor>++@+let picked = "picked"++ clusters = [ \"none\", \"Blanco1 \", \"IC2391 \", \"IC2602 \", \"NGC2451 \" ]+ sel = selection+ . select picked Single [ Fields [ \"Cluster\" ]+ , 'Bind' [ 'ISelect' \"Cluster\" [ 'InOptions' clusters ] ]+ , Empty+ ]++ conf = configure+ . configuration (Background "beige")+ +in toVegaLite (conf [] :+ sel [] :+ selectionProperties picked \"Please select a cluster\")+@++Note that the selection works both ways: the HTML widget can be used+to select a cluster, and clicking on a point on the visualization will+update the HTML widget.++Unlike the other plots shown in the tutorial, this is a screen grab+rather than a PNG file created by Vega Embed. The background color was+changed - following the approach used in+'stripPlotWithBackground' - to show where the visualization "ends" and+the HTML select element starts. It also shows the Vega Embed "drop-down"+menu in the top-right corner, namely the three dots in a circle.++-}++widgetSelection :: VegaLite+widgetSelection =+ let picked = "picked"++ clusters = [ "none", "Blanco1 ", "IC2391 ", "IC2602 ", "NGC2451 " ]+ sel = selection+ . select picked Single [ Fields [ "Cluster" ]+ , Bind [ ISelect "Cluster" [ InOptions clusters ] ]+ , Empty+ ]++ conf = configure+ . configuration (Background "beige")+ + in toVegaLite (conf [] :+ sel [] :+ selectionProperties picked "Please select a cluster")++++{-|++The selection can also be bound to an axis (or both axes, as in this+case), using 'BindScales' (applying it to the 'intervalSelectionY' plot).++<<images/vl/bindscales.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoARAUQH0BJAMIAlAMpgAPGAC0AJgAMkAL4BdADTgoWeLADWdSAAd0pRNEjqIkRtHh1QES81jl9AC2jQDyXAHofCAHc2AHNSaFdmACNmZBoAY3RTKlM2BKwfDnRmYIAhJx0qH1cANypg+B8tZGpYItLyn2sK8tJ4KXg2gDYARk727rkpG0jyKm74NkR0KVcqeHoaNmhkYvMNSwxsJjtDbVidgHEtYP1EVkiacygDcgAPU-PL1SgqHhv7-EgzrAvaRUUNIoLFAACTIOKzLRuDxeXw+eoTULhKJsUjoHzgyEVBFSchhQrFADMbAAVshEmtLLFRnFoGjEHZ1tdSHECvQdpETOzPuD4KNkFdIMkEvQTMEBfgCJAAJ6C+5qKDQaUGKj6Ew1Yp8pSA4EwMKjHbUW5mT4cBDBMCYMAAL3Q6CwYHCVDA8FuVAFz0gmFIyRNUEi6A89qUuuF6FFiBO+HsDkgCXImEZDljmvIzFVn2CsCosuBybjiVFdIp0aZ+bIVHI3KgAjT1SeZdj1KotPp+gMLLZlOTsaVKtO9pMWsbAOTQKZkGQpGtGbAxFT6boAFZPQlEEW29HIAvZwAWOSe5utkvM1lUdn-PNQdAGeBxMKyrc7uhyNiE1eFsKbufbvmL-DdIelYtsWDKfB2Z4XuO+YfD+FZVvoRzwCch5xHys7EDOsDoHQqB8rEQKKsqs6QAAjswSB0jYdKlCGE6PnBPoIeBdyCryBpblhOH4Hh5AEZ6fYkeRlFhEwpC0aOYDQVAa5kFGc4AooQA Open this visualization in the Vega Editor>++@+let picked = "picked"++ sel = selection+ . select picked Interval [ Encodings [ 'ChX', ChY ], 'BindScales' ]+ +in toVegaLite (sel [] : selectionProperties picked "Drag or zoom the axes")+@++The image here was created after panning and zooming into the data.++-}++bindScales :: VegaLite+bindScales =+ let picked = "picked"++ sel = selection+ . select picked Interval [ Encodings [ ChY, ChX ], BindScales ]+ + in toVegaLite (sel [] : selectionProperties picked "Drag or zoom the axes")+++-- $intro-coordinated-views+-- One of the more powerful aspects of selection-based interaction is in+-- coordinating different views – a selection of a data subset is projected+-- onto all other views of the same data.++{-|++The following plot doesn't contain anything new, but allows us to+select a rectangular-range on one plot, and see the same selection+automatically applied to the other plots. This is achieved by+combining the 'repeat' fuction with the 'selection'; this causes the+selection to be projected across all views as it is duplicated.++For this example we use all the clusters, rather than the subset of+Southern ones. One trick I use is to convert the Right Ascension+values (which have a domain of 0 to 360 degrees, and wrap around at+the 0\/360 mark), into their cosine values (remembering to convert to+radians first), and display that instead. This ensures the \"Blanco1\"+cluster members are spatially co-located on this axis - with values+close to 1 - rather than appearing near 0 and 360.++<<images/vl/coordinatedviews.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEBOCmAOsCGAXSAuMwYHsDuGYA2pAMY4DOASgIKQA0UAIgKID6AkgMJUDKkAXUZkcAGwCuAWwB2hEvFEAPBlADikpAHNBAX3rgoFRKUKgIESCmhJpFAGY5okuQfNZISCoRHU6w0kiipOKiqLDe5BQAFAAmqFIAdLScPLxgAFRgAAocYAD0YACMABwADACUkDquYEI1kBrQANYRAJbQpKLh+m6QcShIpjUW4tCi3gAWKCjwFOh5edZ4CZqtKBPiAEbiFLAdONIosIcJ5JJ5TDjimgBCo02weRMAbrCaSHkaFEfQT6-veX6H3erSQAFokOCAGyFKEQwqlMEDTZdQpIBLSHBgibIGJ7BIoCjPBjDKAOJyoIZuXrwJDQXamSDqLTeaRSTZ7FSQBTKTCQNmSDnQLmwNg81nsznValgaXmPT1XZdUgoVoHRnwVqkB4xRkoACeiG8rUOe2egSqCt6x3IMRN2kwZmpIlEjipMqg5ok4T5mjg+pJHqg5GkdtV6sdpN6dlasFEur5XAk305PSDhjjsBVatkfM12tgurTQcshp9UExkhNFqjstJVudvPcMbjCfccEQlL55AkMiqwgNRr5AEdxDZVQNVa9+6TIAHHZAW-HGR3kGg+dB8P2oIPy5BR+O1qhWtO5RA5Q3IAASCikHEaSbTWbzPL-dGrdZbBJqvK3+8fN8wVENZHmeABmBIACsKHVNMRGkGMHSwaodCAA Open this visualization in the Vega Editor>++@+let enc = encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName \"picked\")+ [ MName \"Cluster\", MmType Nominal ]+ [ MString \"grey\" ]+ ]++ sel = selection+ . select \"picked\" Interval [ ]++ trans = transform+ . calculateAs "cos(datum.RA_ICRS * PI / 180)" "cosRA"++ spec = asSpec+ [ gaiaData+ , trans []+ , mark Circle []+ , enc []+ , sel []+ ]++in toVegaLite+ [ repeat+ [ RowFields [ \"cosRA\", \"DE_ICRS\" ]+ , ColumnFields [ \"plx\", \"Gmag\" ]+ ]+ , specification spec+ ]+@++-}++coordinatedViews :: VegaLite+coordinatedViews =+ let enc = encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName "picked")+ [ MName "Cluster", MmType Nominal ]+ [ MString "grey" ]+ ]++ sel = selection+ . select "picked" Interval [ ]++ trans = transform+ . calculateAs "cos(datum.RA_ICRS * PI / 180)" "cosRA"++ spec = asSpec+ [ gaiaData+ , trans []+ , mark Circle []+ , enc []+ , sel []+ ]+ + in toVegaLite+ [ repeat+ [ RowFields [ "cosRA", "DE_ICRS" ]+ , ColumnFields [ "plx", "Gmag" ]+ ]+ , specification spec+ ]+++{-|++If the interval selection is bound the the axes with 'BindScales'+then we can zoom and pan the related plots - i.e. changing the+range displayed in one plot will also change the two plots that+it shares an axis with in this two by two arrangement. The conditional+encoding of the 'color' channel has also been removed.++<<images/vl/coordinatedviews2.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEBOCmAOsCGAXSAuMwYHsDuGYA2pAEoCCA+gJIDCpAypADRQAiAojfUwLquQAxjgA2AVwC2AO0Il4IgB4soAcQlIA5pF4BfZuCgBnRIMKgIESOugBrQkICW0QSNgsDlgCaokZjxcgxaBF7AAsUFHhDdAB6GOgkPAA6DQcUULEAIzFDWGccKRRYQqThCRi2HDENACEgm1gY0IA3WA0kGPVDIugm1vaY7xQO9ockAFokCYA2AEZpydmABnHhzNdZpCSpHHHQ5E88pJRDZvcLAIAzHGh1NExzC4D4JGhcs0g1TXspSUy85SQeRKTCQX4Sf7QQGwSjAn5-AE6fwQJEXPT+SC5VyCFAOAofeAOQQNTwfTIOKSk0GGQRIVyGQEoACeiHsFJ6zTpkB06IukGKwk8FK0D2RUGEIhuH0uDlgIipUFo4m6AIEzNZoJ2EgpXN5T0gIKwkBlcoV2DgiFQ9glkhkeig6rcoIAjmIkIU0qgHK1ufonlAmdLZfKPhbkPcoNB8L6HSynVBXe7ccNcT7URZ03rIAASGn7dRhCJRWIxfpbVLpLJJPExPOwdSltoTERpRrNADMSQAVoZ8X7xQUZSKsEidEA Open this visualization in the Vega Editor>++The image was captured after panning and zooming in the+\"parallax-RA_ICRS\" plot.++@+let enc = encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color [ MName \"Cluster\", MmType Nominal ]++ sel = selection+ . select \"picked\" Interval [ BindScales ]++ spec = asSpec+ [ gaiaData+ , mark Circle []+ , enc []+ , sel []+ ]++in toVegaLite+ [ repeat+ [ RowFields [ \"RA_ICRS\", \"DE_ICRS\" ]+ , ColumnFields [ \"plx\", \"Gmag\" ]+ ]+ , specification spec+ ]+@++The \"cosine\" transformation has been removed in comparison to+'coordinatedViews'.++-}++coordinatedViews2 :: VegaLite+coordinatedViews2 =+ let enc = encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color [ MName "Cluster", MmType Nominal ]++ sel = selection+ . select "picked" Interval [ BindScales ]++ spec = asSpec+ [ gaiaData+ , mark Circle []+ , enc []+ , sel []+ ]+ + in toVegaLite+ [ repeat+ [ RowFields [ "RA_ICRS", "DE_ICRS" ]+ , ColumnFields [ "plx", "Gmag" ]+ ]+ , specification spec+ ]+ ++{-|++The ability to determine the scale of a chart based on a selection is+useful in implementing a common visualization design pattern, that of+'context and focus' (or sometimes referred to as 'overview and detail+on demand'). We can achieve this by setting the scale of one view+based on the selection in another. The detail view is updated whenever+the selected region is changed through interaction:++<<images/vl/contextandfocus.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAmCGAutIC4yghSBXATgGxSgAt54AHAZ2QHpqdYB3AOgHMBLeIrAIywoFMcAYwD2AO3j8JTUQFtqAERFYWAIVwBrftSIA3fi1jVZsCpJw79h6nETVDbWAFpYzgGwBGNy48AGJ4jcePwesExiIk5E-LDQgkzwFLqQADTgGJAAZiI4JvCEwJBksDgCBZAA4iYshJBiWLLcgqlQZHgAHrX1jc0pUPwA+m2dqHUNTTiQAL5T6VNpmLqiYkIIhADa6RDoGJjRbCwkhAAcvgu7UCY4GrVkImwSqVsZDGzQnIQALL5nz5gCwSE8DY4nK3BwfCI5SkomgDxYFA2kAAnpAALp9SDwZFkfi1B7mXSwAgzc67LEcYK1ADK-EB8DAsDAAE0wPQxCx+GB4CIwAAvEQiWRgB5gJp4EQMJ4XforERwjkFP4ZEZoZXkzJsOnQWpVWA1MkyqAUVZU1CFPmCESETLEgTzdUZbG42oARywsAkHAQbH0kEdDqNUFR5qyWrwOtGwxaWJxeNG7s9wMQwL9sxl6YwgYwO3JVxuUfuj0NmFe7yhqG+vxlkBh8vhSqDkFEEsmoc12tqAGE8HxzDHnfGoBFZA9idMSyrG0GoB2I7rqtKZ5ATcShxarTa7fxs03B26PV6U768ZPybB2mxEaHk2awPU8HhMxmz8Hp0255HWh0l03V3fCmgIVYAecoAX4IEQTEWpwUhaZdyNWMXQTQ9kx9P0A2VZ8wEzDF0kgAASE1ohMWoSHIKhaCsMJ2E4HgmBBahiP4ExqGopw8A4bRdAAZiYAArChQXOZtxE1GpzVmKYgA Open this visualization in the Vega Editor>++@+let sel = selection . select \"brush\" Interval [ Encodings [ ChY ] ]++ encContext = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, PScale [ SZero False ] ]+ . position Y [ PName \"plx\", PmType Quantitative ]++ specContext = asSpec [ width 400+ , height 80+ , sel []+ , mark Point []+ , encContext []+ , title \"Select a Y range to zoom in below\" []+ ]++ encDetail = encoding+ . position X [ PName \"Gmag\"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ 'AxNoTitle' ]+ ]+ . position Y [ PName \"plx\"+ , PmType Quantitative+ , PScale [ SDomain ('DSelection' \"brush\") ]+ ]+ . color [ MName \"Cluster\", MmType Nominal ]++ specDetail =+ asSpec [ width 400, mark Point [], encDetail [] ]++in toVegaLite+ [ gaiaData+ , vConcat [ specContext, specDetail ]+ ]+@++Not shown here, but selecting a range of y-values in the top plot+(@specContext@) will cause the second plot (@specDetail@) to zoom+in on that range, as the selection is bound to the y axis of this+plot via 'DSelection'.++-}++contextAndFocus :: VegaLite+contextAndFocus =+ let+ sel =+ selection . select "brush" Interval [ Encodings [ ChY ] ]++ encContext =+ encoding+ . position X [ PName "Gmag", PmType Quantitative, PScale [ SZero False ] ]+ . position Y [ PName "plx", PmType Quantitative ]++ specContext =+ asSpec [ width 400, height 80, sel [], mark Point [], encContext []+ , title "Select a Y range to zoom in below" []+ ]++ encDetail =+ encoding+ . position X+ [ PName "Gmag"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ AxNoTitle ]+ ]+ . position Y [ PName "plx"+ , PmType Quantitative+ , PScale [ SDomain (DSelection "brush") ]+ ]+ . color [ MName "Cluster", MmType Nominal ]++ specDetail =+ asSpec [ width 400, mark Point [], encDetail [] ]+ + in+ toVegaLite+ [ gaiaData+ , vConcat [ specContext, specDetail ]+ ]+++-- $intro-crossfilter+-- The final example in this section brings together ideas of view+-- composition and interactive selection with data filtering by implementing+-- /cross-filtering/: the selection of a subset of the data in one+-- view then only displaying that data in the other views.++{-|++Here we show distributions of the four main numeric quantities+in the dataset - position, magnitude, and prallax - using the+@totalEnc@ encoding, and add a second layer which repeats this+data but with a different color (@selectedEnc@), and that is tied to+the interval-selection along the x axis ('ChX').++<<images/vl/crossfilter.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEBOCmAOsCGAXSAuMxIGMD2ANgK4C2AdhmANqQBKAggPoCSAwrQMqQA0UAIgFEW7Lr0gBxEkgDmPKPAIAPSAF0Avt3BQAzohyVQECJAAmqJAa1GoRaAUqQAFihTxt6APQfoSAO4A6aQBLFEciACMibVhofDIUWHj-fBIPPjwiaQAhWwBrWA9HADdYaSQPKW0E6EKSso8zFHKyoKQAWiR2gDYARi6OnoAGNqbwglgepH8yPDbHZBMY-xRtIp4rI0gAMzxoKTRMQ2tN+CRoaIMJKVlMSDJScJi5SAVlW-uSR+hn2EZXhw+X0gag2EBB1g0G0gBCQAE8npgqKCsMjjFJoLkHOEzutjptEvgTEEyDcUXjrJA3lhtkFYAQTJc4IhUA58MRyMCxChYYgHABHIhIeIhVBBEqc1GbWGXGTSOBlBKsjLxZ7c3m3AVClAi7Xi8Hk-UQzR4o54yAoHxkbQ7PaUKjYLZBAjVS7RcY4bV4Ci3cLQKKOYFqFTG8mQdGYn04kNmt2wD1BL2XX3+y4EvBEknaO2U1RcnmwBzE6pFJD2NSQ8lQNMZ0mm0Ns3aXEvEAu3aSERZkaDpiWV4xUh20+mMhDIA5QNmkCgaKBq1tQTXCpq6gsVvuQaWHSCy+Woee4ZVoPPqheCpeivWSw1Ga8qLRryAAEm0OHmUgczlc7i8dSmwVCET+AmHgvm+5S-m0BAhAURQAMz+AAVtoiYhgeZCOrWIJqEAA Open this visualization in the Vega Editor>++Selecting a small range of parallax values in the fourth plot+highlights the associated data in the other three plots.++@+let sel = selection . select "brush" Interval [ Encodings [ ChX ] ]++ filterTrans = transform . filter ('FSelection' "brush")++ -- borrow a function from Elm+ pQuant = PmType Quantitative+ + totalEnc = encoding+ . position X [ PRepeat Column, pQuant ]+ . position Y [ PAggregate Count, pQuant ]++ selectedEnc = totalEnc+ . color [ MString "goldenrod" ]+ +in toVegaLite+ [ repeat [ ColumnFields [ \"RA_ICRS\", \"DE_ICRS\", \"Gmag\", \"plx\" ] ]+ , specification $+ asSpec+ [ gaiaData+ , layer+ [ asSpec [ mark Bar [], totalEnc [] ]+ , asSpec [ sel [], filterTrans [], mark Bar [], selectedEnc [] ]+ ]+ ]+ ]+@++-}++crossFilter :: VegaLite+crossFilter =+ let+ sel =+ selection . select "brush" Interval [ Encodings [ ChX ] ]++ filterTrans =+ transform+ . filter (FSelection "brush")++ -- borrow a function from Elm+ pQuant = PmType Quantitative+ + totalEnc =+ encoding+ . position X [ PRepeat Column, pQuant ]+ . position Y [ PAggregate Count, pQuant ]++ selectedEnc =+ totalEnc+ . color [ MString "goldenrod" ]+ + in+ toVegaLite+ [ repeat [ ColumnFields [ "RA_ICRS", "DE_ICRS", "Gmag", "plx" ] ]+ , specification $+ asSpec+ [ gaiaData+ , layer+ [ asSpec [ mark Bar [], totalEnc [] ]+ , asSpec [ sel [], filterTrans [], mark Bar [], selectedEnc [] ]+ ]+ ]+ ] ++-- $intro-error+-- Here we dive into some of the ways for representing the spread+-- of a value, focussing on the \"error\" of a variable.++{-|+We have already seen "error bars" in the 'layeredDiversion' plot, where+the 'Rule' type was used to draw a line between the 'Y' and 'Y2'+encodings. In that example the two positions were calculated \"on the+fly\" by Vega-Lite (using the 'Min' and 'Max' aggregation operations).+In this example I use the data to calculate the display range,+namely @plx - e_plx@ to @plx + e_plx@. These are mapped to the+'X' and 'X2' channels (not because it makes a better visualization,+but just to show you can create lines along the x axis), and a+small-multiples approach is used to separate out the clusters, but+only after a filter designed to select the two clusters - with the+\"most interesting\" data for this plot - has been applied.++<<images/vl/errormanual.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1wIxhJUBLAG2gFNY8oATeaAVywDoBhKt5OrAIAGALpgAvBLABybjLAAfRWBbsuvfoJHipsgBIzIAXwA0xCGXjJGkAA5UAHgH0q6SKagBjeFS9sqVlpbNQ5OB0cwAFpVVjDaZwiTcxJSSGtbCOcACwoPb19-QLoQuK4IsABqWPVOBKTjYlEUqCx4WABrW1gA4JbINXhGUFTINlgqW2zoaDtkXAB6BYQAd04AcwpobLYAI356L3REOhPOI6wFgBF0NnWAIXGO2gXsgDdadfgFtoF6V4+XwWgwWXwo8Ci8AhADYAIzQyGw4RRaDwXZUWiw+CcRDoKLZWjwJj0TjQZBvDwWKAYbCsYb2drIYL4MgAcTa61siA4u3o+XsTi5PL5nkg9UF+Eg3KwvIYxkaEDMxEgABJkF4CW0pjM5osFoDsZttntOBR0At1ZrvgaolQti83gBmTgAK2Qx0pEEgTIxXmgZsQ9LsFC8zyY9N2FEQ4cl6t8tBsougAE87MyoFHBG9fCYlV7aIgjkwo5yWVTII4AEz0yi0KgxqBZXLJcuOYZUr21+uZJyudwtUZxjH0gBe9Hc+FQviZedSUBTadsAEc2Eh-aj-R9PXP0o4KDYWTAtsPJXZ2r5ApEABS-ACUJips69Rz4WEDh67Dcgmj+DCTqfTKV0CwKMcyfKBkxrCg6y-dl4E5f9F0lFc1y2VgKC3BUwFnSAjkQShS1IRpjCAA Open this visualization in the Vega Editor>++@+let trans = transform+ . filter (FExpr \"datum.Cluster[0] == \'C\' || datum.Cluster[0] == \'H\'\")+ . calculateAs \"datum.plx - datum.e_plx\" \"plx_lo\"+ . calculateAs \"datum.plx + datum.e_plx\" \"plx_hi\"+ + errorEnc = encoding+ . position X [ PName \"plx_lo\"+ , PmType Quantitative+ , PScale [SZero False]+ , PAxis [ AxTitle "parallax (mas)" ]+ ]+ . position 'X2' [ PName \"plx_hi\" ]+ . position Y [ PName \"Gmag\", PmType Quantitative ]+ . column [ FName \"Cluster\", FmType Nominal ]+ + sel = selection+ . select "picked" Interval [ BindScales ]++in toVegaLite [ gaiaData+ , trans []+ , errorEnc []+ , mark Rule []+ , sel []+ ]+@++For the interested reader, it was the calculation of the @\"plx_hi\"@+column that lead me to the discovery that the columns were being+read in as a string, and the introduction of the 'Parse' option+to 'gaiaData'.++As can be seen, the @e_plx@ terms are generally very small. This is+good for anyone using the data, as we want precise measurements, but +makes it harder for me to come up with meaningful visualizations! I+have taken advantage of the 'BindScales' interaction to zoom in on+a subset of stars which show larger parallax errors:++<<images/vl/errormanual-zoomed.png>>++-}++errorManual :: VegaLite+errorManual =+ let trans = transform+ . filter (FExpr "datum.Cluster[0] == 'C' || datum.Cluster[0] == 'H'")+ . calculateAs "datum.plx - datum.e_plx" "plx_lo"+ . calculateAs "datum.plx + datum.e_plx" "plx_hi"+ + errorEnc = encoding+ . position X [ PName "plx_lo"+ , PmType Quantitative+ , PScale [SZero False]+ , PAxis [ AxTitle "parallax (mas)" ]+ ]+ . position X2 [ PName "plx_hi" ]+ . position Y [ PName "Gmag", PmType Quantitative ]+ . column [ FName "Cluster", FmType Nominal ]++ sel = selection+ . select "picked" Interval [ BindScales ]++ in toVegaLite [ gaiaData+ , trans []+ , errorEnc []+ , mark Rule []+ , sel []+ ]++{-|++Alternatively, I could have made life simpler for myself and used+the 'ErrorBar' (or 'ErrorBand') mark type, together with 'XError'+(or 'YError') to indicate that the channel gives the offset from+the central value. For this visualization I restrict to a single+cluster (since I now know there's only one in this sample which+begins with @C@), but retain the 'column' encoding as a means+to getting a useful title. I've also switched things so that the+errors are back along the y axis.++<<images/vl/errorauto.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJUBLAG2gFNY8oATeaAVywDoBhc55a2AgAwBdMAF5RYAOQdJkAL5CANOChZ4sANZ1INWJgBG6yMoiRG0eHVARTzWOW0ALaNAAOyXAHpPCAO5sAc1JoR2Z9HhoAY3REali2aKxPABF0ZgCAITsNKk9HADcqAPhPNV4aPMLiz3MS4tJ4AFp4JoA2AEZW5vaBRot9cip2+DZEdEbHKnh6GjZoZHzjFVMMbCYrSFd1ZCoNgHE1AO1EVn0aYyhXcgAPY9PzxSgqAH0r2-xIE6wz2jk5FTkJigABJkJFJmonC53F5PFURkEQmE2KR0J4wRCSvDGuRgrl8gBmNgAK2QMSWpioiGi9FIiCO+GsNkgAE8AKKwPS0RkkUhUcj0bQvN7yIGmd5gYhkfmCj4HeBHR4wFmuXYfACOzCQ0GCTFIhVFyyg0W4WEQG2lAu0XB4fAuytVx3QWDp8AcgKNrKsRpWfKtHxFYuZYLdaslkAAXjR0HRUG6dh6bMzoCqw5BNdrdTqDUHTPBrqRkBsddBBtotghyOR82AABRlACU8iN-wgieNMTIDMl-zkQA Open this visualization in the Vega Editor>++@+let trans = transform+ . filter (FExpr \"datum.Cluster[0] == \'C\'\")++ errorEnc = encoding+ . position Y [ PName \"plx\"+ , PmType Quantitative+ , PScale [SZero False]+ , PAxis [ AxTitle \"parallax (mas)\" ]+ ]+ . position 'YError' [ PName \"e_plx\" ]+ . position X [ PName \"Gmag\", PmType Quantitative ]+ . column [ FName \"Cluster\", FmType Nominal ]++in toVegaLite [ gaiaData+ , trans []+ , errorEnc []+ , mark 'ErrorBar' []+ ]+@+-}++errorAuto :: VegaLite+errorAuto =+ let trans = transform+ . filter (FExpr "datum.Cluster[0] == 'C'")+ + errorEnc = encoding+ . position Y [ PName "plx"+ , PmType Quantitative+ , PScale [SZero False]+ , PAxis [ AxTitle "parallax (mas)" ]+ ]+ . position YError [ PName "e_plx" ]+ . position X [ PName "Gmag", PmType Quantitative ]+ . column [ FName "Cluster", FmType Nominal ]++ in toVegaLite [ gaiaData+ , trans []+ , errorEnc []+ , mark ErrorBar []+ ]++++{-|++In this plot the error range is calculated by Vega-Lite,+and is taken from the standard deviation of the @Gmag@ field+('StdDev'). The 'MTicks' and 'MRule' constructors are used to+color the different parts of the error bars. Since the error bar+does not reference the central value, a separate layer is used+to add a square symbol ('SymSquare') at the average ('Mean')+value of the distribution.++<<images/vl/errorbars.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFACYCGKpGYoEEkArgE4A2VMKKADgM7oD0fRqQDuAOkTwU0egCN63WIwDGAewB2KWBtGqAtnwAiK+ogBCTANaw+0AG6xEpPrtLdNjG-cd8yFPo-hSAFpSYIA2AEYwkIicIIoZZlgI0lE1FSC4UmJFURRuW0hCWigAMxVGFzRMYEhOUkYFKlqAcRdENjV6XRlFIqhOZgAPTu7exn7IWAB9QZHMSC6evoBfFaIV4qhheGIpKlwCIkgAEm4lOBc2VC5eAS9UiSlZUXgVPnPLpweg5klrWxYUQAK246iKx2YpAAnn1MABtIgQGglKAuRgWZpI1GQRj0JLNSCqZgVNiaUisTbYkpTIaaDRsNw5QpbVFQFDQziwNiKRgVGQNCFsugoeBKCzcQnE0kLThMQbc9ZsqlsqZqVTEeBqDo1am0SDQwmleCwZjENhtUgdfBQc4U7k1SAAL0UKiopQpCk27M5DqgAEd6KQNJJyPB7JAlaioxAVbQUTT0ZjHdx4C6qAAmAi26CkLmMwMNbk2yAc-OylRatBxmlaDVanXUPV0Q2O42m80LS3WqBWxCMBzkP2QXSwYOTMvDwshiiiiMx2gLqMAXS2avr2sJ82okHbZrYAGFmPJ3BPfZ0VLotRTI3GiepjY3gOsVkA Open this visualization in the Vega Editor>++@+let cluster = position X [ PName \"Cluster\", PmType Nominal ]+ + barOpts = [ 'MExtent' 'StdDev'+ , 'MTicks' [ 'MColor' \"purple\" ]+ , 'MRule' [ MColor \"teal\" ]+ ]+ range = [ mark ErrorBar barOpts+ , encoding+ . position Y [ PName \"Gmag\"+ , PmType Quantitative+ , PScale [ SZero False ]+ ]+ $ []+ ]++ center = [ mark Point [ 'MShape' 'SymSquare', 'MSize' 20 ]+ , encoding+ . position Y [ PName \"Gmag\"+ , PmType Quantitative+ , PmType 'Mean'+ ]+ $ []+ ]++in toVegaLite+ [ gaiaData+ , encoding (cluster [])+ , layer (map asSpec [ range, center ])+ , width 300+ , height 300+ ]+@++-}++errorBars :: VegaLite+errorBars = + let cluster = position X [ PName "Cluster", PmType Nominal ]+ + barOpts = [ MExtent StdDev+ , MTicks [ MColor "purple" ]+ , MRule [ MColor "teal" ]+ ]+ range = [ mark ErrorBar barOpts+ , encoding+ . position Y [ PName "Gmag"+ , PmType Quantitative+ , PScale [ SZero False ]+ ]+ $ []+ ]++ point = [ mark Point [ MShape SymSquare, MSize 20 ]+ , encoding+ . position Y [ PName "Gmag"+ , PmType Quantitative+ , PAggregate Mean+ ]+ $ []+ ]++ in toVegaLite+ [ gaiaData+ , encoding (cluster [])+ , layer (map asSpec [ range, point ])+ , width 300+ , height 300+ ]+++{-|+The next plot shows the 'ErrorBand' mark, which fills the area between+the chosen range with a color, and optional borders. Here the+blue band shows the calculated standard deviation - as used in+'errorBars' - and the gray band with borders shows the inter-quartile+range. On top of these are drawn the median (blue) and median (green+dashed) lines.++<<images/vl/errorband.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFACYCGKpGYoEEkArgE4A2VMKKADgM7oD0fRqQDuAOkTwU0egCN63WIwDGAewB2KWBtGqAtnwAiK+ogBCTANaw+0AG6xEpPrtLdNjG-cd8yFPo-hSAFpSYIA2AEYwkIicIIoZZlgI0lE1FSC4UmJFURRuW0hCWigAMxVGFzRMYEhOUkYFKlqAcRdENjV6XRlFIqhOZgAPTu7exn7IWAB9QZHMSC6evoBfFaIV4qhheGIpKlwCIkgAEm4lOBc2VC5eAS9UiSlZUXgVPnPLpweg5klrWxYUQAK246iKxxQkiSbAAwipdPVGPA1IgwEJUbBuBC6MxSABPPqYADaRAgNBKUBcjAszSmQ00GjYbhyhXwUBQ+M4sDYikYFRkpDUxEgmzJtCmalUxBRHRq4pKkHxdNK8FgzBFCzapA67Mg51IMJqkAAXooVFRSoaFJsOVyeQsAI70IVQihQ+yihVgdYlMUlCmK6m0+WUiUyCo5Rp0tz8qwGVzQKjEsLsgBMAF1-WGoKpmBU2IghMqtmH6YzqlB4I6JqXKZBOdzeYx+YxBcLIN7s4qtNLZc1vXRlcbVerNVBtbqoAajdRTebLdbYLaG-a2M7XZJyPBPb7KXuIN3qN7IMG2H81Dy63ReyoZaiBzmoMPj0+6KONWxJzi3-qlIaHTnM1+UXZgbWvesdSLBxyEA09YBlIUfyfVcmydF0NC3D0eUHH0u3FI9AwlM9jTzAsFmgrRJljFR40TZNUzANN2QAFnTDM9UbOCLx5I8bylO9+1DHMlUfX8P3HSBvwgxUZ0A2pgItTArTA5cZIlKDGBgzQ2F0WAkPUuguPXDC3W3T1cIPWgrL3Djjlve85TneY5wkuFmHkdxJmMhZ0l0FFDVFbNIFUNRVSc4B1hWIA Open this visualization in the Vega Editor>++@+let posY extra = position Y ([ PName \"Gmag\"+ , PmType Quantitative+ , PScale [ SZero False ]+ ] ++ extra) []+ + bands = [ [ encoding (posY [])+ , mark 'ErrorBand' [ MExtent StdDev ]+ ]+ , [ encoding (posY [])+ , mark ErrorBand [ MExtent 'Iqr'+ , 'MBorders' [ 'MStrokeDash' [ 6, 2 ] ]+ , MColor "gray"+ ]+ ]+ , [ encoding (posY [ PAggregate Median ])+ , mark Line []+ ]+ , [ encoding (posY [ PAggregate Mean ])+ , mark Line [ MColor \"green\"+ , MStrokeDash [ 6, 2, 4, 2 ]+ ]+ ]+ ]+ +in toVegaLite+ [ gaiaData+ , encoding (position X [ PName \"Cluster\", PmType Nominal ] [])+ , layer (map asSpec bands)+ , width 300+ , height 300+ , title "Comparing ranges" []+ ]+@++Note that I don't think this is a good visualization+for this /particular/ dataset, since it implies there's a+connection or correlation between clusters, as given by the+x-axis ordering, but the aim here is to show how to use @hvega@+rather than creating sensible plots!++-}++errorBand :: VegaLite+errorBand = + let posY extra = position Y ([ PName "Gmag"+ , PmType Quantitative+ , PScale [ SZero False ]+ ] ++ extra) []+ + bands = [ [ encoding (posY [])+ , mark ErrorBand [ MExtent StdDev ]+ ]+ , [ encoding (posY [])+ , mark ErrorBand [ MExtent Iqr+ , MBorders [ MStrokeDash [ 6, 2 ] ]+ , MColor "gray"+ ]+ ]+ , [ encoding (posY [ PAggregate Median ])+ , mark Line []+ ]+ , [ encoding (posY [ PAggregate Mean ])+ , mark Line [ MColor "green"+ , MStrokeDash [ 6, 2, 4, 2 ]+ ]+ ]+ ]+ + in toVegaLite+ [ gaiaData+ , encoding (position X [ PName "Cluster", PmType Nominal ] [])+ , layer (map asSpec bands)+ , width 300+ , height 300+ , title "Comparing ranges" []+ ]+++{-|++An alternative visualization of a distribution is the \"box and+whiskers\" plot, which can be achieved in @hvega@ with the+'Boxplot' mark. The example below shows the default settings, but+the various components can be controlled with 'MBox', 'MMedian',+'MOutliers', and 'MTicks'.++<<images/vl/errorbox.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAWCmCWBzaAXSAuMBmADDgNOFALYCGATgNYZQBGA9gB4AOANvWoRJACakqkaoCNwCu5VjRgoUzAM7oA9IvKkA7gDpE8FNFG1Rc2OQDG9AHYpYljWeKKAIvVGIAQuMqxF0AG6xEpIpkclbk3n4BinwCigHwpAC0pIkAbACMKUlpOAkCtKywaaQa5vQJcKQ8xhoocj6QXCKQAGb05GRomMCQzBRGQpAA4mSIUuaixLTGDVBsjGMTU+QzkLAA+nMLk9MAvjtEO42QavA8ujS4BESQACRyJnBkUqiyCsoRxdq6+hrw9Ir3R6BD4JVg6Lw+LAaABWcgsDWu1jMPHg5lGXSI3HmXRa8FgrB4UgAwqxDKEVigAJ7MWBjejEVGkSSHTFQSkDZp4glSYakUb4KBUmlSACOolIlh0-Hgfkg+wgLO4ZnMnPRYGA+x2QA Open this visualization in the Vega Editor>++@+toVegaLite+ [ gaiaData+ , encoding+ . position X [ PName \"Cluster\", PmType Nominal ]+ . position Y [ PName \"Gmag\", PmType Quantitative ]+ $ []+ , mark 'Boxplot' []+ , width 300+ , height 300+ ]+@++The 'Boxplot' option supports two different \"ranges\":++ * the default is the Tukey Box plot, where the whiskers span+ a range @Q1 - k * IQR@ to @Q3 + k * IQR@, @IQR = Q3 - Q1@,+ @Q1@ and @Q3@ are the lower and upper inter-quartile values+ (so 25 and 75 per cent of the distribution), and @k@+ defaults to 1.5 but can be changed with 'IqrScale';++ * or 'ExRange', which uses the full range of the data (i.e.+ minimum to maximum values).++-}++errorBox :: VegaLite+errorBox = + toVegaLite+ [ gaiaData+ , encoding+ . position X [ PName "Cluster", PmType Nominal ]+ . position Y [ PName "Gmag", PmType Quantitative ]+ $ []+ , mark Boxplot []+ , width 300+ , height 300+ ]+++{-|++Here I combine 'errorBox' with 'smallMultiples2' so we can compare+the distribution (from the histogram) with that from the box plot.++<<images/vl/comparingerrors.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAmCGAutIC4yghSBXATgGxSgAt54AHAZ2QHpqdYB3AOgHMBLeIrAIywoFMcAYwD2AO3j8JTUQFtqAERFYWAIVwBrftSIA3fi1jVZsCpJw79h6nETVDbWAFpYzgGwBGNy48AGJ4jcePwesExiIk5E-LDQgkzwFLqQADTgGJAAZiI4JvCEwJBksDgCBZAA4iYshJBiWLLcgqlQZHgAHrX1jc0pUPwA+m2dqHUNTTiQAL5T6VNpmBRk-EIF6Zh4sACezagA2usY6BgnkCY4GrXcJamHp1Ki0GxiNajHJ6eieDnlmWz8eGgtQAwng+OYWpB4Ftll0RLJnrACH1IMEWFIgah6ng8PM7h9ICM0Fl-oDalVYDUUdxnoR4DgsPwUdDYaMAI5YWASDgINj6aYLD6nLZrIVCyCUlg4AwIfi1URYCS3MUElly9mc7mIeB8uWClWYWDtNgUco6+DBWoAOXGgjAIkyYAAyohStN8SdZiqvR88UL3gTzpc3h6MrJ+E8ueUvj9RkFYEJLn6DZBuCIiYUzDgRFpagwiBw5cmVZBlBb-m7UJkkQJ9WKoTD1VA0+02iJ8qHiwSHiIni9RSmY5M3iSAZioKDwb0oGq4QixEjIWiMYRsbi6+KM6OyaMKVSZ43ahyuebefyu+KRSPdEjGYQABy+H1C58YV8AXTmgsgABIKEJohMWoSHIKhaCsMJ2E4HgmDYERqH-QCjAgpw8ELahdAAZiYAArChxGVKAvgaMRTVQAAWb9qyEfh8hHP4xxBMEzGnBtWSgCJ50XZNIFEMQ-leNBZimIA Open this visualization in the Vega Editor>++@+let histEnc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative, PBin [] ]+ . position Y yAxis+ . color [ MName \"Cluster\", MmType Nominal, MLegend [] ]++ errEnc = encoding+ . position X [ PName \"Gmag\", PmType Quantitative ]+ . position Y [ 'PNumber' 80 ]+ . color [ MName \"Cluster\", MmType Nominal, MLegend [] ]+ + yAxis = [ PAggregate Count+ , PmType Quantitative+ , PAxis [ AxTitle \"Number of Stars\" ]+ ]++ boxOpts = [ 'MMedian' [ MColor \"black\" ]+ , 'MBox' [ MStroke \"white\" ]+ , 'MNoOutliers'+ ]+ + histSpec = asSpec [ mark Bar [], histEnc [] ]+ errSpec = asSpec [ mark Boxplot boxOpts, errEnc [] ]++ combinedSpec = asSpec [ layer [ histSpec, errSpec ] ]+ +in toVegaLite+ [ gaiaData+ , columns 4+ , facetFlow [ FName \"Cluster\", FmType Nominal ]+ , specification combinedSpec+ ]+@++The main additions here are the configuration of the box plot - with+'MMedian', 'MBox' (used to ensure the box is visually distinct from+the bar for the Pleiades cluster, where they overlap), and 'MNoOutliers'+(to turn off the display of the outliers) - and the use of 'PNumber'+to define the location on the y axis of the boxplot visualization.+Note that 'PNumber' is defined in pixel units, with 0 being the+top of the visualization and 80 was found by trial and error.++-}++comparingErrors :: VegaLite+comparingErrors =+ let histEnc = encoding+ . position X [ PName "Gmag", PmType Quantitative, PBin [] ]+ . position Y yAxis+ . color [ MName "Cluster", MmType Nominal, MLegend [] ]++ errEnc = encoding+ . position X [ PName "Gmag", PmType Quantitative ]+ . position Y [ PNumber 80 ]+ . color [ MName "Cluster", MmType Nominal, MLegend [] ]+ + yAxis = [ PAggregate Count+ , PmType Quantitative+ , PAxis [ AxTitle "Number of Stars" ]+ ]++ boxOpts = [ MMedian [ MColor "black" ]+ , MBox [ MStroke "white" ]+ , MNoOutliers+ ]+ + histSpec = asSpec [ mark Bar [], histEnc [] ]+ errSpec = asSpec [ mark Boxplot boxOpts, errEnc [] ]++ combinedSpec = asSpec [ layer [ histSpec, errSpec ] ]+ + in toVegaLite+ [ gaiaData+ , columns 4+ , facetFlow [ FName "Cluster", FmType Nominal ]+ , specification combinedSpec+ ]+++-- $intro-dashboard+-- In the following visualization I try to combine as many of the+-- concepts we have explored in this tutorial into one. There are+-- layers, combined visualizations, and a selection that ties the+-- different plots together.++{-|++This is based on the+<https://vega.github.io/vega-lite/examples/concat_marginal_histograms.html Marginal Histogram>+example from the Vega-Lite+<https://vega.github.io/vega-lite/examples/ Example Gallery>.+There is very-little new in this plot, in that pretty-much everything+has been shown before. However, there are some interesting wrinkles,+such as++ * combining multiple plots, in this case the \"top\" area - which is+ a histogram on top of a plot which is itself a \"map\" and+ a histogram - and \"bottom" area - which is just a point plot -+ requires judicious use of 'asSpec';++ * selection works in __both__ the main plots - the \"map\" and \"point\"+ plots - to highlight all stars in the same cluster, and I was+ pleasantly surprised to find out I could just use the same selection+ specification (@selCluster@) in both (hopefully I am not just+ ejnoying a hole in the Vega Lite specification);++ * I have been perhaps too defensive in defining the Right Ascension+ and Declination axes in the relevant plots, as I want to make sure+ the histogram bins and plot axes are well aligned (that is the+ @'Nice' False@ statements may not be needed when defining the+ histogram axes);++ * I am not 100% sure I understand what is going on with the+ grid labels on the Declination axis, as I had thought I was+ asking for marks every 15 degrees, but the plot shows them+ every 30 degrees (however, if I change the @deTicks@ array then+ the marks change in ways I currently do not understand);++ * and I have decided to display Right Ascension in hours, rather than+ degrees, because why have one way to measure a value when you can+ have many!++<<images/vl/combinedplot.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEAuBOCGA7AzgMwPawLaQFxgG1hJ5k8oAlAQUgBooBjeAGwYFdn5oBTcyAEy5ssAOmoB9AJIBhCgGUwAejABGAKyQAvgF1a4RukSoAlgHNyxAG7HuAdwuRkcdAGte+GAhQAHeLG6I0FqaehACXPAW+mFssMx8ABbQ0N7IuIqKCLYipsbQCWwARmzI3LAMhjyBIhVYigAi6GymAEKxbooJltym8IpYpDywnd29ioLQfb3G8AC08HMAbCqL8yoADLOThczcKvAiiOizCdzw-GUi0MiWdNFQGNhcDr6wpQ4A4gPmHojChWU6FBvMwAB58P5YAGwIGQbjiEHg37-QGaTT6EL6SCWCqIJhBfAEe6gCCkqA4wz48hEslkkm0smQU5mJLkDbrUIM0mQWzGfj5cgAFnWHPuDMgnAAnoDCWKufSubTIANYC4HBVmJg+KYEJLYdBJd53FBCn4tJzFYyAhV+MZED8wArLYykY65c6wiZuMx+HxqHcPVzIIU7Q5uKCqgTCBywAAmQW6KBObjecix+iQRDGBjG1AsUqYwPi5CYKMCbjIHOIW32gNFxkGo18ACObCQ0DyXGM3Tr9bC8FBxjI+D+zGY7sthb7kD1+Cd9ccTF2Dn46AGocJMYAzCL1top32oPBTDqelxjZAKmxAr3p42L63252Oz2LdOB0OHB3oMuRxxmOih6AUWwHOgelrzpanhIGgmA4ISxAmMwQwOKUuwMB2hh8N42ZqmiugTuKKpqh4powm+zpwni6A1g6kGURqWpzoRUGWCwbAXqeeoUUWl6GLamGIFEh6Ml6Pp8NIzAlChPELmh3AYcYWEeDhDBqrJvH3hCa52iwkAsYqoEgRpiqQK69EepAYm+h4-omVBIZCXOcIRgEUYEDG8aJo4PCpvg6ZQFmObkHmzAFvZpklrAZYXJWAS0beC5aR4j6BM+3a8BFQYfsOYCjuOQFZYys5uiJSZLsaxCruuTnRvQO4ivuRVKsep69DwfBXjezUNoaD5tmlkwvplBnZYOuXEN+v55f+RmBnNk6jQtZLaBO4F0ixTK4lSsqBhZ4rMqYrL4MKooLsRDjoL4DB5CV6wiGoGbJYwxjlMu61Qby-IJEKIrNY43oKYJLy4V+fV8MgdqmMuGbWblBCQJJ0mAvuH2mdaNFQ8J06MTCzFldi7Gcf43GjeKuICUptX7ZZ1kSVJybkWTQbyYpynAqDPVKs9mY6YgenM2Sy2TlzZnY4eVk2OJtk0FzYSViwlUCGu8AbnVcYJhmQW5vm3Bo5ZUUxRWVYJXLUA86l35dq+gvcjlX55NNkAUCy0BgFQcUoFTYAABQJE0bwAJRaLb+umSVNOmXTHj1AAolIshyIlvEK9NVUq2rBCzAAnDGufedrIW62HUEWwNVvDcngYkON4siYTUkVtStsMjnZ1laSswAOyPS3tKzIs7cd2AsyCr3w8QLMO5m2SszqDPpJDx38992S0+r6SY8LxAg-b2APd77nG8EcPMCOxe9QKcwumCb7FynhWwd98LhnMy-pIlxAkfcodx1gKd-0voCnwOyf6UoZSEFtt-IifgSKOj4pqPGUAdTwG4ubcGpEzSfyDBjBK+MO5i3wafVOStqqq1qh5equ4mob37Cefw7ULxdSCHvGAGCoCW3SjbCeR5a7OSmsafK78wILxnHXAm0coBxwTvIKu05HJhlcjeQkbd6D5wzMmPyqhHqBWzDrMKetWFlyfENDKciFz2z-GODewiuS2KFlzaB3MvCwWwNSRCxhkIQOIKzYGKlQb4TNsqWBfAyLmKgrgrGRD6643EfXNijdtQk3CdXCmeQqZxIkVLGyUAkaMxSSnQGbNaqQFUupWh3IeZHCwLpeIFT7F2NEeZCpi5FYrgzhQ7c1DsGUVagw88nUmjdRacYwa1sRo8Jrp+fh59yBCJsaIiOLTJGQGkTIWRrCFHOXDJGakqiwDqKTL5NkOjMx6KLgYnppd2GQE4aY7hE8pm5XyjY5+odmarXmixE+UFkDXSiXGJe4pChDP4LlKyDMfprTlD8xkfz4A3VrP5IFJpQXgtQJC-SDjiRymCaqS6-yDTkHuqcnmN03q8A+jyPkwCwBqFjCigG6E-HwLKWDJsHhIb2hhg8bJ8NEYMxQqjHiVEbQAosggpipVWJEySdwUmDF+LpPZt-SW3ockCuRkzauviMn+LUgUthHLAp8wFmBNaGlCHSqjtk7CYJwmtLTkai8mpzBa3OfgUK4VNqjIrmY+yTyHY-gvK8FgnBQS+xqWOYw8xyilApsHYW+sxHRPFCsr4x4HW+q4RMqClj4ECL4B8MA3wszQDYBcEOr8GRGWAj8yAAASSspwBiJGSKkdIihRgHFyPkIoIglKKGbdwAYXazyzGvjwLtW4RAACsSxCU5GfYNX4dlFtVvAMAExN2oFgGuMAfgAAa3ZcAqAABzrEFCIdY2ctxdzPbCJADB-ZIOVHyfg70QCaCAA Open this visualization in the Vega Editor (although the link is long, and may not work with Internet Explorer)>++@+let trans = transform+ . calculateAs \"datum.RA_ICRS / 15\" \"RA\"+ + quant n = [ PName n, PmType Quantitative ]++ big = 400+ small = 100+ wmain = width big+ hmain = height big+ wsub = width small+ hsub = height small+ noTitle = PAxis [ AxNoTitle ]+ + raAxis = [ PScale [ SDomain (DNumbers [ 0, 24 ])+ , SNice (IsNice False)+ ]+ , PSort [ Descending ]+ , PAxis [ AxTitle \"Right Ascension (hours)\" ]+ ]++ deMin = -90+ deMax = 90+ deStep = 15++ -- we do not get ticks/grids at all these values, but it does+ -- something (e.g. if do not specify the axis ticks are different)+ --+ deTicks = Numbers [ deMin, deMin + deStep .. deMax ]+ deAxis = [ PScale [ SDomain (DNumbers [ deMin, deMax ])+ , SNice (IsNice False)+ ]+ , PAxis [ AxTitle \"Declination (degrees)\"+ , AxValues deTicks+ ]+ ]++ colorEnc = color [ MSelectionCondition (SelectionName \"pick\")+ [ MName \"Cluster\", MmType Nominal ]+ [ MString \"grey\" ]+ ]+ mapEnc = encoding+ . position X (quant \"RA\" ++ raAxis)+ . position Y (quant \"DE_ICRS\" ++ deAxis)+ . colorEnc++ circleMark = mark Circle [ MOpacity 0.5 ]+ + mapSpec = asSpec [ mapEnc []+ , circleMark+ , wmain+ , hmain+ , selCluster []+ ]++ -- histogram of the RA values+ --+ raBinning = [ PBin [ 'Extent' 0 24+ , Step 2+ , Nice False+ ]+ , PSort [ Descending ]+ , PAxis []+ ]+ + -- histogram of the Declination values+ --+ deBinning = [ PBin [ Extent deMin deMax+ , Step deStep+ , Nice False+ ]+ , PAxis []+ ]++ histAxis = [ PAggregate Count+ , PmType Quantitative+ , noTitle+ , PScale [ SDomain (DNumbers [ 0, 3000 ]) ]+ ]+ + raEnc = encoding+ . position X (quant \"RA\" ++ raBinning)+ . position Y histAxis+ + deEnc = encoding+ . position Y (quant \"DE_ICRS\" ++ deBinning)+ . position X histAxis++ allRA = [ raEnc []+ , mark Bar [ MColor \"gray\" ]+ ]+ filtRA = [ filterCluster []+ , raEnc+ . colorEnc+ $ []+ , mark Bar []+ ]+ + allDE = [ deEnc []+ , mark Bar [ MColor \"gray\" ]+ ]+ filtDE = [ filterCluster []+ , deEnc+ . colorEnc+ $ []+ , mark Bar []+ ]++ raSpec = asSpec [ wmain, hsub, layer [ asSpec allRA, asSpec filtRA ] ]+ deSpec = asSpec [ hmain, wsub, layer [ asSpec allDE, asSpec filtDE ] ]++ borderSpacing = 20++ mapAndDecSpec = asSpec [ spacing borderSpacing+ , 'bounds' 'Flush'+ , 'hConcat' [ mapSpec, deSpec ]+ ]+ + histSpecs = [ raSpec, mapAndDecSpec ]++ -- select the cluster which the star belongs to; do not use+ -- \"nearest click\" as that means a user can not cancel the+ -- selection.+ --+ pick = \"pick\"+ selCluster = selection+ . select pick Single [ Fields [ \"Cluster\" ] ]++ filterCluster = transform+ . filter (FSelection pick)++ plxOpts = [ PScale [ SType ScLog, SNice (IsNice False) ]+ , PAxis [ AxTitle \"parallax (milli-arcsecond)\" ]+ ]+ gmagOpts = [ PAxis [ AxTitle \"G magnitude\" ] ]+ + encData = encoding+ . position X (quant \"plx\" ++ plxOpts)+ . position Y (quant \"Gmag\" ++ gmagOpts)++ parallaxSpec = asSpec [ width (big + borderSpacing + small)+ , encData+ . colorEnc+ $ []+ , circleMark+ , selCluster []+ ]+ + allSpecs = [ asSpec [ spacing borderSpacing+ , bounds Flush+ , vConcat histSpecs+ ]+ , parallaxSpec ]+ + +in toVegaLite+ [ gaiaData+ , trans []+ , vConcat allSpecs+ -- remove the "other" axis (e.g. top of Y, right for X)+ , configure+ . configuration ('View' [ 'ViewStroke' (Just \"transparent\") ])+ $ []+ , title \"Gaia data from arXiv:1804.09378\" [ 'TAnchor' 'AMiddle' ]+ ]+@++Here is the visualization after selecting a star:++<<images/vl/combinedplot-selected.png>>++-}++combinedPlot :: VegaLite+combinedPlot =+ let trans = transform+ . calculateAs "datum.RA_ICRS / 15" "RA"+ + quant n = [ PName n, PmType Quantitative ]++ big = 400+ small = 100+ wmain = width big+ hmain = height big+ wsub = width small+ hsub = height small+ noTitle = PAxis [ AxNoTitle ]+ + raAxis = [ PScale [ SDomain (DNumbers [ 0, 24 ])+ , SNice (IsNice False)+ ]+ , PSort [ Descending ]+ , PAxis [ AxTitle "Right Ascension (hours)" ]+ ]++ deMin = -90+ deMax = 90+ deStep = 15++ -- we do not get ticks/grids at all these values, but it does+ -- something (e.g. if do not specify the axis ticks are different)+ --+ deTicks = Numbers [ deMin, deMin + deStep .. deMax ]+ deAxis = [ PScale [ SDomain (DNumbers [ deMin, deMax ])+ , SNice (IsNice False)+ ]+ , PAxis [ AxTitle "Declination (degrees)"+ , AxValues deTicks+ ]+ ]++ colorEnc = color [ MSelectionCondition (SelectionName "pick")+ [ MName "Cluster", MmType Nominal ]+ [ MString "grey" ]+ ]+ mapEnc = encoding+ . position X (quant "RA" ++ raAxis)+ . position Y (quant "DE_ICRS" ++ deAxis)+ . colorEnc++ circleMark = mark Circle [ MOpacity 0.5 ]+ + mapSpec = asSpec [ mapEnc []+ , circleMark+ , wmain+ , hmain+ , selCluster []+ ]++ -- histogram of the RA values+ --+ raBinning = [ PBin [ Extent 0 24+ , Step 2+ , Nice False+ ]+ , PSort [ Descending ]+ , PAxis []+ ]+ + -- histogram of the Declination values+ --+ deBinning = [ PBin [ Extent deMin deMax+ , Step deStep+ , Nice False+ ]+ , PAxis []+ ]++ histAxis = [ PAggregate Count+ , PmType Quantitative+ , noTitle+ , PScale [ SDomain (DNumbers [ 0, 3000 ]) ]+ ]+ + raEnc = encoding+ . position X (quant "RA" ++ raBinning)+ . position Y histAxis+ + deEnc = encoding+ . position Y (quant "DE_ICRS" ++ deBinning)+ . position X histAxis++ allRA = [ raEnc []+ , mark Bar [ MColor "gray" ]+ ]+ filtRA = [ filterCluster []+ , raEnc+ . colorEnc+ $ []+ , mark Bar []+ ]+ + allDE = [ deEnc []+ , mark Bar [ MColor "gray" ]+ ]+ filtDE = [ filterCluster []+ , deEnc+ . colorEnc+ $ []+ , mark Bar []+ ]++ raSpec = asSpec [ wmain, hsub, layer [ asSpec allRA, asSpec filtRA ] ]+ deSpec = asSpec [ hmain, wsub, layer [ asSpec allDE, asSpec filtDE ] ]++ borderSpacing = 20++ mapAndDecSpec = asSpec [ spacing borderSpacing+ , bounds Flush+ , hConcat [ mapSpec, deSpec ]+ ]+ + histSpecs = [ raSpec, mapAndDecSpec ]++ -- select the cluster which the star belongs to; do not use+ -- "nearest click" as that means a user can not cancel the+ -- selection.+ --+ pick = "pick"+ selCluster = selection+ . select pick Single [ Fields [ "Cluster" ] ]++ filterCluster = transform+ . filter (FSelection pick)++ plxOpts = [ PScale [ SType ScLog, SNice (IsNice False) ]+ , PAxis [ AxTitle "parallax (milli-arcsecond)" ]+ ]+ gmagOpts = [ PAxis [ AxTitle "G magnitude" ] ]+ + encData = encoding+ . position X (quant "plx" ++ plxOpts)+ . position Y (quant "Gmag" ++ gmagOpts)++ parallaxSpec = asSpec [ width (big + borderSpacing + small)+ , encData+ . colorEnc+ $ []+ , circleMark+ , selCluster []+ ]+ + allSpecs = [ asSpec [ spacing borderSpacing+ , bounds Flush+ , vConcat histSpecs+ ]+ , parallaxSpec ]+ + + in toVegaLite+ [ gaiaData+ , trans []+ , vConcat allSpecs+ -- remove the "other" axis (e.g. top of Y, right for X)+ , configure+ . configuration (View [ ViewStroke (Just "transparent") ])+ $ []+ , title "Gaia data from arXiv:1804.09378" [ TAnchor AMiddle ]+ ]+++{-++Other things to do:++ - add some description of magnitude / parallax meanings+ (since talk about astronomy being awkward)++ - tooltips++-}+
@@ -1,4611 +1,10330 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-}--{-|-Module : Graphics.Vega.VegaLite-Copyright : (c) Douglas Burke, 2018-2019-License : BSD3--Maintainer : dburke.gw@gmail.com-Stability : unstable-Portability : OverloadedStrings, TupleSections--This is essentially a straight port of the-<http://package.elm-lang.org/packages/gicentre/elm-vega/2.2.1/VegaLite Elm Vega Lite module>-(version 2.2.1).-It allows users to create a Vega-Lite specification, targeting-version 3 of the <https://vega.github.io/schema/vega-lite/v3.json JSON schema>.-The ihaskell-hvega module provides an easy way to embed Vega-Lite-visualizations in an IHaskell notebook (using-<https://vega.github.io/vega-lite/usage/embed.html Vega-Embed>).--The major changes to version 2.2.1 of the Elm version is that the type representing-the full Vega-Lite specification - that is, the return value of-'toVegaLite' - is not a 'VLSpec' (an alias for 'Data.Aeson.Value')-but is instead a newtype around this ('VegaLite'). There are also some minor-changes to the exported types and symbols (e.g. 'Utc' is exported rather than-@utc@ and @bin@ is not exported). As time goes on there are more-changes (in particular the Elm module is being updated much-more rapidly-than this is).--Note that this module exports several symbols that are exported-by the Prelude, namely 'filter', 'lookup',-and 'repeat'; to avoid name clashes it's therefore advised-to either import the module qualified, for example:--@-import qualified Graphics.Vega.VegaLite as VL-@--or to hide the clashing names explicitly:--@-import Prelude hiding (filter, lookup)-@--In the following example, we'll assume the latter.--== Example--Let's say we have the following plot declaration in a module:--@-\{\-\# language OverloadedStrings \#\-\}--vl1 = 'toVegaLite' ['description' desc, 'background' "white", 'dat' [], 'mark' 'Bar' 'barOpts', enc []] where- desc = "A very exciting bar chart"-- dat = 'dataFromRows' ['Parse' [("start", 'FoDate' "%Y-%m-%d")]]- . 'dataRow' [("start", 'Str' "2011-03-25"), ("count", 'Number' 23)]- . dataRow [("start", Str "2011-04-02"), ("count", Number 45)]- . dataRow [("start", Str "2011-04-12"), ("count", Number 3)]-- barOpts = ['MOpacity' 0.4, 'MColor' "teal"]-- enc = 'encoding'- . 'position' 'X' ['PName' "start", 'PmType' 'Temporal', 'PAxis' ['AxTitle' "Inception date"]]- . position Y [PName "count", PmType Quantitative]-@--We can inspect how the encoded JSON looks like in an GHCi session:--@-> 'A.encode' $ 'fromVL' vl1-> "{\"mark\":{\"color\":\"teal\",\"opacity\":0.4,\"type\":\"bar\"},\"data\":{\"values\":[{\"start\":\"2011-03-25\",\"count\":23},{\"start\":\"2011-04-02\",\"count\":45},{\"start\":\"2011-04-12\",\"count\":3}],\"format\":{\"parse\":{\"start\":\"date:'%Y-%m-%d'\"}}},\"$schema\":\"https://vega.github.io/schema/vega-lite/v3.json\",\"encoding\":{\"x\":{\"field\":\"start\",\"type\":\"temporal\",\"axis\":{\"title\":\"Inception date\"}},\"y\":{\"field\":\"count\",\"type\":\"quantitative\"}},\"background\":\"white\",\"description\":\"A very exciting bar chart\"}"-@--The produced JSON can then be processed with vega-lite, which renders the following image :--<<images/example.png>>---}--module Graphics.Vega.VegaLite- (- -- * Creating a Vega-Lite Specification-- toVegaLite- , fromVL- , VLProperty- , VLSpec- , VegaLite- , LabelledSpec- , BuildLabelledSpecs- , combineSpecs- , toHtml- , toHtmlFile-- -- * Creating the Data Specification- --- -- Functions and types for declaring the input data to the- -- visualization.-- , dataFromUrl- , dataFromColumns- , dataFromRows- , dataFromJson- , dataFromSource- , datasets- , dataColumn- , dataRow- , geometry- , geoFeatureCollection- , geometryCollection- , Data- , DataColumn- , DataRow- , Format(..)- , Geometry(..)- , DataType(..)-- -- * Creating the Transform Specification- --- -- Functions and types for declaring the transformation rules that- -- are applied to data fields or geospatial coordinates before they- -- are encoded visually.-- , transform- , projection- , ProjectionProperty(..)- , Projection(..)- , ClipRect(..)-- -- ** Aggregation-- , aggregate- , Operation(..)- , opAs- , timeUnitAs-- -- ** Binning-- , binAs- , BinProperty(..)-- -- ** Data Calculation-- , calculateAs-- -- ** Filtering-- , filter- , Filter(..)- , FilterRange(..)-- -- ** Relational Joining (lookup)-- , lookup- , lookupAs-- -- * Creating the Mark Specification- --- -- Types and functions for declaring the type of visual- -- marks used in the visualization.-- , mark- , Mark(..)- , MarkProperty(..)- , MarkOrientation(..)- , MarkInterpolation(..)- , Symbol(..)- , Cursor(..)-- -- * Creating the Encoding Specification- --- -- $encoding-- , encoding- , Measurement(..)-- -- ** Position Channels- --- -- Control where items appear in the visualization.-- , position- , PositionChannel(..)- , Position(..)- , SortProperty(..)- , StackProperty(..)- , AxisProperty(..)- , OverlapStrategy(..)- , Side(..)- , HAlign(..)- , VAlign(..)- , FontWeight(..)- , TimeUnit(..)-- -- ** Mark channels- --- -- Control the appearance of the visual marks in the visualization- -- (e.g. 'color' and 'size').-- , size- , color- , fill- , stroke- , opacity- , shape- , MarkChannel(..)- , LegendProperty(..)- , Legend(..)- , LegendOrientation(..)- , LegendValues(..)-- -- ** Text Channels- --- -- Control the appearance of the text and tooltip elements in the visualization.-- , text- , tooltip- , tooltips- , TextChannel(..)-- -- ** Hyperlink Channels- --- -- $hyperlink-- , hyperlink- , HyperlinkChannel(..)-- -- ** Order Channels- --- -- $order-- , order- , OrderChannel(..)-- -- ** Facet Channels- --- -- $facet-- , row- , column-- -- ** Level of detail Channel- --- -- $detail-- , detail- , DetailChannel(..)-- -- ** Scaling- --- -- How the encoding of a data field is applied.-- , ScaleProperty(..)- , Scale(..)- , categoricalDomainMap- , domainRangeMap- , ScaleDomain(..)- , ScaleRange(..)- , ScaleNice(..)- , CInterpolate(..)-- -- * Creating view compositions- --- -- $view-- , layer- , hConcat- , vConcat- , resolve- , resolution- , Resolve(..)- , Channel(..)- , Resolution(..)-- -- ** Faceted views- -- #facetview#- --- -- $facetview-- , repeat- , RepeatFields(..)- , facet- , FacetMapping(..)- , FacetChannel(..)- , asSpec- , specification- , Arrangement(..)- , HeaderProperty(..)-- -- * Creating Selections for Interaction- --- -- $selections-- , selection- , select- , Selection(..)- , SelectionProperty(..)- , Binding(..)- , InputProperty(..)- , SelectionResolution(..)- , SelectionMarkProperty(..)-- -- ** Making conditional channel encodings- --- -- $conditional-- , BooleanOp(..)-- -- * Global Configuration- --- -- Configuration options that affect the entire visualization. These are in addition- -- to the data and transform options described above.-- , name- , title- , description- , height- , width- , padding- , autosize- , background- , configure- , configuration- , ConfigurationProperty(..)- , Autosize(..)- , Padding(..)- , AxisConfig(..)- , LegendConfig(..)- , ScaleConfig(..)- , TitleConfig(..)- , APosition(..)- , ViewConfig(..)- , RangeConfig(..)- , FieldTitleProperty(..)-- -- * General Data types- --- -- In addition to more general data types like integers and string, the following types- -- can carry data used in specifications.-- , DataValue(..)- , DataValues(..)- , DateTime(..)- , MonthName(..)- , DayName(..)-- )- where---- VegaLite uses these symbols.-import Prelude hiding (filter, lookup, repeat)--import qualified Data.Aeson as A-import qualified Data.Aeson.Text as A-import qualified Data.Text as T-import qualified Data.Text.Lazy as TL-import qualified Data.Text.Lazy.IO as TL-import qualified Data.Vector as V--import Control.Arrow (first, second)---- Aeson's Value type conflicts with the Number type-import Data.Aeson ((.=), Value, decode, encode, object, toJSON)-import Data.Maybe (fromMaybe, mapMaybe)-import Data.Monoid ((<>))---- Documentation---- $encoding--- Types and functions for declaring which data fields are mapped to which--- channels. Channels can include: position on screen (e.g. 'X', 'Y'); visual--- mark properties ('color', 'size', 'stroke', 'shape'); 'text'; 'hyperlink';--- ordering ('order'); level of 'detail'; and facets for composed--- visualizations ('facet'). All can be further customised via a series of--- properties that determine how the encoding is implemented (such as--- scaling, sorting, and spacing).---- $hyperlink--- Channels which offer a clickable URL destination. Unlike most other--- channels, the hyperlink channel has no direct visual expression other than the--- option of changing the cursor style when hovering, so an encoding will usually--- pair hyperlinks with other visual channels such as marks or texts.---- $order--- Channels that relate to the order of data fields such as for sorting stacking order--- or order of data points in a connected scatterplot. See the--- <https://vega.github.io/vega-lite/docs/encoding.html#order Vega-Lite documentation>--- for further details.---- $facet--- Channels for faceting single plots into small multiples. Can be used to create--- trellis plots or other arrangements in rows and columns. See the--- <https://vega.github.io/vega-lite/docs/encoding.html#facet Vega-Lite documentation>--- for further details. See also, <#facetview faceted views> for a more flexible (but--- more verbose) way of defining faceted views.---- NOTE: the facetview link above doesn't seem to work. Argh.---- $detail--- Used for grouping data but without changing the visual appearance of a mark. When,--- for example, a field is encoded by color, all data items with the same value for--- that field are given the same color. When a detail channel encodes a field, all--- data items with the same value are placed in the same group. This allows, for example--- a line chart with multiple lines to be created – one for each group. See the--- <https://vega.github.io/vega-lite/docs/encoding.html#detail Vega-Lite documentation>--- for more information.---- $view--- Views can be combined to create more complex multiview displays. This may involve--- layering views on top of each other (superposition) or laying them out in adjacent--- spaces (juxtaposition using 'repeat', 'facet', 'hConcat', or 'vConcat'). Where different--- views have potentially conflicting channels (for example, two position scales in--- a layered visualization) the rules for resolving them can be defined with 'resolve'.--- For details of creating composite views see the--- <https://vega.github.io/vega-lite/docs/composition.html Vega-Lite documentation>.---- $facetview--- These are small multiples each of which show subsets of the same dataset. The specification--- determines which field should be used to determine subsets along with their spatial--- arrangement (in rows or columns). For details see the--- <https://vega.github.io/vega-lite/docs/facet.html Vega-Lite documentation>.---- $selections--- Selections are the way in which interactions (such as clicking or dragging) can be--- responded to in a visualization. They transform interactions into data queries.--- For details, see the--- <https://vega.github.io/vega-lite/docs/selection.html Vega-Lite documentation>.---- $conditional--- Sometimes it is useful to make channel encoding conditional on something. For example,--- on the result of some interaction such as clicking or dragging or some data property--- such whether null or an outlier. 'MSelectionCondition' and 'TSelectionCondition' will--- encode a mark or text dependent on an interactive selection. 'MDataCondition'--- and 'TDataCondition' will encode it dependening on some data property.------ For interaction, once a selection has been defined and named, supplying a set of--- 'MSelectionCondition' encodings allow mark encodings to become dependent on that selection.--- 'MSelectionCondition' is followed firstly by a Boolean expression relating to the--- selection upon which it is dependent, then an \"if\" and an \"else\" clause. Each clause--- is a list of mark field encodings that should be applied when the selection is true--- (the \"if clause\") and when it is false (the \"else clause\"). The color encoding below--- is saying \"whenever data marks are selected with an interval mouse drag, encode--- the cylinder field with an ordinal color scheme, else make them grey\".------ @--- sel = 'selection' . 'select' "myBrush" 'Interval' []------ enc = 'encoding'--- . 'position' 'X' [ 'PName' \"Horsepower\", 'PmType' 'Quantitative' ]--- . position 'Y' [ PName \"Miles_per_Gallon\", PmType Quantitative ]--- . 'color'--- [ 'MSelectionCondition' ('SelectionName' "myBrush")--- [ 'MName' \"Cylinders\", 'MmType' 'Ordinal' ]--- [ 'MString' "grey" ]--- ]--- @------ In a similar way, 'MDataCondition' will encocode a mark in one of two ways depending--- on whether a predicate test is satisfied.------ @--- enc = encoding--- . position X [ PName \"IMDB_Rating\", PmType Quantitative ]--- . position Y [ PName \"Rotten_Tomatoes_Rating\", PmType Quantitative ]--- . color--- [ 'MDataCondition'--- ('Or' ('Expr' "datum.IMDB_Rating === null")--- (Expr "datum.Rotten_Tomatoes_Rating === null")--- )--- [ MString "#ddd" ]--- [ MString "#0099ee" ]--- ]--- @------ For details, see the--- <https://vega.github.io/vega-lite/docs/condition.html Vega-Lite documentation>.----- helpers not in VegaLite.elm--aggregate_ :: Operation -> LabelledSpec-aggregate_ op = "aggregate" .= operationLabel op--field_ :: T.Text -> LabelledSpec-field_ f = "field" .= f--op_ :: Operation -> LabelledSpec-op_ op = "op" .= operationLabel op--repeat_ :: Arrangement -> LabelledSpec-repeat_ arr = "repeat" .= arrangementLabel arr--sort_ :: [SortProperty] -> LabelledSpec-sort_ ops = "sort" .= sortPropertySpec ops--timeUnit_ :: TimeUnit -> LabelledSpec-timeUnit_ tu = "timeUnit" .= timeUnitLabel tu--type_ :: Measurement -> LabelledSpec-type_ m = "type" .= measurementLabel m--value_ :: T.Text -> LabelledSpec-value_ v = "value" .= v--fromT :: T.Text -> VLSpec-fromT = toJSON--fromF :: Double -> VLSpec-fromF = toJSON---------------- | A Vega Lite visualization, created by--- 'toVegaLite'. The contents can be extracted with 'fromVL'.----newtype VegaLite =- VL {- fromVL :: VLSpec- -- ^ Extract the specification for passing to a VegaLite visualizer.- --- -- > let vlSpec = fromVL vl- -- > Data.ByteString.Lazy.Char8.putStrLn (Data.Aeson.Encode.Pretty.encodePretty vlSpec)- --- -- Note that there is __no__ validation done to ensure that the output matches- -- the Vega Lite schema. That is, it is possible to create an invalid visualization- -- with this module (e.g. missing a data source or referring to an undefined- -- field).- }---- | The specification is represented as JSON.-type VLSpec = Value--vlSchemaName :: T.Text-vlSchemaName = "https://vega.github.io/schema/vega-lite/v3.json"--{-|--Convert a list of Vega-Lite specifications into a single JSON object that may be-passed to Vega-Lite for graphics generation. Commonly these will include at least-a data, mark, and encoding specification.--While simple properties like 'mark' may be provided directly, it is usually clearer-to label more complex ones such as encodings as separate expressions. This becomes-increasingly helpful for visualizations that involve composition of layers, repeats-and facets.--Specifications can be built up by chaining a series of functions (such as 'dataColumn'-or 'position' in the example below). Functional composition using the '.' operator-allows this to be done compactly.--@-let dat = 'dataFromColumns' []- . 'dataColumn' "a" ('Strings' [ \"C", \"C", \"D", \"D", \"E", \"E" ])- . dataColumn "b" ('Numbers' [ 2, 7, 1, 2, 6, 8 ])-- enc = 'encoding'- . 'position' 'X' [ 'PName' "a", 'PmType' 'Nominal' ]- . position 'Y' [ PName "b", 'PmType' 'Quantitative', 'PAggregate' 'Mean' ]--in toVegaLite [ dat [], mark 'Bar' [], enc [] ]-@--The schema used is <https://github.com/vega/schema version 3 of Vega-Lite>.---}-toVegaLite :: [(VLProperty, VLSpec)] -> VegaLite-toVegaLite vals =- let kvals = ("$schema" .= vlSchemaName)- : map toProp vals- toProp = first vlPropertyLabel-- in VL { fromVL = object kvals }---{-|--Combines a list of labelled specifications into a single specification.-This is useful when you wish to create-a single page with multiple visulizualizations.--@-combineSpecs- [ ( "vis1", myFirstVis )- , ( "vis2", mySecondVis )- , ( "vis3", myOtherVis )- ]-@--}-combineSpecs :: [LabelledSpec] -> VLSpec-combineSpecs = object--{-|--Converts VegaLite to html Text. Uses Vega-Embed.--@since 0.2.1.0--}-toHtml :: VegaLite -> TL.Text-toHtml vl = TL.unlines- [ "<!DOCTYPE html>"- , "<html>"- , "<head>"- , " <!-- Import Vega 5 & Vega-Lite 3 (does not have to be from CDN) -->"- , " <script src=\"https://cdn.jsdelivr.net/npm/vega@3\"></script>"- , " <script src=\"https://cdn.jsdelivr.net/npm/vega-lite@2\"></script>"- , " <!-- Import vega-embed -->"- , " <script src=\"https://cdn.jsdelivr.net/npm/vega-embed@3\"></script>"- , "</head>"- , "<body>"- , "<div id=\"vis\"></div>"- , "<script type=\"text/javascript\">"- , (" var spec = " <> (A.encodeToLazyText $ fromVL vl) <> ";")- , " vegaEmbed(\'#vis\', spec).then(function(result) {"- , " // Access the Vega view instance (https://vega.github.io/vega/docs/api/view/) as result.view"- , " }).catch(console.error);"- , "</script>"- , "</body>"- , "</html>"- ]--{-|--Converts VegaLite to an html file. Uses Vega-Embed.--@since 0.2.1.0--}-toHtmlFile :: FilePath -> VegaLite -> IO ()-toHtmlFile file = TL.writeFile file . toHtml--{-|--Create a specification sufficient to define an element in a composed visualization-such as a superposed layer or juxtaposed facet. Typically a layer will contain a-full set of specifications that define a visualization with-the exception of the data specification which is usually defined outside of any one-layer. Whereas for repeated and faceted specs, the entire specification is provided.--@-spec1 = asSpec [ enc1 [], mark Line [] ]-@--}-asSpec :: [(VLProperty, VLSpec)] -> VLSpec-asSpec = object . map (first vlPropertyLabel)---{-|--Specifies a list of geo features to be used in a geoShape specification.-Each feature object in this collection can be created with the 'geometry'-function.--@-geojson =- geoFeatureCollection- [ 'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( -3, 52 ), ( 4, 52 ), ( -3, 59 ) ] ])- [ ( "myRegionName", 'Str' "Northern region" ) ]- , geometry (GeoPolygon [ [ ( -3, 52 ), ( 4, 52 ), ( 4, 45 ), ( -3, 52 ) ] ])- [ ( "myRegionName", Str "Southern region" ) ]- ]-@--}-geoFeatureCollection :: [VLSpec] -> VLSpec-geoFeatureCollection geoms =- object [ "type" .= ("FeatureCollection" :: T.Text)- , "features" .= geoms- ]---{-|--Specifies a list of geometry objects to be used in a geoShape specification.-Each geometry object in this collection can be created with the 'geometry'-function.--@-geojson =- geometryCollection- [ 'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 59 ) ] ]) []- , geometry ('GeoPoint' -3.5 55.5) []- ]-@--}-geometryCollection :: [VLSpec] -> VLSpec-geometryCollection geoms =- object [ "type" .= ("GeometryCollection" :: T.Text)- , "geometries" .= geoms- ]---{-|--Create a named aggregation operation on a field that can be added to a transformation.-For further details see the-<https://vega.github.io/vega-lite/docs/aggregate.html#aggregate-op-def Vega-Lite documentation>.--@-trans =- 'transform'- . 'aggregate'- [ opAs 'Min' "people" "lowerBound"- , opAs 'Max' "people" "upperBound"- ]- [ "age" ]-@--}-opAs ::- Operation- -- ^ The aggregation operation to use.- -> T.Text- -- ^ The name of the field which is to be aggregated.- -> T.Text- -- ^ The name given to the transformed data.- -> VLSpec-opAs op field label =- object [ op_ op- , field_ field- , "as" .= label- ]---{-|--Top-level Vega-Lite properties. These are the ones that define the core of the-visualization grammar. All properties are created by functions which can be-arranged into seven broad groups:--[Data Properties] These relate to the input data to be visualized. Generated by-'dataFromColumns', 'dataFromRows', 'dataFromUrl', 'dataFromSource' and-'dataFromJson'.--[Transform Properties] These indicate that some transformation of input data should-be applied before encoding them visually. Generated by 'transform'-and 'projection' they can include data transformations such as 'filter',-'binAs' and 'calculateAs' and geo transformations of longitude, latitude coordinates-used by marks such as 'Geoshape', 'Point', and 'Line'.--[Mark Properties] These relate to the symbols used to visualize data items. They-are generated by 'mark', and include types such as 'Circle', 'Bar', and 'Line'.--[Encoding Properties] These specify which data elements are mapped to which mark characteristics-(known as /channels/). Generated by 'encoding', they include encodings-such as 'position', 'color', 'size', 'shape', 'text' and 'hyperlink'.--[Composition Properties] These allow visualization views to be combined to form more-complex visualizations. Generated by 'layer', 'repeat', 'facet',-'hConcat', 'vConcat', 'spec', and 'resolve'.--[Interaction Properties] These allow interactions such as clicking, dragging and others-generated via a GUI or data stream to influence the visualization. Generated by-'selection'.--[Supplementary and Configuration Properties] These provide a means to add metadata and-styling to one or more visualizations. Generated by 'name', 'title', 'description',-'background', 'height', 'width', 'padding', 'autosize', and 'configure'.--}-data VLProperty- = VLName- | VLDescription- | VLTitle- | VLWidth- | VLHeight- | VLAutosize- | VLPadding- | VLBackground- | VLData- | VLDatasets- | VLMark- | VLTransform- | VLProjection- | VLEncoding- | VLLayer- | VLHConcat- | VLVConcat- | VLRepeat- | VLFacet- | VLSpec- | VLResolve- | VLConfig- | VLSelection---vlPropertyLabel :: VLProperty -> T.Text-vlPropertyLabel VLName = "name"-vlPropertyLabel VLDescription = "description"-vlPropertyLabel VLTitle = "title"-vlPropertyLabel VLWidth = "width"-vlPropertyLabel VLHeight = "height"-vlPropertyLabel VLPadding = "padding"-vlPropertyLabel VLAutosize = "autosize"-vlPropertyLabel VLBackground = "background"-vlPropertyLabel VLData = "data"-vlPropertyLabel VLDatasets = "datasets"-vlPropertyLabel VLProjection = "projection"-vlPropertyLabel VLMark = "mark"-vlPropertyLabel VLTransform = "transform"-vlPropertyLabel VLEncoding = "encoding"-vlPropertyLabel VLConfig = "config"-vlPropertyLabel VLSelection = "selection"-vlPropertyLabel VLHConcat = "hconcat"-vlPropertyLabel VLVConcat = "vconcat"-vlPropertyLabel VLLayer = "layer"-vlPropertyLabel VLRepeat = "repeat"-vlPropertyLabel VLFacet = "facet"-vlPropertyLabel VLSpec = "spec"-vlPropertyLabel VLResolve = "resolve"---{-|--Indicates the type of data to be parsed when reading input data. For @FoDate@-and @FoUtc@, the formatting specification can be specified using-<https://vega.github.io/vega-lite/docs/data.html#format D3's formatting specifiers>-or left as an empty string if default date formatting is to be applied. Care should-be taken when assuming default parsing of dates because different browsers can-parse dates differently. Being explicit about the date format is usually safer.--}-data DataType- = FoNumber- | FoBoolean- | FoDate T.Text- | FoUtc T.Text---{-|--Specifies the type of format a data source uses. If the format is indicated by-the file name extension (@".tsv"@, @".csv"@, @".json"@) there is no need to indicate the-format explicitly. However this can be useful if the filename extension does not-indicate type (e.g. @".txt"@) or you wish to customise the parsing of a file. For-example, when specifying the @JSON@ format, its parameter indicates the name of-property field containing the attribute data to extract. For details see the-<https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>.--}-data Format- = JSON T.Text- | CSV- | TSV- | TopojsonFeature T.Text- | TopojsonMesh T.Text- | Parse [(T.Text, DataType)]---{-|--Represents a named Vega-Lite specification, usually generated by a-function in this module. You shouldn't need to create @LabelledSpec@-tuples directly, but they can be useful for type annotations.--}-type LabelledSpec = (T.Text, VLSpec)--{-|--Represent those functions which can be chained together using function-composition to append new specifications onto an existing list.--}-type BuildLabelledSpecs = [LabelledSpec] -> [LabelledSpec]--{-|--Represents a single column of data. Used when generating inline data with-'dataColumn'.--}-type DataColumn = [LabelledSpec]--{-|--Represents a single row of data. Used when generating inline data with-'dataRow'.--}-type DataRow = VLSpec--{-|--Convenience type annotation label for use with data generation functions.--@-myRegion : ['DataColumn'] -> Data-myRegion =- 'dataFromColumns' []- . 'dataColumn' "easting" ('Numbers' [ -3, 4, 4, -3, -3 ])- . dataColumn "northing" (Numbers [ 52, 52, 45, 45, 52 ])-@--}-type Data = (VLProperty, VLSpec)---formatProperty :: Format -> [LabelledSpec]-formatProperty (JSON js) =- let ps = [("type", "json")]- <> if T.null (T.strip js) then [] else [("property", js)]- in map (second toJSON) ps--formatProperty CSV = [("type", "csv")]-formatProperty TSV = [("type", "tsv")]-formatProperty (TopojsonFeature os) = [ ("type", "topojson")- , ("feature", toJSON os) ]-formatProperty (TopojsonMesh os) = [ ("type", "topojson")- , ("mesh", toJSON os) ]-formatProperty (Parse fmts) =- let pObj = object (map (second dataTypeSpec) fmts)- in [("parse", pObj)]---dataTypeSpec :: DataType -> VLSpec-dataTypeSpec dType =- let s = case dType of- FoNumber -> "number"- FoBoolean -> "boolean"- FoDate fmt | T.null fmt -> "date"- | otherwise -> "date:'" <> fmt <> "'"- FoUtc fmt | T.null fmt -> "utc"- | otherwise -> "utc:'" <> fmt <> "'"- in toJSON s---{-|--Create a row of data. A row comprises a list of (columnName, value) pairs.-The final parameter is the list of any other rows to which this is added.--@-dataRow [(\"Animal\", 'Str' \"Fish\"), (\"Age\", 'Number' 28), (\"Year\", Str "2010")] []-@--}-dataRow :: [(T.Text, DataValue)] -> [DataRow] -> [DataRow]-dataRow rw = (object (map (second dataValueSpec) rw) :)---{-|--Create a dataset comprising a collection of named 'Data' items. Each data item-can be created with normal data generating functions such as 'dataFromRows' or-'dataFromJson'. These can be later referred to using 'dataFromSource'.--@-let toJS = Data.Aeson.toJSON- obj = Data.Aeson.object-- data = 'dataFromRows' []- . 'dataRow' [ ( "cat", 'Str' "a" ), ( "val", 'Number' 10 ) ]- . dataRow [ ( "cat", Str "b" ), ( "val", Number 18 ) ]- json = toJS- [ obj [ ( "cat", toJS "a" ), ( "val", toJS 120 ) ]- , obj [ ( "cat", toJS "b" ), ( "val", toJS 180 ) ]- ]-- enc = ...--in 'toVegaLite'- [ datasets [ ( "myData", data [] ), ( "myJson", 'dataFromJson' json [] ) ]- , 'dataFromSource' "myData" []- , 'mark' 'Bar' []- , enc []- ]-@--}-datasets :: [(T.Text, Data)] -> Data-datasets namedData =- -- follow Elm in parsing the structure to get what we want, but the code is- -- written rather differently- --- -- The input is expected to be a singleton list containing a pair.- let convert = extract . snd- specs = map (second convert) namedData-- extract din =- let extract' :: [(T.Text, Value)] -> Value- extract' [(_, v)] = v- extract' _ = din-- in maybe din extract' (decode (encode din))-- in (VLDatasets, object specs)---{-|--Declare a data source from a provided list of column values. Each column contains-values of the same type, but columns each with a different type are permitted.-Columns should all contain the same number of items; if not the dataset will be-truncated to the length of the shortest column. An optional list of field formatting-instructions can be provided as the first parameter or an empty list to use the-default formatting. See the-<https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>-for details. The columns themselves are most easily generated with 'dataColumn'--@-data =- dataFromColumns [ 'Parse' [ ( \"Year\", 'FoDate' "%Y" ) ] ]- . 'dataColumn' \"Animal\" ('Strings' [ \"Fish\", \"Dog\", \"Cat\" ])- . dataColumn \"Age\" ('Numbers' [ 28, 12, 6 ])- . dataColumn \"Year\" (Strings [ "2010", "2014", "2015" ])-@--}-dataFromColumns :: [Format] -> [DataColumn] -> Data-dataFromColumns fmts cols =- let dataArray = map object (transpose cols)-- vals = [("values", toJSON dataArray)]- <> if null fmts- then []- else [("format", toJSON fmtObject)]-- fmtObject = object (concatMap formatProperty fmts)-- in (VLData, object vals)---transpose :: [[a]] -> [[a]]-transpose [] = []-transpose ([]:xss) = transpose xss-transpose ((x:xs) : xss) =- let heads = filterMap elmHead xss --- tails = filterMap elmTail xss-- elmHead (h:_) = Just h- elmHead [] = Nothing-- elmTail [] = Nothing- elmTail (_:ts) = Just ts-- filterMap = mapMaybe-- in (x : heads) : transpose (xs : tails)---{-|--Declare a data source from a provided json specification. The most likely use-case-for specifying json inline is when creating <http://geojson.org geojson> objects,-when 'geometry', 'geometryCollection', and 'geoFeatureCollection' functions-may be used. For more general cases of json creation, consider 'Data.Aeson.encode'.--@-let geojson =- 'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 59 ) ] ]) []-in 'toVegaLite'- [ 'width' 200- , 'height' 200- , dataFromJson geojson []- , 'projection' [ 'PType' 'Orthographic' ]- , 'mark' 'Geoshape' []- ]-@--}-dataFromJson :: VLSpec -> [Format] -> Data-dataFromJson vlspec fmts =- let js = if null fmts- then object [("values", vlspec)]- else object [ ("values", vlspec)- , ("format",- object (concatMap formatProperty fmts)) ]- in (VLData, js)---{-|--A single data value. This is used when a function can accept values of different-types (e.g. either a number or a string).--}-data DataValue- = Boolean Bool- | DateTime [DateTime]- | Number Double- | Str T.Text---dataValueSpec :: DataValue -> VLSpec-dataValueSpec (Boolean b) = toJSON b-dataValueSpec (DateTime dt) = object (map dateTimeProperty dt)-dataValueSpec (Number x) = toJSON x-dataValueSpec (Str t) = toJSON t---{-|--A list of data values. This is used when a function can accept lists of-different types (e.g. either a list of numbers or a list of strings).--}-data DataValues- = Booleans [Bool]- | DateTimes [[DateTime]]- | Numbers [Double]- | Strings [T.Text]---{-|--Create a column of data. A column has a name and a list of values. The final-parameter is the list of any other columns to which this is added.--@-dataColumn \"Animal\" ('Strings' [ \"Cat\", \"Dog\", \"Mouse\"]) []-@--}-dataColumn :: T.Text -> DataValues -> [DataColumn] -> [DataColumn]-dataColumn colName dVals xs =- let col = case dVals of- Booleans cs -> map toJSON cs- DateTimes cs -> map dtToJSON cs- Numbers cs -> map toJSON cs- Strings cs -> map toJSON cs-- dtToJSON = object . map dateTimeProperty- x = map (colName,) col-- in x : xs---{-|--Declare a data source from a provided list of row values. Each row contains-a list of tuples where the first value is a string representing the column name, and the-second the column value for that row. Each column can have a value of a different type-but you must ensure that when subsequent rows are added, they match the types of previous-values with shared column names. An optional list of field formatting instructions can-be provided as the first parameter or an empty list to use the default formatting. See the-<https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>-for details.--The rows themselves are most easily generated with 'dataRow'. Note though that generally-if you are creating data inline (as opposed to reading from a file), adding data by column-is more efficient and less error-prone.--@-data = dataFromRows [ 'Parse' [ ( \"Year\", 'FoDate' "%Y" ) ] ]- . 'dataRow' [ ( \"Animal\", 'Str' \"Fish\" ), ( \"Age\", 'Number' 28 ), ( \"Year\", Str "2010" ) ]- . dataRow [ ( \"Animal\", Str \"Dog\" ), ( \"Age\", Number 12 ), ( \"Year\", Str "2014" ) ]- . dataRow [ ( \"Animal\", Str \"Cat\" ), ( \"Age\", Number 6 ), ( \"Year\", Str "2015" ) ]-@--}-dataFromRows :: [Format] -> [DataRow] -> Data-dataFromRows fmts rows =- let kvs = ("values", toJSON rows)- : if null fmts- then []- else [("format", object (concatMap formatProperty fmts))]- in (VLData, object kvs)---{-|--Declare data from a named source. The source may be from named 'datasets' within-a specification or a named data source created via the-<https://vega.github.io/vega/docs/api/view/#data Vega View API>.-An optional list of field formatting instructions can be provided as the second-parameter or an empty list to use the default formatting. See the-<https://vega.github.io/vega-lite/docs/data.html#named Vega-Lite documentation>-for details.--@-'toVegaLite'- [ 'datasets' [ ( "myData", data [] ), ( "myJson", 'dataFromJson' json [] ) ]- , dataFromSource "myData" []- , 'mark' 'Bar' []- , enc []- ]-@--}-dataFromSource :: T.Text -> [Format] -> Data-dataFromSource sourceName fmts =- let kvs = ("name" .= sourceName)- : if null fmts- then []- else [("format", object (concatMap formatProperty fmts))]- in (VLData, object kvs)---{-|--Declare data source from a url. The url can be a local path on a web server-or an external http(s) url. Used to create a data ( property, specification ) pair.-An optional list of field formatting instructions can be provided as the second-parameter or an empty list to use the default formatting. See the-<https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>-for details.--@-'toVegaLite'- [ dataFromUrl "data/weather.csv" [ 'Parse' [ ( "date", 'FoDate' "%Y-%m-%d %H:%M" ) ] ]- , 'mark' 'Line' []- , enc []- ]-@--}--- TODO: should use a URL type-dataFromUrl :: T.Text -> [Format] -> Data-dataFromUrl url fmts =- let kvs = ("url" .= url)- : if null fmts- then []- else [("format", object (concatMap formatProperty fmts))]- in (VLData, object kvs)----- | Type of visual mark used to represent data in the visualization.-data Mark- = Area- | Bar- | Circle- | Geoshape- | Line- | Point- | Rect- | Rule- | Square- | Text- | Tick---markLabel :: Mark -> T.Text-markLabel Area = "area"-markLabel Bar = "bar"-markLabel Circle = "circle"-markLabel Line = "line"-markLabel Geoshape = "geoshape"-markLabel Point = "point"-markLabel Rect = "rect"-markLabel Rule = "rule"-markLabel Square = "square"-markLabel Text = "text"-markLabel Tick = "tick"---{-|--Create a mark specification. All marks must have a type (first parameter) and-can optionally be customised with a list of mark properties such as interpolation-style for lines. To keep the default style for the mark, just provide an empty list-for the second parameter.--@-mark 'Circle' []-mark 'Line' [ 'MInterpolate' 'StepAfter' ]-@--}-mark :: Mark -> [MarkProperty] -> (VLProperty, VLSpec)-mark mrk props =- let jsName = toJSON (markLabel mrk)- vals = if null props- then jsName- else object (("type" .= jsName) : map markProperty props)-- in (VLMark, vals)---{-|--Mark channel properties used for creating a mark channel encoding.--}-data MarkChannel- = MName T.Text- | MRepeat Arrangement- | MmType Measurement- | MScale [ScaleProperty]- -- ^ Use an empty list to remove the scale.- | MBin [BinProperty]- | MTimeUnit TimeUnit- | MAggregate Operation- | MLegend [LegendProperty]- -- ^ Use an empty list to remove the legend.- | MSelectionCondition BooleanOp [MarkChannel] [MarkChannel]- | MDataCondition BooleanOp [MarkChannel] [MarkChannel]- | MPath T.Text- | MNumber Double- | MString T.Text- | MBoolean Bool---markChannelProperty :: MarkChannel -> [LabelledSpec]-markChannelProperty (MName s) = [field_ s]-markChannelProperty (MRepeat arr) = ["field" .= object [repeat_ arr]]-markChannelProperty (MmType t) = [type_ t]-markChannelProperty (MScale sps) =- [("scale", if null sps then A.Null else object (map scaleProperty sps))]-markChannelProperty (MLegend lps) =- [("legend", if null lps then A.Null else object (map legendProperty lps))]-markChannelProperty (MBin bps) = [bin bps]-markChannelProperty (MSelectionCondition selName ifClause elseClause) =- let h = ("condition", hkey)- toProps = concatMap markChannelProperty- hkey = object (("selection", booleanOpSpec selName) : toProps ifClause)- hs = toProps elseClause- in h : hs-markChannelProperty (MDataCondition predicate ifClause elseClause) =- let h = ("condition", hkey)- toProps = concatMap markChannelProperty- hkey = object (("test", booleanOpSpec predicate) : toProps ifClause)- hs = toProps elseClause- in h : hs-markChannelProperty (MTimeUnit tu) = [timeUnit_ tu]-markChannelProperty (MAggregate op) = [aggregate_ op]-markChannelProperty (MPath s) = ["value" .= s]-markChannelProperty (MNumber x) = ["value" .= x]-markChannelProperty (MString s) = ["value" .= s]-markChannelProperty (MBoolean b) = ["value" .= b]---{-|--Properties for customising the appearance of a mark. For details see the-<https://vega.github.io/vega-lite/docs/mark.html#config Vega-Lite documentation>.--Not all properties are valid for each mark type.--}-data MarkProperty- = MAlign HAlign- | MAngle Double- | MBandSize Double- | MBaseline VAlign- | MBinSpacing Double- | MClip Bool- | MColor T.Text- | MCursor Cursor- | MContinuousBandSize Double- | MDiscreteBandSize Double- | MdX Double- | MdY Double- | MFill T.Text- | MFilled Bool- | MFillOpacity Double- | MFont T.Text- | MFontSize Double- | MFontStyle T.Text- | MFontWeight FontWeight- | MInterpolate MarkInterpolation- | MOpacity Double- | MOrient MarkOrientation- | MRadius Double- | MShape Symbol- | MShortTimeLabels Bool- | MSize Double- | MStroke T.Text- | MStrokeDash [Double]- | MStrokeDashOffset Double- | MStrokeOpacity Double- | MStrokeWidth Double- | MStyle [T.Text]- | MTension Double- | MText T.Text- | MTheta Double- | MThickness Double---markProperty :: MarkProperty -> LabelledSpec-markProperty (MFilled b) = ("filled", toJSON b)-markProperty (MClip b) = ("clip", toJSON b)-markProperty (MColor col) = ("color", toJSON col)-markProperty (MCursor cur) = ("cursor", toJSON (cursorLabel cur))-markProperty (MFill col) = ("fill", toJSON col)-markProperty (MStroke t) = ("stroke", toJSON t)-markProperty (MStrokeOpacity x) = ("strokeOpacity", toJSON x)-markProperty (MStrokeWidth w) = ("strokeWidth", toJSON w)-markProperty (MStrokeDash xs) = ("strokeDash", toJSON (map toJSON xs))-markProperty (MStrokeDashOffset x) = ("strokeDashOffset", toJSON x)-markProperty (MOpacity x) = ("opacity", toJSON x)-markProperty (MFillOpacity x) = ("fillOpacity", toJSON x)-markProperty (MStyle styles) = ("style", toJSON (map toJSON styles))-markProperty (MInterpolate interp) = ("interpolate", toJSON (markInterpolationLabel interp))-markProperty (MTension x) = ("tension", toJSON x)-markProperty (MOrient orient) = ("orient", toJSON (markOrientationLabel orient))-markProperty (MShape sym) = ("shape", toJSON (symbolLabel sym))-markProperty (MSize x) = ("size", toJSON x)-markProperty (MAngle x) = ("angle", toJSON x)-markProperty (MAlign align) = ("align", toJSON (hAlignLabel align))-markProperty (MBaseline va) = ("baseline", toJSON (vAlignLabel va))-markProperty (MdX dx) = ("dx", toJSON dx)-markProperty (MdY dy) = ("dy", toJSON dy)-markProperty (MFont fnt) = ("font", toJSON fnt)-markProperty (MFontSize x) = ("fontSize", toJSON x)-markProperty (MFontStyle fSty) = ("fontStyle", toJSON fSty)-markProperty (MFontWeight w) = ("fontWeight", fontWeightSpec w)-markProperty (MRadius x) = ("radius", toJSON x)-markProperty (MText txt) = ("text", toJSON txt)-markProperty (MTheta x) = ("theta", toJSON x)-markProperty (MBinSpacing x) = ("binSpacing", toJSON x)-markProperty (MContinuousBandSize x) = ("continuousBandSize", toJSON x)-markProperty (MDiscreteBandSize x) = ("discreteBandSize", toJSON x)-markProperty (MShortTimeLabels b) = ("shortTimeLabels", toJSON b)-markProperty (MBandSize x) = ("bandSize", toJSON x)-markProperty (MThickness x) = ("thickness", toJSON x)---{-|--Create an encoding specification from a list of channel encodings.--@-enc = encoding- . 'position' 'X' [ 'PName' \"Animal\", 'PmType' 'Ordinal' ]- . position 'Y' [ PName \"Age\", PmType 'Quantitative' ]- . 'shape' [ 'MName' \"Species\", 'MmType' 'Nominal' ]- . 'size' [ MName \"Population\", MmType Quantitative ]-@--}-encoding :: [LabelledSpec] -> (VLProperty, VLSpec)-encoding channels = (VLEncoding, object channels)---{-|--Type of position channel, @X@ and @Y@ represent horizontal and vertical axis-dimensions on a plane and @X2@ and @Y2@ represent secondary axis dimensions where-two scales are overlaid in the same space. Geographic positions represented by-longitude and latiutude values are identified with @Longitude@, @Latitude@ and-their respective secondary equivalents. Such geographic position channels are-subject to a map projection (set using 'projection') before being placed graphically.--}-data Position- = X- | Y- | X2- | Y2- | Longitude- | Latitude- | Longitude2- | Latitude2---{-|--Type of measurement to be associated with some channel.---}--data Measurement- = Nominal- -- ^ Data are categories identified by name alone and which have no intrinsic order.- | Ordinal- -- ^ Data are also categories, but ones which have some natural order.- | Quantitative- -- ^ Data are numeric measurements typically on a continuous scale.- | Temporal- -- ^ Data represents time in some manner.- | GeoFeature- -- ^ Geospatial position encoding ('Longitude' and 'Latitude') should specify the 'PmType'- -- as @Quantitative@. Geographically referenced features encoded as 'shape' marks- -- should specify 'MmType' as @GeoFeature@ (Vega-Lite currently refers to this type- -- as @<https://vega.github.io/vega-lite/docs/encoding.html geojson>@.---{-|--Type of binning property to customise. See the-<https://vega.github.io/vega-lite/docs/bin.html Vega-Lite documentation> for-more details.--}--data BinProperty- = Base Double- | Divide Double Double- | Extent Double Double- | MaxBins Int- | MinStep Double- | Nice Bool- | Step Double- | Steps [Double]---binProperty :: BinProperty -> LabelledSpec-binProperty (MaxBins n) = ("maxbins", toJSON n)-binProperty (Base x) = ("base", toJSON x)-binProperty (Step x) = ("step", toJSON x)-binProperty (Steps xs) = ("steps", toJSON (map toJSON xs))-binProperty (MinStep x) = ("minstep", toJSON x)-binProperty (Divide x y) = ("divide", toJSON [ toJSON x, toJSON y ])-binProperty (Extent mn mx) = ("extent", toJSON [ toJSON mn, toJSON mx ])-binProperty (Nice b) = ("nice", toJSON b)---bin :: [BinProperty] -> LabelledSpec-bin bProps =- let ans = if null bProps- then toJSON True- else object (map binProperty bProps)- in ("bin", ans)---{-|--Type of aggregation operation. See the-<https://vega.github.io/vega-lite/docs/aggregate.html#ops Vega-Lite documentation>-for more details.--}-data Operation- = ArgMax- | ArgMin- | Average- | CI0- | CI1- | Count- | Distinct- | Max- | Mean- | Median- | Min- | Missing- | Q1- | Q3- | Stderr- | Stdev- | StdevP- | Sum- | Valid- | Variance- | VarianceP---operationLabel :: Operation -> T.Text-operationLabel ArgMax = "argmax"-operationLabel ArgMin = "argmin"-operationLabel Average = "average"-operationLabel CI0 = "ci0"-operationLabel CI1 = "ci1"-operationLabel Count = "count"-operationLabel Distinct = "distinct"-operationLabel Max = "max"-operationLabel Mean = "mean"-operationLabel Median = "median"-operationLabel Min = "min"-operationLabel Missing = "missing"-operationLabel Q1 = "q1"-operationLabel Q3 = "q3"-operationLabel Stderr = "stderr"-operationLabel Stdev = "stdev"-operationLabel StdevP = "stdevp"-operationLabel Sum = "sum"-operationLabel Valid = "valid"-operationLabel Variance = "variance"-operationLabel VarianceP = "variancep"----- | Identifies whether a repeated or faceted view is arranged in rows or columns.--data Arrangement- = Column- | Row--arrangementLabel :: Arrangement -> T.Text-arrangementLabel Column = "column"-arrangementLabel Row = "row"----- | Describes the type of stacking to apply to a bar chart.--data StackProperty- = StZero- | StNormalize- | StCenter- | NoStack---stackProperty :: StackProperty -> LabelledSpec-stackProperty StZero = ("stack", "zero")-stackProperty StNormalize = ("stack", "normalize")-stackProperty StCenter = ("stack", "center")-stackProperty NoStack = ("stack", A.Null)---{-|--Individual scale property. These are used to customise an individual scale-transformation. To customise all scales use 'config' and supply relevant-'ScaleConfig' values. For more details see the-<https://vega.github.io/vega-lite/docs/scale.html Vega-Lite documentation>.---}--data ScaleProperty- = SType Scale- | SDomain ScaleDomain- | SRange ScaleRange- | SScheme T.Text [Double]- | SPadding Double- | SPaddingInner Double- | SPaddingOuter Double- | SRangeStep (Maybe Double)- | SRound Bool- | SClamp Bool- -- TODO: Need to restrict set of valid scale types that work with color interpolation.- | SInterpolate CInterpolate- | SNice ScaleNice- | SZero Bool- -- TODO: remove this- | SReverse Bool- -- ^ This is a Vega, rather than Vega-Lite, property and its use will generate- -- warnings when you validate the JSON against the schema. The order- -- of a scale (e.g. axis) can be reversed by setting @'PSort' ['Descending']@.- --- -- This property will be removed in a future release.---scaleProperty :: ScaleProperty -> LabelledSpec-scaleProperty (SType sType) = ("type", toJSON (scaleLabel sType))-scaleProperty (SDomain sdType) = ("domain", scaleDomainSpec sdType)-scaleProperty (SRange range) =- let js = case range of- RNumbers xs -> toJSON (map toJSON xs)- RStrings ss -> toJSON (map toJSON ss)- RName s -> toJSON s- in ("range", js)-scaleProperty (SScheme nme extent) = schemeProperty nme extent-scaleProperty (SPadding x) = ("padding", toJSON x)-scaleProperty (SPaddingInner x) = ("paddingInner", toJSON x)-scaleProperty (SPaddingOuter x) = ("paddingOuter", toJSON x)-scaleProperty (SRangeStep numOrNull) = ("rangeStep", maybe A.Null toJSON numOrNull)-scaleProperty (SRound b) = ("round", toJSON b)-scaleProperty (SClamp b) = ("clamp", toJSON b)-scaleProperty (SInterpolate interp) = ("interpolate", cInterpolateSpec interp)-scaleProperty (SNice ni) = ("nice", scaleNiceSpec ni)-scaleProperty (SZero b) = ("zero", toJSON b)-scaleProperty (SReverse b) = ("reverse", toJSON b)---schemeProperty :: T.Text -> [Double] -> LabelledSpec-schemeProperty nme extent =- let js = case extent of- [mn, mx] -> object ["name" .= nme, "extent" .= [mn, mx]]- _ -> toJSON nme-- in ("scheme", js)----- | Used to indicate the type of scale transformation to apply.--data Scale- = ScLinear- | ScPow- | ScSqrt- | ScLog- | ScTime- | ScUtc- | ScSequential- | ScOrdinal- | ScBand- | ScPoint- | ScBinLinear- | ScBinOrdinal---scaleLabel :: Scale -> T.Text-scaleLabel ScLinear = "linear"-scaleLabel ScPow = "pow"-scaleLabel ScSqrt = "sqrt"-scaleLabel ScLog = "log"-scaleLabel ScTime = "time"-scaleLabel ScUtc = "utc"-scaleLabel ScSequential = "sequential"-scaleLabel ScOrdinal = "ordinal"-scaleLabel ScBand = "band"-scaleLabel ScPoint = "point"-scaleLabel ScBinLinear = "bin-linear"-scaleLabel ScBinOrdinal = "bin-ordinal"---{-|--Describes the scale domain (type of data in scale). For full details see the-<https://vega.github.io/vega-lite/docs/scale.html#domain Vega-Lite documentation>.--}--data ScaleDomain- = DNumbers [Double]- | DStrings [T.Text]- | DDateTimes [[DateTime]]- | DSelection T.Text- | Unaggregated---scaleDomainSpec :: ScaleDomain -> VLSpec-scaleDomainSpec (DNumbers nums) = toJSON (map toJSON nums)-scaleDomainSpec (DDateTimes dts) = toJSON (map (object . map dateTimeProperty) dts)-scaleDomainSpec (DStrings cats) = toJSON (map toJSON cats)-scaleDomainSpec (DSelection selName) = object ["selection" .= selName]-scaleDomainSpec Unaggregated = "unaggregated"---{-|--Describes the way a scale can be rounded to \"nice\" numbers. For full details see the-<https://vega.github.io/vega-lite/docs/scale.html#continuous Vega-Lite documentation>.--}-data ScaleNice- = NMillisecond- | NSecond- | NMinute- | NHour- | NDay- | NWeek- | NMonth- | NYear- | NInterval TimeUnit Int- | IsNice Bool- | NTickCount Int---scaleNiceSpec :: ScaleNice -> VLSpec-scaleNiceSpec NMillisecond = fromT "millisecond"-scaleNiceSpec NSecond = fromT "second"-scaleNiceSpec NMinute = fromT "minute"-scaleNiceSpec NHour = fromT "hour"-scaleNiceSpec NDay = fromT "day"-scaleNiceSpec NWeek = fromT "week"-scaleNiceSpec NMonth = fromT "month"-scaleNiceSpec NYear = fromT "year"-scaleNiceSpec (NInterval tu step) =- object ["interval" .= timeUnitLabel tu, "step" .= step]-scaleNiceSpec (IsNice b) = toJSON b-scaleNiceSpec (NTickCount n) = toJSON n---{-|--Describes a scale range of scale output values. For full details see the-<https://vega.github.io/vega-lite/docs/scale.html#range Vega-Lite documentation>.--}--data ScaleRange- = RNumbers [Double]- | RStrings [T.Text]- | RName T.Text---{-|--Indicates the type of color interpolation to apply, when mapping a data field-onto a color scale. Note that color interpolation cannot be applied with the default-\"sequential\" color scale ('ScSequential'), so additionally, you should set the-'SType' to another continuous scale such as 'ScLinear' and 'ScPow'.--For details see the-<https://vega.github.io/vega-lite/docs/scale.html#continuous Vega-Lite documentation>.--}-data CInterpolate- = CubeHelix Double- -- ^ The numeric value is the gamma value for the scheme (the recommended- -- value is 1).- | CubeHelixLong Double- -- ^ The numeric value is the gamma value for the scheme (the recommended- -- value is 1).- | Hcl- | HclLong- | Hsl- | HslLong- | Lab- | Rgb Double- -- ^ The numeric value is the gamma value for the scheme (the recommended- -- value is 1).----- Need to tie down some types as things are too polymorphic,--- particularly in the presence of OverloadedStrings.----pairT :: T.Text -> T.Text -> (T.Text, Value)-pairT a b = a .= b---cInterpolateSpec :: CInterpolate -> VLSpec-cInterpolateSpec (Rgb gamma) = object [pairT "type" "rgb", "gamma" .= gamma]-cInterpolateSpec Hsl = object [pairT "type" "hsl"]-cInterpolateSpec HslLong = object [pairT "type" "hsl-long"]-cInterpolateSpec Lab = object [pairT "type" "lab"]-cInterpolateSpec Hcl = object [pairT "type" "hcl"]-cInterpolateSpec HclLong = object [pairT "type" "hcl-long"]-cInterpolateSpec (CubeHelix gamma) = object [pairT "type" "cubehelix", "gamma" .= gamma]-cInterpolateSpec (CubeHelixLong gamma) = object [pairT "type" "cubehelix-long", "gamma" .= gamma]---{-|--Allow type of sorting to be customised. For details see the-<https://vega.github.io/vega-lite/docs/sort.html Vega-Lite documentation>.--}-data SortProperty- = Ascending- | Descending- | Op Operation- | ByField T.Text- | ByRepeat Arrangement---sortProperty :: SortProperty -> LabelledSpec-sortProperty Ascending = "order" .= fromT "ascending"-sortProperty Descending = "order" .= fromT "descending"-sortProperty (ByField field) = field_ field-sortProperty (Op op) = op_ op-sortProperty (ByRepeat arr) = ("field", object [repeat_ arr])---sortPropertySpec :: [SortProperty] -> VLSpec-sortPropertySpec [] = A.Null-sortPropertySpec [Ascending] = fromT "ascending"-sortPropertySpec [Descending] = fromT "descending"-sortPropertySpec ops = object (map sortProperty ops)----- | Position channel properties used for creating a position channel encoding.--data PositionChannel- = PName T.Text- | PRepeat Arrangement- | PmType Measurement- | PBin [BinProperty]- | PTimeUnit TimeUnit- | PAggregate Operation- | PScale [ScaleProperty]- | PAxis [AxisProperty]- | PSort [SortProperty]- | PStack StackProperty---positionChannelProperty :: PositionChannel -> LabelledSpec-positionChannelProperty (PName s) = field_ s-positionChannelProperty (PRepeat arr) = "field" .= object [repeat_ arr]-positionChannelProperty (PmType m) = type_ m-positionChannelProperty (PBin b) = bin b-positionChannelProperty (PTimeUnit tu) = timeUnit_ tu-positionChannelProperty (PAggregate op) = aggregate_ op-positionChannelProperty (PScale sps) =- let js = if null sps- then A.Null- else object (map scaleProperty sps)- in "scale" .= js-positionChannelProperty (PAxis aps) =- let js = if null aps- then A.Null- else object (map axisProperty aps)- in "axis" .= js-positionChannelProperty (PSort ops) = sort_ ops-positionChannelProperty (PStack sp) = stackProperty sp---measurementLabel :: Measurement -> T.Text-measurementLabel Nominal = "nominal"-measurementLabel Ordinal = "ordinal"-measurementLabel Quantitative = "quantitative"-measurementLabel Temporal = "temporal"-measurementLabel GeoFeature = "geojson"---positionLabel :: Position -> T.Text-positionLabel X = "x"-positionLabel Y = "y"-positionLabel X2 = "x2"-positionLabel Y2 = "y2"-positionLabel Longitude = "longitude"-positionLabel Latitude = "latitude"-positionLabel Longitude2 = "longitude2"-positionLabel Latitude2 = "latitude2"---{-|--Set the background color of the visualization. Should be specified with a CSS-string such as @\"#ffe\"@ or @\"rgb(200,20,150)\"@. If not specified the background will-be transparent.--@-'toVegaLite'- [ background "rgb(251,247,238)"- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-background :: T.Text -> (VLProperty, VLSpec)-background colour = (VLBackground, toJSON colour)---{-|--Provides an optional description to be associated with the visualization.--@-'toVegaLite'- [ description "Population change of key regions since 1900"- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-description :: T.Text -> (VLProperty, VLSpec)-description s = (VLDescription, toJSON s)---{-|--Provide an optional title to be displayed in the visualization.--@-'toVegaLite'- [ title "Population Growth"- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-title :: T.Text -> (VLProperty, VLSpec)-title s = (VLTitle, toJSON s)---{-|--Axis customisation properties. These are used for customising individual axes.-To configure all axes, use 'AxisConfig' with a 'configuration' instead. See the-<https://vega.github.io/vega-lite/docs/axis.html#axis-properties Vega-Lite documentation>-for more details.--}-data AxisProperty- = AxDomain Bool- | AxFormat T.Text- | AxGrid Bool- | AxLabelAngle Double- | AxLabelOverlap OverlapStrategy- | AxLabelPadding Double- | AxLabels Bool- | AxMaxExtent Double- | AxMinExtent Double- | AxOffset Double- | AxOrient Side- | AxPosition Double- | AxTicks Bool- | AxTickCount Int- | AxTickSize Double- | AxTitle T.Text- | AxTitleAlign HAlign- | AxTitleAngle Double- | AxTitleMaxLength Double- | AxTitlePadding Double- | AxValues [Double]- | AxDates [[DateTime]]- | AxZIndex Int---axisProperty :: AxisProperty -> LabelledSpec-axisProperty (AxFormat fmt) = "format" .= fmt-axisProperty (AxLabels b) = "labels" .= b-axisProperty (AxLabelAngle a) = "labelAngle" .= a-axisProperty (AxLabelOverlap s) = "labelOverlap" .= overlapStrategyLabel s-axisProperty (AxLabelPadding pad) = "labelPadding" .= pad-axisProperty (AxDomain b) = "domain" .= b-axisProperty (AxGrid b) = "grid" .= b-axisProperty (AxMaxExtent n) = "maxExtent" .= n-axisProperty (AxMinExtent n) = "minExtent" .= n-axisProperty (AxOrient side) = "orient" .= sideLabel side-axisProperty (AxOffset n) = "offset" .= n-axisProperty (AxPosition n) = "position" .= n-axisProperty (AxZIndex n) = "zindex" .= n-axisProperty (AxTicks b) = "ticks" .= b-axisProperty (AxTickCount n) = "tickCount" .= n-axisProperty (AxTickSize sz) = "tickSize" .= sz-axisProperty (AxValues vals) = "values" .= map toJSON vals-axisProperty (AxDates dtss) = "values" .= map (object . map dateTimeProperty) dtss-axisProperty (AxTitle ttl) = "title" .= ttl-axisProperty (AxTitleAlign align) = "titleAlign" .= hAlignLabel align-axisProperty (AxTitleAngle angle) = "titleAngle" .= angle-axisProperty (AxTitleMaxLength len) = "titleMaxLength" .= len-axisProperty (AxTitlePadding pad) = "titlePadding" .= pad----- | Indicates the horizontal alignment of text such as on an axis or legend.--data HAlign- = AlignCenter- | AlignLeft- | AlignRight----- | Indicates the vertical alignment of text that may be attached to a mark.--data VAlign- = AlignTop- | AlignMiddle- | AlignBottom---hAlignLabel :: HAlign -> T.Text-hAlignLabel AlignLeft = "left"-hAlignLabel AlignCenter = "center"-hAlignLabel AlignRight = "right"---vAlignLabel :: VAlign -> T.Text-vAlignLabel AlignTop = "top"-vAlignLabel AlignMiddle = "middle"-vAlignLabel AlignBottom = "bottom"----- | Represents one side of a rectangular space.--data Side- = STop- | SBottom- | SLeft- | SRight---sideLabel :: Side -> T.Text-sideLabel STop = "top"-sideLabel SBottom = "bottom"-sideLabel SLeft = "left"-sideLabel SRight = "right"---{-|--Type of overlap strategy to be applied when there is not space to show all items-on an axis. See the-<https://vega.github.io/vega-lite/docs/axis.html#labels Vega-Lite documentation>-for more details.--}--data OverlapStrategy- = ONone- | OParity- | OGreedy---overlapStrategyLabel :: OverlapStrategy -> T.Text-overlapStrategyLabel ONone = "false"-overlapStrategyLabel OParity = "parity"-overlapStrategyLabel OGreedy = "greedy"---{-|--Allows a date or time to be represented. This is typically part of a list of-@DateTime@ items to provide a specific point in time. For details see the-<https://vega.github.io/vega-lite/docs/types.html#datetime Vega-Lite documentation>.--}--data DateTime- = DTYear Int- | DTQuarter Int- | DTMonth MonthName- | DTDate Int- | DTDay DayName- | DTHours Int- | DTMinutes Int- | DTSeconds Int- | DTMilliseconds Int----- | Identifies the day of the week.--data DayName- = Mon- | Tue- | Wed- | Thu- | Fri- | Sat- | Sun----- | Identifies a month of the year.--data MonthName- = Jan- | Feb- | Mar- | Apr- | May- | Jun- | Jul- | Aug- | Sep- | Oct- | Nov- | Dec---{-|--Describes a unit of time. Useful for encoding and transformations. See the-<https://vega.github.io/vega-lite/docs/timeunit.html Vega-Lite documentation>-for further details.--@-'encoding'- . 'position' 'X' [ 'PName' "date", 'PmType' 'Temporal', 'PTimeUnit' (Utc 'YearMonthDateHours') ]-@--}--data TimeUnit- = Year- | YearQuarter- | YearQuarterMonth- | YearMonth- | YearMonthDate- | YearMonthDateHours- | YearMonthDateHoursMinutes- | YearMonthDateHoursMinutesSeconds- | Quarter- | QuarterMonth- | Month- | MonthDate- | Date- | Day- | Hours- | HoursMinutes- | HoursMinutesSeconds- | Minutes- | MinutesSeconds- | Seconds- | SecondsMilliseconds- | Milliseconds- | Utc TimeUnit- -- ^ Encode a time as UTC (coordinated universal time, independent of local time- -- zones or daylight saving).---dateTimeProperty :: DateTime -> LabelledSpec-dateTimeProperty (DTYear y) = "year" .= y-dateTimeProperty (DTQuarter q) = "quarter" .= q-dateTimeProperty (DTMonth mon) = "month" .= monthNameLabel mon-dateTimeProperty (DTDate dt) = "date" .= dt-dateTimeProperty (DTDay day) = "day" .= dayLabel day-dateTimeProperty (DTHours h) = "hours" .= h-dateTimeProperty (DTMinutes m) = "minutes" .= m-dateTimeProperty (DTSeconds s) = "seconds" .= s-dateTimeProperty (DTMilliseconds ms) = "milliseconds" .= ms---dayLabel :: DayName -> T.Text-dayLabel Mon = "Mon"-dayLabel Tue = "Tue"-dayLabel Wed = "Wed"-dayLabel Thu = "Thu"-dayLabel Fri = "Fri"-dayLabel Sat = "Sat"-dayLabel Sun = "Sun"---monthNameLabel :: MonthName -> T.Text-monthNameLabel Jan = "Jan"-monthNameLabel Feb = "Feb"-monthNameLabel Mar = "Mar"-monthNameLabel Apr = "Apr"-monthNameLabel May = "May"-monthNameLabel Jun = "Jun"-monthNameLabel Jul = "Jul"-monthNameLabel Aug = "Aug"-monthNameLabel Sep = "Sep"-monthNameLabel Oct = "Oct"-monthNameLabel Nov = "Nov"-monthNameLabel Dec = "Dec"---timeUnitLabel :: TimeUnit -> T.Text-timeUnitLabel Year = "year"-timeUnitLabel YearQuarter = "yearquarter"-timeUnitLabel YearQuarterMonth = "yearquartermonth"-timeUnitLabel YearMonth = "yearmonth"-timeUnitLabel YearMonthDate = "yearmonthdate"-timeUnitLabel YearMonthDateHours = "yearmonthdatehours"-timeUnitLabel YearMonthDateHoursMinutes = "yearmonthdatehoursminutes"-timeUnitLabel YearMonthDateHoursMinutesSeconds = "yearmonthdatehoursminutesseconds"-timeUnitLabel Quarter = "quarter"-timeUnitLabel QuarterMonth = "quartermonth"-timeUnitLabel Month = "month"-timeUnitLabel MonthDate = "monthdate"-timeUnitLabel Date = "date"-timeUnitLabel Day = "day"-timeUnitLabel Hours = "hours"-timeUnitLabel HoursMinutes = "hoursminutes"-timeUnitLabel HoursMinutesSeconds = "hoursminutesseconds"-timeUnitLabel Minutes = "minutes"-timeUnitLabel MinutesSeconds = "minutesseconds"-timeUnitLabel Seconds = "seconds"-timeUnitLabel SecondsMilliseconds = "secondsmilliseconds"-timeUnitLabel Milliseconds = "milliseconds"-timeUnitLabel (Utc tu) = "utc" <> timeUnitLabel tu---{-|--Represents the type of cursor to display. For an explanation of each type,-see the-<https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Keyword%20values CSS documentation>.--}-data Cursor- = CAuto- | CDefault- | CNone- | CContextMenu- | CHelp- | CPointer- | CProgress- | CWait- | CCell- | CCrosshair- | CText- | CVerticalText- | CAlias- | CCopy- | CMove- | CNoDrop- | CNotAllowed- | CAllScroll- | CColResize- | CRowResize- | CNResize- | CEResize- | CSResize- | CWResize- | CNEResize- | CNWResize- | CSEResize- | CSWResize- | CEWResize- | CNSResize- | CNESWResize- | CNWSEResize- | CZoomIn- | CZoomOut- | CGrab- | CGrabbing---cursorLabel :: Cursor -> T.Text-cursorLabel CAuto = "auto"-cursorLabel CDefault = "default"-cursorLabel CNone = "none"-cursorLabel CContextMenu = "context-menu"-cursorLabel CHelp = "help"-cursorLabel CPointer = "pointer"-cursorLabel CProgress = "progress"-cursorLabel CWait = "wait"-cursorLabel CCell = "cell"-cursorLabel CCrosshair = "crosshair"-cursorLabel CText = "text"-cursorLabel CVerticalText = "vertical-text"-cursorLabel CAlias = "alias"-cursorLabel CCopy = "copy"-cursorLabel CMove = "move"-cursorLabel CNoDrop = "no-drop"-cursorLabel CNotAllowed = "not-allowed"-cursorLabel CAllScroll = "all-scroll"-cursorLabel CColResize = "col-resize"-cursorLabel CRowResize = "row-resize"-cursorLabel CNResize = "n-resize"-cursorLabel CEResize = "e-resize"-cursorLabel CSResize = "s-resize"-cursorLabel CWResize = "w-resize"-cursorLabel CNEResize = "ne-resize"-cursorLabel CNWResize = "nw-resize"-cursorLabel CSEResize = "se-resize"-cursorLabel CSWResize = "sw-resize"-cursorLabel CEWResize = "ew-resize"-cursorLabel CNSResize = "ns-resize"-cursorLabel CNESWResize = "nesw-resize"-cursorLabel CNWSEResize = "nwse-resize"-cursorLabel CZoomIn = "zoom-in"-cursorLabel CZoomOut = "zoom-out"-cursorLabel CGrab = "grab"-cursorLabel CGrabbing = "grabbing"----- | Indicates the weight options for a font.--data FontWeight- = Bold- | Bolder- | Lighter- | Normal- | W100- | W200- | W300- | W400- | W500- | W600- | W700- | W800- | W900---fontWeightSpec :: FontWeight -> VLSpec-fontWeightSpec Bold = fromT "bold"-fontWeightSpec Bolder = fromT "bolder"-fontWeightSpec Lighter = fromT "lighter"-fontWeightSpec Normal = fromT "normal"-fontWeightSpec W100 = fromF 100-fontWeightSpec W200 = fromF 200-fontWeightSpec W300 = fromF 300-fontWeightSpec W400 = fromF 400-fontWeightSpec W500 = fromF 500-fontWeightSpec W600 = fromF 600-fontWeightSpec W700 = fromF 700-fontWeightSpec W800 = fromF 800-fontWeightSpec W900 = fromF 900---{-|--Indicates mark interpolation style. See the-<https://vega.github.io/vega-lite/docs/mark.html#mark-def Vega-Lite documentation>-for details.--}-data MarkInterpolation- = Basis- | BasisClosed- | BasisOpen- | Bundle- | Cardinal- | CardinalClosed- | CardinalOpen- | Linear- | LinearClosed- | Monotone- | StepAfter- | StepBefore- | Stepwise---markInterpolationLabel :: MarkInterpolation -> T.Text-markInterpolationLabel Linear = "linear"-markInterpolationLabel LinearClosed = "linear-closed"-markInterpolationLabel Stepwise = "step"-markInterpolationLabel StepBefore = "step-before"-markInterpolationLabel StepAfter = "step-after"-markInterpolationLabel Basis = "basis"-markInterpolationLabel BasisOpen = "basis-open"-markInterpolationLabel BasisClosed = "basis-closed"-markInterpolationLabel Cardinal = "cardinal"-markInterpolationLabel CardinalOpen = "cardinal-open"-markInterpolationLabel CardinalClosed = "cardinal-closed"-markInterpolationLabel Bundle = "bundle"-markInterpolationLabel Monotone = "monotone"---{-|--Indicates desired orientation of a mark (e.g. horizontally or vertically-oriented bars).--}-data MarkOrientation- = Horizontal- | Vertical---markOrientationLabel :: MarkOrientation -> T.Text-markOrientationLabel Horizontal = "horizontal"-markOrientationLabel Vertical = "vertical"----- | Identifies the type of symbol.--data Symbol- = SymCircle- | SymSquare- | Cross- | Diamond- | TriangleUp- | TriangleDown- | Path T.Text- -- ^ Define a custom shape with a SVG path description.---symbolLabel :: Symbol -> T.Text-symbolLabel SymCircle = "circle"-symbolLabel SymSquare = "square"-symbolLabel Cross = "cross"-symbolLabel Diamond = "diamond"-symbolLabel TriangleUp = "triangle-up"-symbolLabel TriangleDown = "triangle-down"-symbolLabel (Path svgPath) = svgPath---{-|--Indicates the auto-sizing characteristics of the visualization such as amount-of padding, whether it should fill the parent container etc. For more details see the-<https://vega.github.io/vega-lite/docs/size.html#autosize Vega-Lite documentation>.--}--data Autosize- = AContent- | AFit- | ANone- | APad- | APadding- | AResize---autosizeProperty :: Autosize -> LabelledSpec-autosizeProperty APad = ("type", fromT "pad")-autosizeProperty AFit = ("type", fromT "fit")-autosizeProperty ANone = ("type", fromT "none")-autosizeProperty AResize = "resize".= True-autosizeProperty AContent = ("contains", fromT "content")-autosizeProperty APadding = ("contains", fromT "padding")---{-|--Declare the way the view is sized. See the-<https://vega.github.io/vega-lite/docs/size.html#autosize Vega-Lite documentation>-for details.--@-'toVegaLite'- [ 'width' 250- , 'height' 300- , autosize [ 'AFit', 'APadding', 'AResize' ]- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-autosize :: [Autosize] -> (VLProperty, VLSpec)-autosize aus = (VLAutosize, object (map autosizeProperty aus))----- | Indicates the style in which field names are displayed.--data FieldTitleProperty- = Verbal- -- ^ Creates \"Sum of field\", \"Year of date\", \"field (binned)\", etc.- | Function- -- ^ Creates \"SUM(field)\", \"YEAR(date)\", \"BIN(field)\", etc.- | Plain- -- ^ Just use the field name without any extra text.---fieldTitleLabel :: FieldTitleProperty -> T.Text-fieldTitleLabel Verbal = "verbal"-fieldTitleLabel Function = "function"-fieldTitleLabel Plain = "plain"----- | Indicates the type of legend to create.--data Legend- = Gradient- -- ^ Typically used for continuous quantitative data.- | Symbol- -- ^ Typically used for categorical data.---legendLabel :: Legend -> T.Text-legendLabel Gradient = "gradient"-legendLabel Symbol = "symbol"---{-|--Legend configuration options. For more detail see the-<https://vega.github.io/vega-lite/docs/legend.html#config Vega-Lite documentation>.--}--data LegendConfig- = CornerRadius Double- | FillColor T.Text- | Orient LegendOrientation- | Offset Double- | StrokeColor T.Text- | LeStrokeDash [Double]- | LeStrokeWidth Double- | LePadding Double- | GradientLabelBaseline VAlign- | GradientLabelLimit Double- | GradientLabelOffset Double- | GradientStrokeColor T.Text- | GradientStrokeWidth Double- | GradientHeight Double- | GradientWidth Double- | LeLabelAlign HAlign- | LeLabelBaseline VAlign- | LeLabelColor T.Text- | LeLabelFont T.Text- | LeLabelFontSize Double- | LeLabelLimit Double- | LeLabelOffset Double- | LeShortTimeLabels Bool- | EntryPadding Double- | SymbolColor T.Text- | SymbolType Symbol- | SymbolSize Double- | SymbolStrokeWidth Double- | LeTitleAlign HAlign- | LeTitleBaseline VAlign- | LeTitleColor T.Text- | LeTitleFont T.Text- | LeTitleFontSize Double- | LeTitleFontWeight FontWeight- | LeTitleLimit Double- | LeTitlePadding Double---legendConfigProperty :: LegendConfig -> LabelledSpec-legendConfigProperty (CornerRadius r) = "cornerRadius" .= r-legendConfigProperty (FillColor s) = "fillColor" .= s-legendConfigProperty (Orient orl) = "orient" .= legendOrientLabel orl-legendConfigProperty (Offset x) = "offset" .= x-legendConfigProperty (StrokeColor s) = "strokeColor" .= s-legendConfigProperty (LeStrokeDash xs) = "strokeDash" .= map toJSON xs-legendConfigProperty (LeStrokeWidth x) = "strokeWidth" .= x-legendConfigProperty (LePadding x) = "padding" .= x-legendConfigProperty (GradientLabelBaseline va) = "gradientLabelBaseline" .= vAlignLabel va-legendConfigProperty (GradientLabelLimit x) = "gradientLabelLimit" .= x-legendConfigProperty (GradientLabelOffset x) = "gradientLabelOffset" .= x-legendConfigProperty (GradientStrokeColor s) = "gradientStrokeColor" .= s-legendConfigProperty (GradientStrokeWidth x) = "gradientStrokeWidth" .= x-legendConfigProperty (GradientHeight x) = "gradientHeight" .= x-legendConfigProperty (GradientWidth x) = "gradientWidth" .= x-legendConfigProperty (LeLabelAlign ha) = "labelAlign" .= hAlignLabel ha-legendConfigProperty (LeLabelBaseline va) = "labelBaseline" .= vAlignLabel va-legendConfigProperty (LeLabelColor s) = "labelColor" .= s-legendConfigProperty (LeLabelFont s) = "labelFont" .= s-legendConfigProperty (LeLabelFontSize x) = "labelFontSize" .= x-legendConfigProperty (LeLabelLimit x) = "labelLimit" .= x-legendConfigProperty (LeLabelOffset x) = "labelOffset" .= x-legendConfigProperty (LeShortTimeLabels b) = "shortTimeLabels" .= b-legendConfigProperty (EntryPadding x) = "entryPadding" .= x-legendConfigProperty (SymbolColor s) = "symbolColor" .= s-legendConfigProperty (SymbolType s) = "symbolType" .= symbolLabel s-legendConfigProperty (SymbolSize x) = "symbolSize" .= x-legendConfigProperty (SymbolStrokeWidth x) = "symbolStrokeWidth" .= x-legendConfigProperty (LeTitleAlign ha) = "titleAlign" .= hAlignLabel ha-legendConfigProperty (LeTitleBaseline va) = "titleBaseline" .= vAlignLabel va-legendConfigProperty (LeTitleColor s) = "titleColor" .= s-legendConfigProperty (LeTitleFont s) = "titleFont" .= s-legendConfigProperty (LeTitleFontSize x) = "titleFontSize" .= x-legendConfigProperty (LeTitleFontWeight fw) = "titleFontWeight" .= fontWeightSpec fw-legendConfigProperty (LeTitleLimit x) = "titleLimit" .= x-legendConfigProperty (LeTitlePadding x) = "titlePadding" .= x---{-|--Indicates the legend orientation. See the-<https://vega.github.io/vega-lite/docs/legend.html#config Vega-Lite documentation>-for more details.--}--data LegendOrientation- = LOBottomLeft- | LOBottomRight- | LOLeft- | LONone- | LORight- | LOTopLeft- | LOTopRight---legendOrientLabel :: LegendOrientation -> T.Text-legendOrientLabel LOLeft = "left"-legendOrientLabel LOBottomLeft = "bottom-left"-legendOrientLabel LOBottomRight = "bottom-right"-legendOrientLabel LORight = "right"-legendOrientLabel LOTopLeft = "top-left"-legendOrientLabel LOTopRight = "top-right"-legendOrientLabel LONone = "none"---{-|--Legend properties. For more detail see the-<https://vega.github.io/vega-lite/docs/legend.html#legend-properties Vega-Lite documentation>.--}-data LegendProperty- = LEntryPadding Double- | LFormat T.Text- | LOffset Double- | LOrient LegendOrientation- | LPadding Double- | LTickCount Double- | LTitle T.Text- | LType Legend- | LValues LegendValues- | LZIndex Int---legendProperty :: LegendProperty -> LabelledSpec-legendProperty (LType lType) = "type" .= legendLabel lType-legendProperty (LEntryPadding x) = "entryPadding" .= x-legendProperty (LFormat s) = "format" .= s-legendProperty (LOffset x) = "offset" .= x-legendProperty (LOrient orl) = "orient" .= legendOrientLabel orl-legendProperty (LPadding x) = "padding" .= x-legendProperty (LTickCount x) = "tickCount" .= x-legendProperty (LTitle ttl) = "title" .= if T.null ttl then A.Null else fromT ttl-legendProperty (LValues vals) =- let ls = case vals of- LNumbers xs -> map toJSON xs- LDateTimes dts -> map (object . map dateTimeProperty) dts- LStrings ss -> map toJSON ss- in "values" .= ls-legendProperty (LZIndex n) = "zindex" .= n----- | A list of data values suitable for setting legend values.--data LegendValues- = LDateTimes [[DateTime]]- | LNumbers [Double]- | LStrings [T.Text]----- | Specify the padding dimensions in pixel units.--data Padding- = PSize Double- -- ^ Use the same padding on all four edges of the container.- | PEdges Double Double Double Double- -- ^ Specify the padding for the left, top, right, and bottom edges.---paddingSpec :: Padding -> VLSpec-paddingSpec (PSize p) = toJSON p-paddingSpec (PEdges l t r b) =- object [ "left" .= l- , "top" .= t- , "right" .= r- , "bottom" .= b- ]--{-|--Types of geographic map projection. These are based on a subset of those provided-by the <https://github.com/d3/d3-geo d3-geo library>. For details of available-projections see the-<https://vega.github.io/vega-lite/docs/projection.html#projection-types Vega-Lite documentation>.--}-data Projection- = Albers- | AlbersUsa- | AzimuthalEqualArea- | AzimuthalEquidistant- | ConicConformal- | ConicEqualArea- | ConicEquidistant- | Custom T.Text- -- ^ Specify the name of the custom D3 prohection to use. See the- -- <https://vega.github.io/vega/docs/projections/#register Vega API>- -- for more information.- | Equirectangular- | Gnomonic- | Mercator- | Orthographic- | Stereographic- | TransverseMercator---projectionLabel :: Projection -> T.Text-projectionLabel Albers = "albers"-projectionLabel AlbersUsa = "albersUsa"-projectionLabel AzimuthalEqualArea = "azimuthalEqualArea"-projectionLabel AzimuthalEquidistant = "azimuthalEquidistant"-projectionLabel ConicConformal = "conicConformal"-projectionLabel ConicEqualArea = "conicEqualarea"-projectionLabel ConicEquidistant = "conicEquidistant"-projectionLabel (Custom pName) = pName-projectionLabel Equirectangular = "equirectangular"-projectionLabel Gnomonic = "gnomonic"-projectionLabel Mercator = "mercator"-projectionLabel Orthographic = "orthographic"-projectionLabel Stereographic = "stereographic"-projectionLabel TransverseMercator = "transverseMercator"----- | Specifies a clipping rectangle in pixel units for defining--- the clip extent of a map projection.--data ClipRect- = NoClip- | LTRB Double Double Double Double- -- ^ The left, top, right, and bottom extents.---{-|--Properties for customising a geospatial projection that converts longitude,latitude-pairs into planar @(x,y)@ coordinate pairs for rendering and query. For details see the-<https://vega.github.io/vega-lite/docs/projection.html Vega-Lite documentation>.--}-data ProjectionProperty- = PType Projection- | PClipAngle (Maybe Double)- | PClipExtent ClipRect- | PCenter Double Double- | PRotate Double Double Double- | PPrecision Double- | PCoefficient Double- | PDistance Double- | PFraction Double- | PLobes Int- | PParallel Double- | PRadius Double- | PRatio Double- | PSpacing Double- | PTilt Double---projectionProperty :: ProjectionProperty -> LabelledSpec-projectionProperty (PType proj) = "type" .= projectionLabel proj-projectionProperty (PClipAngle numOrNull) = "clipAngle" .= maybe A.Null toJSON numOrNull-projectionProperty (PClipExtent rClip) =- ("clipExtent", case rClip of- NoClip -> A.Null- LTRB l t r b -> toJSON (map toJSON [l, t, r, b])- )-projectionProperty (PCenter lon lat) = "center" .= map toJSON [lon, lat]-projectionProperty (PRotate lambda phi gamma) = "rotate" .= map toJSON [lambda, phi, gamma]-projectionProperty (PPrecision pr) = "precision" .= pr-projectionProperty (PCoefficient x) = "coefficient" .= x-projectionProperty (PDistance x) = "distance" .= x-projectionProperty (PFraction x) = "fraction" .= x-projectionProperty (PLobes n) = "lobes" .= n-projectionProperty (PParallel x) = "parallel" .= x-projectionProperty (PRadius x) = "radius" .= x-projectionProperty (PRatio x) = "ratio" .= x-projectionProperty (PSpacing x) = "spacing" .= x-projectionProperty (PTilt x) = "tilt" .= x---{-|--Sets the cartographic projection used for geospatial coordinates. A projection-defines the mapping from @(longitude,latitude)@ to an @(x,y)@ plane used for rendering.-This is useful when using the 'Geoshape' mark. For further details see the-<https://vega.github.io/vega-lite/docs/projection.html Vega-Lite documentation>.--@-proj = projection [ PType Orthographic, PRotate (-40) 0 0 ]-@--}-projection :: [ProjectionProperty] -> (VLProperty, VLSpec)-projection pProps = (VLProjection, object (map projectionProperty pProps))---{-|--Properties for customising the colors of a range. The parameter should be a-named color scheme such as @\"accent\"@ or @\"purpleorange-11\"@. For details see the-<https://vega.github.io/vega/docs/schemes/#scheme-properties Vega-Lite documentation>.--}-data RangeConfig- = RCategory T.Text- | RDiverging T.Text- | RHeatmap T.Text- | ROrdinal T.Text- | RRamp T.Text- | RSymbol T.Text---rangeConfigProperty :: RangeConfig -> LabelledSpec-rangeConfigProperty rangeCfg =- let (l, n) = case rangeCfg of- RCategory nme -> ("category", nme)- RDiverging nme -> ("diverging", nme)- RHeatmap nme -> ("heatmap", nme)- ROrdinal nme -> ("ordinal", nme)- RRamp nme -> ("ramp", nme)- RSymbol nme -> ("symbol", nme)-- in l .= object [schemeProperty n []]---{-|--Scale configuration property. These are used to configure all scales.-For more details see the-<https://vega.github.io/vega-lite/docs/scale.html#scale-config Vega-Lite documentation>.--}-data ScaleConfig- = SCBandPaddingInner Double- | SCBandPaddingOuter Double- | SCClamp Bool- | SCMaxBandSize Double- | SCMinBandSize Double- | SCMaxFontSize Double- | SCMinFontSize Double- | SCMaxOpacity Double- | SCMinOpacity Double- | SCMaxSize Double- | SCMinSize Double- | SCMaxStrokeWidth Double- | SCMinStrokeWidth Double- | SCPointPadding Double- | SCRangeStep (Maybe Double)- | SCRound Bool- | SCTextXRangeStep Double- | SCUseUnaggregatedDomain Bool---scaleConfigProperty :: ScaleConfig -> LabelledSpec-scaleConfigProperty (SCBandPaddingInner x) = "bandPaddingInner" .= x-scaleConfigProperty (SCBandPaddingOuter x) = "bandPaddingOuter" .= x-scaleConfigProperty (SCClamp b) = "clamp" .= b-scaleConfigProperty (SCMaxBandSize x) = "maxBandSize" .= x-scaleConfigProperty (SCMinBandSize x) = "minBandSize" .= x-scaleConfigProperty (SCMaxFontSize x) = "maxFontSize" .= x-scaleConfigProperty (SCMinFontSize x) = "minFontSize" .= x-scaleConfigProperty (SCMaxOpacity x) = "maxOpacity" .= x-scaleConfigProperty (SCMinOpacity x) = "minOpacity" .= x-scaleConfigProperty (SCMaxSize x) = "maxSize" .= x-scaleConfigProperty (SCMinSize x) = "minSize" .= x-scaleConfigProperty (SCMaxStrokeWidth x) = "maxStrokeWidth" .= x-scaleConfigProperty (SCMinStrokeWidth x) = "minStrokeWidth" .= x-scaleConfigProperty (SCPointPadding x) = "pointPadding" .= x-scaleConfigProperty (SCRangeStep numOrNull) = "rangeStep" .= maybe A.Null toJSON numOrNull-scaleConfigProperty (SCRound b) = "round" .= b-scaleConfigProperty (SCTextXRangeStep x) = "textXRangeStep" .= x-scaleConfigProperty (SCUseUnaggregatedDomain b) = "useUnaggregatedDomain" .= b----- | Indicates the type of selection to be generated by the user.--data Selection- = Single- -- ^ Allows one mark at a time to be selected.- | Multi- -- ^ Allows multiple items to be selected (e.g. with- -- shift-click).- | Interval- -- ^ Allows a bounding rectangle to be dragged by the user,- -- selecting all items which intersect it.---selectionLabel :: Selection -> T.Text-selectionLabel Single = "single"-selectionLabel Multi = "multi"-selectionLabel Interval = "interval"---{-|--Properties for customising the nature of the selection. See the-<https://vega.github.io/vega-lite/docs/selection.html#selection-properties Vega-Lite documentation>-for details.--}-data SelectionProperty- = On T.Text- -- ^ A <https://vega.github.io/vega/docs/event-streams Vega event stream>- -- or the empty string (which sets the property to @false@).- | Translate T.Text- -- ^ A <https://vega.github.io/vega/docs/event-streams Vega event stream>- -- or the empty string (which sets the property to @false@).- | Zoom T.Text- -- ^ A <https://vega.github.io/vega/docs/event-streams Vega event stream>- -- or the empty string (which sets the property to @false@).- | Fields [T.Text]- | Encodings [Channel]- | Empty- | ResolveSelections SelectionResolution- | SelectionMark [SelectionMarkProperty]- | BindScales- | Bind [Binding]- | Nearest Bool- | Toggle T.Text- -- ^ A <https://vega.github.io/vega/docs/expressions Vega expression> that evaluates- -- to @true@ or @false@.---selectionProperty :: SelectionProperty -> LabelledSpec-selectionProperty (Fields fNames) = "fields" .= map toJSON fNames-selectionProperty (Encodings channels) = "encodings" .= map (toJSON . channelLabel) channels-selectionProperty (On e) = "on" .= e-selectionProperty Empty = "empty" .= ("none" :: T.Text)-selectionProperty (ResolveSelections res) = "resolve" .= selectionResolutionLabel res-selectionProperty (SelectionMark markProps) = "mark" .= object (map selectionMarkProperty markProps)-selectionProperty BindScales = "bind" .= ("scales" :: T.Text)-selectionProperty (Bind binds) = "bind" .= object (map bindingSpec binds)-selectionProperty (Nearest b) = "nearest" .= b-selectionProperty (Toggle expr) = "toggle" .= expr-selectionProperty (Translate e) = "translate" .= if T.null e then toJSON False else toJSON e-selectionProperty (Zoom e) = "zoom" .= if T.null e then toJSON False else toJSON e----- | Indicates a channel type to be used in a resolution specification.--data Channel- = ChX- | ChY- | ChX2- | ChY2- | ChColor- | ChFill -- ^ @since 0.3.0.0- | ChStroke -- ^ @since 0.3.0.0- | ChOpacity- | ChShape- | ChSize---channelLabel :: Channel -> T.Text-channelLabel ChX = "x"-channelLabel ChY = "y"-channelLabel ChX2 = "x2"-channelLabel ChY2 = "y2"-channelLabel ChColor = "color"-channelLabel ChFill = "fill"-channelLabel ChStroke = "stroke"-channelLabel ChOpacity = "opacity"-channelLabel ChShape = "shape"-channelLabel ChSize = "size"---{-|--Determines how selections in faceted or repeated views are resolved. See the-<https://vega.github.io/vega-lite/docs/selection.html#resolve Vega-Lite documentation>-for details--}-data SelectionResolution- = Global- | Union- | Intersection---selectionResolutionLabel :: SelectionResolution -> T.Text-selectionResolutionLabel Global = "global"-selectionResolutionLabel Union = "union"-selectionResolutionLabel Intersection = "intersect"---{-|--Properties for customising the appearance of an interval selection mark (dragged-rectangle). For details see the-<https://vega.github.io/vega-lite/docs/selection.html#interval-mark Vega-Lite documentation>.--}-data SelectionMarkProperty- = SMFill T.Text- | SMFillOpacity Double- | SMStroke T.Text- | SMStrokeOpacity Double- | SMStrokeWidth Double- | SMStrokeDash [Double]- | SMStrokeDashOffset Double---selectionMarkProperty :: SelectionMarkProperty -> LabelledSpec-selectionMarkProperty (SMFill colour) = "fill" .= colour-selectionMarkProperty (SMFillOpacity x) = "fillOpacity" .= x-selectionMarkProperty (SMStroke colour) = "stroke" .= colour-selectionMarkProperty (SMStrokeOpacity x) = "strokeOpacity" .= x-selectionMarkProperty (SMStrokeWidth x) = "strokeWidth" .= x-selectionMarkProperty (SMStrokeDash xs) = "strokeDash" .= map toJSON xs-selectionMarkProperty (SMStrokeDashOffset x) = "strokeDashOffset" .= x---{-|--GUI Input properties. The type of relevant property will depend on the type of-input element selected. For example an @InRange@ (slider) can have numeric min,-max and step values; @InSelect@ (selector) has a list of selection label options.-For details see the-<https://vega.github.io/vega/docs/signals/#bind Vega input element binding documentation>.--The @debounce@ property, available for all input types allows a delay in input event-handling to be added in order to avoid unnecessary event broadcasting. The @Element@-property is an optional CSS selector indicating the parent element to which the-input element should be added. This allows the option of the input element to be-outside the visualization container.--}-data InputProperty- = Debounce Double- | Element T.Text- | InOptions [T.Text]- | InMin Double- | InMax Double- | InName T.Text- | InStep Double- | InPlaceholder T.Text---inputProperty :: InputProperty -> LabelledSpec-inputProperty (InMin x) = "min".= x-inputProperty (InMax x) = "max".= x-inputProperty (InStep x) = "step".= x-inputProperty (Debounce x) = "debounce".= x-inputProperty (InName s) = "name" .= s-inputProperty (InOptions opts) = "options" .= map toJSON opts-inputProperty (InPlaceholder el) = "placeholder" .= toJSON el-inputProperty (Element el) = "element" .= toJSON el---{-|--Describes the binding property of a selection based on some HTML input element-such as a checkbox or radio button. For details see the-<https://vega.github.io/vega-lite/docs/bind.html#scale-binding Vega-Lite documentation>-and the-<https://vega.github.io/vega/docs/signals/#bind Vega input binding documentation>.--}-data Binding- = IRange T.Text [InputProperty]- | ICheckbox T.Text [InputProperty]- | IRadio T.Text [InputProperty]- | ISelect T.Text [InputProperty]- -- TODO: Check validity: The following input types can generate a warning if options are included even if options appear to have an effect (e.g. placeholder)- | IText T.Text [InputProperty]- | INumber T.Text [InputProperty]- | IDate T.Text [InputProperty]- | ITime T.Text [InputProperty]- | IMonth T.Text [InputProperty]- | IWeek T.Text [InputProperty]- | IDateTimeLocal T.Text [InputProperty]- | ITel T.Text [InputProperty]- | IColor T.Text [InputProperty]---bindingSpec :: Binding -> LabelledSpec-bindingSpec bnd =- let (lbl, input, ps) = case bnd of- IRange label props -> (label, "range" :: T.Text, props)- ICheckbox label props -> (label, "checkbox", props)- IRadio label props -> (label, "radio", props)- ISelect label props -> (label, "select", props)- IText label props -> (label, "text", props)- INumber label props -> (label, "number", props)- IDate label props -> (label, "date", props)- ITime label props -> (label, "time", props)- IMonth label props -> (label, "month", props)- IWeek label props -> (label, "week", props)- IDateTimeLocal label props -> (label, "datetimelocal", props)- ITel label props -> (label, "tel", props)- IColor label props -> (label, "color", props)-- in (lbl, object (("input" .= input) : map inputProperty ps))----- | Indicates the anchor position for text.--data APosition- = AStart- | AMiddle- | AEnd---anchorLabel :: APosition -> T.Text-anchorLabel AStart = "start"-anchorLabel AMiddle = "middle"-anchorLabel AEnd = "end"---{-|--Title configuration properties. These are used to configure the default style-of all titles within a visualization.-For further details see the-<https://vega.github.io/vega-lite/docs/title.html#config Vega-Lite documentation>.--}-data TitleConfig- = TAnchor APosition- | TAngle Double- | TBaseline VAlign- | TColor T.Text- | TFont T.Text- | TFontSize Double- | TFontWeight FontWeight- | TLimit Double- | TOffset Double- | TOrient Side---titleConfigSpec :: TitleConfig -> LabelledSpec-titleConfigSpec (TAnchor an) = "anchor" .= anchorLabel an-titleConfigSpec (TAngle x) = "angle" .= x-titleConfigSpec (TBaseline va) = "baseline" .= vAlignLabel va-titleConfigSpec (TColor clr) = "color" .= clr-titleConfigSpec (TFont fnt) = "font" .= fnt-titleConfigSpec (TFontSize x) = "fontSize" .= x-titleConfigSpec (TFontWeight w) = "fontWeight" .= fontWeightSpec w-titleConfigSpec (TLimit x) = "limit" .= x-titleConfigSpec (TOffset x) = "offset" .= x-titleConfigSpec (TOrient sd) = "orient" .= sideLabel sd---{-|--View configuration property. These are used to configure the style of a single-view within a visualization such as its size and default fill and stroke colors.-For further details see the-<https://vega.github.io/vega-lite/docs/spec.html#config Vega-Lite documentation>.--}-data ViewConfig- = ViewWidth Double- | ViewHeight Double- | Clip Bool- | Fill (Maybe T.Text)- | FillOpacity Double- | Stroke (Maybe T.Text)- | StrokeOpacity Double- | StrokeWidth Double- | StrokeDash [Double]- | StrokeDashOffset Double---viewConfigProperty :: ViewConfig -> LabelledSpec-viewConfigProperty (ViewWidth x) = "width" .= x-viewConfigProperty (ViewHeight x) = "height" .= x-viewConfigProperty (Clip b) = "clip" .= b-viewConfigProperty (Fill ms) = "fill" .= fromMaybe "" ms-viewConfigProperty (FillOpacity x) = "fillOpacity" .= x-viewConfigProperty (Stroke ms) = "stroke" .= fromMaybe "" ms-viewConfigProperty (StrokeOpacity x) = "strokeOpacity" .= x-viewConfigProperty (StrokeWidth x) = "strokeWidth" .= x-viewConfigProperty (StrokeDash xs) = "strokeDash" .= map toJSON xs-viewConfigProperty (StrokeDashOffset x) = "strokeDashOffset" .= x---{-|-Type of configuration property to customise. See the-<https://vega.github.io/vega-lite/docs/config.html Vega-Lite documentation>-for details.--}-data ConfigurationProperty- = AreaStyle [MarkProperty]- | Autosize [Autosize]- | Axis [AxisConfig]- | AxisX [AxisConfig]- | AxisY [AxisConfig]- | AxisLeft [AxisConfig]- | AxisRight [AxisConfig]- | AxisTop [AxisConfig]- | AxisBottom [AxisConfig]- | AxisBand [AxisConfig]- | Background T.Text- | BarStyle [MarkProperty]- | CircleStyle [MarkProperty]- | CountTitle T.Text- | FieldTitle FieldTitleProperty- | Legend [LegendConfig]- | LineStyle [MarkProperty]- | MarkStyle [MarkProperty]- | NamedStyle T.Text [MarkProperty]- | NumberFormat T.Text- | Padding Padding- | PointStyle [MarkProperty]- | Projection [ProjectionProperty]- | Range [RangeConfig]- | RectStyle [MarkProperty]- | RemoveInvalid Bool- | RuleStyle [MarkProperty]- | Scale [ScaleConfig]- | SelectionStyle [(Selection, [SelectionProperty])]- | SquareStyle [MarkProperty]- | Stack StackProperty- | TextStyle [MarkProperty]- | TickStyle [MarkProperty]- | TitleStyle [TitleConfig]- | TimeFormat T.Text- | View [ViewConfig]---configProperty :: ConfigurationProperty -> LabelledSpec-configProperty (Autosize aus) = "autosize" .= object (map autosizeProperty aus)-configProperty (Background bg) = "background" .= bg-configProperty (CountTitle ttl) = "countTitle" .= ttl-configProperty (FieldTitle ftp) = "fieldTitle" .= fieldTitleLabel ftp-configProperty (RemoveInvalid b) = "invalidValues" .= if b then "filter" else A.Null-configProperty (NumberFormat fmt) = "numberFormat" .= fmt-configProperty (Padding pad) = "padding" .= paddingSpec pad-configProperty (TimeFormat fmt) = "timeFormat" .= fmt-configProperty (Axis acs) = "axis" .= object (map axisConfigProperty acs)-configProperty (AxisX acs) = "axisX" .= object (map axisConfigProperty acs)-configProperty (AxisY acs) = "axisY" .= object (map axisConfigProperty acs)-configProperty (AxisLeft acs) = "axisLeft" .= object (map axisConfigProperty acs)-configProperty (AxisRight acs) = "axisRight" .= object (map axisConfigProperty acs)-configProperty (AxisTop acs) = "axisTop" .= object (map axisConfigProperty acs)-configProperty (AxisBottom acs) = "axisBottom" .= object (map axisConfigProperty acs)-configProperty (AxisBand acs) = "axisBand" .= object (map axisConfigProperty acs)-configProperty (Legend lcs) = "legend" .= object (map legendConfigProperty lcs)-configProperty (MarkStyle mps) = "mark" .= object (map markProperty mps)-configProperty (Projection pps) = "projection" .= object (map projectionProperty pps)-configProperty (AreaStyle mps) = "area" .= object (map markProperty mps)-configProperty (BarStyle mps) = "bar" .= object (map markProperty mps)-configProperty (CircleStyle mps) = "circle" .= object (map markProperty mps)-configProperty (LineStyle mps) = "line" .= object (map markProperty mps)-configProperty (PointStyle mps) = "point" .= object (map markProperty mps)-configProperty (RectStyle mps) = "rect" .= object (map markProperty mps)-configProperty (RuleStyle mps) = "rule" .= object (map markProperty mps)-configProperty (SquareStyle mps) = "square" .= object (map markProperty mps)-configProperty (TextStyle mps) = "text" .= object (map markProperty mps)-configProperty (TickStyle mps) = "tick" .= object (map markProperty mps)-configProperty (TitleStyle tcs) = "title" .= object (map titleConfigSpec tcs)-configProperty (NamedStyle nme mps) = "style" .= object [nme .= object (map markProperty mps)]-configProperty (Scale scs) = "scale" .= object (map scaleConfigProperty scs)-configProperty (Stack sp) = stackProperty sp-configProperty (Range rcs) = "range" .= object (map rangeConfigProperty rcs)-configProperty (SelectionStyle selConfig) =- let selProp (sel, sps) = selectionLabel sel .= object (map selectionProperty sps)- in "selection" .= object (map selProp selConfig)-configProperty (View vcs) = "view" .= object (map viewConfigProperty vcs)---{-|--Axis configuration options for customising all axes. See the-<https://vega.github.io/vega-lite/docs/axis.html#general-config Vega-Lite documentation>-for more details.--}-data AxisConfig- = BandPosition Double- | Domain Bool- | DomainColor T.Text- | DomainWidth Double- | MaxExtent Double- | MinExtent Double- | Grid Bool- | GridColor T.Text- | GridDash [Double]- | GridOpacity Double- | GridWidth Double- | Labels Bool- | LabelAngle Double- | LabelColor T.Text- | LabelFont T.Text- | LabelFontSize Double- | LabelLimit Double- | LabelOverlap OverlapStrategy- | LabelPadding Double- | ShortTimeLabels Bool- | Ticks Bool- | TickColor T.Text- | TickRound Bool- | TickSize Double- | TickWidth Double- | TitleAlign HAlign- | TitleAngle Double- | TitleBaseline VAlign- | TitleColor T.Text- | TitleFont T.Text- | TitleFontWeight FontWeight- | TitleFontSize Double- | TitleLimit Double- | TitleMaxLength Double- | TitlePadding Double- | TitleX Double- | TitleY Double---axisConfigProperty :: AxisConfig -> LabelledSpec-axisConfigProperty (BandPosition x) = ("bandPosition", toJSON x)-axisConfigProperty (Domain b) = ("domain", toJSON b)-axisConfigProperty (DomainColor c) = ("domainColor", fromT c)-axisConfigProperty (DomainWidth w) = ("domainWidth", toJSON w)-axisConfigProperty (MaxExtent n) = ("maxExtent", toJSON n)-axisConfigProperty (MinExtent n) = ("minExtent", toJSON n)-axisConfigProperty (Grid b) = ("grid", toJSON b)-axisConfigProperty (GridColor c) = ("gridColor", fromT c)-axisConfigProperty (GridDash ds) = ("gridDash", toJSON (map toJSON ds))-axisConfigProperty (GridOpacity o) = ("gridOpacity", toJSON o)-axisConfigProperty (GridWidth x) = ("gridWidth", toJSON x)-axisConfigProperty (Labels b) = ("labels", toJSON b)-axisConfigProperty (LabelAngle angle) = ("labelAngle", toJSON angle)-axisConfigProperty (LabelColor c) = ("labelColor", fromT c)-axisConfigProperty (LabelFont f) = ("labelFont", fromT f)-axisConfigProperty (LabelFontSize x) = ("labelFontSize", toJSON x)-axisConfigProperty (LabelLimit x) = ("labelLimit", toJSON x)-axisConfigProperty (LabelOverlap strat) = ("labelOverlap", fromT (overlapStrategyLabel strat))-axisConfigProperty (LabelPadding pad) = ("labelPadding", toJSON pad)-axisConfigProperty (ShortTimeLabels b) = ("shortTimeLabels", toJSON b)-axisConfigProperty (Ticks b) = ("ticks", toJSON b)-axisConfigProperty (TickColor c) = ("tickColor", fromT c)-axisConfigProperty (TickRound b) = ("tickRound", toJSON b)-axisConfigProperty (TickSize x) = ("tickSize", toJSON x)-axisConfigProperty (TickWidth x) = ("tickWidth", toJSON x)-axisConfigProperty (TitleAlign align) = ("titleAlign", fromT (hAlignLabel align))-axisConfigProperty (TitleAngle angle) = ("titleAngle", toJSON angle)-axisConfigProperty (TitleBaseline va) = ("titleBaseline", fromT (vAlignLabel va))-axisConfigProperty (TitleColor c) = ("titleColor", fromT c)-axisConfigProperty (TitleFont f) = ("titleFont", fromT f)-axisConfigProperty (TitleFontWeight w) = ("titleFontWeight", fontWeightSpec w)-axisConfigProperty (TitleFontSize x) = ("titleFontSize", toJSON x)-axisConfigProperty (TitleLimit x) = ("titleLimit", toJSON x)-axisConfigProperty (TitleMaxLength x) = ("titleMaxLength", toJSON x)-axisConfigProperty (TitlePadding x) = ("titlePadding", toJSON x)-axisConfigProperty (TitleX x) = ("titleX", toJSON x)-axisConfigProperty (TitleY y) = ("titleY", toJSON y)---{-|--Used for creating logical compositions. For example--@-'color'- [ 'MSelectionCondition' (Or ('SelectionName' "alex") (SelectionName "morgan"))- [ 'MAggregate' 'Count', 'MName' "*", 'MmType' 'Quantitative' ]- [ 'MString' "gray" ]- ]-@--Logical compositions can be nested to any level as shown in this example--@-Not (And (Expr "datum.IMDB_Rating === null") (Expr "datum.Rotten_Tomatoes_Rating === null") )-@--}-data BooleanOp- = Expr T.Text- | Selection T.Text- | SelectionName T.Text- | And BooleanOp BooleanOp- | Or BooleanOp BooleanOp- | Not BooleanOp---booleanOpSpec :: BooleanOp -> VLSpec-booleanOpSpec (Expr expr) = toJSON expr-booleanOpSpec (SelectionName selName) = toJSON selName-booleanOpSpec (Selection sel) = object ["selection" .= sel]-booleanOpSpec (And operand1 operand2) = object ["and" .= [booleanOpSpec operand1, booleanOpSpec operand2]]-booleanOpSpec (Or operand1 operand2) = object ["or" .= [booleanOpSpec operand1, booleanOpSpec operand2]]-booleanOpSpec (Not operand) = object ["not" .= booleanOpSpec operand]---{-|--Type of filtering operation. See the-<https://vega.github.io/vega-lite/docs/filter.html Vega-Lite documentation>-for details.--}-data Filter- = FEqual T.Text DataValue- | FExpr T.Text- | FCompose BooleanOp- | FSelection T.Text- | FOneOf T.Text DataValues- | FRange T.Text FilterRange---{-|--A pair of filter range data values. The first argument is the inclusive minimum-vale to accept and the second the inclusive maximum.--}-data FilterRange- = NumberRange Double Double- | DateRange [DateTime] [DateTime]---{-|--Specifies the type and content of geometry specifications for programatically-creating GeoShapes. These can be mapped to the-<https://tools.ietf.org/html/rfc7946#section-3.1 GeoJson geometry object types>-where the pluralised type names refer to their @Multi@ prefixed equivalent in the-GeoJSON specification.--}-data Geometry- = GeoPoint Double Double- | GeoPoints [(Double, Double)]- | GeoLine [(Double, Double)]- | GeoLines [[(Double, Double)]]- | GeoPolygon [[(Double, Double)]]- | GeoPolygons [[[(Double, Double)]]]---{-|--Specifies a geometric object to be used in a geoShape specification. The first-parameter is the geometric type, the second an optional list of properties to be-associated with the object.--@-geojson =- geometry ('GeoPolygon' [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 59 ) ] ]) []-@--}-geometry :: Geometry -> [(T.Text, DataValue)] -> VLSpec-geometry gType properties =- object ([ ("type", fromT "Feature")- , ("geometry", geometryTypeSpec gType) ]- <> if null properties- then []- else [("properties",- object (map (second dataValueSpec) properties))]- )---geometryTypeSpec :: Geometry -> VLSpec-geometryTypeSpec gType =- let toCoords :: [(Double, Double)] -> VLSpec- toCoords = toJSON -- rely on Aeson converting a pair to a 2-element list-- toCoordList :: [[(Double, Double)]] -> VLSpec- toCoordList = toJSON . map toCoords -- this is just toJSON isn't it?-- -- can we replace this infinite tower of toJSON calls with one toJSON call?- (ptype, cs) = case gType of- GeoPoint x y -> ("Point", toJSON [x, y])- GeoPoints coords -> ("MultiPoint", toCoords coords)- GeoLine coords -> ("LineString", toCoords coords)- GeoLines coords -> ("MultiLineString", toCoordList coords)- GeoPolygon coords -> ("Polygon", toCoordList coords)- GeoPolygons ccoords -> ("MultiPolygon", toJSON (map toCoordList ccoords))-- in object [("type", ptype), ("coordinates", cs)]---{-|--Indicates whether or not a scale domain should be independent of others in a-composite visualization. See the-<https://vega.github.io/vega-lite/docs/resolve.html Vega-Lite documentation> for-details.--}-data Resolution- = Shared- | Independent---resolutionLabel :: Resolution -> T.Text-resolutionLabel Shared = "shared"-resolutionLabel Independent = "independent"---{-|--Used to determine how a channel's axis, scale or legend domains should be resolved-if defined in more than one view in a composite visualization. See the-<https://vega.github.io/vega-lite/docs/resolve.html Vega-Lite documentation>-for details.--}-data Resolve- = RAxis [(Channel, Resolution)]- | RLegend [(Channel, Resolution)]- | RScale [(Channel, Resolution)]---resolveProperty :: Resolve -> LabelledSpec-resolveProperty res =- let (nme, rls) = case res of- RAxis chRules -> ("axis", chRules)- RLegend chRules -> ("legend", chRules)- RScale chRules -> ("scale", chRules)-- ans = map (\(ch, rule) -> (channelLabel ch .= resolutionLabel rule)) rls- in (nme, object ans)---{-|--Represents a facet header property. For details, see the-<https://vega.github.io/vega-lite/docs/facet.html#header Vega-Lite documentation>.--}-data HeaderProperty- = HFormat T.Text- | HTitle T.Text---headerProperty :: HeaderProperty -> LabelledSpec-headerProperty (HFormat fmt) = "format" .= fmt-headerProperty (HTitle ttl) = "title" .= ttl----- | Types of hyperlink channel property used for linking marks or text to URLs.--data HyperlinkChannel- = HName T.Text- | HRepeat Arrangement- | HmType Measurement- | HBin [BinProperty]- | HAggregate Operation- | HTimeUnit TimeUnit- | HSelectionCondition BooleanOp [HyperlinkChannel] [HyperlinkChannel]- | HDataCondition BooleanOp [HyperlinkChannel] [HyperlinkChannel]- | HString T.Text---hyperlinkChannelProperty :: HyperlinkChannel -> [LabelledSpec]-hyperlinkChannelProperty (HName s) = [field_ s]-hyperlinkChannelProperty (HRepeat arr) = ["field" .= object [repeat_ arr]]-hyperlinkChannelProperty (HmType t) = [type_ t]-hyperlinkChannelProperty (HBin bps) = [bin bps]-hyperlinkChannelProperty (HSelectionCondition selName ifClause elseClause) =- let h = ("condition", hkey)- toProps = concatMap hyperlinkChannelProperty- hkey = object (("selection", booleanOpSpec selName) : toProps ifClause)- hs = toProps elseClause- in h : hs-hyperlinkChannelProperty (HDataCondition predicate ifClause elseClause) =- let h = ("condition", hkey)- toProps = concatMap hyperlinkChannelProperty- hkey = object (("test", booleanOpSpec predicate) : toProps ifClause)- hs = toProps elseClause- in h : hs-hyperlinkChannelProperty (HTimeUnit tu) = [timeUnit_ tu]-hyperlinkChannelProperty (HAggregate op) = [aggregate_ op]-hyperlinkChannelProperty (HString s) = [value_ s]--------{-|--Create a pair of continuous domain to color mappings suitable for customising-ordered scales. The first parameter is a tuple representing the mapping of the lowest-numeric value in the domain to its equivalent color; the second tuple the mapping-of the highest numeric value to color. If the domain contains any values between-these lower and upper bounds they are interpolated according to the scale's interpolation-function. This is a convenience function equivalent to specifying separate 'SDomain'-and 'SRange' lists and is safer as it guarantees a one-to-one correspondence between-domain and range values.--@-'color'- [ 'MName' "year"- , 'MmType' 'Ordinal'- , 'MScale' (domainRangeMap ( 1955, "#e6959c" ) ( 2000, "#911a24" ))- ]-@--}--domainRangeMap :: (Double, T.Text) -> (Double, T.Text) -> [ScaleProperty]-domainRangeMap lowerMap upperMap =- let (domain, range) = unzip [lowerMap, upperMap]- in [SDomain (DNumbers domain), SRange (RStrings range)]---{-|--Create a set of discrete domain to color mappings suitable for customising categorical-scales. The first item in each tuple should be a domain value and the second the-color value with which it should be associated. It is a convenience function equivalent-to specifying separate 'SDomain' and 'SRange' lists and is safer as it guarantees-a one-to-one correspondence between domain and range values.--@-'color'- [ 'MName' "weather"- , 'MmType' Nominal- , 'MScale' (- categoricalDomainMap- [ ( "sun", "yellow" )- , ( "rain", "blue" )- , ( "fog", "grey" )- ]- )- ]-@--}--categoricalDomainMap :: [(T.Text, T.Text)] -> [ScaleProperty]-categoricalDomainMap scaleDomainPairs =- let (domain, range) = unzip scaleDomainPairs- in [SDomain (DStrings domain), SRange (RStrings range)]---{-|--Create a list of fields to use in set of repeated small multiples. The list of-fields named here can be referenced in an encoding with @PRepeat Column@-or @PRepeat Row@.--}-data RepeatFields- = RowFields [T.Text]- | ColumnFields [T.Text]---repeatFieldsProperty :: RepeatFields -> LabelledSpec-repeatFieldsProperty rfs =- let (nme, vs) = case rfs of- RowFields fields -> ("row", fields)- ColumnFields fields -> ("column", fields)-- in nme .= map toJSON vs---{-|--Types of facet channel property used for creating a composed facet view of small-multiples.--}-data FacetChannel- = FName T.Text- | FmType Measurement- | FBin [BinProperty]- | FAggregate Operation- | FTimeUnit TimeUnit- | FHeader [HeaderProperty]---facetChannelProperty :: FacetChannel -> LabelledSpec-facetChannelProperty (FName s) = field_ s-facetChannelProperty (FmType measure) = type_ measure-facetChannelProperty (FBin bps) = bin bps-facetChannelProperty (FAggregate op) = aggregate_ op-facetChannelProperty (FTimeUnit tu) = timeUnit_ tu-facetChannelProperty (FHeader hProps) = "header" .= object (map headerProperty hProps)----- | Types of text channel property used for displaying text as part of the visualization.--data TextChannel- = TName T.Text- | TRepeat Arrangement- | TmType Measurement- | TBin [BinProperty]- | TAggregate Operation- | TTimeUnit TimeUnit- | TSelectionCondition BooleanOp [TextChannel] [TextChannel]- | TDataCondition BooleanOp [TextChannel] [TextChannel]- | TFormat T.Text---textChannelProperty :: TextChannel -> [LabelledSpec]-textChannelProperty (TName s) = [field_ s]-textChannelProperty (TRepeat arr) = ["field" .= object [repeat_ arr]]-textChannelProperty (TmType measure) = [type_ measure]-textChannelProperty (TBin bps) = [bin bps]-textChannelProperty (TAggregate op) = [aggregate_ op]-textChannelProperty (TTimeUnit tu) = [timeUnit_ tu]-textChannelProperty (TFormat fmt) = ["format" .= fmt]-textChannelProperty (TSelectionCondition selName ifClause elseClause) =- let h = ("condition", hkey)- toProps = concatMap textChannelProperty- hkey = object (("selection", booleanOpSpec selName) : toProps ifClause)- hs = toProps elseClause- in h : hs-textChannelProperty (TDataCondition predicate ifClause elseClause) =- let h = ("condition", hkey)- toProps = concatMap textChannelProperty- hkey = object (("test", booleanOpSpec predicate) : toProps ifClause)- hs = toProps elseClause- in h : hs----- | Properties of an ordering channel used for sorting data fields.--data OrderChannel- = OName T.Text- | ORepeat Arrangement- | OmType Measurement- | OBin [BinProperty]- | OAggregate Operation- | OTimeUnit TimeUnit- | OSort [SortProperty]---orderChannelProperty :: OrderChannel -> LabelledSpec-orderChannelProperty (OName s) = field_ s-orderChannelProperty (ORepeat arr) = "field" .= object [repeat_ arr]-orderChannelProperty (OmType measure) = type_ measure-orderChannelProperty (OBin bps) = bin bps-orderChannelProperty (OAggregate op) = aggregate_ op-orderChannelProperty (OTimeUnit tu) = timeUnit_ tu-orderChannelProperty (OSort ops) = sort_ ops----- | Level of detail channel properties used for creating a grouped channel encoding.--data DetailChannel- = DName T.Text- | DmType Measurement- | DBin [BinProperty]- | DTimeUnit TimeUnit- | DAggregate Operation---detailChannelProperty :: DetailChannel -> LabelledSpec-detailChannelProperty (DName s) = field_ s-detailChannelProperty (DmType t) = type_ t-detailChannelProperty (DBin bps) = bin bps-detailChannelProperty (DTimeUnit tu) = timeUnit_ tu-detailChannelProperty (DAggregate op) = aggregate_ op---{-|--Provides details of the mapping between a row or column and its field-definitions in a set of faceted small multiples. For details see the-<https://vega.github.io/vega-lite/docs/facet.html#mapping Vega-Lite documentation>.--}-data FacetMapping- = ColumnBy [FacetChannel]- | RowBy [FacetChannel]---facetMappingProperty :: FacetMapping -> LabelledSpec-facetMappingProperty (RowBy fFields) =- "row" .= object (map facetChannelProperty fFields)-facetMappingProperty (ColumnBy fFields) =- "column" .= object (map facetChannelProperty fFields)---{-|--Create a single global configuration from a list of configuration specifications.-Configurations are applied to all relevant items in the specification. See the-<https://vega.github.io/vega-lite/docs/config.html Vega-Lite documentation> for-more details.--@-config =- configure- . 'configuration' ('Axis' [ 'DomainWidth' 1 ])- . configuration ('View' [ 'Stroke' (Just "transparent") ])- . configuration ('SelectionStyle' [ ( 'Single', [ 'On' "dblclick" ] ) ])-@--}-configure :: [LabelledSpec] -> (VLProperty, VLSpec)-configure configs = (VLConfig, object configs)---{-|--Defines the fields that will be used to facet a view in rows or columns to create-a set of small multiples. This is used where the encoding of the visualization in small-multiples is identical, but data for each is grouped by the given fields. When-creating a faceted view in this way you also need to define a full specification-to apply to each of those facets using 'asSpec'.--@-'toVegaLite'- [ facet [ 'RowBy' [ 'FName' \"Origin\", 'FmType' 'Nominal' ] ]- , 'specifcation' spec- ]-@--See the-<https://vega.github.io/vega-lite/docs/facet.html Vega-Lite documentation>-for further details.---}--facet :: [FacetMapping] -> (VLProperty, VLSpec)-facet fMaps = (VLFacet, object (map facetMappingProperty fMaps))---{-|--Overrides the default height of the visualization. If not specified the height-will be calculated based on the content of the visualization.--@-'toVegaLite'- [ height 300- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-height :: Double -> (VLProperty, VLSpec)-height h = (VLHeight, toJSON h)---{-|--Assigns a list of specifications to be juxtaposed horizontally in a visualization.--@-'toVegaLite'- [ 'dataFromUrl' "data/driving.json" []- , hConcat [ spec1, spec2 ]- ]-@--}-hConcat :: [VLSpec] -> (VLProperty, VLSpec)-hConcat specs = (VLHConcat, toJSON specs)---{-|--Assigns a list of specifications to superposed layers in a visualization.--@-'toVegaLite'- [ 'dataFromUrl' "data/driving.json" []- , layer [ spec1, spec2 ]- ]-@--}-layer :: [VLSpec] -> (VLProperty, VLSpec)-layer specs = (VLLayer, toJSON specs)---{-|--Provides an optional name to be associated with the visualization.--@-'toVegaLite'- [ name "PopGrowth"- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-name :: T.Text -> (VLProperty, VLSpec)-name s = (VLName, toJSON s)---{-|--Set the padding around the visualization in pixel units. The way padding is-interpreted will depend on the 'autosize' properties. See the-<https://vega.github.io/vega-lite/docs/spec.html#top-level-specifications Vega-Lite documentation>-for details.--@-'toVegaLite'- [ 'width' 500- , padding ('PEdges' 20 10 5 15)- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-padding :: Padding -> (VLProperty, VLSpec)-padding pad = (VLPadding, paddingSpec pad)---{-|--Define the fields that will be used to compose rows and columns of a set of-small multiples. This is used where the encoding of the visualization in small-multiples is largely identical, but the data field used in each might vary. When-a list of fields is identified with @repeat@ you also need to define a full specification-to apply to each of those fields using 'asSpec'.--@-'toVegaLite'- [ repeat [ 'ColumnFields' [ \"Cat\", \"Dog\", \"Fish\" ] ]- , 'specification' ('asSpec' spec)- ]-@--See the-<https://vega.github.io/vega-lite/docs/repeat.html Vega-Lite documentation>-for further details.---}-repeat :: [RepeatFields] -> (VLProperty, VLSpec)-repeat fields = (VLRepeat, object (map repeatFieldsProperty fields))---{-|--Determine whether scales, axes or legends in composite views should share channel-encodings. This allows, for example, two different color encodings to be created-in a layered view, which otherwise by default would share color channels between-layers. Each resolution rule should be in a tuple pairing the channel to which it-applies and the rule type.--@-let res = resolve- . 'resolution' ('RLegend' [ ( 'ChColor', 'Independent' ) ])-in 'toVegaLite'- [ 'dataFromUrl' "data/movies.json" []- , 'vConcat' [ heatSpec, barSpec ]- , res []- ]-@--For more information see the-<https://vega.github.io/vega-lite/docs/resolve.html Vega-Lite documentation>.---}-resolve :: [LabelledSpec] -> (VLProperty, VLSpec)-resolve res = (VLResolve, object res)---{-|--Create a full selection specification from a list of selections. For details-see the-<https://vega.github.io/vega-lite/docs/selection.html Vega-Lite documentation>.--@-sel = selection . 'select' "view" 'Interval' [ 'BindScales' ]-@--}-selection :: [LabelledSpec] -> (VLProperty, VLSpec)-selection sels = (VLSelection, object sels)---{-|--Defines a specification object for use with faceted and repeated small multiples.--@-'toVegaLite'- [ 'facet' [ 'RowBy' [ 'FName' \"Origin\", 'FmType' 'Nominal' ] ]- , specifcation spec- ]-@--}-specification :: VLSpec -> (VLProperty, VLSpec)-specification spec = (VLSpec, spec)---{-|--Create a single transform from a list of transformation specifications. Note-that the order of transformations can be important, especially if labels created-with 'calculateAs', 'timeUnitAs', and 'binAs' are used in other transformations.-Using the functional composition pipeline idiom (as example below) allows you to-provide the transformations in the order intended in a clear manner.--@-trans = transform- . 'filter' ('FExpr' "datum.year == 2010")- . 'calculateAs' "datum.sex == 2 ? 'Female' : 'Male'" "gender"-@--}--transform :: [LabelledSpec] -> (VLProperty, VLSpec)-transform transforms =- let js = if null transforms then A.Null else toJSON (map assemble transforms)-- -- use the same approach as Elm of encoding the spec, then decoding it,- -- rather than inspecting the structure of the JSON- --- assemble :: LabelledSpec -> VLSpec- assemble (str, val) =-- let dval = decode (encode val)- in case str of- "aggregate" ->- case dval of- Just (A.Array vs) | V.length vs == 2 -> object [ ("aggregate", vs V.! 0)- , ("groupby", vs V.! 1) ]- _ -> A.Null-- "bin" ->- case dval of- Just (A.Array vs) | V.length vs == 3 -> object [ ("bin", vs V.! 0)- , ("field", vs V.! 1)- , ("as", vs V.! 2) ]- _ -> A.Null-- "calculate" ->- case dval of- Just (A.Array vs) | V.length vs == 2 -> object [ ("calculate", vs V.! 0)- , ("as", vs V.! 1) ]- _ -> A.Null-- "lookup" ->- case dval of- Just (A.Array vs) | V.length vs == 4 -> object [ ("lookup", vs V.! 0)- , ("from",- object [ ("data", vs V.! 1)- , ("key", vs V.! 2)- , ("fields", vs V.! 3) ] )- ]- _ -> A.Null-- "lookupAs" ->- case dval of- Just (A.Array vs) | V.length vs == 4 -> object [ ("lookup", vs V.! 0)- , ("from",- object [ ("data", vs V.! 1)- , ("key", vs V.! 2) ] )- , ("as", vs V.! 3) ]- _ -> A.Null-- "timeUnit" ->- case dval of- Just (A.Array vs) | V.length vs == 3 -> object [ ("timeUnit", vs V.! 0)- , ("field", vs V.! 1)- , ("as", vs V.! 2) ]- _ -> A.Null-- _ -> object [(str, val)]-- in (VLTransform, js)---{-|--Assigns a list of specifications to be juxtaposed vertically in a visualization.--@-'toVegaLite'- [ 'dataFromUrl' "data/driving.json" []- , vConcat [ spec1, spec2 ]- ]-@--}-vConcat :: [VLSpec] -> (VLProperty, VLSpec)-vConcat specs = (VLVConcat, toJSON specs)---{-|--Override the default width of the visualization. If not specified the width-will be calculated based on the content of the visualization.--@-'toVegaLite'- [ width 500- , 'dataFromUrl' "data/population.json" []- , 'mark' 'Bar' []- , enc []- ]-@--}-width :: Double -> (VLProperty, VLSpec)-width w = (VLWidth, toJSON w)---{-|--Defines a set of named aggregation transformations to be used when encoding-channels. This is useful when, for example, you wish to apply the same transformation-to a number of channels but do not want to define it each time. For further details-see the-<https://vega.github.io/vega-lite/docs/aggregate.html#aggregate-op-def Vega-Lite documentation>.--@-trans =- 'transform'- . aggregate- [ 'opAs' 'Min' "people" "lowerBound", opAs 'Max' "people" "upperBound" ]- [ "age" ]-@--}-aggregate ::- [VLSpec]- -- ^ The named aggregation operations to apply.- -> [T.Text]- -- ^ The \"group by\" fields.- -> BuildLabelledSpecs-aggregate ops groups ols =- let ags = toJSON [toJSON ops, toJSON (map toJSON groups)]- in ("aggregate", ags) : ols---{-|--Create a named binning transformation that may be referenced in other Transformations-or encodings. See the-<https://vega.github.io/vega-lite/docs/bin.html Vega-Lite documentation> for-more details. Note that usually, direct binning within an encoding is preferred-over this form of bin transformation.--@-trans =- 'transform'- . binAs [ 'MaxBins' 3 ] \"IMDB_Rating\" "ratingGroup"-@--}-binAs ::- [BinProperty]- -- ^ An empty list means that the default binning is used.- -> T.Text- -- ^ The field to bin.- -> T.Text- -- ^ The label for the binned data.- -> BuildLabelledSpecs-binAs bProps field label ols =- let js = if null bProps- then [toJSON True, toJSON field, toJSON label]- else [object (map binProperty bProps), toJSON field, toJSON label]- in ("bin" .= js) : ols---{-|--Creates a new data field based on calculations from existing fields.-See the <https://vega.github.io/vega-lite/docs/calculate.html Vega-Lite documentation>-for further details.--@-trans = 'transform' . calculateAs "datum.sex == 2 ? 'F' : 'M'" "gender"-@--}-calculateAs ::- T.Text- -- ^ The calculation to perform.- -> T.Text- -- ^ The field to assign the new values.- -> BuildLabelledSpecs-calculateAs expr label ols = ("calculate" .= [expr, label]) : ols---{-|--Encode a color channel.--@-color [ 'MName' \"Species\", 'MmType' 'Nominal' ] []-@--Encoding a color channel will generate a legend by default. To stop the legend-appearing, just supply an empty list of legend properties to 'MLegend':--@-color [ MName \"Species\", MmType Nominal, 'MLegend' [] ] []-@--}-color ::- [MarkChannel]- -- ^ Control how the data field is encoded by color.- -> BuildLabelledSpecs-color markProps ols =- let cs = object (concatMap markChannelProperty markProps)- in ("color", cs) : ols---{-|--Encodes a new facet to be arranged in columns.--@-enc =- 'encoding'- . 'position' 'X' [ 'PName' "people", 'PmType' 'Quantitative' ]- . position 'Y' [ PName "gender", PmType 'Nominal' ]- . column [ 'FName' "age", 'FmType' 'Ordinal' ]-@--}-column ::- [FacetChannel]- -- ^ The list of properties that define the faceting channel. At a minimum- -- this should include the data field ('FName') and its measurement type- -- ('FmType').- -> BuildLabelledSpecs-column fFields ols =- ("column" .= object (map facetChannelProperty fFields)) : ols---{-|--Defines a single configuration option to be applied globally across the visualization.-The first parameter identifies the type of configuration, the second a list of previous-configurations to which this one may be added.--@-configuration ('Axis' [ 'DomainWidth' 4 ]) []-@--}-configuration :: ConfigurationProperty -> BuildLabelledSpecs-configuration cfg ols = configProperty cfg : ols---{-|--Encode a \"level of detail\" channel. This provides a way of grouping by a field-but unlike, say 'color', all groups have the same visual properties. The first-parameter is a list of the field characteristics to be grouped. The second parameter-is a list of any previous channels to which this detail channel should be added. See the-<https://vega.github.io/vega-lite/docs/encoding.html#detail Vega-Lite documentation>-for details.--@-detail [ 'DName' \"Species\", 'DmType' 'Nominal' ] []-@--}-detail :: [DetailChannel] -> BuildLabelledSpecs-detail detailProps ols =- ("detail" .= object (map detailChannelProperty detailProps)) : ols---{-|--Encode a fill channel. This acts in a similar way to encoding by 'color' but-only affects the interior of closed shapes. The first parameter is a list of mark-channel properties that characterise the way a data field is encoded by fill.-The second parameter is a list of any previous channels to which this fill channel-should be added.--@-fill [ 'MName' \"Species\", 'MmType' 'Nominal' ] []-@--Note that if both @fill@ and 'color' encodings are specified, @fill@ takes precedence.---}-fill :: [MarkChannel] -> BuildLabelledSpecs-fill markProps ols =- ("fill" .= object (concatMap markChannelProperty markProps)) : ols---{-|--Adds the given filter operation a list of transformations that may be applied-to a channel or field. The first parameter is the filter operation and the second,-often implicit, parameter is the list of other filter operations to which this-should be added in sequence.--@-trans =- 'transform'- . filter ('FEqual' \"Animal\" ('Str' \"Cat\"))-@--Filter operations can combine selections and data predicates with 'BooleanOp'-expressions:--@-trans =- transform- . filter ('FCompose' ('And' ('Expr' "datum.Weight_in_lbs > 3000") ('Selection' "brush")))-@--}-filter :: Filter -> BuildLabelledSpecs-filter f ols =- let js = case f of- FExpr expr -> toJSON expr- FCompose boolExpr -> booleanOpSpec boolExpr-- FEqual field val -> object [field_ field, "equal" .= dataValueSpec val]-- FSelection selName -> object ["selection" .= selName]-- FRange field vals ->- let ans = case vals of- NumberRange mn mx -> map toJSON [mn, mx]- DateRange dMin dMax ->- [ object (map dateTimeProperty dMin)- , object (map dateTimeProperty dMax)- ]- in object [field_ field, "range" .= ans]-- FOneOf field vals ->- let ans = case vals of- Numbers xs -> map toJSON xs- DateTimes dts -> map (object . map dateTimeProperty) dts- Strings ss -> map toJSON ss- Booleans bs -> map toJSON bs-- in object [field_ field, "oneOf" .= ans]-- in ("filter", js) : ols---{-|--Encode a hyperlink channel. The first parameter is a list of hyperlink channel-properties that characterise the hyperlinking such as the destination url and cursor-type. The second parameter is a list of any previous encoding channels to which-this hyperlink channel should be added.--@-hyperlink [ 'HName' \"Species\", 'HmType' 'Nominal' ] []-@--For further details see the-<https://vega.github.io/vega-lite/docs/encoding.html#href Vega-Lite documentation>.---}-hyperlink :: [HyperlinkChannel] -> BuildLabelledSpecs-hyperlink hyperProps ols =- ("href" .= object (concatMap hyperlinkChannelProperty hyperProps)) : ols---{-|--Perform a lookup of named fields between two data sources. This allows you to-find values in one data source based on the values in another (like a relational-join).--Unlike 'lookupAs', this function will only return the specific fields named in the-fourth parameter. If you wish to return the entire set of fields in the secondary-data source as a single object, use 'lookupAs'.--See the <https://vega.github.io/vega-lite/docs/lookup.html Vega-Lite documentation>-for further details.--The following would return the values in the @age@ and @height@ fields from-@lookup_people.csv@ for all rows where the value in the @name@ column in that-file matches the value of @person@ in the primary data source.--@-trans =- 'transform'- . lookup "person" ('dataFromUrl' "data/lookup_people.csv" []) "name" [ "age", "height" ]-@--}-lookup ::- T.Text- -- ^ The field in the primary data structure acting as the key.- -> Data- -- ^ The secondary data source (e.g. the return from the data-generating- -- functions such as 'dataFromUrl').- -> T.Text- -- ^ The name of the field in the secondary data source to match against- -- the primary key.- -> [T.Text]- -- ^ The list of fields to store when the keys match.- -> BuildLabelledSpecs-lookup key1 (_, spec) key2 fields ols =- let js = [toJSON key1, spec, toJSON key2, toJSON (map toJSON fields)]- in ("lookup" .= js) : ols---{-|--Perform an object lookup between two data sources. This allows you to find-values in one data source based on the values in another (like a relational-join).--Unlike 'lookup', this function returns the entire set of field values from the-secondary data source when keys match. Those fields are stored as an object with-the name provided in the fourth parameter.--See the-<https://vega.github.io/vega-lite/docs/lookup.html Vega-Lite documentation>-for further details.--In the following example, @personDetails@ would reference all the field values in-@lookup_people.csv@ for each row where the value in the @name@ column in that-file matches the value of @person@ in the primary data source.--@-trans = 'transform'- . lookupAs "person" ('dataFromUrl' "data/lookup_people.csv" []) "name" "personDetails"-@--}-lookupAs ::- T.Text- -- ^ The field in the primary data structure acting as the key.- -> Data- -- ^ The secondary data source (e.g. the return from the data-generating- -- functions such as 'dataFromUrl').- -> T.Text- -- ^ The name of the field in the secondary data source to match against- -- the primary key.- -> T.Text- -- ^ The field name for the new data.- -> BuildLabelledSpecs-lookupAs key1 (_, spec) key2 asName ols =- ("lookupAs" .= [toJSON key1, spec, toJSON key2, toJSON asName]) : ols---{-|--Encode an opacity channel. The first parameter is a list of mark channel properties-that characterise the way a data field is encoded by opacity. The second parameter-is a list of any previous channels to which this opacity channel should be added.--@-opacity [ 'MName' \"Age\", 'MmType' 'Quantitative' ] []-@--}-opacity :: [MarkChannel] -> BuildLabelledSpecs-opacity markProps ols =- ("opacity" .= object (concatMap markChannelProperty markProps)) : ols---{-|--Encode an order channel. The first parameter is a list of order field definitions-to define the channel. The second parameter is a list of any previous channels to-which this order channel is to be added.--@-enc =- 'encoding'- . 'position' 'X' [ 'PName' "miles", 'PmType' 'Quantitative' ]- . position 'Y' [ PName "gas", PmType Quantitative ]- . order [ 'OName' "year", 'OmType' 'Temporal' ]-@--}-order :: [OrderChannel] -> BuildLabelledSpecs-order oDefs ols =- ("order" .= object (map orderChannelProperty oDefs)) : ols---{-|--Encode a position channel.--@-enc =- 'encoding'- . position 'X' [ 'PName' \"Animal\", 'PmType' 'Ordinal' ]-@--Encoding by position will generate an axis by default. To prevent the axis from-appearing, simply provide an empty list of axis properties to 'PAxis':--@-enc =- encoding- . position X [ PName \"Animal\", PmType Ordinal, 'PAxis' [] ]-@--}-position ::- Position- -- ^ The channel to encode.- -> [PositionChannel]- -- ^ The options for the channel; this will usually include the name ('PName')- -- and measurement type ('PmType'), but can be a reference to a row or- -- column repeat field.- -> BuildLabelledSpecs-position pos pDefs ols =- let defs = object (map positionChannelProperty pDefs)- in (positionLabel pos, defs) : ols---{-|--Define a single resolution option to be applied when scales, axes or legends-in composite views share channel encodings. This allows, for example, two different-color encodings to be created in a layered view, which otherwise by default would-share color channels between layers. Each resolution rule should be in a tuple-pairing the channel to which it applies and the rule type.--@-'resolve'- . resolution ('RScale' [ ( 'ChY', 'Independent' ) ])-@--}-resolution :: Resolve -> BuildLabelledSpecs-resolution res ols = resolveProperty res : ols---{-|--Encode a new facet to be arranged in rows.--@-enc =- 'encoding'- . 'position' 'X' [ 'PName' "people", 'PmType' 'Quantitative' ]- . position 'Y' [ PName "gender", PmType 'Nominal' ]- . row [ 'FName' "age", 'FmType' 'Ordinal' ]-@--}-row ::- [FacetChannel]- -- ^ The facet properties for the channel; this should include the name of- -- the field ('FName') and its measurement type ('FmType').- -> BuildLabelledSpecs-row fFields ols = ("row" .= object (map facetChannelProperty fFields)) : ols---{-|--Create a single named selection that may be applied to a data query or transformation.--@-sel =- 'selection'- . select "view" 'Interval' [ 'BindScales' ] []- . select "myBrush" Interval []- . select "myPaintbrush" 'Multi' [ 'On' "mouseover", 'Nearest' True ]-@--}-select ::- T.Text- -- ^ The name given to the selection.- -> Selection- -- ^ The type of the selection.- -> [SelectionProperty]- -- ^ What options are applied to the selection.- -> BuildLabelledSpecs-select nme sType options ols =- let selProps = ("type" .= selectionLabel sType) : map selectionProperty options- in (nme .= object selProps) : ols---{-|--Encode a shape channel.--@-shape [ 'MName' \"Species\", 'MmType' 'Nominal' ] []-@--}-shape ::- [MarkChannel]- -- ^ What data values are used to control the shape parameters of the mark.- -> BuildLabelledSpecs-shape markProps ols = ("shape" .= object (concatMap markChannelProperty markProps)) : ols---{-|--Encode a size channel.--@-size [ 'MName' \"Age\", 'MmType' 'Quantitative' ] []-@--}-size ::- [MarkChannel]- -- ^ What data values are used to control the size parameters of the mark.- -> BuildLabelledSpecs-size markProps ols = ("size" .= object (concatMap markChannelProperty markProps)) : ols---{-|--Encode a stroke channel. This acts in a similar way to encoding by 'color' but-only affects the exterior boundary of marks.--@-stroke [ 'MName' \"Species\", 'MmType' 'Nominal' ] []-@--Note that if both @stroke@ and 'color' encodings are specified, @stroke@ takes-precedence.---}-stroke ::- [MarkChannel]- -- ^ What data values are used to control the stoke parameters of the mark.- -> BuildLabelledSpecs-stroke markProps ols =- ("stroke" .= object (concatMap markChannelProperty markProps)) : ols---{-|--Encode a text channel. See the-<https://vega.github.io/vega-lite/docs/encoding.html#text Vega-Lite documentation>-for further details on the text and tooltip channels and-<https://vega.github.io/vega-lite/docs/format.html Vega-Lite formatting documentation>-for formatting the appearance of the text.--@-enc =- 'encoding'- . 'position' 'X' [ 'PName' "miles", 'PmType' 'Quantitative' ]- . position 'Y' [ PName "gas", PmType Quantitative ]- . text [ 'TName' "miles", 'TmType' Quantitative ]-@--}-text ::- [TextChannel]- -- ^ What data values are used to control the text parameters.- -> BuildLabelledSpecs-text tDefs ols =- ("text" .= object (concatMap textChannelProperty tDefs)) : ols---{-|--Creates a new data field based on the given temporal binning. Unlike the-direct encoding binning, this transformation is named and so can be referred-to in multiple encodings. Note though that usually it is easer to apply the temporal-binning directly as part of the encoding as this will automatically format the-temporal axis. See the-<https://vega.github.io/vega-lite/docs/timeunit.html#transform Vega-Lite documentation>-for further details.--The following example takes a temporal dataset and encodes daily totals from it-grouping by month:--@-trans = 'transform' . timeUnitAs 'Month' "date" "monthly"--enc = 'encoding'- . 'position' 'X' [ 'PName' "date", 'PmType' 'Temporal', 'PTimeUnit' 'Day' ]- . position 'Y' [ 'PAggregate' 'Sum', PmType 'Quantitative' ]- . 'detail' [ 'DName' "monthly", 'DmType' 'Temporal' ]-@--}-timeUnitAs ::- TimeUnit- -- ^ The width of each bin.- -> T.Text- -- ^ The field to bin.- -> T.Text- -- ^ The name of the binned data created by this routine.- -> BuildLabelledSpecs-timeUnitAs tu field label ols =- ("timeUnit" .= [timeUnitLabel tu, field, label]) : ols---{-|--Encode a tooltip channel. See the-<https://vega.github.io/vega-lite/docs/encoding.html#text Vega-Lite documentation>-for further details on the text and tooltip channels and-<https://vega.github.io/vega-lite/docs/format.html Vega-Lite formatting documentation>-for formatting the appearance of the text.--@-enc = 'encoding'- . 'position' 'X' [ 'PName' \"Horsepower\", 'PmType' 'Quantitative' ]- . position 'Y' [ PName \"Miles_per_Gallon\", PmType Quantitative ]- . tooltip [ 'TName' \"Year\", 'TmType' 'Temporal', 'TFormat' "%Y" ]-@--}-tooltip ::- [TextChannel]- -- ^ The properties for the channel.- -> BuildLabelledSpecs-tooltip tDefs ols =- ("tooltip" .= object (concatMap textChannelProperty tDefs)) : ols--{-|--Encode a tooltip channel with multiple tooltips.-The first parameter is a list of the multiple tooltips, each of which is a list of text-channel properties that define the channel.--@since 0.3.0.0--@-enc = 'encoding'- . 'position' 'X' [ 'PName' \"Horsepower\", 'PmType' 'Quantitative' ]- . position 'Y' [ PName \"Miles_per_Gallon\", PmType Quantitative ]- . tooltips [ [ 'TName' \"Year\", 'TmType' 'Temporal', 'TFormat' "%Y" ]- ,[ TName \"Month\", TmType Temporal, TFormat "%Y" ] ]-@--}-tooltips ::- [[TextChannel]]- -- ^ A separate list of properties for each channel.- -> BuildLabelledSpecs-tooltips tDefs ols =- ("tooltip" .= toJSON (map (object . (concatMap textChannelProperty)) tDefs)) : ols+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}++{-|+Module : Graphics.Vega.VegaLite+Copyright : (c) Douglas Burke, 2018-2019+License : BSD3++Maintainer : dburke.gw@gmail.com+Stability : unstable+Portability : OverloadedStrings, TupleSections++This is a port of the+<http://package.elm-lang.org/packages/gicentre/elm-vegalite/latest Elm Vega Lite module>,+written by Jo Wood of the giCentre at the City+University of London. It was originally based on version @2.2.1@ but+it has been updated to match later versions. This module allows users+to create a Vega-Lite specification, targeting __version 3__ of the+<https://vega.github.io/schema/vega-lite/v3.json JSON schema>. The+ihaskell-hvega module provides an easy way to embed Vega-Lite+visualizations in an IHaskell notebook (using+<https://vega.github.io/vega-lite/usage/embed.html Vega-Embed>).++Although this is based on the Elm module, there are differences, such+as using type constructors rather than functions for many properties -+such as @PName \"HorsePower\"@ rather than @pName \"HorsePower\"@ -+and the return value of 'toVegaLite'. The intention is to keep close+to the Elm module, but it is more a guide than an absolute+requirement!++Please see "Graphics.Vega.Tutorials.VegaLite" for an introduction+to using @hvega@ to create visualizations.++== Example++Note that this module exports several symbols that are exported+by the Prelude, such as 'filter', 'lookup',+and 'repeat'; to avoid name clashes it's therefore advised+to either import the module qualified, for example:++@+import qualified Graphics.Vega.VegaLite as VL+@++or to hide the clashing names explicitly:++@+import Prelude hiding (filter, lookup, repeat)+@++In the following example, we'll assume the latter.++Let's say we have the following plot declaration in a module:++@+\{\-\# language OverloadedStrings \#\-\}++vl1 =+ let desc = "A very exciting bar chart"++ dat = 'dataFromRows' ['Parse' [("start", 'FoDate' "%Y-%m-%d")]]+ . 'dataRow' [("start", 'Str' "2011-03-25"), ("count", 'Number' 23)]+ . 'dataRow' [("start", 'Str' "2011-04-02"), ("count", 'Number' 45)]+ . 'dataRow' [("start", 'Str' "2011-04-12"), ("count", 'Number' 3)]++ barOpts = ['MOpacity' 0.4, 'MColor' "teal"]++ enc = 'encoding'+ . 'position' 'X' ['PName' "start", 'PmType' 'Temporal', 'PAxis' ['AxTitle' "Inception date"]]+ . 'position' 'Y' ['PName' "count", 'PmType' 'Quantitative']++ in 'toVegaLite' ['description' desc, 'background' "white"+ , dat [], 'mark' 'Bar' barOpts, enc []]+@++We can inspect how the encoded JSON looks like in an GHCi session:++@+> 'A.encode' $ 'fromVL' vl1+> "{\"mark\":{\"color\":\"teal\",\"opacity\":0.4,\"type\":\"bar\"},\"data\":{\"values\":[{\"start\":\"2011-03-25\",\"count\":23},{\"start\":\"2011-04-02\",\"count\":45},{\"start\":\"2011-04-12\",\"count\":3}],\"format\":{\"parse\":{\"start\":\"date:'%Y-%m-%d'\"}}},\"$schema\":\"https://vega.github.io/schema/vega-lite/v3.json\",\"encoding\":{\"x\":{\"field\":\"start\",\"type\":\"temporal\",\"axis\":{\"title\":\"Inception date\"}},\"y\":{\"field\":\"count\",\"type\":\"quantitative\"}},\"background\":\"white\",\"description\":\"A very exciting bar chart\"}"+@++The produced JSON can then be processed with vega-lite, which renders the following image:++<<images/example.png>>++which can also be+<https://vega.github.io/editor/#/url/vega-lite/N4KABGBEC2CGBOBrSAuMxIGMD2Abb8qUALgKay6QA0U2ADrJgJbECeRADAHQAsNkbOqSKQARgkgBfKuCgATWMVhFQECJABuFAK6kAzkQDastekh6l8YiIBMHAIz2AtBwDMTmwFZqUHNoB21mg2rtImahgWCEFQdo4uPC42PljYATE8nmGmEJGWMZBxzhyJ9sn8foFEoeEAujKmkABmBHAxGAzwesJoedEiCmQoAOQApACaTqPQU3LDUpKy2VAAJHqYABakcCIbxMR0eigA9McapADmsFwXLBvaolxM2MfrW3Bnl7BOuCykZ64uAArPTYfzUWSQUj+HByJj+C4qcKQAAeSJyUCaTFIuDkIiiVghGIErCEIjI0DoBAoRJykFgKKYBl6AhYuB6UAAkjDSHRiM9-GBBsJFqZlup2CysTi8WhUukUoIOZAAI7aWCBFiKJjnKRLBpQcSYRAXeBpfyyqAAdw2f1pkDk+kw8CYfIFIgAgmBzvBWGBSCjmPyEWBxPAwJt+gbUv4sYjeotJEA displayed in the Vega Editor>.++Output can be achieved in a Jupyter Lab session with the @vlShow@ function,+provided by @ihaskell-vega@, or 'toHtmlFile' can be used to write out a page of+HTML that includes pointer to JavaScript files which will display a Vega-Lite+specification (there are also functions which provide more control over+the embedding).++-}++module Graphics.Vega.VegaLite+ (+ -- * Creating a Vega-Lite Specification++ toVegaLite+ , toVegaLiteSchema+ , vlSchema2, vlSchema3, vlSchema4, vlSchema+ , fromVL+ , VLProperty(..)+ , VLSpec+ , VegaLite+ , PropertySpec+ , LabelledSpec+ , BuildLabelledSpecs+ , Angle+ , Color+ , Opacity+ , ZIndex+ , combineSpecs+ , toHtml+ , toHtmlFile+ , toHtmlWith+ , toHtmlFileWith++ -- * Creating the Data Specification+ --+ -- $dataspec++ , dataFromUrl+ , dataFromColumns+ , dataFromRows+ , dataFromJson+ , dataFromSource+ , dataName+ , datasets+ , dataColumn+ , dataRow+ , noData+ , Data+ , DataColumn+ , DataRow++ -- ** Geographic Data++ , geometry+ , geoFeatureCollection+ , geometryCollection+ , Geometry(..)++ -- ** Data Generators+ --+ -- $datagen++ , dataSequence+ , dataSequenceAs+ , sphere+ , graticule+ , GraticuleProperty(..)++ -- ** Formatting Input Data+ --+ -- $dataformat++ , Format(..)+ , DataType(..)++ -- * Creating the Transform Specification+ --+ -- $transform++ , transform++ -- ** Map Projections+ --+ -- $projections++ , projection+ , ProjectionProperty(..)+ , Projection(..)+ , ClipRect(..)++ -- ** Aggregation+ --+ -- $aggregation++ , aggregate+ , joinAggregate+ , opAs+ , timeUnitAs+ , Operation(..)++ -- ** Binning+ --+ -- $binning++ , binAs+ , BinProperty(..)++ -- ** Stacking+ --+ -- $stacking++ , stack+ , StackProperty(..)+ , StackOffset(..)++ -- ** Data Calculation+ --+ -- $calculate++ , calculateAs++ -- ** Filtering+ --+ -- $filtering++ , filter+ , Filter(..)+ , FilterRange(..)++ -- ** Flattening+ --+ -- $flattening++ , flatten+ , flattenAs+ , fold+ , foldAs++ -- ** Relational Joining (lookup)+ --+ -- $joining++ , lookup+ , lookupAs++ -- ** Data Imputation+ --+ -- $imputation++ , impute+ , ImputeProperty(..)+ , ImMethod(..)++ -- ** Data sampling+ --+ -- $sampling++ , sample++ -- ** Window Transformations+ --+ -- $window++ , window+ , Window(..)+ , WOperation(..)+ , WindowProperty(..)++ -- * Creating the Mark Specification+ --+ -- $markspec++ , mark+ , Mark(..)++ -- ** Mark properties+ --+ -- $markproperties++ , MarkProperty(..)+ , StrokeCap(..)+ , StrokeJoin(..)++ -- *** Used by Mark Properties++ , Orientation(..)+ , MarkInterpolation(..)+ , Symbol(..)+ , PointMarker(..)+ , LineMarker(..)+ , MarkErrorExtent(..)+ , TooltipContent(..)++ -- ** Cursors+ --+ -- $cursors++ , Cursor(..)++ -- * Creating the Encoding Specification+ --+ -- $encoding++ , encoding+ , Measurement(..)++ -- ** Position Channels+ --+ -- $position++ , position+ , Position(..)++ -- *** Position channel properties++ , PositionChannel(..)++ -- ** Sorting properties+ --+ -- $sortprops++ , SortProperty(..)+ , SortField(..)++ -- ** Axis properties+ --+ -- $axisprops++ , AxisProperty(..)++ -- ** Positioning Constants+ --+ -- *** Text Alignment++ , HAlign(..)+ , VAlign(..)++ -- *** Overlapping text++ , OverlapStrategy(..)++ -- *** Legends++ , Side(..)++ -- ** Mark channels+ --+ -- $markprops++ , size+ , color+ , fill+ , stroke+ , strokeWidth+ , opacity+ , fillOpacity+ , strokeOpacity+ , shape++ -- *** Mark Channel properties++ , MarkChannel(..)++ -- *** Mark Legends+ --+ -- $marklegends++ , LegendType(..)+ , LegendProperty(..)+ , LegendOrientation(..)+ , LegendValues(..)++ -- ** Text Channels+ --+ -- $textchannels++ , text+ , tooltip+ , tooltips+ , TextChannel(..)+ , FontWeight(..)++ -- ** Hyperlink Channels+ --+ -- $hyperlink++ , hyperlink+ , HyperlinkChannel(..)++ -- ** Order Channel+ --+ -- $order++ , order+ , OrderChannel(..)++ -- ** Facet Channel+ --+ -- $facet++ , row+ , column++ -- ** Level of detail Channel+ --+ -- $detail++ , detail+ , DetailChannel(..)++ -- ** Scaling+ --+ -- $scaling++ , ScaleProperty(..)+ , Scale(..)+ , categoricalDomainMap+ , domainRangeMap+ , ScaleDomain(..)+ , ScaleRange(..)+ , ScaleNice(..)++ -- *** Color scaling+ --+ -- $color++ , CInterpolate(..)++ -- * Creating view compositions+ --+ -- $view++ , layer+ , vlConcat+ , columns+ , hConcat+ , vConcat+ , align+ , alignRC+ , spacing+ , spacingRC+ , center+ , centerRC+ , bounds+ , Bounds(..)+ , CompositionAlignment(..)++ -- ** Resolution+ --+ -- $resolution++ , resolve+ , resolution+ , Resolve(..)+ , Channel(..)+ , Resolution(..)++ -- ** Faceted views+ --+ -- $facetview++ , repeat+ , repeatFlow+ , RepeatFields(..)+ , facet+ , facetFlow+ , FacetMapping(..)+ , FacetChannel(..)+ , asSpec+ , specification+ , Arrangement(..)++ -- *** Facet Headers+ --+ -- $facetheaders++ , HeaderProperty(..)++ -- * Creating Selections for Interaction+ --+ -- $selections++ , selection+ , select+ , Selection(..)+ , SelectionProperty(..)+ , Binding(..)+ , InputProperty(..)+ , SelectionMarkProperty(..)++ -- ** Selection Resolution+ --+ -- $selectionresolution++ , SelectionResolution(..)++ -- ** Making conditional channel encodings+ --+ -- $conditional++ , BooleanOp(..)++ -- ** Top-level Settings+ --+ -- $toplevel++ , name+ , description+ , height+ , width+ , padding+ , autosize+ , background+ , usermetadata+ , Padding(..)+ , Autosize(..)++ -- *** Title+ --+ -- $title++ , title++ -- *** View Backgroud+ --+ -- $viewbackground++ , viewBackground+ , ViewBackground(..)++ -- ** Style Setting++ , configure+ , configuration+ , ConfigurationProperty(..)++ -- ** Axis Configuration Options+ --+ -- $axisconfig++ , AxisConfig(..)++ -- ** Legend Configuration Options+ --++ , LegendConfig(..)+ , LegendLayout(..)+ , BaseLegendLayout(..)++ -- ** Scale Configuration Options+ --+ -- $scaleconfig++ , ScaleConfig(..)++ -- ** Scale Range Configuration Options+ --+ -- $scalerangeconfig++ , RangeConfig(..)++ -- ** Title Configuration Options+ --+ -- $titleconfig++ , TitleConfig(..)+ , TitleFrame(..)++ -- ** View Configuration Options+ --+ -- $viewconfig++ , ViewConfig(..)+ , APosition(..)+ , FieldTitleProperty(..)++ -- ** Facet Configuration Options+ --+ -- $facetconfig++ , FacetConfig(..)++ -- ** Concatenated View Configuration Options+ --+ -- $concatconfig++ , ConcatConfig(..)++ -- * General Data types+ --+ -- $generaldatatypes++ , DataValue(..)+ , DataValues(..)++ -- ** Temporal data+ --+ -- $temporaldata++ , DateTime(..)+ , MonthName(..)+ , DayName(..)+ , TimeUnit(..)++ -- * Update notes+ --+ -- $update++ -- ** Version 0.4+ --+ -- $update0400++ )+ where++-- VegaLite uses these symbols.+import Prelude hiding (filter, lookup, repeat)++import qualified Data.Aeson as A+import qualified Data.Aeson.Text as A+import qualified Data.HashMap.Strict as HM+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.IO as TL+import qualified Data.Vector as V++import Control.Arrow (first, second)++-- Aeson's Value type conflicts with the Number type+import Data.Aeson (Value, decode, encode, object, toJSON, (.=))+import Data.Maybe (catMaybes, fromMaybe, mapMaybe)+import Data.Monoid ((<>))++-- added in base 4.8.0.0 / ghc 7.10.1+import Numeric.Natural (Natural)+++-- Documentation++-- $dataspec+-- Functions and types for declaring the input data to the+-- visualization. See the+-- [Vega-Lite documentation](https://vega.github.io/vega-lite/docs/data.html#format).++-- $datagen+-- Functions that create new data sources.++-- $dataformat+-- See the Vega-Lite+-- [format](https://vega.github.io/vega-lite/docs/data.html#format) and+-- [JSON](https://vega.github.io/vega-lite/docs/data.html#json) documentation.++-- $transform+-- Functions and types for declaring the transformation rules that+-- are applied to data fields or geospatial coordinates before they+-- are encoded visually.++-- $projections+-- See the+-- [Vega-Lite map projection documentation](https://vega.github.io/vega-lite/docs/projection.html).++-- $aggregation+-- See the+-- [Vega-Lite aggregate documentation](https://vega.github.io/vega-lite/docs/aggregate.html).++-- $binning+-- See the+-- [Vega-Lite binning documentation](https://vega.github.io/vega-lite/docs/bin.html).++-- $stacking+-- See the [Vega-Lite stack documentation](https://vega.github.io/vega-lite/docs/stack.html).++-- $calculate+-- See the+-- [Vega-Lite calculate documentation](https://vega.github.io/vega-lite/docs/calculate.html).++-- $filtering+-- See the+-- [Vega-Lite filter documentation](https://vega.github.io/vega-lite/docs/filter.html).++-- $flattening+-- See the Vega-Lite [flatten](https://vega.github.io/vega-lite/docs/flatten.html)+-- and [fold](https://vega.github.io/vega-lite/docs/fold.html)+-- documentation.++-- $joining+-- See the+-- [Vega-Lite lookup documentation](https://vega.github.io/vega-lite/docs/lookup.html).++-- $imputation+-- Impute missing data. See the+-- [Vega-Lite impute documentation](https://vega.github.io/vega-lite/docs/impute.html#transform).++-- $sampling+-- See the [Vega-Lite sample documentation](https://vega.github.io/vega-lite/docs/sample.html)++-- $window+-- See the Vega-Lite+-- [window transform field](https://vega.github.io/vega-lite/docs/window.html#field-def)+-- and+-- [window transform](https://vega.github.io/vega-lite/docs/window.html#window-transform-definition)+-- documentation.++-- $markspec+-- Types and functions for declaring the type of visual+-- marks used in the visualization.++-- $markproperties+-- See the Vega-Lite+-- [general mark](https://vega.github.io/vega-lite/docs/mark.html#general-mark-properties),+-- [area mark](https://vega.github.io/vega-lite/docs/area.html#properties),+-- [bar mark](https://vega.github.io/vega-lite/docs/bar.html#properties),+-- [boxplot](https://vega.github.io/vega-lite/docs/boxplot.html#properties),+-- [circle mark](https://vega.github.io/vega-lite/docs/circle.html#properties),+-- [error band](https://vega.github.io/vega-lite/docs/errorband.html#properties),+-- [error bar](https://vega.github.io/vega-lite/docs/errorbar.html#properties),+-- [hyperlink mark](https://vega.github.io/vega-lite/docs/mark.html#hyperlink),+-- [line mark](https://vega.github.io/vega-lite/docs/line.html#properties),+-- [point mark](https://vega.github.io/vega-lite/docs/point.html#properties),+-- [square mark](https://vega.github.io/vega-lite/docs/square.html#properties),+-- [text mark](https://vega.github.io/vega-lite/docs/text.html#properties) and+-- [tick mark](https://vega.github.io/vega-lite/docs/tick.html#properties)+-- property documentation.++-- $cursors+-- See the+-- [CSS cursor documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Keyword%20values)++-- $encoding+-- Types and functions for declaring which data fields are mapped to which+-- channels. Channels can include: position on screen (e.g. 'X', 'Y'); visual+-- mark properties ('color', 'size', 'stroke', 'shape'); 'text'; 'hyperlink';+-- ordering ('order'); level of 'detail'; and facets for composed+-- visualizations ('facet'). All can be further customised via a series of+-- properties that determine how the encoding is implemented (such as+-- scaling, sorting, and spacing).++-- $position+-- Control where items appear in the visualization. See the+-- [Vega-Lite position documentation](https://vega.github.io/vega-lite/docs/encoding.html#position).++-- $sortprops+-- See the+-- [Vega-Lite sort documentation](https://vega.github.io/vega-lite/docs/sort.html).++-- $axisprops+-- See the+-- Vega-Lite axis property documentation](https://vega.github.io/vega-lite/docs/axis.html#axis-properties).++-- $markprops+-- Control the appearance of the visual marks in the visualization+-- (e.g. 'color' and 'size').++-- $marklegends+-- See the+-- [Vega-Lite legend property documentation](https://vega.github.io/vega-lite/docs/legend.html#legend-properties).++-- $textchannels+-- Control the appearance of the text and tooltip elements in the visualization.++-- $hyperlink+-- Channels which offer a clickable URL destination. Unlike most other+-- channels, the hyperlink channel has no direct visual expression other than the+-- option of changing the cursor style when hovering, so an encoding will usually+-- pair hyperlinks with other visual channels such as marks or texts.++-- $order+-- Channels that relate to the order of data fields such as for sorting stacking order+-- or order of data points in a connected scatterplot. See the+-- <https://vega.github.io/vega-lite/docs/encoding.html#order Vega-Lite documentation>+-- for further details.++-- $facet+-- Channels for faceting single plots into small multiples. Can be used to create+-- trellis plots or other arrangements in rows and columns. See the+-- <https://vega.github.io/vega-lite/docs/encoding.html#facet Vega-Lite documentation>+-- for further details. See also, <#facetview faceted views> for a more flexible (but+-- more verbose) way of defining faceted views.++-- $detail+-- Used for grouping data but without changing the visual appearance of a mark. When,+-- for example, a field is encoded by color, all data items with the same value for+-- that field are given the same color. When a detail channel encodes a field, all+-- data items with the same value are placed in the same group. This allows, for example+-- a line chart with multiple lines to be created – one for each group. See the+-- <https://vega.github.io/vega-lite/docs/encoding.html#detail Vega-Lite documentation>+-- for more information.++-- $scaling+-- Used to specify how the encoding of a data field should be applied. See the+-- [Vega-Lite scale documentation](https://vega.github.io/vega-lite/docs/scale.html).++-- $color+-- For color interpolation types, see the+-- [Vega-Lite continuous scale documentation](https://vega.github.io/vega-lite/docs/scale.html#continuous).++-- $view+-- Views can be combined to create more complex multiview displays. This may involve+-- layering views on top of each other (superposition) or laying them out in adjacent+-- spaces (juxtaposition using 'repeat', 'repeatFlow', 'facet', 'facetFlow',+-- 'vlConcat', 'hConcat', or 'vConcat'). Where different views have potentially conflicting+-- channels (for example, two position scales in a layered visualization) the rules for+-- resolving them can be defined with 'resolve'. For details of creating composite views see the+-- <https://vega.github.io/vega-lite/docs/composition.html Vega-Lite documentation>.++-- $resolution+-- Control the independence between composed views.+--+-- See the [Vega-Lite resolve documentation](https://vega.github.io/vega-lite/docs/resolve.html).++-- $facetview+-- #facetview#+-- These are small multiples each of which show subsets of the same dataset. The specification+-- determines which field should be used to determine subsets along with their spatial+-- arrangement (in rows or columns). For details see the+-- <https://vega.github.io/vega-lite/docs/facet.html Vega-Lite documentation>.++-- $facetheaders+-- See the+-- [Vega-Lite header documentation](https://vega.github.io/vega-lite/docs/header.html).++-- $selections+-- Selections are the way in which interactions (such as clicking or dragging) can be+-- responded to in a visualization. They transform interactions into data queries.+-- For details, see the+-- <https://vega.github.io/vega-lite/docs/selection.html Vega-Lite documentation>.++-- $selectionresolution+-- Determines how selections are made across multiple views.+-- See the [Vega-lite resolve selection documentation](https://vega.github.io/vega-lite/docs/selection.html#resolve).++-- $conditional+-- To make channel encoding conditional on the result of some interaction, use+-- 'MSelectionCondition', 'TSelectionCondition', or 'HSelectionCondition'. Similarly+-- 'MDataCondition', 'TDataCondition', or 'HDataCondition' will encode a mark+-- conditionally depending on some data properties such as whether a datum is null+-- or an outlier.+--+-- For interaction, once a selection has been defined and named, supplying a set of+-- encodings allow mark encodings to become dependent on that selection.+-- 'MSelectionCondition' is followed firstly a (Boolean) selection and then an+-- encoding if that selection is true and another encoding to be applied if it is false.+-- The color specification below states \"whenever data marks are selected with an+-- interval mouse drag, encode the cylinder field with an ordinal color scheme,+-- otherwise make them grey\":+--+-- @+-- sel = 'selection' . 'select' "myBrush" 'Interval' []+--+-- enc = 'encoding'+-- . 'position' 'X' [ 'PName' \"Horsepower\", 'PmType' 'Quantitative' ]+-- . 'position' 'Y' [ 'PName' \"Miles_per_Gallon\", 'PmType' Quantitative ]+-- . 'color'+-- [ 'MSelectionCondition' ('SelectionName' "myBrush")+-- [ 'MName' \"Cylinders\", 'MmType' 'Ordinal' ]+-- [ 'MString' "grey" ]+-- ]+-- @+--+-- In a similar way, 'MDataCondition' will encode a mark depending on whether any+-- predicate tests are satisfied. Unlike selections, multiple conditions and associated+-- encodings can be specified. Each test condition is evaluated in order and only on+-- failure of the test does encoding proceed to the next test. If no tests are true,+-- the encoding in the final parameter is applied in a similar way to @case of@+-- expressions:+--+-- @+-- enc = 'encoding'+-- . 'position' X [ 'PName' \"value\", 'PmType' 'Quantitative' ]+-- . 'color'+-- [ 'MDataCondition'+-- [ ( 'Expr' "datum.value < 40", [ 'MString' "blue" ] )+-- , ( 'Expr' "datum.value < 50", [ 'MString' "red" ] )+-- , ( 'Expr' "datum.value < 60", [ 'MString' "yellow" ] )+-- ]+-- [ 'MString' "black" ]+-- ]+-- @+--+-- For more details, see the+-- <https://vega.github.io/vega-lite/docs/condition.html Vega-Lite documentation>.++-- $toplevel+-- These are in addition to the data and transform options described above,+-- and are described in the+-- [Vega-Lite top-level spec documentation](https://vega.github.io/vega-lite/docs/spec.html#top-level-specifications).++-- $title+-- Per-title settings. Use 'TitleStyle' to change the appearance of all+-- titles in a multi-view specification.++-- $viewbackground+-- The background of a single view in a view composition can be styled independently+-- of other views. For more details see the+-- [Vega-Lite view background documentation](https://vega.github.io/vega-lite/docs/spec.html#view-background).++-- $axisconfig+-- See the+-- [Vega-Lite axis config documentation](https://vega.github.io/vega-lite/docs/axis.html#general-config).++-- $scaleconfig+-- See the+-- [Vega-Lite scale configuration documentation](https://vega.github.io/vega-lite/docs/scale.html#scale-config).++-- $scalerangeconfig+-- See the+-- [Vega-Lite scheme configuration documentation](https://vega.github.io/vega/docs/schemes/#scheme-properties).++-- $titleconfig+-- Unlike 'title', these options apply to __all__ titles if multiple views+-- are created. See the+-- [Vega-Lite title configuration documentation](https://vega.github.io/vega-lite/docs/title.html#config).++-- $viewconfig+-- See the+-- [Vega-Lite view configuration documentation](https://vega.github.io/vega-lite/docs/spec.html#config).++-- $facetconfig+-- See the+-- [Vega-Lite facet configuration documentation](https://vega.github.io/vega-lite/docs/facet.html#facet-configuration).++-- $concatconfig+-- See the+-- [Vega-Lite concat configuration documentation](https://vega.github.io/vega-lite/docs/concat.html#concat-configuration).++-- $generaldatatypes+-- In addition to more general data types like integers and string, the following types+-- can carry data used in specifications.++-- $temporaldata+-- See the+-- [Vega-Lite dateTime documentation](https://vega.github.io/vega-lite/docs/types.html#datetime)+-- and the [Vega-Lite time unit documentation](https://vega.github.io/vega-lite/docs/timeunit.html).++-- $update+-- The following section describes how to update code that used+-- an older version of @hvega@.++-- $update0400+-- The @0.4.0.0@ release added a large number of functions, types, and+-- constructors, including:+--+-- 'toVegaLiteSchema' has been added to allow you to specify a+-- different Vega-Lite schema. 'toVegaLite' uses version 3 but+-- version 4 is being worked on as I type this. The 'vlSchema'+-- function has been added, along with 'vlSchema4', 'vlSchema3',+-- and 'vlSchema2' values. The 'toHtmlWith' and 'toHtmlFileWith'+-- functions have been added to support more control over the+-- embedding of the Vega-Lite visualizations, and the versions of+-- the required Javascript libraries used by the @toHtmlXXX@ routines+-- has been updated.+--+-- The 'VLProperty' type now exports its constructors, to support users+-- who may need to tweak or augment the JSON Vega-Lite specification+-- created by @hvega@: see [issue+-- 17](https://github.com/DougBurke/hvega/issues/17). It has also gained+-- several new constructors and associated functions, which are given in+-- brackets after the constructor: 'VLAlign' ('align'); 'VLBounds'+-- ('bounds'); 'VLCenter' ('center', 'centerRC'); 'VLColumns'+-- ('columns'); 'VLConcat' ('vlConcat'); 'VLSpacing' ('alignRC',+-- 'spacing', 'spacingRC'); 'VLUserMetadata' ('usermetadata'); and+-- 'VLViewBackground' ('viewBackground'). It is expected that you will be+-- using the functions rather the constructors!+-- +-- Four new type aliases have been added: 'Angle', 'Color', 'Opacity',+-- and 'ZIndex'. These do not provide any new functionality but do+-- document intent.+-- +-- The 'noData' function has been added to let compositions define the+-- source of the data (whether it is from the parent or not), and data+-- sources can be named with 'dataName'. Data can be created with+-- 'dataSequence', 'dataSequenceAs', and 'sphere'. Graticules can be+-- created with 'graticule'. The 'NullValue' type has been added to+-- 'DataValue' to support data sources that are missing elements, but for+-- more-complex cases it is suggested that you create your data as an+-- Aeson Value and then use 'dataFromJson'. Support for data imputation+-- (creating new values based on existing data) has been added, as+-- discussed below.+-- +-- The alignment, size, and composition of plots can be defined and+-- changed with 'align', 'alignRC', 'bounds', 'center', 'centerRC',+-- 'columns', 'spacing', and 'spacingRC'.+-- +-- Plots can be combined and arranged with: 'facet', 'facetFlow',+-- 'repeat', 'repeatFlow', and 'vlConcat'+-- +-- New functions for use in a 'transform': 'flatten', 'flattenAs',+-- 'fold', 'foldAs', 'impute', and 'stack'.+-- +-- New functions for use with 'encoding': 'fillOpacity', 'strokeOpacity',+-- 'strokeWidth',+-- +-- The ability to arrange specifications has added the "flow" option+-- (aka "repeat"). This is seen in the addition of the 'Flow' constructor+-- to the 'Arrangement' type - which is used with 'ByRepeatOp',+-- 'HRepeat', 'MRepeat', 'ORepeat', 'PRepeat', and 'TRepeat'.+-- +-- The 'Mark' type has gained 'Boxplot', 'ErrorBar', 'ErrorBand', and+-- 'Trail' constructors. The 'MarkProperty' type has gained 'MBorders',+-- 'MBox', 'MExtent', 'MHeight', 'MHRef', 'MLine', 'MMedian', 'MOrder',+-- 'MOutliers', 'MNoOutliers', 'MPoint', 'MRule', 'MStrokeCap', 'MStrokeJoin',+-- 'MStrokeMiterLimit', 'MTicks', 'MTooltip', 'MWidth', 'MX', 'MX2',+-- 'MXOffset', 'MX2Offset', 'MY', 'MY2', 'MYOffset', and 'MY2Offset'+-- constructors.+-- +-- The 'Position' type has added 'XError', 'XError2', 'YError', and+-- 'YError2' constructors.+-- +-- The 'MarkErrorExtent' type was added.+-- +-- The 'BooleanOp' type has gained the 'FilterOp' and 'FilterOpTrans'+-- constructors which lets you use 'Filter' expressions as part of a+-- boolean operation. The 'Filter' type has also gained expresiveness,+-- with the 'FLessThan', 'FLessThanEq', 'FGreaterThan', 'FGreaterThanEq',+-- and 'FValid'.+-- +-- The 'Format' type has gained the 'DSV' constructor, which allow you+-- to specify the separator character for column data.+-- +-- The MarkChannel type has been expanded to include: 'MBinned', 'MSort',+-- 'MTitle', and 'MNoTitle'. The PositionChannel type has added+-- 'PHeight', 'PWidth', 'PNumber', 'PBinned', 'PImpute', 'PTitle', and+-- 'PNoTitle' constructors.+-- +-- The LineMarker and PointMarker types have been added for use with+-- 'MLine' and 'MPoint' respectively (both from 'MarkProperty').+-- +-- The ability to define the binning property with +-- 'binAs', 'DBin', 'FBin', 'HBin', 'MBin', 'OBin', 'PBin', and 'TBin' has+-- been expanded by adding the 'AlreadyBinned' and 'BinAnchor'+-- constructors to 'BinProperty', as well as changing the 'Divide'+-- constructor (as described below).+-- +-- The 'StrokeCap' and 'StrokeJoin' types has been added. These are used+-- with 'MStrokeCap', 'VBStrokeCap', and 'ViewStrokeCap' and+-- 'MStrokeJoin', 'VBStrokeJoin', and 'ViewStrokeJoin' respectively.+-- +-- The 'StackProperty' constructor has been added with the 'StOffset'+-- and 'StSort' constructors. As discussed below this is a breaking change+-- since the old StackProperty type has been renamed to 'StackOffset'.+-- +-- The 'ScaleProperty' type has seen significant enhancement, by adding+-- the constructors: 'SAlign', 'SBase', 'SBins', 'SConstant' and+-- 'SExponent'. THe 'Scale' tye has added 'ScSymLog' 'ScQuantile',+-- 'ScQuantize', and 'ScThreshold'.+-- +-- The 'SortProperty' type has new constructors: 'CustomSort',+-- 'ByRepeatOp', 'ByFieldOp', and 'ByChannel'. See the breaking-changes+-- section below for the constructors that were removed.+-- +-- The 'AxisProperty' type has seen significant additions, including:+-- 'AxBandPosition', 'AxDomainColor', 'AxDomainDash',+-- 'AxDomainDashOffset', 'AxDomainOpacity', 'AxDomainWidth',+-- 'AxFormatAsNum', 'AxFormatAsTemporal', 'AxGridColor', 'AxGridDash',+-- 'AxGridDashOffset', 'AxGridOpacity', 'AxGridWidth', 'AxLabelAlign',+-- 'AxLabelBaseline', 'AxLabelNoBound', 'AxLabelBound', 'AxLabelBoundValue',+-- 'AxLabelColor', 'AxLabelNoFlush', 'AxLabelFlush', 'AxLabelFlushValue',+-- 'AxLabelFlushOffset', 'AxLabelFont', 'AxLabelFontSize',+-- 'AxLabelFontStyle', 'AxLabelFontWeight', 'AxLabelLimit',+-- 'AxLabelOpacity', 'AxLabelSeparation', 'AxTickColor', 'AxTickDash',+-- 'AxTickDashOffset', 'AxTickExtra', 'AxTickMinStep', 'AxTickOffset',+-- 'AxTickOpacity', 'AxTickRound', 'AxTickWidth', 'AxNoTitle',+-- 'AxTitleAnchor', 'AxTitleBaseline', 'AxTitleColor', 'AxTitleFont',+-- 'AxTitleFontSize', 'AxTitleFontStyle', 'AxTitleFontWeight',+-- 'AxTitleLimit', 'AxTitleOpacity', 'AxTitleX', and 'AxTitleY'.+-- +-- The 'AxisConfig' has seen a similar enhancement, and looks similar+-- to the above apart from the constructors do not start with @Ax@.+-- +-- The 'LegendConfig' type has been significantly expanded and, as+-- discussed in the Breaking Changes section, changed. It has gained:+-- 'LeClipHeight', 'LeColumnPadding', 'LeColumns', 'LeGradientDirection',+-- 'LeGradientHorizontalMaxLength', 'LeGradientHorizontalMinLength',+-- 'LeGradientLength', 'LeGradientOpacity', 'LeGradientThickness',+-- 'LeGradientVerticalMaxLength', 'LeGradientVerticalMinLength',+-- 'LeGridAlign', 'LeLabelFontStyle', 'LeLabelFontWeight',+-- 'LeLabelOpacity', 'LeLabelOverlap', 'LeLabelPadding',+-- 'LeLabelSeparation', 'LeLayout', 'LeLeX', 'LeLeY', 'LeRowPadding',+-- 'LeSymbolBaseFillColor', 'LeSymbolBaseStrokeColor', 'LeSymbolDash',+-- 'LeSymbolDashOffset', 'LeSymbolDirection', 'LeSymbolFillColor',+-- 'LeSymbolOffset', 'LeSymbolOpacity', 'LeSymbolStrokeColor', 'LeTitle',+-- 'LeNoTitle', 'LeTitleAnchor', 'LeTitleFontStyle', 'LeTitleOpacity',+-- and 'LeTitleOrient'.+-- +-- The 'LegendOrientation' type has gained 'LOTop' and 'LOBottom'.+-- +-- The 'LegendLayout' and 'BaseLegendLayout' types are new, and used+-- with 'LeLayout' to define the legent orient group.+-- +-- The 'LegendProperty' type gained: 'LClipHeight', 'LColumnPadding',+-- 'LColumns', 'LCornerRadius', 'LDirection', 'LFillColor',+-- 'LFormatAsNum', 'LFormatAsTemporal', 'LGradientLength',+-- 'LGradientOpacity', 'LGradientStrokeColor', 'LGradientStrokeWidth',+-- 'LGradientThickness', 'LGridAlign', 'LLabelAlign', 'LLabelBaseline',+-- 'LLabelColor', 'LLabelFont', 'LLabelFontSize', 'LLabelFontStyle',+-- 'LLabelFontWeight', 'LLabelLimit', 'LLabelOffset', 'LLabelOpacity',+-- 'LLabelOverlap', 'LLabelPadding', 'LLabelSeparation', 'LRowPadding',+-- 'LStrokeColor', 'LSymbolDash', 'LSymbolDashOffset',+-- 'LSymbolFillColor', 'LSymbolOffset', 'LSymbolOpacity', 'LSymbolSize',+-- 'LSymbolStrokeColor', 'LSymbolStrokeWidth', 'LSymbolType',+-- 'LTickMinStep', 'LNoTitle', 'LTitleAlign', 'LTitleAnchor',+-- 'LTitleBaseline', 'LTitleColor', 'LTitleFont', 'LTitleFontSize',+-- 'LTitleFontStyle', 'LTitleFontWeight', 'LTitleLimit', 'LTitleOpacity',+-- 'LTitleOrient', 'LTitlePadding', 'LeX', and 'LeY'.+-- +-- 'Projection' has gained the 'Identity' constructor. The+-- 'ProjectionProperty' type has gained 'PrScale', 'PrTranslate',+-- 'PrReflectX', and 'PrReflectY'. The 'GraticuleProperty' type was+-- added to configure the appearance of graticules created with+-- 'graticule'.+-- +-- The 'CompositionAlignment' type was added and is used with 'align',+-- 'alignRC', 'LeGridAlign', and 'LGridAlign'.+-- +-- The 'Bounds' type was added for use with 'bounds'.+-- +-- The 'ImputeProperty' and 'ImMethod' types were added for use with+-- 'impute' and 'PImpute'.+-- +-- The 'ScaleConfig' type has gained 'SCBarBandPaddingInner',+-- 'SCBarBandPaddingOuter', 'SCRectBandPaddingInner', and+-- 'SCRectBandPaddingOuter'.+-- +-- The 'SelectionProperty' type has gained 'Clear', 'SInit', and+-- 'SInitInterval'.+-- +-- The Channel type has gained: 'ChLongitude', 'ChLongitude2',+-- 'ChLatitude', 'ChLatitude2', 'ChFill', 'ChFillOpacity', 'ChHref',+-- 'ChKey', 'ChStroke', 'ChStrokeOpacity'. 'ChStrokeWidth', 'ChText',+-- and 'ChTooltip'.+-- +-- The 'TitleConfig' type has gained: 'TFontStyle', 'TFrame', 'TStyle',+-- and 'TZIndex'.+-- +-- The 'TitleFrame' type is new and used with 'TFrame' from 'TitleConfig'.+-- +-- The 'ViewBackground' type is new and used with 'viewBackground'.+-- +-- The 'ViewConfig' type has gained 'ViewCornerRadius', 'ViewOpacity',+-- 'ViewStrokeCap', 'ViewStrokeJoin', and 'ViewStrokeMiterLimit'.+-- +-- The 'ConfigurationProperty' type, used with 'configuration', has+-- gained 'ConcatStyle', 'FacetStyle', 'GeoshapeStyle', 'HeaderStyle',+-- 'NamedStyles', and 'TrailStyle' constructors.+-- +-- The 'ConcatConfig' type was added for use with the 'ConcatStyle',+-- and the 'FacetConfig' type for the 'FacetStyle'+-- configuration settings.+-- +-- The 'HeaderProperty' type has gained: 'HFormatAsNum',+-- 'HFormatAsTemporal', 'HNoTitle', 'HLabelAlign', 'HLabelAnchor',+-- 'HLabelAngle', 'HLabelColor', 'HLabelFont', 'HLabelFontSize',+-- 'HLabelLimit', 'HLabelOrient', 'HLabelPadding', 'HTitleAlign',+-- 'HTitleAnchor', 'HTitleAngle', 'HTitleBaseline', 'HTitleColor',+-- 'HTitleFont', 'HTitleFontSize', 'HTitleFontWeight', 'HTitleLimit',+-- 'HTitleOrient', and 'HTitlePadding'.+-- +-- The 'HyperlinkChannel' type has gained 'HBinned'.+-- +-- The 'FacetChannel' type has gained 'FSort', 'FTitle', and 'FNoTitle'.+-- +-- The 'TextChannel' type has gained 'TBinned', 'TFormatAsNum',+-- 'TFormatAsTemporal', 'TTitle', and 'TNoTitle'.+-- +-- The 'TooltipContent' type was added, for use with 'MTooltip'.+--+-- The 'Symbol' type has gained: 'SymArrow', 'SymStroke',+-- 'SymTriangle', 'SymTriangleLeft', 'SymTriangleRight', and+-- 'SymWedge'.+--+-- There are a number of __breaking changes__ in this release (some+-- of which were mentioned above):+--+-- * The 'title' function now takes a second argument, a list of 'TitleConfig'+-- values for configuring the appearance of the title.+--+-- * The @SReverse@ constructor was removed from 'ScaleProperty' as it+-- represented a Vega, rather than Vega-Lite, property. The @xSort@+-- constructors are used to change the order of an item (e.g.+-- 'PSort', 'MSort').+--+-- * The @ScSequential@ constructor was removed from 'Scale' as+-- 'ScLinear' should be used.+--+-- * The 'SortProperty' type has had a number of changes: the @Op@,+-- @ByField@, and @ByRepeat@ constructors have been removed, and+-- 'ByRepeatOp', 'ByFieldOp', and 'ByChannel' constructors have been+-- added.+--+-- * The @AxTitleMaxLength@ and @TitleMaxLength@ constructors have been+-- removed (from 'AxisProperty' and 'AxisConfig' respectively) as they+-- are invalid. The 'AxTitleLimit' (new in this release) and+-- 'TitleLimit' constructors should be used instead.+--+-- * 'AxisProperty': the 'AxValues' constructor has been changed from+-- accepting a list of doubles to 'DataValues'. The 'AxDates'+-- constructor has been deprecated and 'AxValues' should be used+-- instead.+--+-- * There have been significant changes to the 'LegendConfig' type: the+-- @EntryPadding@, @GradientHeight@, @GradientLabelBaseline@,+-- @GradientWidth@, and @SymbolColor@ constructors have been removed;+-- the renaming constructors have been renamed so they all begin with+-- @Le@ (e.g. @Orient@ is now 'LeOrient', and 'Orient' has been added+-- to 'AxisConfig'); and new constructors have been added.+--+-- * The @StackProperty@ type has been renamed to 'StackOffset' and its+-- constructors have changed, and a new 'StackProperty'+-- type has been added (that references the 'StackOffset' type).+--+-- * The @Average@ constructor of 'Operation' was removed, and 'Mean'+-- should be used instead.+--+-- * The @LEntryPadding@ constructor of 'LegendProperty' was removed.+--+-- * The arguments to the 'MDataCondition', 'TDataCondition', and+-- 'HDataCondition' constructors - of 'MarkChannel', 'TextChannel',+-- and 'HyperlinkChannel' respectively - have changed to support+-- accepting multiple expressions.+--+-- * The @MarkOrientation@ type has been renamed 'Orientation'.+--+-- * The constructors of the 'ViewConfig' type have been renamed so they+-- all begin with @View@ (to match 'ViewWidth' and 'ViewHeight').+--+-- * The constructors of the 'ProjectionProperty' type have been renamed+-- so that they begin with @Pr@ rather than @P@ (to avoid conflicts+-- with the 'PositionChannel' type).+--+-- * The 'Divide' constructor of 'BinProperty' now takes a list of+-- Doubles rather than two.+--+-- * The 'TitleConfig' type has gained the following constructors:+-- 'TFontStyle', 'TFrame', 'TStyle', and 'TZIndex'. The 'TitleFrame'+-- type was added for use with 'TFrame'.+--+-- * The 'ArgMax' and 'ArgMin' constructors of 'Operation' now take an+-- optional field name, to allow them to be used as part of an encoding+-- aggregation (e.g. with 'PAggregate').+--+-- * The \"z index" value has changed from an 'Int' to the 'ZIndex' type.+--+-- * The constructors for the 'Symbol' type now all start with @Sym@, so+-- @Cross@, @Diamond@, @TriangleUp@, @TriangleDown@, and @Path@ have+-- been renamed to 'SymCross', 'SymDiamond', 'SymTriangleUp',+-- 'SymTriangleDown', and 'SymPath', respectively.+--+-- * The `Legend` type has been renamed `LegendType` and its constructors+-- have been renamed 'GradientLegend' and 'SymbolLegend'.++--- helpers++-- This could be extended to any Ord type but specialize for now to Double+clamped ::+ Double+ -- ^ minimum value allowed+ -> Double+ -- ^ maximum value allowed (must be > the minimum value)+ -> Double+ -- ^ user value+ -> Double+clamped xmin xmax x = max xmin (min xmax x)+++aggregate_ :: Operation -> LabelledSpec+aggregate_ op = "aggregate" .= operationSpec op++type_ :: T.Text -> LabelledSpec+type_ t = "type" .= t++field_ :: T.Text -> LabelledSpec+field_ f = "field" .= f++-- could restrict to ascending/descending+order_ :: T.Text -> LabelledSpec+order_ o = "order" .= o++op_ :: Operation -> LabelledSpec+op_ op = "op" .= operationSpec op++repeat_ :: Arrangement -> LabelledSpec+repeat_ arr = "repeat" .= arrangementLabel arr++sort_ :: [SortProperty] -> LabelledSpec+sort_ ops = "sort" .= sortPropertySpec ops++header_ :: [HeaderProperty] -> LabelledSpec+header_ hps = "header" .= object (map headerProperty hps)++impute_ :: [ImputeProperty] -> LabelledSpec+impute_ ips = "impute" .= object (map imputeProperty ips)++-- TODO: should this turn an empty list into true?+mprops_ :: T.Text -> [MarkProperty] -> LabelledSpec+mprops_ f mps = f .= object (map markProperty mps)++mchan_ :: T.Text -> [MarkChannel] -> LabelledSpec+mchan_ f ms = f .= object (concatMap markChannelProperty ms)++timeUnit_ :: TimeUnit -> LabelledSpec+timeUnit_ tu = "timeUnit" .= timeUnitLabel tu++mtype_ :: Measurement -> LabelledSpec+mtype_ m = "type" .= measurementLabel m++-- The assumption at the moment is that it's always correct to+-- replace the empty list by null.+--+scaleProp_ :: [ScaleProperty] -> LabelledSpec+scaleProp_ [] = "scale" .= A.Null+scaleProp_ sps = "scale" .= object (map scaleProperty sps)++scaleConfig_ :: [ScaleConfig] -> LabelledSpec+-- scaleConfig_ [] = "scale" .= A.Null -- not sure here+scaleConfig_ scs = "scale" .= object (map scaleConfigProperty scs)+++legendProp_ :: [LegendProperty] -> LabelledSpec+legendProp_ [] = "legend" .= A.Null+legendProp_ lps = "legend" .= object (map legendProperty lps)+++value_ :: T.Text -> LabelledSpec+value_ v = "value" .= v+++selCond_ :: (a -> [LabelledSpec]) -> BooleanOp -> [a] -> [a] -> [LabelledSpec]+selCond_ getProps selName ifClause elseClause =+ let h = ("condition", hkey)+ toProps = concatMap getProps+ hkey = object (("selection", booleanOpSpec selName) : toProps ifClause)+ hs = toProps elseClause+ in h : hs++-- Special case the single-condition check, so that I don't get false+-- positives when comparing against the Vega-Lite specification. There+-- should be no actionable difference from this special case (i.e.+-- the output being '[object]' and 'object' have the same meaning).+--+-- There is also the simplification to replace+-- test: { selection: xxx }+-- by+-- selection: xxx+-- which happens for the Selection operator.+--+dataCond_ :: (a -> [LabelledSpec]) -> [(BooleanOp, [a])] -> [a] -> [LabelledSpec]+dataCond_ getProps tests elseClause =+ let h = ("condition", condClause)+ condClause = case conds of+ [cond] -> cond+ _ -> toJSON conds+ conds = map testClause tests+ testClause (Selection sel, ifClause) =+ object (("selection" .= sel) : toProps ifClause)+ testClause (predicate, ifClause) =+ object (("test", booleanOpSpec predicate) : toProps ifClause)+ toProps = concatMap getProps+ hs = toProps elseClause+ in h : hs++++fromT :: T.Text -> VLSpec+fromT = toJSON++fromF :: Double -> VLSpec+fromF = toJSON++---------+++-- | A Vega Lite visualization, created by+-- 'toVegaLite'. The contents can be extracted with 'fromVL'.+--+newtype VegaLite =+ VL {+ fromVL :: VLSpec+ -- ^ Extract the specification for passing to a VegaLite visualizer.+ --+ -- > let vlSpec = fromVL vl+ -- > Data.ByteString.Lazy.Char8.putStrLn (Data.Aeson.Encode.Pretty.encodePretty vlSpec)+ --+ -- Note that there is __no__ validation done to ensure that the+ -- output matches the Vega Lite schema. That is, it is possible to+ -- create an invalid visualization with this module (e.g. missing a+ -- data source or referring to an undefined field).+ }++-- | The Vega-Lite specification is represented as JSON.+type VLSpec = Value++baseSchema :: T.Text+baseSchema = "https://vega.github.io/schema/vega-lite/"++-- | The latest version 2 Vega-Lite schema (equivalent to+-- @'vlSchema' 2 Nothing Nothing Nothing@).+vlSchema2 :: T.Text+vlSchema2 = vlSchema 2 Nothing Nothing Nothing++-- | The latest version 3 Vega-Lite schema (equivalent to+-- @'vlSchema' 3 Nothing Nothing Nothing@).+vlSchema3 :: T.Text+vlSchema3 = vlSchema 3 Nothing Nothing Nothing++-- | The latest version 4 Vega-Lite schema (equivalent to+-- @'vlSchema' 4 Nothing Nothing Nothing@).+vlSchema4 :: T.Text+vlSchema4 = vlSchema 4 Nothing Nothing Nothing++-- | Create the Vega-Lite schema for an arbitrary version. See+-- <https://github.com/vega/schema> for more information on naming+-- and availability.+--+-- There is no validation of the input values.+--+-- At the time of writing the latest version 4 schema - which+-- is @https://vega.github.io/schema/vega-lite/v4.0.0-beta.0.json@ -+-- can be specified as+--+-- @vlSchema 4 (Just 0) (Just 0) (Just "-beta.0")@+--+-- whereas+--+-- @vlSchema 4 Nothing Nothing Nothing@+--+-- refers to the latest version.+--+vlSchema ::+ Natural+ -- ^ The major version+ -> Maybe Natural+ -- ^ The minor version+ -> Maybe Natural+ -- ^ The \"micro\" version+ -> Maybe T.Text+ -- ^ Anything beyond "major.minor.micro" (e.g. \"-beta.0").+ -> T.Text+ -- ^ The Vega-Lite Schema+vlSchema major mminor mmicro mextra =+ let versions = [ pure (showNat major)+ , showNat <$> mminor+ , showNat <$> mmicro+ ]+ version = T.intercalate "." (catMaybes versions)++ in baseSchema <> "v" <> version <> fromMaybe "" mextra <> ".json"+++showNat :: Natural -> T.Text+showNat = T.pack . show+++{-|++Convert a list of Vega-Lite specifications into a single JSON object+that may be passed to Vega-Lite for graphics generation. Commonly+these will include at least a data, mark, and encoding specification.++While simple properties like 'mark' may be provided directly, it is+usually clearer to label more complex ones such as encodings as+separate expressions. This becomes increasingly helpful for+visualizations that involve composition of layers, repeats and facets.++Specifications can be built up by chaining a series of functions (such+as 'dataColumn' or 'position' in the example below). Functional+composition using the '.' operator allows this to be done compactly.++@+let dat = 'dataFromColumns' []+ . 'dataColumn' "a" ('Strings' [ \"C", \"C", \"D", \"D", \"E", \"E" ])+ . 'dataColumn' "b" ('Numbers' [ 2, 7, 1, 2, 6, 8 ])++ enc = 'encoding'+ . 'position' 'X' [ 'PName' "a", 'PmType' 'Nominal' ]+ . 'position' 'Y' [ 'PName' "b", 'PmType' 'Quantitative', 'PAggregate' 'Mean' ]++in 'toVegaLite' [ dat [], 'mark' 'Bar' [], enc [] ]+@++The schema used is <https://github.com/vega/schema version 3 of Vega-Lite>,+although there are some differences, in part because of bugs in @hvega@ -+in which case please [report an issue](https://github.com/DougBurke/hvega/issues) - but also because of issues with the Vega-Lite spec (for instance there+are several minor issues I have reported against version 3.3.0 of the+Vega-Lite schema).++Use 'toVegaLiteSchema' if you need to create a Vega-Lite specification+which uses a different version of the schema.++-}++-- TODO:+-- Should the input data, or converted to VLSpec, be stored+-- without the $schema key, so it can be easily combined with+-- other visualizations?+--+-- Could we make VegaLite a Semigroup so you can easily combine+-- specifications? However, what would that mean (concatenation,+-- if so what direction, anything else?)++toVegaLite :: [PropertySpec] -> VegaLite+toVegaLite = toVegaLiteSchema vlSchema3+++{-|+A version of 'toVegaLite' that allows you to change the Vega-Lite+schema version of the visualization.++@+'toVegaLiteSchema' 'vlSchema4' props+@+-}++toVegaLiteSchema ::+ T.Text+ -- ^ The schema to use (e.g. 'vlSchema4' or created with 'vlSchema').+ -> [PropertySpec]+ -- ^ The visualization.+ -> VegaLite+toVegaLiteSchema schema props =+ let kvals = ("$schema" .= schema) : map toProp props+ toProp = first vlPropertyLabel++ in VL { fromVL = object kvals }+++{-|++Combines a list of labelled specifications into a single specification.+This is useful when you wish to create+a single page with multiple visulizualizations.++@+'combineSpecs'+ [ ( "vis1", myFirstVis )+ , ( "vis2", mySecondVis )+ , ( "vis3", myOtherVis )+ ]+@+-}+combineSpecs :: [LabelledSpec] -> VLSpec+combineSpecs = object++{-|++Converts VegaLite to html Text. Uses Vega-Embed with the+default options. See 'toHtmlWith' for more control.++@since 0.2.1.0+-}+toHtml :: VegaLite -> TL.Text+toHtml = toHtmlWith Nothing++{-|++Converts VegaLite to an html file. Uses Vega-Embed with the+default options. See 'toHtmlFileWith' for more control.++@since 0.2.1.0+-}+toHtmlFile :: FilePath -> VegaLite -> IO ()+toHtmlFile file = TL.writeFile file . toHtml++{-|++Converts VegaLite to html Text. Uses Vega-Embed and is for when+some control is needed over the output: 'toHtml' is a simpler+form which just uses the default Vega-Embed options.++The render you use to view the output file must support Javascript,+since it is needed to create the visualization from the Vega-Lite+specification. The Vega and Vega-Lite Javascript versions are pegged+to 5 and 3, but no limit is applied to the Vega-Embed library.++@since 0.4.0.0+-}+toHtmlWith ::+ Maybe Value+ -- ^ The options to pass to the Vega-Embed @embed@ routine. See+ -- <https://github.com/vega/vega-embed#options> for the+ -- supported options.+ -> VegaLite+ -- ^ The Vega-Lite specification to display.+ -> TL.Text+toHtmlWith mopts vl =+ let spec = A.encodeToLazyText (fromVL vl)+ opts = maybe "" (\o -> "," <> A.encodeToLazyText o) mopts++ in TL.unlines+ [ "<!DOCTYPE html>"+ , "<html>"+ , "<head>"+ -- versions are fixed at vega 5, vega-lite 3+ , " <script src=\"https://cdn.jsdelivr.net/npm/vega@5\"></script>"+ , " <script src=\"https://cdn.jsdelivr.net/npm/vega-lite@3\"></script>"+ , " <script src=\"https://cdn.jsdelivr.net/npm/vega-embed\"></script>"+ , "</head>"+ , "<body>"+ , "<div id=\"vis\"></div>"+ , "<script type=\"text/javascript\">"+ , (" var spec = " <> spec <> ";")+ , " vegaEmbed(\'#vis\', spec" <> opts <> ").then(function(result) {"+ , " // Access the Vega view instance (https://vega.github.io/vega/docs/api/view/) as result.view"+ , " }).catch(console.error);"+ , "</script>"+ , "</body>"+ , "</html>"+ ]++{-|++Converts VegaLite to an html file. Uses Vega-Embed and is for when+some control is needed over the output: 'toHtmlFile' is a simpler+form which just uses the default Vega-Embed options.++@since 0.4.0.0+-}+toHtmlFileWith ::+ Maybe Value+ -- ^ The options to pass to the Vega-Embed @embed@ routine. See+ -- <https://github.com/vega/vega-embed#options> for the+ -- supported options.+ -> FilePath+ -- ^ The output file name (it will be over-written if it already exists).+ -> VegaLite+ -- ^ The Vega-Lite specification to display.+ -> IO ()+toHtmlFileWith mopts file = TL.writeFile file . toHtmlWith mopts+++{-|++Create a specification sufficient to define an element in a composed visualization+such as a superposed layer or juxtaposed facet. Typically a layer will contain a+full set of specifications that define a visualization with+the exception of the data specification which is usually defined outside of any one+layer. Whereas for repeated and faceted specs, the entire specification is provided.++@+spec1 = asSpec [ enc1 [], 'mark' 'Line' [] ]+@+-}+asSpec :: [PropertySpec] -> VLSpec+asSpec = object . map (first vlPropertyLabel)+++{-|++Specifies a list of geo features to be used in a geoShape specification.+Each feature object in this collection can be created with the 'geometry'+function.++@+'geoFeatureCollection'+ [ 'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( -3, 52 ), ( 4, 52 ), ( -3, 59 ) ] ])+ [ ( "myRegionName", 'Str' "Northern region" ) ]+ , 'geometry' ('GeoPolygon' [ [ ( -3, 52 ), ( 4, 52 ), ( 4, 45 ), ( -3, 52 ) ] ])+ [ ( "myRegionName", 'Str' "Southern region" ) ]+ ]+@+-}+geoFeatureCollection :: [VLSpec] -> VLSpec+geoFeatureCollection geoms =+ object [ type_ "FeatureCollection"+ , "features" .= geoms+ ]+++{-|++Specifies a list of geometry objects to be used in a geoShape specification.+Each geometry object in this collection can be created with the 'geometry'+function.++@+'geometryCollection'+ [ 'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 59 ) ] ]) []+ , 'geometry' ('GeoPoint' -3.5 55.5) []+ ]+@+-}+geometryCollection :: [VLSpec] -> VLSpec+geometryCollection geoms =+ object [ type_ "GeometryCollection"+ , "geometries" .= geoms+ ]+++{-|++Create a named aggregation operation on a field that can be added to a transformation.+For further details see the+<https://vega.github.io/vega-lite/docs/aggregate.html#aggregate-op-def Vega-Lite documentation>.++@+'transform'+ . 'aggregate'+ [ 'opAs' 'Min' "people" "lowerBound"+ , 'opAs' 'Max' "people" "upperBound"+ ]+ [ "age" ]+@+-}+opAs ::+ Operation+ -- ^ The aggregation operation to use.+ -> T.Text+ -- ^ The name of the field which is to be aggregated (when the operation+ -- is 'Count' leave as the empty string).+ -> T.Text+ -- ^ The name given to the transformed data.+ -> VLSpec++-- The Count case is special-cased purely to make it easier to compare+-- the hvega output against the Veg-Lite examples. There should be no+-- semantic difference here.+--+opAs Count _ label =+ object [ op_ Count, "as" .= label ]+opAs op field label =+ object [ op_ op, field_ field, "as" .= label ]+++{-|++Top-level Vega-Lite properties. These are the ones that define the core of the+visualization grammar. All properties are created by functions which can be+arranged into seven broad groups:++[Data Properties] These relate to the input data to be visualized. Generated by+'dataFromColumns', 'dataFromRows', 'dataFromUrl', 'dataFromSource',+'dataFromJson', 'dataSequence', 'sphere', and 'graticule'.++[Transform Properties] These indicate that some transformation of input data should+be applied before encoding them visually. Generated by 'transform'+and 'projection' they can include data transformations such as 'filter',+'binAs' and 'calculateAs' and geo transformations of longitude, latitude coordinates+used by marks such as 'Geoshape', 'Point', and 'Line'.++[Mark Properties] These relate to the symbols used to visualize data items. They+are generated by 'mark', and include types such as 'Circle', 'Bar', and 'Line'.++[Encoding Properties] These specify which data elements are mapped to which mark characteristics+(known as /channels/). Generated by 'encoding', they include encodings+such as 'position', 'color', 'size', 'shape', 'text', 'hyperlink', and+'order'.++[Composition Properties] These allow visualization views to be combined to form more+complex visualizations. Generated by 'layer', 'repeat', 'repeatFlow', 'facet', 'facetFlow',+'vlConcat', 'columns', 'hConcat', 'vConcat', 'asSpec', and 'resolve'.++[Interaction Properties] These allow interactions such as clicking, dragging and others+generated via a GUI or data stream to influence the visualization. Generated by+'selection'.++[Supplementary and Configuration Properties] These provide a means to add metadata and+styling to one or more visualizations. Generated by 'name', 'title', 'description',+'background', 'height', 'width', 'padding', 'autosize', 'viewBackground',+and 'configure'.++Prior to @0.4.0.0@ this was an opaque data type, as the constructors+were not exported. It is suggested that you do not import the+constructors to @VLProperty@ unless you need to transform the+Vega-Lite code in some manner (e.g. because @hvega@ is missing needed+functionality or is buggy).++Note that there is only a very-limited attempt to enforce the Vega-Lite+Schema (e.g. to ensure the required components are provided).++-}++-- based on schema 3.3.0 #/definitions/TopLevelSpec+-- which accepts one of+-- #/definitions/TopLevelUnitSpec+-- #/definitions/TopLevelFacetSpec+-- #/definitions/TopLevelLayerSpec+-- #/definitions/TopLevelRepeatSpec+-- #/definitions/TopLevelConcatSpec+-- #/definitions/TopLevelVConcatSpec+-- #/definitions/TopLevelHConcatSpec++data VLProperty+ = VLAlign+ -- ^ See 'align'.+ --+ -- @since 0.4.0.0+ | VLAutosize+ -- ^ See 'autosize'.+ | VLBackground+ -- ^ See 'background'.+ | VLBounds+ -- ^ See 'bounds'.+ --+ -- @since 0.4.0.0+ | VLCenter+ -- ^ See 'center' and 'centerRC'.+ --+ -- @since 0.4.0.0+ | VLColumns+ -- ^ See 'columns'.+ --+ -- @since 0.4.0.0+ | VLConcat+ -- ^ See 'vlConcat'.+ --+ -- @since 0.4.0.0+ | VLConfig+ -- ^ See 'configure'.+ | VLData+ -- ^ See 'dataFromColumns', 'dataFromJson', 'dataFromRows',+ -- 'dataFromSource', 'dataFromUrl', 'dataName', 'dataSequence',+ -- 'dataSequenceAs', 'graticule', 'noData', and 'sphere'.+ | VLDatasets+ -- ^ See 'datasets'.+ | VLDescription+ -- ^ See 'description'.+ | VLEncoding+ -- ^ See 'encoding'.+ | VLFacet+ -- ^ See 'facet' and 'facetFlow'.+ | VLHConcat+ -- ^ See 'hConcat'.+ | VLHeight+ -- ^ See 'height'.+ | VLLayer+ -- ^ See 'layer'.+ | VLMark+ -- ^ See 'mark'.+ | VLName+ -- ^ See 'name'.+ | VLPadding+ -- ^ See 'padding'.+ | VLProjection+ -- ^ See 'projection'.+ | VLRepeat+ -- ^ See 'repeat' and 'repeatFlow'.+ | VLResolve+ -- ^ See 'resolve'.+ | VLSelection+ -- ^ See 'selection'.+ | VLSpacing+ -- ^ See 'alignRC', 'spacing', and 'spacingRC'.+ --+ -- @since 0.4.0.0+ | VLSpecification+ -- ^ See 'specification'.+ | VLTitle+ -- ^ See 'title'.+ | VLTransform+ -- ^ See 'transform'.+ | VLUserMetadata+ -- ^ see 'usermetadata'.+ --+ -- @since 0.4.0.0+ | VLVConcat+ -- ^ See 'vConcat'.+ | VLViewBackground+ -- ^ See 'viewBackground'.+ --+ -- @since 0.4.0.0+ | VLWidth+ -- ^ See 'width'.+++vlPropertyLabel :: VLProperty -> T.Text+vlPropertyLabel VLAlign = "align"+vlPropertyLabel VLAutosize = "autosize"+vlPropertyLabel VLBackground = "background"+vlPropertyLabel VLBounds = "bounds"+vlPropertyLabel VLCenter = "center"+vlPropertyLabel VLColumns = "columns"+vlPropertyLabel VLConcat = "concat"+vlPropertyLabel VLConfig = "config"+vlPropertyLabel VLData = "data"+vlPropertyLabel VLDatasets = "datasets"+vlPropertyLabel VLDescription = "description"+vlPropertyLabel VLEncoding = "encoding"+vlPropertyLabel VLFacet = "facet"+vlPropertyLabel VLHConcat = "hconcat"+vlPropertyLabel VLHeight = "height"+vlPropertyLabel VLLayer = "layer"+vlPropertyLabel VLMark = "mark"+vlPropertyLabel VLName = "name"+vlPropertyLabel VLPadding = "padding"+vlPropertyLabel VLProjection = "projection"+vlPropertyLabel VLRepeat = "repeat"+vlPropertyLabel VLResolve = "resolve"+vlPropertyLabel VLSelection = "selection"+vlPropertyLabel VLSpacing = "spacing"+vlPropertyLabel VLSpecification = "spec"+vlPropertyLabel VLTitle = "title"+vlPropertyLabel VLTransform = "transform"+vlPropertyLabel VLUserMetadata = "usermeta"+vlPropertyLabel VLVConcat = "vconcat"+vlPropertyLabel VLViewBackground = "view"+vlPropertyLabel VLWidth = "width"+++{-|++Indicates the type of data to be parsed when reading input data. For @FoDate@+and @FoUtc@, the formatting specification can be specified using+<https://vega.github.io/vega-lite/docs/data.html#format D3's formatting specifiers>+or left as an empty string if default date formatting is to be applied. Care should+be taken when assuming default parsing of dates because different browsers can+parse dates differently. Being explicit about the date format is usually safer.++-}+data DataType+ = FoNumber+ -- ^ Indicate numeric data type to be parsed when reading input data.+ | FoBoolean+ -- ^ Indicate Boolean data type to be parsed when reading input data.+ | FoDate T.Text+ -- ^ Date format for parsing input data using+ -- [D3's formatting specifiers](https://vega.github.io/vega-lite/docs/data.html#format)+ -- or left as an empty string for default formatting.+ | FoUtc T.Text+ -- ^ Similar to 'FoDate' but for UTC format dates.+++{-|++Specifies the type of format a data source uses. If the format is indicated by+the file name extension (@".tsv"@, @".csv"@, @".json"@) there is no need to indicate the+format explicitly. However this can be useful if the filename extension does not+indicate type (e.g. @".txt"@) or you wish to customise the parsing of a file. For+example, when specifying the @JSON@ format, its parameter indicates the name of+property field containing the attribute data to extract. For details see the+<https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>.+-}+data Format+ = JSON T.Text+ -- ^ Property to be extracted from some JSON when it has some surrounding structure.+ -- e.g., specifying the property @values.features@ is equivalent to retrieving+ -- @json.values.features@ from a JSON object with a custom delimiter.+ | CSV+ -- ^ Comma-separated (CSV) data file format.+ | TSV+ -- ^ Tab-separated (TSV) data file format+ | DSV Char+ -- ^ The fields are separated by the given character (which must be a+ -- single 16-bit code unit).+ --+ -- @since 0.4.0.0+ {- This isn't in the current vega-lite v3 schema as far as I can see+ | Arrow+ -- ^ <https://observablehq.com/@theneuralbit/introduction-to-apache-arrow Apache Arrow> format.+ --+ -- @since 0.4.0.0+ -}+ | TopojsonFeature T.Text+ -- ^ A topoJSON feature format containing an object with the given name. For example:+ --+ -- @+ -- 'dataFromUrl' \"londonBoroughs.json\" ['TopojsonFeature' \"boroughs\"]+ -- @+ | TopojsonMesh T.Text+ -- ^ A topoJSON mesh format containing an object with the given name. Unlike+ -- 'TopojsonFeature', the corresponding geo data are returned as a single unified mesh,+ -- not as individual GeoJSON features.+ | Parse [(T.Text, DataType)]+ -- ^ Parsing rules when processing some data text, specified as+ -- a list of tuples in the form @(fieldname,+ -- datatype)@. Useful when automatic type inference needs to+ -- be overridden, for example when converting integers representing+ -- years into dates and strings into numbers:+ --+ -- @+ -- 'dataFromUrl' \"myDataFile.csv\"+ -- [ 'Parse' [ ( \"year\", 'FoDate' \"%Y\" ), ( "\y\", 'FoNumber' ) ] ]+ -- @+++{-|++A convenience type-annotation label. It is the same as 'Data'.++@since 0.4.0.0+-}+type PropertySpec = (VLProperty, VLSpec)++{-|++Represents a named Vega-Lite specification, usually generated by a+function in this module. You shouldn't need to create @LabelledSpec@+tuples directly, but they can be useful for type annotations.+-}+type LabelledSpec = (T.Text, VLSpec)++{-|++Represent those functions which can be chained together using function+composition to append new specifications onto an existing list.+-}+type BuildLabelledSpecs = [LabelledSpec] -> [LabelledSpec]++{-|++Represents a single column of data. Used when generating inline data with+'dataColumn' and 'dataFromColumns'.+-}+type DataColumn = [LabelledSpec]++{-|++Represents a single row of data. Used when generating inline data with+'dataRow' and 'dataFromRows'.+-}+type DataRow = VLSpec++{-|++Convenience type-annotation label for use with data generation functions.++@+myRegion : ['DataColumn'] -> 'Data'+myRegion =+ 'dataFromColumns' []+ . 'dataColumn' "easting" ('Numbers' [ -3, 4, 4, -3, -3 ])+ . 'dataColumn' "northing" ('Numbers' [ 52, 52, 45, 45, 52 ])+@++It is the same as 'PropertySpec' (which was added in @0.4.0.0@),+but kept separate to help better-document code.++-}+type Data = (VLProperty, VLSpec)+++{-|++Convenience type-annotation label to indicate a color value.+There is __no attempt__ to validate that the user-supplied input+is a valid color.++Any supported HTML color specification can be used, such as:++@+\"#eee\"+\"#734FD8\"+\"crimson\"+\"rgb(255,204,210)\"+\"hsl(180, 50%, 50%)\"+@++@since 0.4.0.0+-}++type Color = T.Text+++{-|++Convenience type-annotation label to indicate an opacity value, which+lies in the range 0 to 1 inclusive. There is __no attempt__ to validate+that the user-supplied value falls in this range.++A value of 0 indicates fully transparent (see through), and 1 is+fully opaque (does not show anything it is on top of).++@since 0.4.0.0+-}++type Opacity = Double+++{-|++Convenience type-annotation label to indicate an angle, which is measured+in degrees from the horizontal (so anti-clockwise).++The value should be in the range 0 to 360, inclusive, but __no attempt__ is+made to enforce this.++@since 0.4.0.0+-}++type Angle = Double+++{-|++At what "depth" (z index) is the item to be drawn (a relative depth+for items in the visualization). The standard values are @0@ for+back and @1@ for front, but other values can be used if you want+to ensure a certain layering of items.++The following example is taken from a discussion with+<https://github.com/gicentre/elm-vegalite/issues/15#issuecomment-524527125 Jo Wood>:++@+let dcols = 'dataFromColumns' []+ . 'dataColumn' "x" ('Numbers' [ 20, 10 ])+ . 'dataColumn' "y" ('Numbers' [ 10, 20 ])+ . 'dataColumn' "cat" ('Strings' [ "a", "b" ])++ axis lbl z = [ 'PName' lbl, 'PmType' 'Quantitative', 'PAxis' [ 'AxZIndex' z ] ]+ enc = 'encoding'+ . 'position' 'X' (axis "x" 2)+ . 'position' 'Y' (axis "y" 1)+ . 'color' [ 'MName' "cat", 'MmType' 'Nominal', 'MLegend' [] ]++ cfg = 'configure'+ . 'configuration' ('Axis' [ 'GridWidth' 8 ])+ . 'configuration' ('AxisX' [ 'GridColor' "red" ])+ . 'configuration' ('AxisY' [ 'GridColor' "blue" ])++in 'toVegaLite' [ cfg []+ , dcols []+ , enc []+ , 'mark' 'Circle' [ 'MSize' 5000, 'MOpacity' 1 ]+ ]+@++<<images/zindex.png>>++<https://vega.github.io/editor/#/url/vega-lite/N4KABBYEQMYPYDsBmBLA5lAXGUk-QEMAPFAZwE0sdx9ao0AnFAEwGE4AbOBqqAIw4BXAKZQatAL4AacfijEyADSq5acxi3Zce2KA2HMxasNNl55JUirNr6TZgHUWAFwAWVABw2IE2afMAtgQMANbWxlCkKABeotgArAAMyTIRcAAOBDAozgCeVACMqbZ56XHQ2QwwHKJ+xRBQzATOBOG2AG4EQsJW2ADa3viqxnQwzbyt9SPmRFQATIlT0w352AWJg3j+y8PLDWPOvHxQS8tQs2uLm7arYAvXPoMAunWyUAAkpDCuwkG8rs5nOlSJgAPSg9rCNAEAB0aByrkEfBhKDgoK+PyCEKhBAAtBwcsIIQBmGEAK1IiBOb2ECHgzBQCAw2F25ng2ja0ygqGEHEMugO1L2UFK5SgCDgAUZXSFZxqaFp-LACEEHA4g22dAu1GFPL5vFmpzoot4AEdBAQEM4cs0UJDZVyFL0dXtIFBoozmMJtXMHiYNUboLdWbY9UqoPlA+YTbpzZbrS1rfao26nZzXe7Pd7Cn7fMY85BfL4gA View the visualization in the Vega Editor>++@since 0.4.0.0+-}++type ZIndex = Natural+++formatProperty :: Format -> [LabelledSpec]+formatProperty (JSON js) =+ let ps = [("type", "json")]+ <> if T.null (T.strip js) then [] else [("property", js)]+ in map (second toJSON) ps++formatProperty CSV = [("type", "csv")]+formatProperty TSV = [("type", "tsv")]+formatProperty (DSV delim) = [("type", "dsv"), "delimiter" .= delim]+-- formatProperty Arrow = [("type", "arrow")]+formatProperty (TopojsonFeature os) = [("type", "topojson")+ , "feature" .= os+ ]+formatProperty (TopojsonMesh os) = [("type", "topojson")+ , "mesh" .= os+ ]+formatProperty (Parse fmts) =+ let pObj = object (map (second dataTypeSpec) fmts)+ in [("parse", pObj)]+++dataTypeSpec :: DataType -> VLSpec+dataTypeSpec dType =+ let s = case dType of+ FoNumber -> "number"+ FoBoolean -> "boolean"+ FoDate fmt | T.null fmt -> "date"+ | otherwise -> "date:'" <> fmt <> "'"+ FoUtc fmt | T.null fmt -> "utc"+ | otherwise -> "utc:'" <> fmt <> "'"+ in toJSON s+++{-|++Create a row of data. A row comprises a list of (columnName, value) pairs.+The final parameter is the list of any other rows to which this is added.++This is expected to be used with 'dataFromRows'.++@+'dataRow' [(\"Animal\", 'Str' \"Fish\"), (\"Age\", 'Number' 28), (\"Year\", 'Str' "2010")] []+@+-}+dataRow :: [(T.Text, DataValue)] -> [DataRow] -> [DataRow]+dataRow rw = (object (map (second dataValueSpec) rw) :)+++{-|++Create a dataset comprising a collection of named 'Data' items. Each data item+can be created with normal data generating functions such as 'dataFromRows' or+'dataFromJson'. These can be later referred to using 'dataFromSource'.++@+let toJS = Data.Aeson.toJSON+ obj = Data.Aeson.object++ dvals = 'dataFromRows' []+ . 'dataRow' [ ( "cat", 'Str' "a" ), ( "val", 'Number' 10 ) ]+ . 'dataRow' [ ( "cat", 'Str' "b" ), ( "val", 'Number' 18 ) ]+ json = toJS+ [ obj [ ( "cat", toJS "a" ), ( "val", toJS 120 ) ]+ , obj [ ( "cat", toJS "b" ), ( "val", toJS 180 ) ]+ ]++ enc = ...++in 'toVegaLite'+ [ 'datasets' [ ( \"myData\", dvals [] ), ( \"myJson\", 'dataFromJson' json [] ) ]+ , 'dataFromSource' \"myData\" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+datasets :: [(T.Text, Data)] -> Data+datasets namedData =+ -- Follow Elm in parsing the structure to get what we want, but the code is+ -- written rather differently.+ --+ -- The input is expected to be a singleton list containing a pair.+ let converted = extract . snd+ specs = map (second converted) namedData++ convert :: Value -> Maybe [(T.Text, Value)]+ convert v = HM.toList <$> decode (encode v)++ extract din =+ let extract' [(_, v)] = Just v+ extract' _ = Nothing++ in fromMaybe din (convert din >>= extract')++ in (VLDatasets, object specs)+++-- | This is for composed specifications, and it tells the visualization to+-- ignore the data from the parent.+--+-- @since 0.4.0.0+noData :: Data+noData = (VLData, A.Null)+++{-|++Name to give a data source. Useful when a specification needs to reference a+data source, such as one generated via an API call.++@+dvals = 'dataName' \"myName\" ('dataFromUrl' \"myData.json\" [])+@++@since 0.4.0.0++-}++-- TODO: can we restrict this to only those with a VLProperty of VLData?++dataName ::+ T.Text+ -- ^ The name to give the data source+ -> Data+ -- ^ The data source to be named.+ -> Data+ -- ^ If the input @Data@ argument is not a data source then+ -- this is just the input value.+dataName s odata@(_, dataSpec) =+ -- follow Elm in parsing the structure to get what we want, but the code is+ -- written rather differently. This is based on the code used in datasets.+ --+ -- The input is expected to be a singleton list containing a pair.+ --+ let converted = convert >>= extract++ -- Aeson's objects are wrappers around a hash map, so this should be+ -- a relatively easy conversion. The type annotation isn't needed+ -- but left in for reference.+ --+ convert :: Maybe [(T.Text, Value)]+ convert = HM.toList <$> decode (encode dataSpec)++ extract [v] = Just v+ extract _ = Nothing++ in case converted of+ Just v -> (VLData, object [ "name" .= s, v ])+ _ -> odata+++{-|++Generate a sequence of numbers as a data source. The resulting+sequence will have the name @\"data\"@. To give it an alternative name use+'dataSequenceAs'.++@+myData = 'dataSequence' 0 6.28 0.1+@++@since 0.4.0.0++-}+dataSequence ::+ Double -- ^ start of the sequence (inclusive)+ -> Double -- ^ end of the sequence (exclusive)+ -> Double -- ^ step size+ -> Data+dataSequence start stop step =+ let vals = [("sequence", object svals)]+ svals = [ "start" .= start+ , "stop" .= stop+ , "step" .= step+ ]++ in (VLData, object vals)+++{-|++Generate a sequence of numbers as a named data source. This extends+'dataSequence' by allowing you to name the data source.++@+myTheta = 'dataSequenceAs' 0 6.28 0.1 \"theta\"+@++@since 0.4.0.0++-}+dataSequenceAs ::+ Double -- ^ start of the sequence (inclusive)+ -> Double -- ^ end of the sequence (exclusive)+ -> Double -- ^ step size+ -> T.Text -- ^ The name of the data source+ -> Data+dataSequenceAs start stop step outName =+ let vals = [("sequence", object svals)]+ svals = [ "start" .= start+ , "stop" .= stop+ , "step" .= step+ , "as" .= outName+ ]++ in (VLData, object vals)+++{-|++Declare a data source from a list of column values. Each column has a+specific type (e.g. 'Number' or 'String'), but different columns can have+different types.++Note that the columns are truncated to match the length of the shortest column.++@+'dataFromColumns' [ 'Parse' [ ( \"Year\", 'FoDate' "%Y" ) ] ]+ . 'dataColumn' \"Animal\" ('Strings' [ \"Fish\", \"Dog\", \"Cat\" ])+ . 'dataColumn' \"Age\" ('Numbers' [ 28, 12, 6 ])+ . 'dataColumn' \"Year\" ('Strings' [ "2010", "2014", "2015" ])+@+-}+dataFromColumns ::+ [Format]+ -- ^ An optional list of formatting instructions for the columns.+ --+ -- Simple numbers and strings do not normally need formatting, but it is+ -- good practice to explicitly declare date-time formats as handling of+ -- these values can vary between different viewers (e.g. browsers).+ --+ -- See the+ -- <https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>+ -- for more details.+ -> [DataColumn]+ -- ^ The columns to add. This is expected to be created with one or more+ -- calls to 'dataColumn'.+ -> Data+dataFromColumns fmts cols =+ let dataArray = map object (transpose cols)++ vals = [("values", toJSON dataArray)]+ <> if null fmts+ then []+ else [("format", toJSON fmtObject)]++ fmtObject = object (concatMap formatProperty fmts)++ in (VLData, object vals)+++transpose :: [[a]] -> [[a]]+transpose [] = []+transpose ([]:xss) = transpose xss+transpose ((x:xs) : xss) =+ let heads = filterMap elmHead xss --+ tails = filterMap elmTail xss++ elmHead (h:_) = Just h+ elmHead [] = Nothing++ elmTail [] = Nothing+ elmTail (_:ts) = Just ts++ filterMap = mapMaybe++ in (x : heads) : transpose (xs : tails)+++{-|++Declare a data source from a provided json specification. The most likely use-case+for specifying json inline is when creating <http://geojson.org geojson> objects,+when 'geometry', 'geometryCollection', and 'geoFeatureCollection' functions+may be used. For more general cases of json creation, consider 'Data.Aeson.encode'.++@+let geojson =+ 'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 59 ) ] ]) []+in 'toVegaLite'+ [ 'width' 200+ , 'height' 200+ , 'dataFromJson' geojson []+ , 'projection' [ 'PrType' 'Orthographic' ]+ , 'mark' 'Geoshape' []+ ]+@+-}+dataFromJson :: VLSpec -> [Format] -> Data+dataFromJson vlspec fmts =+ let js = if null fmts+ then object [("values", vlspec)]+ else object [ ("values", vlspec)+ , ("format",+ object (concatMap formatProperty fmts)) ]+ in (VLData, js)+++{-|++A single data value. This is used when a function or constructor+can accept values of different types (e.g. either a number or a string),+such as:+'dataRow', 'geometry', many constructors of the 'Filter' type,+'ImNewValue', and 'SInit'.++-}+data DataValue+ = Boolean Bool+ | DateTime [DateTime]+ | Number Double+ | Str T.Text+ | NullValue+ -- ^ Create a JavaScript @null@ value. This can be useful when+ -- explictly recoding a value as undefined, such as in the following+ -- example:+ --+ -- @+ -- 'dataFromRows' []+ -- . 'dataRow' [("x", 'Number' 1), ("y", 'String' "good")]+ -- . 'dataRow' [("x", 'Number' 2), ("y", 'NullValue')]+ -- . 'dataRow' [("x", 'Number' 3), ("y", 'String' "bad")]+ -- @+ --+ -- For more-complex data sources - such as lists of defined+ -- and un-specified values, it is suggested that 'dataFromJson'+ -- be used rather than 'dataFromRows' or 'dataFromColumns'.+ --+ -- @since 0.4.0.0++dataValueSpec :: DataValue -> VLSpec+dataValueSpec (Boolean b) = toJSON b+dataValueSpec (DateTime dt) = object (map dateTimeProperty dt)+dataValueSpec (Number x) = toJSON x+dataValueSpec (Str t) = toJSON t+dataValueSpec NullValue = A.Null+++{-|++A list of data values. This is used when a function or constructor+can accept lists of different types (e.g. either a list of numbers+or a list of strings), such as:+'dataColumn', 'CustomSort', 'FOneOf', or 'ImKeyVals'.++If your data contains undefined values then it is suggested that+you convert it to JSON (e.g. 'Value') and then use 'dataFromJson'.++-}+data DataValues+ = Booleans [Bool]+ | DateTimes [[DateTime]]+ | Numbers [Double]+ | Strings [T.Text]+++dataValuesSpecs :: DataValues -> [VLSpec]+dataValuesSpecs (Booleans bs) = map toJSON bs+dataValuesSpecs (DateTimes dtss) = map (object . map dateTimeProperty) dtss+dataValuesSpecs (Numbers xs) = map toJSON xs+dataValuesSpecs (Strings ss) = map toJSON ss++{-|++Create a column of data. A column has a name and a list of values. The final+parameter is the list of any other columns to which this is added.++This is expected to be used with 'dataFromColumns'.++@+'dataColumn' \"Animal\" ('Strings' [ \"Cat\", \"Dog\", \"Mouse\"]) []+@+-}+dataColumn :: T.Text -> DataValues -> [DataColumn] -> [DataColumn]+dataColumn colName dVals xs =+ let col = case dVals of+ Booleans cs -> map toJSON cs+ DateTimes cs -> map dtToJSON cs+ Numbers cs -> map toJSON cs+ Strings cs -> map toJSON cs++ dtToJSON = object . map dateTimeProperty+ x = map (colName,) col++ in x : xs+++{-|++Declare a data source from a provided list of row values. Each row+contains a list of tuples where the first value is a string+representing the column name, and the second the column value for that+row. Each column can have a value of a different type but+__you must ensure__+that when subsequent rows are added, they match the types of+previous values with shared column names.++Note though that generally if you are creating data inline (as opposed+to reading from a file), adding data by column is more efficient and+less error-prone.++@+dataFromRows [ 'Parse' [ ( \"Year\", 'FoDate' "%Y" ) ] ]+ . 'dataRow' [ ( \"Animal\", 'Str' \"Fish\" ), ( \"Age\", 'Number' 28 ), ( \"Year\", 'Str' "2010" ) ]+ . 'dataRow' [ ( \"Animal\", 'Str' \"Dog\" ), ( \"Age\", 'Number' 12 ), ( \"Year\", 'Str' "2014" ) ]+ . 'dataRow' [ ( \"Animal\", 'Str' \"Cat\" ), ( \"Age\", 'Number' 6 ), ( \"Year\", 'Str' "2015" ) ]+@+-}+dataFromRows ::+ [Format]+ -- ^ An optional list of formatting instructions for the rows.+ --+ -- Simple numbers and strings do not normally need formatting, but it is+ -- good practice to explicitly declare date-time formats as handling of+ -- these values can vary between different viewers (e.g. browsers).+ --+ -- See the+ -- <https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>+ -- for more details.+ -> [DataRow]+ -- ^ The rows to add. This is expected to be created with one or more+ -- calls to 'dataRow'.+ -> Data+dataFromRows fmts rows =+ let kvs = ("values", toJSON rows)+ : if null fmts+ then []+ else [("format", object (concatMap formatProperty fmts))]+ in (VLData, object kvs)+++{-|++Declare data from a named source. The source may be from named 'datasets' within+a specification or a named data source created via the+<https://vega.github.io/vega/docs/api/view/#data Vega View API>.+An optional list of field formatting instructions can be provided as the second+parameter or an empty list to use the default formatting. See the+<https://vega.github.io/vega-lite/docs/data.html#named Vega-Lite documentation>+for details.++@+'toVegaLite'+ [ 'datasets' [ ( "myData", dvals [] ), ( "myJson", 'dataFromJson' json [] ) ]+ , 'dataFromSource' "myData" []+ , 'mark' 'Bar' []+ , ...+ ]+@+-}+dataFromSource :: T.Text -> [Format] -> Data+dataFromSource sourceName fmts =+ let kvs = ("name" .= sourceName)+ : if null fmts+ then []+ else [("format", object (concatMap formatProperty fmts))]+ in (VLData, object kvs)+++{-|++Declare data source from a url. The url can be a local path on a web server+or an external http(s) url. Used to create a data ( property, specification ) pair.+An optional list of field formatting instructions can be provided as the second+parameter or an empty list to use the default formatting. See the+<https://vega.github.io/vega-lite/docs/data.html#format Vega-Lite documentation>+for details.++@+'dataFromUrl' "data/weather.csv" [ 'Parse' [ ( "date", 'FoDate' "%Y-%m-%d %H:%M" ) ] ]+@+-}+-- TODO: should this use a URL type?+dataFromUrl :: T.Text -> [Format] -> Data+dataFromUrl url fmts =+ let kvs = ("url" .= url)+ : if null fmts+ then []+ else [("format", object (concatMap formatProperty fmts))]+ in (VLData, object kvs)+++-- | Type of visual mark used to represent data in the visualization.+--+-- The properties of the mark can be changed with the 'MarkProperty'+-- constructors - such as 'MHeight' and 'MWidth' - although not all+-- properties apply to all marks.+--+data Mark+ = Area+ -- ^ An [area mark](https://vega.github.io/vega-lite/docs/area.html)+ -- for representing a series of data elements, such as in a stacked+ -- area chart or streamgraph.+ | Bar+ -- ^ [Bar mark](https://vega.github.io/vega-lite/docs/bar.html)+ -- for histograms, bar charts etc.+ | Boxplot+ -- ^ [Boxplot composite mark](https://vega.github.io/vega-lite/docs/boxplot.html)+ -- for showing summaries of statistical distributions.+ --+ -- Tick marks can be added using 'MTicks' and outliers turned+ -- off with 'MNoOutliers' or configured with 'MOutliers'.+ -- For example:+ --+ -- @+ -- 'mark' Boxplot+ -- [ 'MTicks' [ 'MColor' \"black\", 'MSize' 8 ]+ -- , 'MBox' [ 'MFill' \"grey\" ]+ -- , 'MOutliers' [ 'MColor' \"firebrick\" ]+ -- ]+ -- @+ --+ -- The range of the box plot is controlled with 'MExtent' with+ -- the 'IqrScale' or 'ExRange' options (the default is+ -- @IqrScale 1.5@).+ --+ -- @since 0.4.0.0+ | Circle+ -- ^ [Circle mark](https://vega.github.io/vega-lite/docs/circle.html)+ -- for representing points.+ | ErrorBar+ -- ^ [Errorbar composite mark](https://vega.github.io/vega-lite/docs/errorbar.html)+ -- for showing summaries of variation along a signal. By default+ -- no ticks are drawn. To add ticks with default properties use+ -- @`MTicks` []@, otherwise supply a list of configuration options:+ --+ -- @+ -- 'mark' ErrorBar [ 'MTicks' [ 'MColor' \"black\", 'MSize' 8 ] ]+ -- @+ --+ -- @since 0.4.0.0+ | ErrorBand+ -- ^ [Errorband composite mark](https://vega.github.io/vega-lite/docs/errorband.html)+ -- for showing summaries of variation along a signal. By default+ -- no border is drawn. To add a border with default properties use+ -- @'MBorders' []@, otherwise supply a list of configuration options:+ --+ -- @+ -- 'mark' ErrorBand [ 'MBorders' [ 'MColor' \"black\", 'MStrokeWidth' 0.5 ] ]+ -- @+ --+ -- @since 0.4.0.0+ | Geoshape+ -- ^ [Geoshape](https://vega.github.io/vega-lite/docs/geoshape.html)+ -- determined by geographically referenced coordinates.+ | Line+ -- ^ [Line mark](https://vega.github.io/vega-lite/docs/line.html)+ -- for symbolising a sequence of values.+ | Point+ -- ^ [Point mark](https://vega.github.io/vega-lite/docs/point.html)+ -- for symbolising a data point with a symbol.+ | Rect+ -- ^ [Rectangle mark](https://vega.github.io/vega-lite/docs/rect.html).+ | Rule+ -- ^ [Rule line](https://vega.github.io/vega-lite/docs/rule.html)+ -- connecting two vertices.+ | Square+ -- ^ [Square mark](https://vega.github.io/vega-lite/docs/square.html)+ -- for symbolising points.+ | Text+ -- ^ [Text mark](https://vega.github.io/vega-lite/docs/text.html)+ -- to be displayed at some point location.+ | Tick+ -- ^ Short line - [tick](https://vega.github.io/vega-lite/docs/tick.html) -+ -- mark for symbolising point locations.+ | Trail+ -- ^ [Trail mark](https://vega.github.io/vega-lite/docs/trail.html)+ -- (line with variable width along its length).+ --+ -- @since 0.4.0.0+++markLabel :: Mark -> T.Text+markLabel Area = "area"+markLabel Bar = "bar"+markLabel Boxplot = "boxplot"+markLabel Circle = "circle"+markLabel ErrorBar = "errorbar"+markLabel ErrorBand = "errorband"+markLabel Line = "line"+markLabel Geoshape = "geoshape"+markLabel Point = "point"+markLabel Rect = "rect"+markLabel Rule = "rule"+markLabel Square = "square"+markLabel Text = "text"+markLabel Tick = "tick"+markLabel Trail = "trail"+++{-|++Create a mark specification. All marks must have a type (first parameter) and+can optionally be customised with a list of mark properties such as interpolation+style for lines. To keep the default style for the mark, just provide an empty list+for the second parameter.++@+'mark' 'Circle' []+'mark' 'Line' ['MInterpolate' 'StepAfter']+@++@+let dvals = 'dataFromUrl' \"city.json\" ['TopojsonFeature' \"boroughs\"] []+ markOpts = 'mark' 'Geoshape' ['MFill' \"lightgrey\", 'MStroke' \"white\"]+in 'toVegaLite' [dvals, markOpts]+@+-}+mark :: Mark -> [MarkProperty] -> PropertySpec+mark mrk props =+ let jsName = toJSON (markLabel mrk)+ vals = if null props+ then jsName+ else object (("type" .= jsName) : map markProperty props)++ in (VLMark, vals)+++{-|++Mark channel properties used for creating a mark channel encoding.+-}++-- https://vega.github.io/vega-lite/docs/encoding.html#mark-prop++data MarkChannel+ = MName T.Text+ -- ^ Field used for encoding with a mark property channel.+ | MRepeat Arrangement+ -- ^ Reference in a mark channel to a field name generated by 'repeatFlow'+ -- or 'repeat'. The parameter identifies whether reference is being made to+ -- fields that are to be arranged in columns, in rows, or a with a flow layout.+ | MmType Measurement+ -- ^ Level of measurement when encoding with a mark property channel.+ | MScale [ScaleProperty]+ -- ^ Scaling applied to a field when encoding with a mark property channel.+ -- The scale will transform a field's value into a color, shape, size etc.+ --+ -- Use an empty list to remove the scale.+ | MBin [BinProperty]+ -- ^ Discretize numeric values into bins when encoding with a mark property channel.+ | MBinned+ -- ^ Indicate that data encoding with a mark are already binned.+ --+ -- @since 0.4.0.0+ | MSort [SortProperty]+ -- ^ Sort order.+ --+ -- @since 0.4.0.0+ | MTimeUnit TimeUnit+ -- ^ Time unit aggregation of field values when encoding with a mark property channel.+ | MTitle T.Text+ -- ^ Title of a field when encoding with a mark property channel.+ --+ -- @since 0.4.0.0+ | MNoTitle+ -- ^ Draw no title.+ --+ -- @since 0.4.0.0+ | MAggregate Operation+ -- ^ Compute aggregate summary statistics for a field to be encoded with a+ -- mark property channel.+ | MLegend [LegendProperty]+ -- ^ Properties of a legend that describes a mark's encoding.+ --+ -- For no legend, provide an empty list.+ | MSelectionCondition BooleanOp [MarkChannel] [MarkChannel]+ -- ^ Make a mark channel conditional on interactive selection. The first parameter+ -- is a selection condition to evaluate; the second the encoding to apply if that+ -- selection is true; the third parameter is the encoding if the selection is false.+ --+ -- @+ -- 'color'+ -- [ MSelectionCondition ('SelectionName' \"myBrush\")+ -- [ 'MName' \"myField\", 'MmType' 'Ordinal' ]+ -- [ 'MString' \"grey\" ]+ -- ]+ -- @+ | MDataCondition [(BooleanOp, [MarkChannel])] [MarkChannel]+ -- ^ Make a text channel conditional on one or more predicate expressions. The first+ -- parameter is a list of tuples each pairing an expression to evaluate with the encoding+ -- if that expression is @True@. The second is the encoding if none of the expressions+ -- evaluate as @True@.+ --+ -- @+ -- 'color'+ -- [ MDataCondition [ ( 'Expr' \"datum.myField === null\", [ 'MString' \"grey\" ] ) ]+ -- [ MString \"black\" ]+ -- ]+ -- @+ --+ -- The arguments to this constructor have changed in @0.4.0.0@+ -- to support multiple expressions.+ | MPath T.Text+ -- ^ SVG path string used when encoding with a mark property channel. Useful+ -- for providing custom shapes.+ | MNumber Double+ -- ^ Literal numeric value when encoding with a mark property channel.+ | MString T.Text+ -- ^ Literal string value when encoding with a mark property channel.+ | MBoolean Bool+ -- ^ Boolean value when encoding with a mark property channel.++markChannelProperty :: MarkChannel -> [LabelledSpec]+markChannelProperty (MName s) = [field_ s]+markChannelProperty (MRepeat arr) = ["field" .= object [repeat_ arr]]+markChannelProperty (MmType t) = [mtype_ t]+markChannelProperty (MScale sps) = [scaleProp_ sps]+markChannelProperty (MLegend lps) = [legendProp_ lps]+markChannelProperty (MBin bps) = [bin bps]+markChannelProperty MBinned = [binned_]+markChannelProperty (MSort ops) = [sort_ ops]+markChannelProperty (MSelectionCondition selName ifClause elseClause) =+ selCond_ markChannelProperty selName ifClause elseClause+markChannelProperty (MDataCondition tests elseClause) =+ dataCond_ markChannelProperty tests elseClause+markChannelProperty (MTimeUnit tu) = [timeUnit_ tu]+markChannelProperty (MAggregate op) = [aggregate_ op]+markChannelProperty (MPath s) = ["value" .= s]+markChannelProperty (MNumber x) = ["value" .= x]+markChannelProperty (MString s) = ["value" .= s]+markChannelProperty (MBoolean b) = ["value" .= b]+markChannelProperty (MTitle s) = ["title" .= s]+markChannelProperty MNoTitle = ["title" .= A.Null]+++{-|++Appearance of a line marker that is overlaid on an area mark.+For use with 'MLine'.++@since 0.4.0.0++-}++data LineMarker+ = LMNone+ -- ^ No line marker.+ | LMMarker [MarkProperty]+ -- ^ The properties of a line marker overlain on an area mark.+ --+ -- Use an empty list to use a filled point with default properties.+++-- An empty object has the same meaning as true, so there is no real need to+-- treat 'LMMarker []' specially, but I don't think it complicates things+-- here.+--+lineMarkerSpec :: LineMarker -> VLSpec+lineMarkerSpec LMNone = toJSON False+lineMarkerSpec (LMMarker []) = toJSON True+lineMarkerSpec (LMMarker mps) = object (map markProperty mps)+++{-|++Properties for customising the appearance of a mark. For details see the+<https://vega.github.io/vega-lite/docs/mark.html#config Vega-Lite documentation>.++Not all properties are valid for each mark type.++The Vega-Lite specification supports setting those properties that take+@['MarkProperty']@ also to a boolean value. This is currently not+supported in @hvega@.++-}++-- based on schema 3.3.0 #/definitions/MarkConfig+--+-- but it also contains a number of other properties++data MarkProperty+ = MAlign HAlign+ -- ^ Horizontal alignment of a text mark.+ | MAngle Angle+ -- ^ Rotation angle of a text mark.+ | MBandSize Double+ -- ^ Band size of a bar mark.+ | MBaseline VAlign+ -- ^ Vertical alignment of a text mark.+ | MBinSpacing Double+ -- ^ Offset between bars for a binned field using a bar mark.+ --+ -- The ideal value for this is either @0@ (preferred by statisticians)+ -- or @1@ (the Vega-Lite default value, D3 example style).+ | MBorders [MarkProperty]+ -- ^ Border properties for an 'ErrorBand' mark.+ --+ -- @since 0.4.0.0+ | MBox [MarkProperty]+ -- ^ Box-symbol properties for a 'Boxplot' mark.+ --+ -- @since 0.4.0.0+ | MClip Bool+ -- ^ Should a mark be clipped to the enclosing group's dimensions.+ | MColor Color+ -- ^ Default color of a mark. Note that 'MFill' and 'MStroke' have higher+ -- precedence and will override this if specified.+ | MCursor Cursor+ -- ^ Cursor to be associated with a hyperlink mark.+ | MContinuousBandSize Double+ -- ^ Continuous band size of a bar mark.+ | MDiscreteBandSize Double+ -- ^ Discrete band size of a bar mark.+ | MdX Double+ -- ^ Horizontal offset between a text mark and its anchor.+ | MdY Double+ -- ^ Vertical offset between a text mark and its anchor.+ | MExtent MarkErrorExtent+ -- ^ Extent of whiskers used with 'Boxplot', 'ErrorBar', and+ -- 'ErrorBand' marks.+ --+ -- @since 0.4.0.0+ | MFill T.Text+ -- ^ Default fill color of a mark.+ | MFilled Bool+ -- ^ Should a mark's color should be used as the fill color instead of+ -- stroke color.+ | MFillOpacity Opacity+ -- ^ Fill opacity of a mark.+ | MFont T.Text+ -- ^ Font of a text mark. Can be any font name made accessible via+ -- a css file (or a generic font like \"serif\", \"monospace\" etc.).+ | MFontSize Double+ -- ^ Font size, in pixels, used by a text mark.+ | MFontStyle T.Text+ -- ^ Font style (e.g. \"italic\") used by a text mark.+ | MFontWeight FontWeight+ -- ^ Font weight used by a text mark.+ | MHeight Double+ -- ^ Explicitly set the height of a mark. See also 'MWidth'.+ --+ -- @since 0.4.0.0+ | MHRef T.Text+ -- ^ Hyperlink to be associated with a mark making it a clickable+ -- hyperlink.+ --+ -- @since 0.4.0.0+ | MInterpolate MarkInterpolation+ -- ^ Interpolation method used by line and area marks.+ | MLine LineMarker+ -- ^ How should the vertices of an area mark be joined?+ --+ -- @since 0.4.0.0+ | MMedian [MarkProperty]+ -- ^ Median-line properties for the 'Boxplot' mark.+ --+ -- @since 0.4.0.0+ | MOpacity Opacity+ -- ^ Overall opacity of a mark in the range 0 to 1.+ | MOrder Bool+ -- ^ Ordering of vertices in a line or area mark. If @True@ (the default),+ -- the order is determined by measurement type or order channel. If+ -- @False@, the original data order is used.+ --+ -- @since 0.4.0.0+ | MOrient Orientation+ -- ^ Orientation of a non-stacked bar, tick, area or line mark.+ | MOutliers [MarkProperty]+ -- ^ Outlier symbol properties for the 'Boxplot' mark.+ --+ -- @since 0.4.0.0+ | MNoOutliers+ -- ^ Do not draw outliers with the 'Boxplot' mark.+ --+ -- @since 0.4.0.0+ | MPoint PointMarker+ -- ^ Appearance of a point marker joining the vertices of a line or area mark.+ --+ -- @since 0.4.0.0+ | MRadius Double+ -- ^ Polar coordinate radial offset of a text mark from its origin.+ | MRule [MarkProperty]+ -- ^ Rule (main line) properties for the 'ErrorBar' and 'Boxplot' marks.+ --+ -- @since 0.4.0.0+ | MShape Symbol+ -- ^ Shape of a point mark.+ | MShortTimeLabels Bool+ -- ^ Aremonth and weekday names are abbreviated in a text mark?+ | MSize Double+ -- ^ Size of a mark.+ | MStroke T.Text+ -- ^ Default stroke color of a mark.+ | MStrokeCap StrokeCap+ -- ^ Cap style of a mark's stroke.+ --+ -- @since 0.4.0.0+ | MStrokeDash [Double]+ -- ^ The stroke dash style used by a mark, defined by an alternating 'on-off'+ -- sequence of line lengths, in pixels.+ | MStrokeDashOffset Double+ -- ^ The number of pixels before the first line dash is drawn.+ | MStrokeJoin StrokeJoin+ -- ^ Line segment join style of a mark's stroke.+ --+ -- @since 0.4.0.0+ | MStrokeMiterLimit Double+ -- ^ Mitre limit at which to bevel a join between line segments of a+ -- mark's stroke.+ --+ -- @since 0.4.0.0+ | MStrokeOpacity Opacity+ -- ^ Stroke opacity of a mark in the range 0 to 1.+ | MStrokeWidth Double+ -- ^ Stroke width of a mark in pixels.+ | MStyle [T.Text]+ -- ^ Names of custom styles to apply to a mark. Each should refer to a named style+ -- defined in a separate style configuration.+ | MTension Double+ -- ^ Interpolation tension used when interpolating line and area marks.+ | MText T.Text+ -- ^ Placeholder text for a text mark for when a text channel is not specified.+ | MTheta Double+ -- ^ Polar coordinate angle (clockwise from north in radians)+ -- of a text mark from the origin (determined by its+ -- x and y properties).+ | MThickness Double+ -- ^ Thickness of a tick mark.+ | MTicks [MarkProperty]+ -- ^ Tick properties for the 'ErrorBar' or 'Boxplot' mark.+ --+ -- @since 0.4.0.0+ | MTooltip TooltipContent+ -- ^ The tooltip content for a mark.+ --+ -- @since 0.4.0.0+ | MWidth Double+ -- ^ Explicitly set the width of a mark (e.g. the bar width). See also+ -- 'MHeight'.+ --+ -- @since 0.4.0.0+ | MX Double+ -- ^ X position of a mark.+ --+ -- @since 0.4.0.0+ | MX2 Double+ -- ^ X2 position of a mark. This is the secondary position for+ -- lines and area marks).+ --+ -- @since 0.4.0.0+ | MXOffset Double+ -- ^ X position offset of a mark.+ --+ -- @since 0.4.0.0+ | MX2Offset Double+ -- ^ X2 position offset of a mark.+ --+ -- @since 0.4.0.0+ | MY Double+ -- ^ Y position of a mark.+ --+ -- @since 0.4.0.0+ | MY2 Double+ -- ^ Y2 position of a mark. This is the secondary position for+ -- lines and area marks).+ --+ -- @since 0.4.0.0+ | MYOffset Double+ -- ^ Y position offset of a mark.+ --+ -- @since 0.4.0.0+ | MY2Offset Double+ -- ^ Y2 position offset of a mark.+ --+ -- @since 0.4.0.0++++markProperty :: MarkProperty -> LabelledSpec+markProperty (MFilled b) = "filled" .= b+markProperty (MBorders mps) = mprops_ "borders" mps+markProperty (MBox mps) = mprops_ "box" mps+markProperty (MClip b) = "clip" .= b+markProperty (MColor col) = "color" .= col+markProperty (MCursor cur) = "cursor" .= cursorLabel cur+markProperty (MFill col) = "fill" .= col+markProperty (MHeight x) = "height" .= x+markProperty (MStroke t) = "stroke" .= t+markProperty (MStrokeCap sc) = "strokeCap" .= strokeCapLabel sc+markProperty (MStrokeOpacity x) = "strokeOpacity" .= x+markProperty (MStrokeWidth w) = "strokeWidth" .= w+markProperty (MStrokeDash xs) = "strokeDash" .= xs+markProperty (MStrokeDashOffset x) = "strokeDashOffset" .= x+markProperty (MStrokeJoin sj) = "strokeJoin" .= strokeJoinLabel sj+markProperty (MStrokeMiterLimit x) = "strokeMiterLimit" .= x+markProperty (MMedian mps) = mprops_ "median" mps+markProperty (MOpacity x) = "opacity" .= x+markProperty (MFillOpacity x) = "fillOpacity" .= x+markProperty (MStyle [style]) = "style" .= style -- special case singleton+markProperty (MStyle styles) = "style" .= styles+markProperty (MInterpolate interp) = "interpolate" .= markInterpolationLabel interp+markProperty (MLine lm) = "line" .= lineMarkerSpec lm+markProperty (MTension x) = "tension" .= x+markProperty (MOrder b) = "order" .= b+markProperty (MOrient orient) = "orient" .= orientationSpec orient+markProperty (MOutliers []) = "outliers" .= True -- TODO: should mprops_ do this?+markProperty (MOutliers mps) = mprops_ "outliers" mps+markProperty MNoOutliers = "outliers" .= False+markProperty (MPoint pm) = "point" .= pointMarkerSpec pm+markProperty (MShape sym) = "shape" .= symbolLabel sym+markProperty (MSize x) = "size" .= x+markProperty (MAngle x) = "angle" .= x+markProperty (MAlign algn) = "align" .= hAlignLabel algn+markProperty (MBaseline va) = "baseline" .= vAlignLabel va+markProperty (MdX dx) = "dx" .= dx+markProperty (MdY dy) = "dy" .= dy+markProperty (MExtent mee) = markErrorExtentLSpec mee+markProperty (MFont fnt) = "font" .= fnt+markProperty (MFontSize x) = "fontSize" .= x+markProperty (MFontStyle fSty) = "fontStyle" .= fSty+markProperty (MFontWeight w) = "fontWeight" .= fontWeightSpec w+markProperty (MHRef s) = "href" .= s+markProperty (MRadius x) = "radius" .= x+markProperty (MRule mps) = mprops_ "rule" mps+markProperty (MText txt) = "text" .= txt+markProperty (MTheta x) = "theta" .= x+markProperty (MTicks mps) = mprops_ "ticks" mps+markProperty (MBinSpacing x) = "binSpacing" .= x+markProperty (MContinuousBandSize x) = "continuousBandSize" .= x+markProperty (MDiscreteBandSize x) = "discreteBandSize" .= x+markProperty (MShortTimeLabels b) = "shortTimeLabels" .= b+markProperty (MBandSize x) = "bandSize" .= x+markProperty (MThickness x) = "thickness" .= x+markProperty (MTooltip TTNone) = "tooltip" .= A.Null+markProperty (MTooltip tc) = "tooltip" .= object ["content" .= ttContentLabel tc]+markProperty (MWidth x) = "width" .= x+markProperty (MX x) = "x" .= x+markProperty (MY x) = "y" .= x+markProperty (MX2 x) = "x2" .= x+markProperty (MY2 x) = "y2" .= x+markProperty (MXOffset x) = "xOffset" .= x+markProperty (MYOffset x) = "yOffset" .= x+markProperty (MX2Offset x) = "x2Offset" .= x+markProperty (MY2Offset x) = "y2Offset" .= x+++-- | How are strokes capped? This is used with 'MStrokeCap', 'VBStrokeCap',+-- and `ViewStrokeCap'.+--+-- @since 0.4.0.0++data StrokeCap+ = CButt+ -- ^ Butt stroke cap.+ | CRound+ -- ^ Rounded stroke cap.+ | CSquare+ -- ^ Square stroke cap.+++strokeCapLabel :: StrokeCap -> T.Text+strokeCapLabel CButt = "butt"+strokeCapLabel CRound = "round"+strokeCapLabel CSquare = "square"+++-- | How are strokes joined? This is used with 'MStrokeJoin', 'VBStrokeJoin',+-- and `ViewStrokeJoin'.+--+--+-- @since 0.4.0.0++data StrokeJoin+ = JMiter+ -- ^ Mitred stroke join.+ | JRound+ -- ^ Rounded stroke join.+ | JBevel+ -- ^ Bevelled stroke join.+++strokeJoinLabel :: StrokeJoin -> T.Text+strokeJoinLabel JMiter = "miter"+strokeJoinLabel JRound = "round"+strokeJoinLabel JBevel = "bevel"+++{-|++Create an encoding specification from a list of channel encodings,+such as 'position', 'color', 'size', 'shape'.++@+enc = 'encoding'+ . 'position' 'X' [ 'PName' \"Animal\", 'PmType' 'Ordinal' ]+ . 'position' 'Y' [ PName \"Age\", 'PmType' 'Quantitative' ]+ . 'shape' [ 'MName' \"Species\", 'MmType' 'Nominal' ]+ . 'size' [ 'MName' \"Population\", 'MmType' 'Quantitative' ]+@++The type of @enc@ in this example is @[LabelledSpec] -> PropertySpec@,+so it can either be used to add further encoding specifications or as+@enc []@ to create a specification.++-}+encoding :: [LabelledSpec] -> PropertySpec+encoding channels = (VLEncoding, object channels)++-- TODO:+--+-- encoding of X2/... shouldn't include the PmType in the output, apparently+-- so we could try and filter that out, or just rely on the user to not+-- add the PmType fields in this case.++{-|++Type of position channel, @X@ and @Y@ represent horizontal and vertical axis+dimensions on a plane and @X2@ and @Y2@ represent secondary axis dimensions where+two scales are overlaid in the same space. Geographic positions represented by+longitude and latiutude values are identified with @Longitude@, @Latitude@ and+their respective secondary equivalents. Such geographic position channels are+subject to a map projection (set using 'projection') before being placed graphically.++-}+data Position+ = X+ | Y+ | X2+ -- ^ The secondary coordinate for ranged 'Area', 'Bar', 'Rect', and 'Rule'+ -- marks.+ | Y2+ -- ^ The secondary coordinate for ranged 'Area', 'Bar', 'Rect', and 'Rule'+ -- marks.+ | XError+ -- ^ Indicates that the 'X' channel represents the mid-point and+ -- the 'XError' channel gives the offset. If 'XError2' is not+ -- defined then this channel value is applied symmetrically.+ --+ -- @since 0.4.0.0+ | XError2+ -- ^ Used to support asymmetric error ranges defined as 'XError'+ -- and 'XError2'. One of 'XError' or 'XError2' channels must+ -- contain positive values and the other negative values.+ --+ -- @since 0.4.0.0+ | YError+ -- ^ Indicates that the 'Y' channel represents the mid-point and+ -- the 'YError' channel gives the offset. If 'YError2' is not+ -- defined then this channel value is applied symmetrically.+ --+ -- @since 0.4.0.0+ | YError2+ -- ^ Used to support asymmetric error ranges defined as 'YError'+ -- and 'YError2'. One of 'YError' or 'YError2' channels must+ -- contain positive values and the other negative values.+ --+ -- @since 0.4.0.0+ | Longitude+ -- ^ The longitude value for projections.+ | Latitude+ -- ^ The latitude value for projections.+ | Longitude2+ -- ^ A second longitude coordinate.+ | Latitude2+ -- ^ A second longitude coordinate.+++{-|++Type of measurement to be associated with some channel.++-}++data Measurement+ = Nominal+ -- ^ Data are categories identified by name alone and which have no intrinsic order.+ | Ordinal+ -- ^ Data are also categories, but ones which have some natural order.+ | Quantitative+ -- ^ Data are numeric measurements typically on a continuous scale.+ | Temporal+ -- ^ Data represents time in some manner.+ | GeoFeature+ -- ^ Geospatial position encoding ('Longitude' and 'Latitude') should specify the 'PmType'+ -- as @Quantitative@. Geographically referenced features encoded as 'shape' marks+ -- should specify 'MmType' as @GeoFeature@ (Vega-Lite currently refers to this type+ -- as @<https://vega.github.io/vega-lite/docs/encoding.html geojson>@.+++{-|++Type of binning property to customise. See the+<https://vega.github.io/vega-lite/docs/bin.html Vega-Lite documentation> for+more details.++This is used with: 'binAs', 'DBin', 'FBin', 'HBin', 'MBin', 'OBin',+'PBin', and 'TBin'.++-}++-- based on schema 3.3.0 #/definitions/BinParams++data BinProperty+ = AlreadyBinned Bool+ -- ^ Should the input data be treated as already binned?+ --+ -- @since 0.4.0.0+ | BinAnchor Double+ -- ^ A value in the binned domain at which to anchor the bins, shifting the bin+ -- boundaries if necessary to ensure that a boundary aligns with the anchor+ -- value.+ --+ -- @since 0.4.0.0+ | Base Double+ -- ^ The number base to use for automatic bin determination.+ --+ -- Default is @10@.+ | Divide [Double]+ -- ^ Scale factors indicating allowable subdivisions.+ --+ -- Default is @[5, 2]@.+ --+ -- Prior to @0.4.0.0@ the @Divide@ constructor took two numbers.+ | Extent Double Double+ -- ^ The range (minimum, maximum) of the desired bin values.+ | MaxBins Int+ -- ^ The maxium number of bins.+ --+ -- Default is @6@ for 'row', 'column', and 'shape' channels,+ -- @10@ otherwise.+ | MinStep Double+ -- ^ A minimum allowable step size.+ | Nice Bool+ -- ^ If @True@, the bin boundaries are adjusted to use human-friendly values,+ -- such as multiples of ten.+ --+ -- Default is @True@.+ | Step Double+ -- ^ The step size to use between bins.+ --+ -- If specified, 'MaxBins' and other related options are ignored.+ | Steps [Double]+ -- ^ Pick the step size from this list.+++binProperty :: BinProperty -> LabelledSpec+binProperty (AlreadyBinned b) = "binned" .= b+binProperty (BinAnchor x) = "anchor" .= x+binProperty (Base x) = "base" .= x+binProperty (Divide xs) = "divide" .= xs+binProperty (Extent mn mx) = "extent" .= [ mn, mx ]+binProperty (MaxBins n) = "maxbins" .= n+binProperty (MinStep x) = "minstep" .= x+binProperty (Nice b) = "nice" .= b+binProperty (Step x) = "step" .= x+binProperty (Steps xs) = "steps" .= xs+++bin :: [BinProperty] -> LabelledSpec+bin [] = "bin" .= True+bin xs = "bin" .= object (map binProperty xs)++binned_ :: LabelledSpec+binned_ = "bin" .= fromT "binned"+++{-|++Type of aggregation operation. See the+<https://vega.github.io/vega-lite/docs/aggregate.html#ops Vega-Lite documentation>+for more details.++The @Average@ constructor was removed in version @0.4.0.0@; use 'Mean' instead.++-}+data Operation+ = ArgMax (Maybe T.Text)+ -- ^ An input data object containing the maximum field value to be used+ -- in an aggregation operation.+ --+ -- If supplied as part of an encoding aggregation, the parameter+ -- should be 'Just' the name of the field to maximise. When used+ -- as part of a transform the parameter should be 'Nothing' as the+ -- field is specified in the 'aggregate' call.+ --+ -- Encoding example, to find the production budget for the maximum+ -- US grossing film in each genre:+ --+ -- @+ -- 'encoding'+ -- . 'position' 'X'+ -- [ 'PName' \"Production_Budget\"+ -- , 'PmType' 'Quantitative'+ -- , 'PAggregate' ('ArgMax' ('Just' \"US_Gross\"))+ -- ]+ -- . 'position' 'Y' ['PName' \"Major_Genre\", 'PmType' 'Nominal']+ -- @+ --+ -- An example of its use as part of an 'aggregate' call:+ --+ -- @+ -- 'transform'+ -- . 'aggregate'+ -- [ 'opAs' ('ArgMax' 'Nothing') \"US_Gross\" \"amUSGross\"]+ -- [\"Major_Genre\"]+ -- @+ --+ -- The optional field name was added in the @0.4.0.0@ release.+ | ArgMin (Maybe T.Text)+ -- ^ An input data object containing the minimum field value to be used+ -- in an aggregation operation. See 'ArgMax' for a discussion of the+ -- optional argument.+ --+ -- The optional field name was added in the @0.4.0.0@ release.+ | CI0+ -- ^ Lower 95% confidence interval to be used in an aggregation operation.+ | CI1+ -- ^ Upper 95% confidence interval to be used in an aggregation operation.+ | Count+ -- ^ Total count of data objects to be used in an aggregation operation.+ | Distinct+ -- ^ Count of distinct data objects to be used in an aggregation operation.+ | Max+ -- ^ Maximum field value to be used in an aggregation operation.+ | Mean+ -- ^ Mean field value to be used in an aggregation operation.+ | Median+ -- ^ Median field value to be used in an aggregation operation.+ | Min+ -- ^ Minimum field value to be used in an aggregation operation.+ | Missing+ -- ^ Count of @null@ or @undefined@ field value to be used in an aggregation operation.+ | Q1+ -- ^ Lower quartile boundary of field values to be used in an aggregation operation.+ | Q3+ -- ^ Upper quartile boundary of field values to be used in an aggregation operation.+ | Stderr+ -- ^ Standard error of field values to be used in an aggregate operation.+ | Stdev+ -- ^ Sample standard deviation of field values to be used in an aggregate operation.+ | StdevP+ -- ^ Population standard deviation of field values to be used in an aggregate operation.+ | Sum+ -- ^ Sum of field values to be used in an aggregate operation.+ | Valid+ -- ^ Count of values that are not @null@, @undefined@, or @NaN@ to be used in an+ -- aggregation operation.+ | Variance+ -- ^ Sample variance of field values to be used in an aggregate operation.+ | VarianceP+ -- ^ Population variance of field values to be used in an aggregate operation.+++-- Unlike Elm, not checking if the string is empty for ArgMin/Max++operationSpec :: Operation -> VLSpec+operationSpec (ArgMax Nothing) = "argmax"+operationSpec (ArgMax (Just s)) = object ["argmax" .= s]+operationSpec (ArgMin Nothing) = "argmin"+operationSpec (ArgMin (Just s)) = object ["argmin" .= s]+operationSpec CI0 = "ci0"+operationSpec CI1 = "ci1"+operationSpec Count = "count"+operationSpec Distinct = "distinct"+operationSpec Max = "max"+operationSpec Mean = "mean"+operationSpec Median = "median"+operationSpec Min = "min"+operationSpec Missing = "missing"+operationSpec Q1 = "q1"+operationSpec Q3 = "q3"+operationSpec Stderr = "stderr"+operationSpec Stdev = "stdev"+operationSpec StdevP = "stdevp"+operationSpec Sum = "sum"+operationSpec Valid = "valid"+operationSpec Variance = "variance"+operationSpec VarianceP = "variancep"+++-- | Identifies how repeated or faceted views are arranged.+--+-- This is used with a number of constructors: 'ByRepeatOp',+-- 'HRepeat', 'MRepeat', 'ORepeat', 'PRepeat', and 'TRepeat'.++-- based on schema 3.3.0 #/definitions/RepeatRef++data Arrangement+ = Column+ -- ^ Column arrangement.+ | Row+ -- ^ Row arrangement.+ | Flow+ -- ^ Flow arrangement (aka \"repeat\").+ --+ -- @since 0.4.0.0+++arrangementLabel :: Arrangement -> T.Text+arrangementLabel Column = "column"+arrangementLabel Row = "row"+arrangementLabel Flow = "repeat" -- NOTE: not "flow"!+++-- | How are stacks applied within a transform?+--+-- Prior to version @0.4.0.0@ the @StackProperty@ type was+-- what is now @StackOffset@.++data StackProperty+ = StOffset StackOffset+ -- ^ Stack offset.+ --+ -- @since 0.4.0.0+ | StSort [SortField]+ -- ^ Ordering within a stack.+ --+ -- @since 0.4.0.0+++-- | Describes the type of stacking to apply to a bar chart.+--+-- In @0.4.0.0@ this was renamed from @StackProperty@ to @StackOffset@,+-- but the constructor names have not changed.+--+data StackOffset+ = StZero+ -- ^ Offset a stacked layout using a baseline at the foot of+ -- the stack.+ | StNormalize+ -- ^ Rescale a stacked layout to use a common height while+ -- preserving the relative size of stacked quantities.+ | StCenter+ -- ^ Offset a stacked layout using a central stack baseline.+ | NoStack+ -- ^ Do not stack marks, but create a layered plot.++stackOffsetSpec :: StackOffset -> VLSpec+stackOffsetSpec StZero = "zero"+stackOffsetSpec StNormalize = "normalize"+stackOffsetSpec StCenter = "center"+stackOffsetSpec NoStack = A.Null++stackOffset :: StackOffset -> LabelledSpec+stackOffset so = "stack" .= stackOffsetSpec so+++stackPropertySpecOffset , stackPropertySpecSort:: StackProperty -> Maybe VLSpec+stackPropertySpecOffset (StOffset op) = Just (stackOffsetSpec op)+stackPropertySpecOffset _ = Nothing++stackPropertySpecSort (StSort sfs) = Just (toJSON (map sortFieldSpec sfs))+stackPropertySpecSort _ = Nothing+++{-|++Apply a stack transform for positioning multiple values. This is an alternative+to specifying stacking directly when encoding position.++@+'transform'+ . 'aggregate' [ 'opAs' 'Count' \"\" \"count_*\" ] [ \"Origin\", \"Cylinders\" ]+ . 'stack' "count_*"+ []+ \"stack_count_Origin1\"+ \"stack_count_Origin2\"+ [ 'StOffset' 'StNormalize', 'StSort' [ 'WAscending' \"Origin\" ] ]+ . 'window'+ [ ( [ 'WAggregateOp' 'Min', 'WField' \"stack_count_Origin1\" ], \"x\" )+ , ( [ 'WAggregateOp' 'Max', 'WField' \"stack_count_Origin2\" ], \"x2\" )+ ]+ [ 'WFrame' Nothing Nothing, 'WGroupBy' [ \"Origin\" ] ]+ . 'stack' \"count_*\"+ [ \"Origin\" ]+ \"y\"+ \"y2\"+ [ 'StOffset' 'StNormalize', 'StSort' [ 'WAscending' \"Cylinders\" ] ]+@++@since 0.4.0.0++-}++stack ::+ T.Text+ -- ^ The field to be stacked.+ -> [T.Text]+ -- ^ The fields to group by.+ -> T.Text+ -- ^ The output field name (start).+ -> T.Text+ -- ^ The output field name (end).+ -> [StackProperty]+ -- ^ Offset and sort properties.+ -> BuildLabelledSpecs+stack f grp start end sProps ols =+ let ags = [ toJSON f, toJSON grp, toJSON start, toJSON end+ , toSpec (mapMaybe stackPropertySpecOffset sProps)+ , toSpec (mapMaybe stackPropertySpecSort sProps)+ ]++ toSpec [x] = x+ toSpec _ = A.Null++ in ("stack", toJSON ags) : ols+++{-|++Individual scale property. These are used to customise an individual scale+transformation. To customise all scales use 'configure' and supply relevant+'ScaleConfig' values. For more details see the+<https://vega.github.io/vega-lite/docs/scale.html Vega-Lite documentation>.++There are two utility routines for constructing a list of scale+properties: 'categoricalDomainMap' and 'domainRangeMap'.++The @SReverse@ constructor was removed in version @0.4.0.0@, as it+represented a Vega, rather than Vega-Lite, property. The order of+a scale can be changed with the 'PSort' constructor.+-}++-- based on schema 3.3.0 #/definitions/Scale++data ScaleProperty+ = SType Scale+ -- ^ Type of scaling to apply.+ | SAlign Double+ -- ^ Alignment of the steps within the scale range. A value of+ -- @0@ shifts the bands to an axis, @1@ away from the axis,+ -- and @0.5@ is centered within the range.+ --+ -- The input is clamped so that values less than 0 are mapped+ -- to 0 and greater than 1 to 1.+ --+ -- @since 0.4.0.0+ | SBase Double+ -- ^ The base to use for log scaling ('ScLog').+ --+ -- Default is @10@.+ --+ -- @since 0.4.0.0+ | SBins [Double]+ -- ^ An array of bin boundaries over the scale domain. If give, axes and legends will use+ -- these boundaries to inform the choice of tick marks and text labels.+ --+ -- @since 0.4.0.0+ | SClamp Bool+ -- ^ Should values outside the data domain be clamped (to the minimum or+ -- maximum value)?+ | SConstant Double+ -- ^ The desired slope of the 'ScSymLog' function at zero.+ --+ -- The default is @1@.+ --+ -- @since 0.4.0.0+ | SDomain ScaleDomain+ -- ^ Custom scaling domain.+ | SExponent Double+ -- ^ The exponent to use for power scaling ('ScPow').+ --+ -- @since 0.4.0.0+ | SInterpolate CInterpolate+ -- ^ Interpolation method for scaling range values.+ | SNice ScaleNice+ -- ^ \"Nice\" minimum and maximum values in a scaling (e.g. multiples of 10).+ | SPadding Double+ -- ^ Padding in pixels to apply to a scaling.+ | SPaddingInner Double+ -- ^ Inner padding to apply to a band scaling.+ | SPaddingOuter Double+ -- ^ Outer padding to apply to a band scaling.+ | SRange ScaleRange+ -- ^ Range of a scaling. The type of range depends on the encoding channel.+ | SRangeStep (Maybe Double)+ -- ^ Distance between the starts of adjacent bands in a band scaling. If+ -- @Nothing@, the distance is determined automatically.+ | SRound Bool+ -- ^ Are numeric values in a scaling are rounded to integers?+ --+ -- The default is @False@.+ | SScheme T.Text [Double]+ -- ^ Color scheme used by a color scaling. The first parameter is the+ -- name of the scheme (e.g. \"viridis\") and the second an optional+ -- specification, which can contain 1, 2, or 3 numbers:+ --+ -- - the number of colors to use (list of one number);+ -- - the extent of the color range to use (list of two numbers between 0 and 1);+ -- - the number of colors and extent (three numbers, first is the number of colors).+ --+ -- The number of colors was broken prior to @0.4.0.0@ and the option to+ -- define both the count and extent was added in @0.4.0.0@.+ | SZero Bool+ -- ^ Should a numeric scaling be forced to include a zero value?+ --+ -- Not all scales support @SZero@ and the default depends on the type of+ -- channel.++scaleProperty :: ScaleProperty -> LabelledSpec+scaleProperty (SType sType) = "type" .= scaleLabel sType+scaleProperty (SAlign c) = "align" .= clamped 0 1 c+scaleProperty (SBase x) = "base" .= x+scaleProperty (SBins xs) = "bins" .= xs+scaleProperty (SClamp b) = "clamp" .= b+scaleProperty (SConstant x) = "constant" .= x+scaleProperty (SDomain sdType) = "domain" .= scaleDomainSpec sdType+scaleProperty (SExponent x) = "exponent" .= x+scaleProperty (SInterpolate interp) = "interpolate" .= cInterpolateSpec interp+scaleProperty (SNice ni) = "nice" .= scaleNiceSpec ni+scaleProperty (SPadding x) = "padding" .= x+scaleProperty (SPaddingInner x) = "paddingInner" .= x+scaleProperty (SPaddingOuter x) = "paddingOuter" .= x+scaleProperty (SRange (RNumbers xs)) = "range" .= xs+scaleProperty (SRange (RStrings ss)) = "range" .= ss+scaleProperty (SRange (RName s)) = "range" .= s+scaleProperty (SRangeStep numOrNull) = "rangeStep" .= maybe A.Null toJSON numOrNull+scaleProperty (SRound b) = "round" .= b+scaleProperty (SScheme nme extent) = schemeProperty nme extent+scaleProperty (SZero b) = "zero" .= b+++-- TODO: there should probably be a more-structured way to specify this+--+-- based on schema 3.3.0 #/definitions/SchemeParams++schemeProperty :: T.Text -> [Double] -> LabelledSpec+schemeProperty nme [n] = "scheme" .= object ["name" .= nme, "count" .= n]+schemeProperty nme [mn, mx] = "scheme" .= object ["name" .= nme, "extent" .= [mn, mx]]+schemeProperty nme [n, mn, mx] = "scheme" .= object ["name" .= nme, "count" .= n, "extent" .= [mn, mx]]+schemeProperty nme _ = "scheme" .= nme+++-- | Used to indicate the type of scale transformation to apply.+--+-- The @0.4.0.0@ release removed the @ScSequential@ constructor, as+-- 'ScLinear' should be used instead.++data Scale+ = ScLinear+ -- ^ A linear scale.+ | ScPow+ -- ^ A power scale. The exponent to use for scaling is specified with+ -- 'SExponent'.+ | ScSqrt+ -- ^ A square-root scale.+ | ScLog+ -- ^ A log scale. Defaults to log of base 10, but can be customised with+ -- 'SBase'.+ | ScSymLog+ -- ^ A [symmetrical log (PDF link)](https://www.researchgate.net/profile/John_Webber4/publication/233967063_A_bi-symmetric_log_transformation_for_wide-range_data/links/0fcfd50d791c85082e000000.pdf)+ -- scale. Similar to a log scale but supports zero and negative values. The slope+ -- of the function at zero can be set with 'SConstant'.+ --+ -- @since 0.4.0.0+ | ScTime+ -- ^ A temporal scale.+ | ScUtc+ -- ^ A temporal scale, in UTC.+ | ScOrdinal+ -- ^ An ordinal scale.+ | ScBand+ -- ^ A band scale.+ | ScPoint+ -- ^ A point scale.+ | ScBinLinear+ -- ^ A linear band scale.+ | ScBinOrdinal+ -- ^ An ordinal band scale.+ | ScQuantile+ -- ^ A quantile scale.+ --+ -- @since 0.4.0.0+ | ScQuantize+ -- ^ A quantizing scale.+ --+ -- @since 0.4.0.0+ | ScThreshold+ -- ^ A threshold scale.+ --+ -- @since 0.4.0.0+++scaleLabel :: Scale -> T.Text+scaleLabel ScLinear = "linear"+scaleLabel ScPow = "pow"+scaleLabel ScSqrt = "sqrt"+scaleLabel ScLog = "log"+scaleLabel ScSymLog = "symlog"+scaleLabel ScTime = "time"+scaleLabel ScUtc = "utc"+scaleLabel ScOrdinal = "ordinal"+scaleLabel ScBand = "band"+scaleLabel ScPoint = "point"+scaleLabel ScBinLinear = "bin-linear"+scaleLabel ScBinOrdinal = "bin-ordinal"+scaleLabel ScQuantile = "quantile"+scaleLabel ScQuantize = "quantize"+scaleLabel ScThreshold = "threshold"+++{-|++Describes the scale domain (type of data in scale). For full details see the+<https://vega.github.io/vega-lite/docs/scale.html#domain Vega-Lite documentation>.+-}++data ScaleDomain+ = DNumbers [Double]+ -- ^ Numeric values that define a scale domain.+ | DStrings [T.Text]+ -- ^ String values that define a scale domain.+ | DDateTimes [[DateTime]]+ -- ^ Date-time values that define a scale domain.+ | DSelection T.Text+ -- ^ Scale domain based on a named interactive selection.+ | Unaggregated+ -- ^ Specify an unaggregated scale domain (type of data in scale).++scaleDomainSpec :: ScaleDomain -> VLSpec+scaleDomainSpec (DNumbers nums) = toJSON (map toJSON nums)+scaleDomainSpec (DDateTimes dts) = toJSON (map (object . map dateTimeProperty) dts)+scaleDomainSpec (DStrings cats) = toJSON (map toJSON cats)+scaleDomainSpec (DSelection selName) = object ["selection" .= selName]+scaleDomainSpec Unaggregated = "unaggregated"+++{-|++Describes the way a scale can be rounded to \"nice\" numbers. For full details see the+<https://vega.github.io/vega-lite/docs/scale.html#continuous Vega-Lite documentation>.+-}+data ScaleNice+ = NMillisecond+ -- ^ Nice time intervals that try to align with rounded milliseconds.+ | NSecond+ -- ^ Nice time intervals that try to align with whole or rounded seconds.+ | NMinute+ -- ^ Nice time intervals that try to align with whole or rounded minutes.+ | NHour+ -- ^ Nice time intervals that try to align with whole or rounded hours.+ | NDay+ -- ^ Nice time intervals that try to align with whole or rounded days.+ | NWeek+ -- ^ Nice time intervals that try to align with whole or rounded weeks.+ | NMonth+ -- ^ Nice time intervals that try to align with whole or rounded months.+ | NYear+ -- ^ Nice time intervals that try to align with whole or rounded years.+ | NInterval TimeUnit Int+ -- ^ \"Nice\" temporal interval values when scaling.+ | IsNice Bool+ -- ^ Enable or disable nice scaling.+ | NTickCount Int+ -- ^ Desired number of tick marks in a \"nice\" scaling.+++scaleNiceSpec :: ScaleNice -> VLSpec+scaleNiceSpec NMillisecond = fromT "millisecond"+scaleNiceSpec NSecond = fromT "second"+scaleNiceSpec NMinute = fromT "minute"+scaleNiceSpec NHour = fromT "hour"+scaleNiceSpec NDay = fromT "day"+scaleNiceSpec NWeek = fromT "week"+scaleNiceSpec NMonth = fromT "month"+scaleNiceSpec NYear = fromT "year"+scaleNiceSpec (NInterval tu step) =+ object ["interval" .= timeUnitLabel tu, "step" .= step]+scaleNiceSpec (IsNice b) = toJSON b+scaleNiceSpec (NTickCount n) = toJSON n+++{-|++Describes a scale range of scale output values. For full details see the+<https://vega.github.io/vega-lite/docs/scale.html#range Vega-Lite documentation>.++For color scales you can also specify a color [scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme)+instead of range.++Any directly specified range for @x@ and @y@ channels will be ignored. Range can be customized+via the view's corresponding [size](https://vega.github.io/vega-lite/docs/size.html)+('width' and 'height') or via range steps and paddings properties (e.g. 'SCRangeStep')+for band and point scales.++-}++data ScaleRange+ = RNumbers [Double]+ -- ^ For [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous),+ -- a two-element array indicating minimum and maximum values, or an array with more than+ -- two entries for specifying a+ -- [piecewise scale](https://vega.github.io/vega-lite/docs/scale.html#piecewise).+ | RStrings [T.Text]+ -- ^ Text scale range for discrete scales.+ | RName T.Text+ -- ^ Name of a [pre-defined named scale range](https://vega.github.io/vega-lite/docs/scale.html#range-config)+ -- (e.g. \"symbol\" or \"diverging\").++{-|++Indicates the type of color interpolation to apply, when mapping a data field+onto a color scale.++For details see the+<https://vega.github.io/vega-lite/docs/scale.html#continuous Vega-Lite documentation>.++-}+data CInterpolate+ = CubeHelix Double+ -- ^ Cube helix color interpolation for continuous color scales using the given+ -- gamma value (anchored at 1).+ | CubeHelixLong Double+ -- ^ Long-path cube helix color interpolation for continuous color scales using+ -- the given gamma value (anchored at 1).+ | Hcl+ -- ^ HCL color interpolation for continuous color scales.+ | HclLong+ -- ^ HCL color interpolation in polar coordinate space for continuous color scales.+ | Hsl+ -- ^ HSL color interpolation for continuous color scales.+ | HslLong+ -- ^ HSL color interpolation in polar coordinate space for continuous color scales.+ | Lab+ -- ^ Lab color interpolation for continuous color scales.+ | Rgb Double+ -- ^ RGB color interpolation for continuous color scales using the given gamma+ -- value (anchored at 1).+++-- Need to tie down some types as things are too polymorphic,+-- particularly in the presence of OverloadedStrings.+--+pairT :: T.Text -> T.Text -> (T.Text, Value)+pairT a b = a .= b+++cInterpolateSpec :: CInterpolate -> VLSpec+cInterpolateSpec (Rgb gamma) = object [pairT "type" "rgb", "gamma" .= gamma]+cInterpolateSpec Hsl = object [pairT "type" "hsl"]+cInterpolateSpec HslLong = object [pairT "type" "hsl-long"]+cInterpolateSpec Lab = object [pairT "type" "lab"]+cInterpolateSpec Hcl = object [pairT "type" "hcl"]+cInterpolateSpec HclLong = object [pairT "type" "hcl-long"]+cInterpolateSpec (CubeHelix gamma) = object [pairT "type" "cubehelix", "gamma" .= gamma]+cInterpolateSpec (CubeHelixLong gamma) = object [pairT "type" "cubehelix-long", "gamma" .= gamma]+++{-|++Allow type of sorting to be customised. For details see the+<https://vega.github.io/vega-lite/docs/sort.html Vega-Lite documentation>.++The constructors have been changed in version @0.4.0.0@, with+@Op@, @ByField@, and @ByRepeat@ removed, and their functionality+replaced with 'ByRepeatOp', 'ByFieldOp', and 'ByChannel'.++-}+data SortProperty+ = Ascending+ -- ^ Sorting is from low to high.+ | Descending+ -- ^ Sorting is from high to low.+ | CustomSort DataValues+ -- ^ Custom sort order listing data values explicitly.+ --+ -- @since 0.4.0.0+ | ByRepeatOp Arrangement Operation+ -- ^ Sort by the aggregated summaries of the given fields+ -- (referenced by a repeat iterator) using an aggregation+ -- operation.+ --+ -- @since 0.4.0.0+ | ByFieldOp T.Text Operation+ -- ^ Sort by the aggregated summary of a field using an aggregation+ -- operation. The following example sorts the categorical data field+ -- @variety@ by the mean age of the data in each variety category:+ --+ -- @+ -- 'position' 'Y'+ -- [ 'PName' "variety"+ -- , 'PmType' 'Ordinal'+ -- , 'PSort' [ ByFieldOp "age" 'Mean', 'Descending' ]+ -- ]+ -- @+ --+ -- @since 0.4.0.0+ | ByChannel Channel+ -- ^ Sort by another channel.+ --+ -- @+ -- 'position' 'Y'+ -- [ 'PName' "age"+ -- , 'PmType' 'Ordinal'+ -- , 'PSort' [ ByChannel 'ChX' ]+ -- ]+ -- @+ --+ -- @since 0.4.0.0+++sortProperty :: SortProperty -> [LabelledSpec]+sortProperty Ascending = [order_ "ascending"]+sortProperty Descending = [order_ "descending"]+sortProperty (ByChannel ch) = ["encoding" .= channelLabel ch]+sortProperty (ByFieldOp field op) = [field_ field, op_ op]+sortProperty (ByRepeatOp arr op) = ["field" .= object [repeat_ arr], op_ op]+sortProperty (CustomSort _) = []+++sortPropertySpec :: [SortProperty] -> VLSpec+sortPropertySpec [] = A.Null+sortPropertySpec [Ascending] = fromT "ascending"+sortPropertySpec [Descending] = fromT "descending"+sortPropertySpec [CustomSort dvs] = toJSON (dataValuesSpecs dvs)+sortPropertySpec sps = object (concatMap sortProperty sps)+++-- | Position channel properties used for creating a position channel encoding.++data PositionChannel+ = PName T.Text+ -- ^ Name of the field used for encoding with a position channel.+ | PHeight+ -- ^ Set the position to the height of the enclosing data space. Useful for placing+ -- a mark relative to the bottom edge of a view.+ --+ -- @since 0.4.0.0+ | PWidth+ -- ^ Set the position to the width of the enclosing data space. Useful for justifying+ -- a mark to the right hand edge of a view. e.g. to position a mark at the right of+ -- the data rectangle:+ --+ -- @+ -- enc =+ -- 'encoding'+ -- . 'position' 'X' [ PWidth ]+ -- @+ --+ -- @since 0.4.0.0+ | PNumber Double+ -- ^ Set a position to an arbitrary value. Useful for placing items at the top of+ -- a plot area (@PNumber 0@) or a fixed number of pixels from the top.+ -- See also 'PHeight' and 'PWidth'.+ --+ -- @since 0.4.0.0+ | PRepeat Arrangement+ -- ^ Reference in a position channel to a field name generated by 'repeatFlow'+ -- or 'repeat'. The parameter identifies whether reference is being made to+ -- fields that are to be arranged in columns, in rows, or a with a flow layout.+ --+ -- For example:+ --+ -- @+ -- enc =+ -- 'encoding'+ -- . 'position' 'X' [ PRepeat 'Flow', 'PmType' 'Quantitative' ]+ --+ -- spec =+ -- 'asSpec' [ dataVals [], 'mark' 'Tick' [], enc [] ]+ --+ -- 'toVegaLite'+ -- [ 'repeatFlow' [ \"Horsepower\", \"Miles_per_Gallon\", \"Acceleration\"]+ -- , 'specification' spec+ -- ]+ -- @+ | PmType Measurement+ -- ^ Level of measurement when encoding with a position channel.+ | PBin [BinProperty]+ -- ^ Discretize numeric values into bins when encoding with a+ -- position channel.+ --+ -- For example, to encode a frequency histogram with bins every 5 units:+ --+ -- @+ -- enc = 'encoding'+ -- . 'position' 'X' [ 'PName' \"x\"+ -- , 'PmType' 'Ordinal'+ -- , 'PBin' ['Step' 5]+ -- ]+ -- . 'position' 'Y' [ 'PmType' 'Quantitative'+ -- , 'PAggregate' 'Count'+ -- ]+ -- @+ | PBinned+ -- ^ Indicate that the data encoded with position is already binned.+ --+ -- @since 0.4.0.0+ | PTimeUnit TimeUnit+ -- ^ Form of time unit aggregation of field values when encoding with a position channel.+ | PTitle T.Text+ -- ^ Title of a field when encoding with a position channel.+ --+ -- @since 0.4.0.0+ | PNoTitle+ -- ^ Draw no title.+ --+ -- @since 0.4.0.0+ | PAggregate Operation+ -- ^ Compute some aggregate summary statistics for a field to be encoded+ -- with a position channel.+ --+ -- @+ -- enc = 'encoding'+ -- . 'position' 'X' [ 'PName' \"role\", 'PmType' 'Ordinal' ]+ -- . 'position' 'Y' [ 'PName' \"salary\"+ -- , 'PmType' 'Quantitative'+ -- , 'PAggregate' 'Mean'+ -- ]+ -- @+ | PScale [ScaleProperty]+ -- ^ Scaling applied to a field when encoding with a position channel.+ -- The scale will transform a field's value into a position along+ -- one axis.+ --+ -- For example, the following will scale the bars positioned along+ -- a horizontal axis to have an inner spacing of 50% (0.5) of the+ -- total space allocated to each bar:+ --+ -- @+ -- enc = 'encoding'+ -- . 'position' 'X' [ 'PName' \"ageGroup\"+ -- , 'PmType' 'Nominal'+ -- , 'PScale' ['SPaddingInner' 0.5]+ -- ]+ -- @+ | PAxis [AxisProperty]+ -- ^ Axis properties used when encoding with a position channel. For no axis,+ -- provide an empty list.+ | PSort [SortProperty]+ -- ^ Sort order for field when encoding with a position channel.+ | PStack StackOffset+ -- ^ Type of stacking offset for the field when encoding with a+ -- position channel.+ --+ -- For example, stacking areas away from a centreline can be used+ -- to create a+ -- [streamgraph](https://vega.github.io/vega-lite/examples/stacked_area_stream.html):+ --+ -- @+ -- enc = 'encoding'+ -- . 'position' 'X' ['PName' \"week\", 'PmType' 'Ordinal']+ -- . 'position' 'Y' [ 'PName' \"takings\"+ -- , 'PmType' 'Quantitative'+ -- , 'PStack' 'StCenter'+ -- ]+ -- . 'color' ['MName' \"shop\", 'MmType' 'Nominal']+ -- @+ --+ -- Changed from @StackProperty@ in version @0.4.0.0@.+ | PImpute [ImputeProperty]+ -- ^ Set the imputation rules for a position channel. See the+ -- [Vega-Lite impute documentation](https://vega.github.io/vega-lite/docs/impute.html).+ --+ -- @since 0.4.0.0+++positionChannelProperty :: PositionChannel -> LabelledSpec+positionChannelProperty (PName s) = field_ s+positionChannelProperty (PmType m) = mtype_ m+positionChannelProperty (PBin b) = bin b+positionChannelProperty PBinned = binned_+positionChannelProperty (PAggregate op) = aggregate_ op+positionChannelProperty (PTimeUnit tu) = timeUnit_ tu+positionChannelProperty (PTitle s) = "title" .= s+positionChannelProperty PNoTitle = "title" .= A.Null+positionChannelProperty (PSort ops) = sort_ ops+positionChannelProperty (PScale sps) = scaleProp_ sps+positionChannelProperty (PAxis aps) =+ let js = if null aps+ then A.Null+ else object (map axisProperty aps)+ in "axis" .= js+positionChannelProperty (PStack so) = stackOffset so+positionChannelProperty (PRepeat arr) = "field" .= object [repeat_ arr]+positionChannelProperty PHeight = value_ "height"+positionChannelProperty PWidth = value_ "width"+positionChannelProperty (PNumber x) = "value" .= x+positionChannelProperty (PImpute ips) = impute_ ips+++measurementLabel :: Measurement -> T.Text+measurementLabel Nominal = "nominal"+measurementLabel Ordinal = "ordinal"+measurementLabel Quantitative = "quantitative"+measurementLabel Temporal = "temporal"+measurementLabel GeoFeature = "geojson"+++positionLabel :: Position -> T.Text+positionLabel X = "x"+positionLabel Y = "y"+positionLabel X2 = "x2"+positionLabel Y2 = "y2"+positionLabel XError = "xError"+positionLabel YError = "yError"+positionLabel XError2 = "xError2"+positionLabel YError2 = "yError2"+positionLabel Longitude = "longitude"+positionLabel Latitude = "latitude"+positionLabel Longitude2 = "longitude2"+positionLabel Latitude2 = "latitude2"+++{-|++Set the background color of the visualization. Should be specified with a CSS+string such as @\"#ffe\"@ or @\"rgb(200,20,150)\"@. If not specified the background will+be transparent.++@+'toVegaLite'+ [ 'background' "rgb(251,247,238)"+ , 'dataFromUrl' "data/population.json" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+background :: T.Text -> PropertySpec+background colour = (VLBackground, toJSON colour)+++{-|++Provides an optional description to be associated with the visualization.++@+'toVegaLite'+ [ 'description' "Population change of key regions since 1900"+ , 'dataFromUrl' "data/population.json" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+description :: T.Text -> PropertySpec+description s = (VLDescription, toJSON s)+++-- | Optional metadata.+--+-- @since 0.4.0.0++usermetadata ::+ A.Object+ -- ^ The metadata is passed around but ignored by VegaLite.+ -> PropertySpec+usermetadata o = (VLUserMetadata, A.Object o)+++{-|++Provide an optional title to be displayed in the visualization.++@+'toVegaLite'+ [ 'title' "Population Growth" ['TColor' \"orange\"]+ , 'dataFromUrl' \"data/population.json\" []+ , 'mark' 'Bar' []+ , 'encoding' ...+ ]+@++Prior to @0.4.0.0@ there was no way to set the title options+(other than using 'configuration' with 'TitleStyle').++-}+title ::+ T.Text+ -> [TitleConfig]+ -- ^ Configure the appearance of the title.+ --+ -- @since 0.4.0.0+ -> PropertySpec+title s [] = (VLTitle, toJSON s)+title s topts = (VLTitle,+ object ("text" .= s : map titleConfigSpec topts))+++{-|++Axis customisation properties. These are used for customising individual axes.+To configure all axes, use 'AxisConfig' with a 'configuration' instead. See the+<https://vega.github.io/vega-lite/docs/axis.html#axis-properties Vega-Lite documentation>+for more details.++The @AxTitleMaxLength@ constructor was removed in release @0.4.0.0@. The+'AxTitleLimit' constructor should be used instead.++-}+{-# DEPRECATED AxDates "Please change AxDates to AxValues" #-}+data AxisProperty+ = AxBandPosition Double+ -- ^ An interpolation fraction indicating where, for @band@ scales, axis ticks should+ -- be position. A value of @0@ places ticks at the left-edge of the band, @0.5@ in+ -- the middle, and @1@ at the right edge.+ --+ -- @since 0.4.0.0+ | AxDomain Bool+ -- ^ Should the axis domain (the baseline) be displayed?+ | AxDomainColor Color+ -- ^ The axis domain color.+ --+ -- @since 0.4.0.0+ | AxDomainDash [Double]+ -- ^ The dash style of the domain (alternating stroke, space lengths+ -- in pixels).+ --+ -- @since 0.4.0.0+ | AxDomainDashOffset Double+ -- ^ The pixel offset at which to start drawing the domain dash array.+ --+ -- @since 0.4.0.0+ | AxDomainOpacity Opacity+ -- ^ The axis domain opacity.+ --+ -- @since 0.4.0.0+ | AxDomainWidth Double+ -- ^ The width of the axis domain.+ --+ -- @since 0.4.0.0+ | AxFormat T.Text+ -- ^ [Formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for+ -- axis values. To distinguish between formatting as numeric values+ -- and data/time values, additionally use 'AxFormatAsNum' or 'AxFormatAsTemporal'.+ | AxFormatAsNum+ -- ^ Facet headers should be formatted as numbers. Use a+ -- [d3 numeric format string](https://github.com/d3/d3-format#locale_format)+ -- with 'AxFormat'.+ --+ -- @since 0.4.0.0+ | AxFormatAsTemporal+ -- ^ Facet headers should be formatted as dates or times. Use a+ -- [d3 date/time format string](https://github.com/d3/d3-time-format#locale_format)+ -- with 'AxFormat'.+ --+ -- @since 0.4.0.0+ | AxGrid Bool+ -- ^ Should an axis grid be displayed?+ | AxGridColor Color+ -- ^ The color for the grid.+ --+ -- @since 0.4.0.0+ | AxGridDash [Double]+ -- ^ The dash style of the grid (alternating stroke, space lengths+ -- in pixels).+ --+ -- @since 0.4.0.0+ | AxGridDashOffset Double+ -- ^ The pixel offset at which to start drawing the grid dash array.+ --+ -- @since 0.4.0.0+ | AxGridOpacity Opacity+ -- ^ The opacity of the grid.+ --+ -- @since 0.4.0.0+ | AxGridWidth Double+ -- ^ The width of the grid lines.+ --+ -- @since 0.4.0.0+ | AxLabels Bool+ -- ^ Should labels be added to an axis?+ | AxLabelAlign HAlign+ -- ^ The horizontal alignment for labels.+ --+ -- @since 0.4.0.0+ | AxLabelAngle Angle+ -- ^ The angle at which to draw labels.+ | AxLabelBaseline VAlign+ -- ^ The vertical alignment for labels.+ --+ -- @since 0.4.0.0+ | AxLabelNoBound+ -- ^ No boundary overlap check is applied to labels. This is the+ -- default behavior.+ --+ -- See also 'AxLabelBound' and 'AxLabelBoundValue'.+ --+ -- @since 0.4.0.0+ | AxLabelBound+ -- ^ Labels are hidden if they exceed the axis range by more than 1+ -- pixel.+ --+ -- See also 'AxLabelNoBound' and 'AxLabelBoundValue'.+ --+ -- @since 0.4.0.0+ | AxLabelBoundValue Double+ -- ^ Labels are hidden if they exceed the axis range by more than+ -- the given number of pixels.+ --+ -- See also 'AxLabelNoBound' and 'AxLabelBound'.+ --+ -- @since 0.4.0.0+ | AxLabelColor Color+ -- ^ The label color.+ --+ -- @since 0.4.0.0+ | AxLabelNoFlush+ -- ^ The labels are not aligned flush to the scale. This is the+ -- default for non-continuous X scales.+ --+ -- See also 'AxLabelFlush' and 'AxLabelFlushValue'.+ --+ -- @since 0.4.0.0+ | AxLabelFlush+ -- ^ The first and last axis labels are aligned flush to the scale+ -- range.+ --+ -- See also 'AxLabelNoFlush' and 'AxLabelFlushValue'.+ --+ -- @since 0.4.0.0+ | AxLabelFlushValue Double+ -- ^ The labels are aligned flush, and the parameter determines+ -- the extra offset, in pixels, to apply to the first and last+ -- labels. This can help the labels better group (visually) with+ -- the corresponding axis ticks.+ --+ -- See also 'AxLabelNoFlush' and 'AxLabelFlush'.+ --+ -- @since 0.4.0.0+ | AxLabelFlushOffset Double+ -- ^ The number of pixels to offset flush-adjusted labels.+ --+ -- @since 0.4.0.0+ | AxLabelFont T.Text+ -- ^ The font for the label.+ --+ -- @since 0.4.0.0+ | AxLabelFontSize Double+ -- ^ The font size of the label.+ --+ -- @since 0.4.0.0+ | AxLabelFontStyle T.Text+ -- ^ The font style of the label.+ --+ -- @since 0.4.0.0+ | AxLabelFontWeight FontWeight+ -- ^ The font weight of the label.+ --+ -- @since 0.4.0.0+ | AxLabelLimit Double+ -- ^ The maximum width of a label, in pixels.+ --+ -- @since 0.4.0.0+ | AxLabelOpacity Opacity+ -- ^ The opacity of the label.+ --+ -- @since 0.4.0.0+ | AxLabelOverlap OverlapStrategy+ -- ^ How should overlapping labels be displayed?+ | AxLabelPadding Double+ -- ^ The padding, in pixels, between the label and the axis.+ | AxLabelSeparation Double+ -- ^ The minimum separation, in pixels, between label bounding boxes+ -- for them to be considered non-overlapping. This is ignored if+ -- the 'AxLabelOverlap' strategy is 'ONone'.+ --+ -- @since 0.4.0.0+ | AxMaxExtent Double+ -- ^ The maximum extent, in pixels, that axis ticks and labels should use.+ -- This determines a maxmium offset value for axis titles.+ | AxMinExtent Double+ -- ^ The minimum extent, in pixels, that axis ticks and labels should use.+ -- This determines a minmium offset value for axis titles.+ | AxOffset Double+ -- ^ The offset, in pixels, between the axis and the edge of the+ -- enclosing group or data rectangle.+ | AxOrient Side+ -- ^ The orientation of the axis.+ | AxPosition Double+ -- ^ The anchor position of the axis in pixels.+ | AxTicks Bool+ -- ^ Should tick marks be drawn on an axis?+ | AxTickColor Color+ -- ^ The color of the ticks.+ --+ -- @since 0.4.0.0+ | AxTickCount Int+ -- ^ The desired number of ticks for axes visualizing quantitative scales.+ -- This is a hint to the system, and the actual number used will be+ -- adjusted to be \"nice\" (multiples of 2, 5, or 10) and lie within the+ -- underlying scale's range.+ | AxTickDash [Double]+ -- ^ The dash style of the ticks (alternating stroke, space lengths+ -- in pixels).+ --+ -- @since 0.4.0.0+ | AxTickDashOffset Double+ -- ^ The pixel offset at which to start drawing the tick dash array.+ --+ -- @since 0.4.0.0+ | AxTickExtra Bool+ -- ^ Should an extra axis tick mark be added for the initial position of+ -- the axis?+ --+ -- @since 0.4.0.0+ | AxTickMinStep Double+ -- ^ The minimum desired step between axis ticks, in terms of the scale+ -- domain values.+ --+ -- @since 0.4.0.0+ | AxTickOffset Double+ -- ^ The position offset, in pixels, to apply to ticks, labels, and grid lines.+ --+ -- @since 0.4.0.0+ | AxTickOpacity Opacity+ -- ^ The opacity of the ticks.+ --+ -- @since 0.4.0.0+ | AxTickRound Bool+ -- ^ Should pixel position values be rounded to the nearest integer?+ --+ -- @since 0.4.0.0+ | AxTickSize Double+ -- ^ The size of the tick marks in pixels.+ | AxTickWidth Double+ -- ^ The width of the tick marks in pixels.+ --+ -- @since 0.4.0.0+ | AxTitle T.Text+ -- ^ The axis title.+ | AxNoTitle+ -- ^ Draw no title for the axis.+ --+ -- @since 0.4.0.0+ | AxTitleAlign HAlign+ -- ^ The horizontal alignment of the axis title.+ | AxTitleAnchor APosition+ -- ^ The text anchor position for placing axis titles.+ --+ -- @since 0.4.0.0+ | AxTitleAngle Angle+ -- ^ The angle of the axis title.+ | AxTitleBaseline VAlign+ -- ^ The vertical alignment of the axis title.+ --+ -- @since 0.4.0.0+ | AxTitleColor Color+ -- ^ The color of the axis title.+ --+ -- @since 0.4.0.0+ | AxTitleFont T.Text+ -- ^ The font for the axis title.+ --+ -- @since 0.4.0.0+ | AxTitleFontSize Double+ -- ^ The font size of the axis title.+ --+ -- @since 0.4.0.0+ | AxTitleFontStyle T.Text+ -- ^ The font style of the axis title.+ --+ -- @since 0.4.0.0+ | AxTitleFontWeight FontWeight+ -- ^ The font weight of the axis title.+ --+ -- @since 0.4.0.0+ | AxTitleLimit Double+ -- ^ The maximum allowed width of the axis title, in pixels.+ --+ -- @since 0.4.0.0+ | AxTitleOpacity Opacity+ -- ^ The opacity of the axis title.+ --+ -- @since 0.4.0.0+ | AxTitlePadding Double+ -- ^ The padding, in pixels, between title and axis.+ | AxTitleX Double+ -- ^ The X coordinate of the axis title, relative to the axis group.+ --+ -- @since 0.4.0.0+ | AxTitleY Double+ -- ^ The Y coordinate of the axis title, relative to the axis group.+ --+ -- @since 0.4.0.0+ | AxValues DataValues+ -- ^ Set the explicit tick, grid, and label values along an axis.+ --+ -- The following three examples are for an axis displaying a+ -- quantitative, categorical, and temporal field respectively.+ --+ -- @+ -- 'PAxis' ['AxValues' ('Numbers' [2, 3, 5, 7, 11, 13, 17])]+ -- 'PAxis' ['AxValues' ('Strings' ["cats", "dogs", "elephants"])]+ -- 'PAxis' ['AxValues' ('DateTimes' [ ['DTYear' 2019, 'DTMonth' 'Mar', 'DTDate' 31]+ -- , ['DTYear' 2019, 'DTMonth' 'Jun', 'DTDate' 30]+ -- , ['DTYear' 2019, 'DTMonth' 'Sep', 'DTDate' 30]+ -- ])]+ -- @+ --+ -- Changed in @0.4.0.0@ to take 'DataValues' rather than @[Double]@.+ | AxDates [[DateTime]]+ -- ^ The dates or times to appear along the axis.+ --+ -- As of version @0.4.0.0@, this is deprecated. The 'AxValues'+ -- constructor should be used instead.+ | AxZIndex ZIndex+ -- ^ The z-index of the axis, relative to the chart marks.+++axisProperty :: AxisProperty -> LabelledSpec+axisProperty (AxBandPosition x) = "bandPosition" .= x+axisProperty (AxDomain b) = "domain" .= b+axisProperty (AxDomainColor s) = "domainColor" .= s+axisProperty (AxDomainDash ds) = "domainDash" .= ds+axisProperty (AxDomainDashOffset x) = "domainDashOffset" .= x+axisProperty (AxDomainOpacity x) = "domainOpacity" .= x+axisProperty (AxDomainWidth x) = "domainWidth" .= x+axisProperty (AxFormat fmt) = "format" .= fmt+axisProperty AxFormatAsNum = "formatType" .= fromT "number"+axisProperty AxFormatAsTemporal = "formatType" .= fromT "time"+axisProperty (AxGrid b) = "grid" .= b+axisProperty (AxGridColor s) = "gridColor" .= s+axisProperty (AxGridDash ds) = "gridDash" .= ds+axisProperty (AxGridDashOffset x) = "gridDashOffset" .= x+axisProperty (AxGridOpacity x) = "gridOpacity" .= x+axisProperty (AxGridWidth x) = "gridWidth" .= x+axisProperty (AxLabels b) = "labels" .= b+axisProperty (AxLabelAlign ha) = "labelAlign" .= hAlignLabel ha+axisProperty (AxLabelAngle a) = "labelAngle" .= a+axisProperty (AxLabelBaseline va) = "labelBaseline" .= vAlignLabel va+axisProperty AxLabelNoBound = "labelBound" .= False+axisProperty AxLabelBound = "labelBound" .= True+axisProperty (AxLabelBoundValue x) = "labelBound" .= x+axisProperty (AxLabelColor s) = "labelColor" .= s+axisProperty AxLabelNoFlush = "labelFlush" .= False+axisProperty AxLabelFlush = "labelFlush" .= True+axisProperty (AxLabelFlushValue x) = "labelFlush" .= x+axisProperty (AxLabelFlushOffset x) = "labelFlushOffset" .= x+axisProperty (AxLabelFont s) = "labelFont" .= s+axisProperty (AxLabelFontSize x) = "labelFontSize" .= x+axisProperty (AxLabelFontStyle s) = "labelFontStyle" .= s+axisProperty (AxLabelFontWeight fw) = "labelFontWeight" .= fontWeightSpec fw+axisProperty (AxLabelLimit x) = "labelLimit" .= x+axisProperty (AxLabelOpacity x) = "labelOpacity" .= x+axisProperty (AxLabelOverlap s) = "labelOverlap" .= overlapStrategyLabel s+axisProperty (AxLabelPadding x) = "labelPadding" .= x+axisProperty (AxLabelSeparation x) = "labelSeparation" .= x+axisProperty (AxMaxExtent n) = "maxExtent" .= n+axisProperty (AxMinExtent n) = "minExtent" .= n+axisProperty (AxOffset n) = "offset" .= n+axisProperty (AxOrient side) = "orient" .= sideLabel side+axisProperty (AxPosition n) = "position" .= n+axisProperty (AxTicks b) = "ticks" .= b+axisProperty (AxTickColor s) = "tickColor" .= s+axisProperty (AxTickCount n) = "tickCount" .= n+axisProperty (AxTickDash ds) = "tickDash" .= ds+axisProperty (AxTickDashOffset x) = "tickDashOffset" .= x+axisProperty (AxTickExtra b) = "tickExtra" .= b+axisProperty (AxTickMinStep x) = "tickMinStep" .= x+axisProperty (AxTickOffset x) = "tickOffset" .= x+axisProperty (AxTickOpacity x) = "tickOpacity" .= x+axisProperty (AxTickRound b) = "tickRound" .= b+axisProperty (AxTickSize x) = "tickSize" .= x+axisProperty (AxTickWidth x) = "tickWidth" .= x+axisProperty (AxTitle ttl) = "title" .= ttl+axisProperty AxNoTitle = "title" .= A.Null+axisProperty (AxTitleAlign ha) = "titleAlign" .= hAlignLabel ha+axisProperty (AxTitleAnchor a) = "titleAnchor" .= anchorLabel a+axisProperty (AxTitleAngle x) = "titleAngle" .= x+axisProperty (AxTitleBaseline va) = "titleBaseline" .= vAlignLabel va+axisProperty (AxTitleColor s) = "titleColor" .= s+axisProperty (AxTitleFont s) = "titleFont" .= s+axisProperty (AxTitleFontSize x) = "titleFontSize" .= x+axisProperty (AxTitleFontStyle s) = "titleFontStyle" .= s+axisProperty (AxTitleFontWeight fw) = "titleFontWeight" .= fontWeightSpec fw+axisProperty (AxTitleLimit x) = "titleLimit" .= x+axisProperty (AxTitleOpacity x) = "titleOpacity" .= x+axisProperty (AxTitlePadding pad) = "titlePadding" .= pad+axisProperty (AxTitleX x) = "titleX" .= x+axisProperty (AxTitleY x) = "titleY" .= x+axisProperty (AxValues vals) = "values" .= dataValuesSpecs vals+axisProperty (AxDates dtss) = "values" .= map (object . map dateTimeProperty) dtss+axisProperty (AxZIndex z) = "zindex" .= z+++-- | Indicates the horizontal alignment of text such as on an axis or legend.++data HAlign+ = AlignCenter+ | AlignLeft+ | AlignRight+++-- | Indicates the vertical alignment of text that may be attached to a mark.++data VAlign+ = AlignTop+ | AlignMiddle+ | AlignBottom+++hAlignLabel :: HAlign -> T.Text+hAlignLabel AlignLeft = "left"+hAlignLabel AlignCenter = "center"+hAlignLabel AlignRight = "right"+++vAlignLabel :: VAlign -> T.Text+vAlignLabel AlignTop = "top"+vAlignLabel AlignMiddle = "middle"+vAlignLabel AlignBottom = "bottom"+++-- | Represents one side of a rectangular space.++data Side+ = STop+ | SBottom+ | SLeft+ | SRight+++sideLabel :: Side -> T.Text+sideLabel STop = "top"+sideLabel SBottom = "bottom"+sideLabel SLeft = "left"+sideLabel SRight = "right"+++{-|++Type of overlap strategy to be applied when there is not space to show all items+on an axis. See the+<https://vega.github.io/vega-lite/docs/axis.html#labels Vega-Lite documentation>+for more details.+-}++data OverlapStrategy+ = ONone+ -- ^ No overlap strategy to be applied when there is not space to show all items+ -- on an axis.+ | OParity+ -- ^ Give all items equal weight in overlap strategy to be applied when there is+ -- not space to show them all on an axis.+ | OGreedy+ -- ^ Greedy overlap strategy to be applied when there is not space to show all+ -- items on an axis.++overlapStrategyLabel :: OverlapStrategy -> T.Text+overlapStrategyLabel ONone = "false"+overlapStrategyLabel OParity = "parity"+overlapStrategyLabel OGreedy = "greedy"+++{-|++Allows a date or time to be represented. This is typically part of a list of+@DateTime@ items to provide a specific point in time. For details see the+<https://vega.github.io/vega-lite/docs/types.html#datetime Vega-Lite documentation>.+-}++data DateTime+ = DTYear Int+ | DTQuarter Int+ | DTMonth MonthName+ | DTDate Int+ | DTDay DayName+ | DTHours Int+ | DTMinutes Int+ | DTSeconds Int+ | DTMilliseconds Int+++-- | Identifies the day of the week.++data DayName+ = Mon+ | Tue+ | Wed+ | Thu+ | Fri+ | Sat+ | Sun+++-- | Identifies a month of the year.++data MonthName+ = Jan+ | Feb+ | Mar+ | Apr+ | May+ | Jun+ | Jul+ | Aug+ | Sep+ | Oct+ | Nov+ | Dec+++{-|++Describes a unit of time. Useful for encoding and transformations. See the+<https://vega.github.io/vega-lite/docs/timeunit.html Vega-Lite documentation>+for further details.++@+'encoding'+ . 'position' 'X' [ 'PName' "date", 'PmType' 'Temporal', 'PTimeUnit' ('Utc' 'YearMonthDateHours') ]+@+-}++data TimeUnit+ = Year+ | YearQuarter+ | YearQuarterMonth+ | YearMonth+ | YearMonthDate+ | YearMonthDateHours+ | YearMonthDateHoursMinutes+ | YearMonthDateHoursMinutesSeconds+ | Quarter+ | QuarterMonth+ | Month+ | MonthDate+ | Date+ | Day+ | Hours+ | HoursMinutes+ | HoursMinutesSeconds+ | Minutes+ | MinutesSeconds+ | Seconds+ | SecondsMilliseconds+ | Milliseconds+ | Utc TimeUnit+ -- ^ Encode a time as UTC (coordinated universal time, independent of local time+ -- zones or daylight saving).+++dateTimeProperty :: DateTime -> LabelledSpec+dateTimeProperty (DTYear y) = "year" .= y+dateTimeProperty (DTQuarter q) = "quarter" .= q+dateTimeProperty (DTMonth mon) = "month" .= monthNameLabel mon+dateTimeProperty (DTDate dt) = "date" .= dt+dateTimeProperty (DTDay day) = "day" .= dayLabel day+dateTimeProperty (DTHours h) = "hours" .= h+dateTimeProperty (DTMinutes m) = "minutes" .= m+dateTimeProperty (DTSeconds s) = "seconds" .= s+dateTimeProperty (DTMilliseconds ms) = "milliseconds" .= ms+++dayLabel :: DayName -> T.Text+dayLabel Mon = "Mon"+dayLabel Tue = "Tue"+dayLabel Wed = "Wed"+dayLabel Thu = "Thu"+dayLabel Fri = "Fri"+dayLabel Sat = "Sat"+dayLabel Sun = "Sun"+++monthNameLabel :: MonthName -> T.Text+monthNameLabel Jan = "Jan"+monthNameLabel Feb = "Feb"+monthNameLabel Mar = "Mar"+monthNameLabel Apr = "Apr"+monthNameLabel May = "May"+monthNameLabel Jun = "Jun"+monthNameLabel Jul = "Jul"+monthNameLabel Aug = "Aug"+monthNameLabel Sep = "Sep"+monthNameLabel Oct = "Oct"+monthNameLabel Nov = "Nov"+monthNameLabel Dec = "Dec"+++timeUnitLabel :: TimeUnit -> T.Text+timeUnitLabel Year = "year"+timeUnitLabel YearQuarter = "yearquarter"+timeUnitLabel YearQuarterMonth = "yearquartermonth"+timeUnitLabel YearMonth = "yearmonth"+timeUnitLabel YearMonthDate = "yearmonthdate"+timeUnitLabel YearMonthDateHours = "yearmonthdatehours"+timeUnitLabel YearMonthDateHoursMinutes = "yearmonthdatehoursminutes"+timeUnitLabel YearMonthDateHoursMinutesSeconds = "yearmonthdatehoursminutesseconds"+timeUnitLabel Quarter = "quarter"+timeUnitLabel QuarterMonth = "quartermonth"+timeUnitLabel Month = "month"+timeUnitLabel MonthDate = "monthdate"+timeUnitLabel Date = "date"+timeUnitLabel Day = "day"+timeUnitLabel Hours = "hours"+timeUnitLabel HoursMinutes = "hoursminutes"+timeUnitLabel HoursMinutesSeconds = "hoursminutesseconds"+timeUnitLabel Minutes = "minutes"+timeUnitLabel MinutesSeconds = "minutesseconds"+timeUnitLabel Seconds = "seconds"+timeUnitLabel SecondsMilliseconds = "secondsmilliseconds"+timeUnitLabel Milliseconds = "milliseconds"+timeUnitLabel (Utc tu) = "utc" <> timeUnitLabel tu+++{-|++Represents the type of cursor to display. For an explanation of each type,+see the+<https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Keyword%20values CSS documentation>.++-}+data Cursor+ = CAuto+ | CDefault+ | CNone+ | CContextMenu+ | CHelp+ | CPointer+ | CProgress+ | CWait+ | CCell+ | CCrosshair+ | CText+ | CVerticalText+ | CAlias+ | CCopy+ | CMove+ | CNoDrop+ | CNotAllowed+ | CAllScroll+ | CColResize+ | CRowResize+ | CNResize+ | CEResize+ | CSResize+ | CWResize+ | CNEResize+ | CNWResize+ | CSEResize+ | CSWResize+ | CEWResize+ | CNSResize+ | CNESWResize+ | CNWSEResize+ | CZoomIn+ | CZoomOut+ | CGrab+ | CGrabbing+++cursorLabel :: Cursor -> T.Text+cursorLabel CAuto = "auto"+cursorLabel CDefault = "default"+cursorLabel CNone = "none"+cursorLabel CContextMenu = "context-menu"+cursorLabel CHelp = "help"+cursorLabel CPointer = "pointer"+cursorLabel CProgress = "progress"+cursorLabel CWait = "wait"+cursorLabel CCell = "cell"+cursorLabel CCrosshair = "crosshair"+cursorLabel CText = "text"+cursorLabel CVerticalText = "vertical-text"+cursorLabel CAlias = "alias"+cursorLabel CCopy = "copy"+cursorLabel CMove = "move"+cursorLabel CNoDrop = "no-drop"+cursorLabel CNotAllowed = "not-allowed"+cursorLabel CAllScroll = "all-scroll"+cursorLabel CColResize = "col-resize"+cursorLabel CRowResize = "row-resize"+cursorLabel CNResize = "n-resize"+cursorLabel CEResize = "e-resize"+cursorLabel CSResize = "s-resize"+cursorLabel CWResize = "w-resize"+cursorLabel CNEResize = "ne-resize"+cursorLabel CNWResize = "nw-resize"+cursorLabel CSEResize = "se-resize"+cursorLabel CSWResize = "sw-resize"+cursorLabel CEWResize = "ew-resize"+cursorLabel CNSResize = "ns-resize"+cursorLabel CNESWResize = "nesw-resize"+cursorLabel CNWSEResize = "nwse-resize"+cursorLabel CZoomIn = "zoom-in"+cursorLabel CZoomOut = "zoom-out"+cursorLabel CGrab = "grab"+cursorLabel CGrabbing = "grabbing"+++-- | Indicates the weight options for a font.++data FontWeight+ = Bold+ | Bolder+ | Lighter+ | Normal+ | W100+ | W200+ | W300+ | W400+ | W500+ | W600+ | W700+ | W800+ | W900+++fontWeightSpec :: FontWeight -> VLSpec+fontWeightSpec Bold = fromT "bold"+fontWeightSpec Bolder = fromT "bolder"+fontWeightSpec Lighter = fromT "lighter"+fontWeightSpec Normal = fromT "normal"+fontWeightSpec W100 = fromF 100+fontWeightSpec W200 = fromF 200+fontWeightSpec W300 = fromF 300+fontWeightSpec W400 = fromF 400+fontWeightSpec W500 = fromF 500+fontWeightSpec W600 = fromF 600+fontWeightSpec W700 = fromF 700+fontWeightSpec W800 = fromF 800+fontWeightSpec W900 = fromF 900+++{-|++Indicates mark interpolation style. See the+<https://vega.github.io/vega-lite/docs/mark.html#mark-def Vega-Lite documentation>+for details.+-}+data MarkInterpolation+ = Basis+ | BasisClosed+ | BasisOpen+ | Bundle+ | Cardinal+ | CardinalClosed+ | CardinalOpen+ | Linear+ | LinearClosed+ | Monotone+ | StepAfter+ | StepBefore+ | Stepwise+++markInterpolationLabel :: MarkInterpolation -> T.Text+markInterpolationLabel Linear = "linear"+markInterpolationLabel LinearClosed = "linear-closed"+markInterpolationLabel Stepwise = "step"+markInterpolationLabel StepBefore = "step-before"+markInterpolationLabel StepAfter = "step-after"+markInterpolationLabel Basis = "basis"+markInterpolationLabel BasisOpen = "basis-open"+markInterpolationLabel BasisClosed = "basis-closed"+markInterpolationLabel Cardinal = "cardinal"+markInterpolationLabel CardinalOpen = "cardinal-open"+markInterpolationLabel CardinalClosed = "cardinal-closed"+markInterpolationLabel Bundle = "bundle"+markInterpolationLabel Monotone = "monotone"+++{-|++The orientation of an item. This is used with:+'BLeLDirection', 'LDirection',+'LeGradientDirection', 'LeLDirection', 'LeSymbolDirection',+and 'MOrient'.++In @0.4.0.0@ this was renamed from @MarkOrientation@ to 'Orientation'.++-}++-- based on schema 3.3.0 #/definitions/Orientation++data Orientation+ = Horizontal+ -- ^ Display horizontally.+ | Vertical+ -- ^ Display vertically.+++orientationSpec :: Orientation -> VLSpec+orientationSpec Horizontal = "horizontal"+orientationSpec Vertical = "vertical"+++{-|++Indicates the extent of the rule used for the error bar. See+<https://vega.github.io/vega-lite/docs/errorbar.html#properties Vega-Lite documentation>+for details.++Note that not all options are valid for all mark types.++This is called @SummaryExtent@ in Elm and the constructors also have+different names.++@since 0.4.0.0+-}++-- based on schema 3.3.0 #/definitions/ErrorBarExtent+-- (ConfidenceInterval to Iqr)+-- and combined with the box/band "min-max" and IQR scaling values+--++data MarkErrorExtent+ = ConfidenceInterval+ -- ^ Band extent between the 95% confidence intervals of a distribution.+ | StdErr+ -- ^ Band extent as the standard error about the mean of a distribution.+ | StdDev+ -- ^ Band extent as the standard deviation of a distribution.+ | Iqr+ -- ^ Band extent between the lower and upper quartiles of a distribution+ -- (the inter-quartile range, q1 to q3).+ | ExRange+ -- ^ Band extent between the minimum and maximum values in a distribution.+ | IqrScale Double+ -- ^ A scaling of the interquartile range to be used as whiskers in a+ -- 'Boxplot'. For example @IqrScale 1.5@ would extend whiskers to+ -- ±1.5x the IQR from the mean.++-- This is a little different from the other calls since I wanted to+-- make sure the scale factor was encoded as a number not a string.+--+extent_ :: T.Text -> LabelledSpec+extent_ v = "extent" .= v++markErrorExtentLSpec :: MarkErrorExtent -> LabelledSpec+markErrorExtentLSpec ConfidenceInterval = extent_ "ci"+markErrorExtentLSpec StdErr = extent_ "stderr"+markErrorExtentLSpec StdDev = extent_ "stdev"+markErrorExtentLSpec Iqr = extent_ "iqr"+markErrorExtentLSpec ExRange = extent_ "min-max"+markErrorExtentLSpec (IqrScale sc) = "extent" .= sc+++-- | Identifies the type of symbol used with the 'Point' mark type.+-- It is used with 'MShape', 'LeSymbolType', and 'LSymbolType'.+--+-- In version @0.4.0.0@ all constructors were changed to start+-- with @Sym@.+--+data Symbol+ = SymCircle+ -- ^ Specify a circular symbol for a shape mark.+ | SymSquare+ -- ^ Specify a square symbol for a shape mark.+ | SymCross+ -- ^ Specify a cross symbol for a shape mark.+ | SymDiamond+ -- ^ Specify a diamond symbol for a shape mark.+ | SymTriangleUp+ -- ^ Specify an upward-triangular symbol for a shape mark.+ | SymTriangleDown+ -- ^ Specify a downward-triangular symbol for a shape mark.+ | SymTriangleRight+ -- ^ Specify an right-facing triangular symbol for a shape mark.+ --+ -- @since 0.4.0.0+ | SymTriangleLeft+ -- ^ Specify an left-facing triangular symbol for a shape mark.+ --+ -- @since 0.4.0.0+ | SymStroke+ -- ^ The line symbol.+ --+ -- @since 0.4.0.0+ | SymArrow+ -- ^ Centered directional shape.+ --+ -- @since 0.4.0.0+ | SymTriangle+ -- ^ Centered directional shape. It is not clear what difference+ -- this is to 'SymTriangleUp'.+ --+ -- @since 0.4.0.0+ | SymWedge+ -- ^ Centered directional shape.+ --+ -- @since 0.4.0.0+ | SymPath T.Text+ -- ^ A custom symbol shape as an+ -- [SVG path description](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths).+ --+ -- For correct sizing, the path should be defined within a square+ -- bounding box, defined on an axis of -1 to 1 for both dimensions.+++symbolLabel :: Symbol -> T.Text+symbolLabel SymCircle = "circle"+symbolLabel SymSquare = "square"+symbolLabel SymCross = "cross"+symbolLabel SymDiamond = "diamond"+symbolLabel SymTriangleUp = "triangle-up"+symbolLabel SymTriangleDown = "triangle-down"+symbolLabel SymTriangleRight = "triangle-right"+symbolLabel SymTriangleLeft = "triangle-left"+symbolLabel SymStroke = "stroke"+symbolLabel SymArrow = "arrow"+symbolLabel SymTriangle = "triangle"+symbolLabel SymWedge = "wedge"+symbolLabel (SymPath svgPath) = svgPath+++{-|++Indicates the auto-sizing characteristics of the visualization such as amount+of padding, whether it should fill the parent container etc. For more details see the+<https://vega.github.io/vega-lite/docs/size.html#autosize Vega-Lite documentation>.++-}++data Autosize+ = AContent+ -- ^ Interpret visualization dimensions to be for the data rectangle (external+ -- padding added to this size).+ | AFit+ -- ^ Interpret visualization dimensions to be for the entire visualization (data+ -- rectangle is shrunk to accommodate external decorations padding).+ | ANone+ -- ^ No autosizing is applied.+ | APad+ -- ^ Automatically expand size of visualization from the given dimensions in order+ -- to fit in all supplementary decorations (legends etc.).+ | APadding+ -- ^ Interpret visualization width to be for the entire visualization (data+ -- rectangle is shrunk to accommodate external padding).+ | AResize+ -- ^ Recalculate autosizing on every view update.+++autosizeProperty :: Autosize -> LabelledSpec+autosizeProperty APad = ("type", fromT "pad")+autosizeProperty AFit = ("type", fromT "fit")+autosizeProperty ANone = ("type", fromT "none")+autosizeProperty AResize = "resize" .= True+autosizeProperty AContent = ("contains", fromT "content")+autosizeProperty APadding = ("contains", fromT "padding")+++{-|++Declare the way the view is sized. See the+<https://vega.github.io/vega-lite/docs/size.html#autosize Vega-Lite documentation>+for details.++@+'toVegaLite'+ [ 'width' 250+ , 'height' 300+ , 'autosize' [ 'AFit', 'APadding', 'AResize' ]+ , 'dataFromUrl' "data/population.json" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+autosize :: [Autosize] -> PropertySpec+autosize aus = (VLAutosize, object (map autosizeProperty aus))+++-- | Indicates the style in which field names are displayed.++data FieldTitleProperty+ = Verbal+ -- ^ Creates \"Sum of field\", \"Year of date\", \"field (binned)\", etc.+ | Function+ -- ^ Creates \"SUM(field)\", \"YEAR(date)\", \"BIN(field)\", etc.+ | Plain+ -- ^ Just use the field name without any extra text.+++fieldTitleLabel :: FieldTitleProperty -> T.Text+fieldTitleLabel Verbal = "verbal"+fieldTitleLabel Function = "functional"+fieldTitleLabel Plain = "plain"+++-- | Indicates the type of legend to create. It is used with 'LType'.+--+-- Prior to version @0.4.0.0.0@ this was called @Legend@ and the+-- constructors did not end in @Legend@.+--+data LegendType+ = GradientLegend+ -- ^ Typically used for continuous quantitative data.+ | SymbolLegend+ -- ^ Typically used for categorical data.+++legendLabel :: LegendType -> T.Text+legendLabel GradientLegend = "gradient"+legendLabel SymbolLegend = "symbol"+++{-|++Legend configuration options. For more detail see the+<https://vega.github.io/vega-lite/docs/legend.html#config Vega-Lite documentation>.++This data type has seen significant changes in the @0.4.0.0@ release:++- the @EntryPadding@, @GradientHeight@, @GradientLabelBaseline@, @GradientWidth@+ and @SymbolColor@ constructors were removed;++- the constructors were removed;++- the remaining constructors that did not begin with @Le@ were renamed (for+ example @Orient@ was changed to 'LeOrient');++- and new constructors were added.++-}++-- based on schema 3.3.0 #/definitions/LegendConfig++data LegendConfig+ = LeClipHeight Double+ -- ^ The height in pixels at which to clip symbol legend entries.+ --+ -- @since 0.4.0.0+ | LeColumnPadding Double+ -- ^ The horizontal padding, in pixels, between symbol legend entries.+ --+ -- @since 0.4.0.0+ | LeColumns Int+ -- ^ The number of columns in which to arrange symbol legend entries. A value+ -- of @0@ or lower indicates a single row with one column per entry.+ --+ -- @since 0.4.0.0+ | LeCornerRadius Double+ -- ^ The corner radius for the full legend.+ | LeFillColor Color+ -- ^ The background fill color for the full legend.+ | LeGradientDirection Orientation+ -- ^ The default direction for gradient legends.+ --+ -- @since 0.4.0.0+ | LeGradientHorizontalMaxLength Double+ -- ^ The maximum legend length for a horizontal gradient.+ --+ -- @since 0.4.0.0+ | LeGradientHorizontalMinLength Double+ -- ^ The minimum legend length for a horizontal gradient.+ --+ -- @since 0.4.0.0+ | LeGradientLabelLimit Double+ -- ^ The maximum allowed length, in pixels, of color-ramp gradient labels.+ | LeGradientLabelOffset Double+ -- ^ The vertical offset in pixels for color-ramp gradient labels.+ | LeGradientLength Double+ -- ^ The length in pixels of the primary axis of a color gradient.+ -- See also 'LeGradientThickness'.+ --+ -- @since 0.4.0.0+ | LeGradientOpacity Opacity+ -- ^ The opacity of the color gradient.+ --+ -- @since 0.4.0.0+ | LeGradientStrokeColor Color+ -- ^ The color of the gradient stroke.+ | LeGradientStrokeWidth Double+ -- ^ The width of the gradient stroke, in pixels.+ | LeGradientThickness Double+ -- ^ The thickness in pixels of the color gradient. See also 'LeGradientLength'.+ --+ -- @since 0.4.0.0+ | LeGradientVerticalMaxLength Double+ -- ^ The maximum legend length for a vertical gradient.+ --+ -- @since 0.4.0.0+ | LeGradientVerticalMinLength Double+ -- ^ The minimum legend length for a vertical gradient.+ --+ -- @since 0.4.0.0+ | LeGridAlign CompositionAlignment+ -- ^ The alignment to apply to symbol legends rows and columns.+ --+ -- @since 0.4.0.0+ | LeLabelAlign HAlign+ -- ^ The alignment of the legend label.+ | LeLabelBaseline VAlign+ -- ^ The position of the baseline of the legend label.+ | LeLabelColor Color+ -- ^ The color of the legend label.+ | LeLabelFont T.Text+ -- ^ The font of the legend label.+ | LeLabelFontSize Double+ -- ^ The font of the legend label.+ | LeLabelFontStyle T.Text+ -- ^ The font style of the legend label.+ --+ -- @since 0.4.0.0+ | LeLabelFontWeight FontWeight+ -- ^ The font weight of the legend label.+ --+ -- @since 0.4.0.0+ | LeLabelLimit Double+ -- ^ The maxumum allowed pixel width of the legend label.+ | LeLabelOffset Double+ -- ^ The offset of the legend label.+ | LeLabelOpacity Opacity+ -- ^ The opacity of the legend label.+ --+ -- @since 0.4.0.0+ | LeLabelOverlap OverlapStrategy+ -- ^ How to resolve overlap of labels in gradient legends.+ --+ -- @since 0.4.0.0+ | LeLabelPadding Double+ -- ^ The passing in pixels between the legend and legend labels.+ --+ -- @since 0.4.0.0+ | LeLabelSeparation Double+ -- ^ The minimum separation between label bounding boxes for them+ -- to be considered non-overlapping (ignored if 'ONone' is the+ -- chosen overlap strategy).+ --+ -- @since 0.4.0.0+ | LeLayout [LegendLayout]+ -- ^ Layout parameters for the legend orient group.+ --+ -- @since 0.4.0.0+ | LeLeX Double+ -- ^ Custom x position for a legend with orientation 'LONone'.+ --+ -- @since 0.4.0.0+ | LeLeY Double+ -- ^ Custom y position for a legend with orientation 'LONone'.+ --+ -- @since 0.4.0.0+ | LeOffset Double+ -- ^ The offset in pixels between the legend and the data rectangle+ -- and axes.+ | LeOrient LegendOrientation+ -- ^ The orientation of the legend.+ | LePadding Double+ -- ^ The padding between the border and content of the legend group.+ | LeRowPadding Double+ -- ^ The vertical padding in pixels between symbol legend entries.+ --+ -- @since 0.4.0.0+ | LeShortTimeLabels Bool+ -- ^ Should month and weekday names be abbreviated?+ | LeStrokeColor Color+ -- ^ The border stoke color for the full legend.+ | LeStrokeDash [Double]+ -- ^ The border stroke dash pattern for the full legend (alternating+ -- stroke, space lengths in pixels).+ | LeStrokeWidth Double+ -- ^ The border stroke width for the full legend.+ | LeSymbolBaseFillColor Color+ -- ^ The fill color for legend symbols. This is only applied if+ -- there is no \"fill\" scale color encoding for the legend.+ --+ -- @since 0.4.0.0+ | LeSymbolBaseStrokeColor Color+ -- ^ The stroke color for legend symbols. This is only applied if+ -- there is no \"fill\" scale color encoding for the legend.+ --+ -- @since 0.4.0.0+ | LeSymbolDash [Double]+ -- ^ The pattern for dashed symbol strokes (alternating+ -- stroke, space lengths in pixels).+ --+ -- @since 0.4.0.0+ | LeSymbolDashOffset Double+ -- ^ The offset at which to start deawing the symbol dash pattern,+ -- in pixels.+ --+ -- @since 0.4.0.0+ | LeSymbolDirection Orientation+ -- ^ The default direction for symbol legends.+ --+ -- @since 0.4.0.0+ | LeSymbolFillColor Color+ -- ^ The color of the legend symbol.+ --+ -- @since 0.4.0.0+ | LeSymbolOffset Double+ -- ^ The horizontal pixel offset for legend symbols.+ --+ -- @since 0.4.0.0+ | LeSymbolOpacity Opacity+ -- ^ The opacity of the legend symbols.+ --+ -- @since 0.4.0.0+ | LeSymbolSize Double+ -- ^ The size of the legend symbol, in pixels.+ | LeSymbolStrokeColor Color+ -- ^ The stroke color for legend symbols.+ --+ -- @since 0.4.0.0+ | LeSymbolStrokeWidth Double+ -- ^ The width of the symbol's stroke.+ | LeSymbolType Symbol+ -- ^ The default shape type for legend symbols.+ | LeTitle T.Text+ -- ^ The legend title.+ --+ -- @since 0.4.0.0+ | LeNoTitle+ -- ^ Draw no title for the legend.+ --+ -- @since 0.4.0.0+ | LeTitleAlign HAlign+ -- ^ The horizontal text alignment for legend titles.+ | LeTitleAnchor APosition+ -- ^ The text anchor position for legend titles.+ --+ -- @since 0.4.0.0+ | LeTitleBaseline VAlign+ -- ^ The vertical text alignment for legend titles.+ | LeTitleColor Color+ -- ^ The color of the legend title.+ | LeTitleFont T.Text+ -- ^ The font of the legend title.+ | LeTitleFontSize Double+ -- ^ The font size of the legend title.+ | LeTitleFontStyle T.Text+ -- ^ The font style for the legend title.+ --+ -- @since 0.4.0.0+ | LeTitleFontWeight FontWeight+ -- ^ The font weight of the legend title.+ | LeTitleLimit Double+ -- ^ The maxmimum pixel width of the legend title.+ | LeTitleOpacity Opacity+ -- ^ The opacity of the legend title.+ --+ -- @since 0.4.0.0+ | LeTitleOrient Side+ -- ^ The orientation of the legend title.+ --+ -- @since 0.4.0.0+ | LeTitlePadding Double+ -- ^ The padding, in pixels, between title and legend.+++legendConfigProperty :: LegendConfig -> LabelledSpec+legendConfigProperty (LeClipHeight x) = "clipHeight" .= x+legendConfigProperty (LeColumnPadding x) = "columnPadding" .= x+legendConfigProperty (LeColumns n) = "columns" .= n+legendConfigProperty (LeCornerRadius x) = "cornerRadius" .= x+legendConfigProperty (LeFillColor s) = "fillColor" .= s+legendConfigProperty (LeGradientDirection o) = "gradientDirection" .= orientationSpec o+legendConfigProperty (LeGradientHorizontalMaxLength x) = "gradientHorizontalMaxLength" .= x+legendConfigProperty (LeGradientHorizontalMinLength x) = "gradientHorizontalMinLength" .= x+legendConfigProperty (LeGradientLabelLimit x) = "gradientLabelLimit" .= x+legendConfigProperty (LeGradientLabelOffset x) = "gradientLabelOffset" .= x+legendConfigProperty (LeGradientLength x) = "gradientLength" .= x+legendConfigProperty (LeGradientOpacity x) = "gradientOpacity" .= x+legendConfigProperty (LeGradientStrokeColor s) = "gradientStrokeColor" .= s+legendConfigProperty (LeGradientStrokeWidth x) = "gradientStrokeWidth" .= x+legendConfigProperty (LeGradientThickness x) = "gradientThickness" .= x+legendConfigProperty (LeGradientVerticalMaxLength x) = "gradientVerticalMaxLength" .= x+legendConfigProperty (LeGradientVerticalMinLength x) = "gradientVerticalMinLength" .= x+legendConfigProperty (LeGridAlign ga) = "gridAlign" .= compositionAlignmentSpec ga+legendConfigProperty (LeLabelAlign ha) = "labelAlign" .= hAlignLabel ha+legendConfigProperty (LeLabelBaseline va) = "labelBaseline" .= vAlignLabel va+legendConfigProperty (LeLabelColor s) = "labelColor" .= s+legendConfigProperty (LeLabelFont s) = "labelFont" .= s+legendConfigProperty (LeLabelFontSize x) = "labelFontSize" .= x+legendConfigProperty (LeLabelFontStyle s) = "labelFontStyle" .= s+legendConfigProperty (LeLabelFontWeight fw) = "labelFontWeight" .= fontWeightSpec fw+legendConfigProperty (LeLabelLimit x) = "labelLimit" .= x+legendConfigProperty (LeLabelOffset x) = "labelOffset" .= x+legendConfigProperty (LeLabelOpacity x) = "labelOapcity" .= x+legendConfigProperty (LeLabelOverlap olap) = "labelOverlap" .= overlapStrategyLabel olap+legendConfigProperty (LeLabelPadding x) = "labelPadding" .= x+legendConfigProperty (LeLabelSeparation x) = "labelSeparation" .= x+legendConfigProperty (LeLayout ll) = "layout" .= object (map legendLayoutSpec ll)+legendConfigProperty (LeLeX x) = "legendX" .= x+legendConfigProperty (LeLeY x) = "legendY" .= x+legendConfigProperty (LeOffset x) = "offset" .= x+legendConfigProperty (LeOrient orl) = "orient" .= legendOrientLabel orl+legendConfigProperty (LePadding x) = "padding" .= x+legendConfigProperty (LeRowPadding x) = "rowPadding" .= x+legendConfigProperty (LeShortTimeLabels b) = "shortTimeLabels" .= b+legendConfigProperty (LeStrokeColor s) = "strokeColor" .= s+legendConfigProperty (LeStrokeDash xs) = "strokeDash" .= xs+legendConfigProperty (LeStrokeWidth x) = "strokeWidth" .= x+legendConfigProperty (LeSymbolBaseFillColor s) = "symbolBaseFillColor" .= s+legendConfigProperty (LeSymbolBaseStrokeColor s) = "symbolBaseStrokeColor" .= s+legendConfigProperty (LeSymbolDash xs) = "symbolDash" .= xs+legendConfigProperty (LeSymbolDashOffset x) = "symbolDashOffset" .= x+legendConfigProperty (LeSymbolDirection o) = "symbolDirection" .= orientationSpec o+legendConfigProperty (LeSymbolFillColor s) = "symbolFillColor" .= s+legendConfigProperty (LeSymbolOffset x) = "symbolOffset" .= x+legendConfigProperty (LeSymbolOpacity x) = "symbolOpacity" .= x+legendConfigProperty (LeSymbolSize x) = "symbolSize" .= x+legendConfigProperty (LeSymbolStrokeColor s) = "symbolStrokeColor" .= s+legendConfigProperty (LeSymbolStrokeWidth x) = "symbolStrokeWidth" .= x+legendConfigProperty (LeSymbolType s) = "symbolType" .= symbolLabel s+legendConfigProperty (LeTitle s) = "title" .= s+legendConfigProperty LeNoTitle = "title" .= A.Null+legendConfigProperty (LeTitleAlign ha) = "titleAlign" .= hAlignLabel ha+legendConfigProperty (LeTitleAnchor anc) = "titleAnchor" .= anchorLabel anc+legendConfigProperty (LeTitleBaseline va) = "titleBaseline" .= vAlignLabel va+legendConfigProperty (LeTitleColor s) = "titleColor" .= s+legendConfigProperty (LeTitleFont s) = "titleFont" .= s+legendConfigProperty (LeTitleFontSize x) = "titleFontSize" .= x+legendConfigProperty (LeTitleFontStyle s) = "titleFontStyle" .= s+legendConfigProperty (LeTitleFontWeight fw) = "titleFontWeight" .= fontWeightSpec fw+legendConfigProperty (LeTitleLimit x) = "titleLimit" .= x+legendConfigProperty (LeTitleOpacity x) = "titleOpacity" .= x+legendConfigProperty (LeTitleOrient orient) = "titleOrient" .= sideLabel orient+legendConfigProperty (LeTitlePadding x) = "titlePadding" .= x+++{-|++Indicates the legend orientation. See the+<https://vega.github.io/vega-lite/docs/legend.html#config Vega-Lite documentation>+for more details.++-}++-- based on schema 3.3.0 #/definitions/LegendOrient++data LegendOrientation+ = LONone+ | LOLeft+ | LORight+ | LOTop+ -- ^ @since 0.4.0.0+ | LOBottom+ -- ^ @since 0.4.0.0+ | LOTopLeft+ | LOTopRight+ | LOBottomLeft+ | LOBottomRight+++legendOrientLabel :: LegendOrientation -> T.Text+legendOrientLabel LONone = "none"+legendOrientLabel LOLeft = "left"+legendOrientLabel LORight = "right"+legendOrientLabel LOTop = "top"+legendOrientLabel LOBottom = "bottom"+legendOrientLabel LOTopLeft = "top-left"+legendOrientLabel LOTopRight = "top-right"+legendOrientLabel LOBottomLeft = "bottom-left"+legendOrientLabel LOBottomRight = "bottom-right"+++{- |++/Highly experimental/ and used with 'LeLayout'.++@since 0.4.0.0++-}++-- based on schema 3.3.0 #/definitions/LegendLayout++-- TODO: support SignalRef?++data LegendLayout+ = LeLAnchor APosition+ -- ^ The anchor point for legend orient group layout.+ | LeLBottom [BaseLegendLayout]+ | LeLBottomLeft [BaseLegendLayout]+ | LeLBottomRight [BaseLegendLayout]+ | LeLBounds Bounds+ -- ^ The bounds calculation to use for legend orient group layout.+ | LeLCenter Bool+ -- ^ A flag to center legends within a shared orient group.+ | LeLDirection Orientation+ -- ^ The layout firection for legend orient group layout.+ | LeLLeft [BaseLegendLayout]+ | LeLMargin Double+ -- ^ The margin, in pixels, between legends within an orient group.+ | LeLOffset Double+ -- ^ The offset, in pixels, from the chart body for a legend orient group.+ | LeLRight [BaseLegendLayout]+ | LeLTop [BaseLegendLayout]+ | LeLTopLeft [BaseLegendLayout]+ | LeLTopRight [BaseLegendLayout]+++legendLayoutSpec :: LegendLayout -> LabelledSpec+legendLayoutSpec (LeLAnchor anc) = "anchor" .= anchorLabel anc+legendLayoutSpec (LeLBottom bl) = "bottom" .= toBLSpec bl+legendLayoutSpec (LeLBottomLeft bl) = "bottom-left" .= toBLSpec bl+legendLayoutSpec (LeLBottomRight bl) = "bottom-right" .= toBLSpec bl+legendLayoutSpec (LeLBounds bnds) = "bounds" .= boundsSpec bnds+legendLayoutSpec (LeLCenter b) = "center" .= b+legendLayoutSpec (LeLDirection o) = "direction" .= orientationSpec o+legendLayoutSpec (LeLLeft bl) = "left" .= toBLSpec bl+legendLayoutSpec (LeLMargin x) = "margin" .= x+legendLayoutSpec (LeLOffset x) = "offset" .= x+legendLayoutSpec (LeLRight bl) = "right" .= toBLSpec bl+legendLayoutSpec (LeLTop bl) = "top" .= toBLSpec bl+legendLayoutSpec (LeLTopLeft bl) = "top-left" .= toBLSpec bl+legendLayoutSpec (LeLTopRight bl) = "top-right" .= toBLSpec bl+++toBLSpec :: [BaseLegendLayout] -> VLSpec+toBLSpec = object . map baseLegendLayoutSpec++{- |++/Highly experimental/ and used with constructors from 'LegendLayout'.++@since 0.4.0.0++-}++-- based on schema 3.3.0 #/definitions/BaseLegendLayout++data BaseLegendLayout+ = BLeLAnchor APosition+ -- ^ The anchor point for legend orient group layout.+ | BLeLBounds Bounds+ -- ^ The bounds calculation to use for legend orient group layout.+ | BLeLCenter Bool+ -- ^ A flag to center legends within a shared orient group.+ | BLeLDirection Orientation+ -- ^ The layout direction for legend orient group layout.+ | BLeLMargin Double+ -- ^ The margin, in pixels, between legends within an orient group.+ | BLeLOffset Double+ -- ^ The offset, in pixels, from the chart body for a legend orient group.+++baseLegendLayoutSpec :: BaseLegendLayout -> LabelledSpec+baseLegendLayoutSpec (BLeLAnchor anc) = "anchor" .= anchorLabel anc+baseLegendLayoutSpec (BLeLBounds bnds) = "bounds" .= boundsSpec bnds+baseLegendLayoutSpec (BLeLCenter b) = "center" .= b+baseLegendLayoutSpec (BLeLDirection o) = "direction" .= orientationSpec o+baseLegendLayoutSpec (BLeLMargin x) = "margin" .= x+baseLegendLayoutSpec (BLeLOffset x) = "offset" .= x+++{-|++Legend properties, set with 'MLegend'. For more detail see the+<https://vega.github.io/vega-lite/docs/legend.html#legend-properties Vega-Lite documentation>.++The @LEntryPadding@ constructor was removed in @0.4.0.0@.++-}++data LegendProperty+ = LClipHeight Double+ -- ^ The height, in pixels, to clip symbol legend entries.+ --+ -- @since 0.4.0.0+ | LColumnPadding Double+ -- ^ The horizontal padding, in pixels, between symbol legend entries.+ --+ -- @since 0.4.0.0+ | LColumns Int+ -- ^ The number of columns in which to arrange symbol legend entries.+ -- A value of @0@ or lower indicates a single row with one column per entry.+ --+ -- @since 0.4.0.0+ | LCornerRadius Double+ -- ^ The corner radius for the full legend.+ --+ -- @since 0.4.0.0+ | LDirection Orientation+ -- ^ The direction of the legend.+ --+ -- @since 0.4.0.0+ | LFillColor Color+ -- ^ The background fill color for the full legend.+ --+ -- @since 0.4.0.0+ | LFormat T.Text+ -- ^ [Formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for+ -- legend values. To distinguish between formatting as numeric values+ -- and data/time values, additionally use 'LFormatAsNum' or 'LFormatAsTemporal'.+ | LFormatAsNum+ -- ^ Legends should be formatted as numbers. Use a+ -- [d3 numeric format string](https://github.com/d3/d3-format#locale_format)+ -- with 'LFormat'.+ --+ -- @since 0.4.0.0+ | LFormatAsTemporal+ -- ^ Legends should be formatted as dates or times. Use a+ -- [d3 date/time format string](https://github.com/d3/d3-time-format#locale_format)+ -- with 'LFormat'.+ --+ -- @since 0.4.0.0+ | LGradientLength Double+ -- ^ The length in pixels of the primary axis of the color gradient.+ --+ -- @since 0.4.0.0+ | LGradientOpacity Opacity+ -- ^ The opacity of the color gradient.+ --+ -- @since 0.4.0.0+ | LGradientStrokeColor Color+ -- ^ The color of the gradient stroke.+ --+ -- @since 0.4.0.0+ | LGradientStrokeWidth Double+ -- ^ The width, in pixels, of the gradient stroke.+ --+ -- @since 0.4.0.0+ | LGradientThickness Double+ -- ^ The thickness, in pixels, of the color gradient.+ --+ -- @since 0.4.0.0+ | LGridAlign CompositionAlignment+ -- ^ The [grid layout](https://vega.github.io/vega/docs/layout) for+ -- the symbol legends.+ --+ -- @since 0.4.0.0+ | LLabelAlign HAlign+ -- ^ @since 0.4.0.0+ | LLabelBaseline VAlign+ -- ^ @since 0.4.0.0+ | LLabelColor Color+ -- ^ @since 0.4.0.0+ | LLabelFont T.Text+ -- ^ @since 0.4.0.0+ | LLabelFontSize Double+ -- ^ @since 0.4.0.0+ | LLabelFontStyle T.Text+ -- ^ @since 0.4.0.0+ | LLabelFontWeight FontWeight+ -- ^ @since 0.4.0.0+ | LLabelLimit Double+ -- ^ @since 0.4.0.0+ | LLabelOffset Double+ -- ^ @since 0.4.0.0+ | LLabelOpacity Opacity+ -- ^ @since 0.4.0.0+ | LLabelOverlap OverlapStrategy+ -- ^ @since 0.4.0.0+ | LLabelPadding Double+ -- ^ @since 0.4.0.0+ | LLabelSeparation Double+ -- ^ @since 0.4.0.0+ | LOffset Double+ -- ^ The offset in pixels by which to displace the legend from+ -- the data rectangle and axes.+ | LOrient LegendOrientation+ -- ^ The legend orientation.+ | LPadding Double+ -- ^ The padding, in pixels, between the border and content of+ -- the legend group.+ | LRowPadding Double+ -- ^ The vertical padding, in pixels, between symbol legend entries.+ --+ -- @since 0.4.0.0+ | LStrokeColor Color+ -- ^ The border stroke color for the full legend.+ --+ -- @since 0.4.0.0+ | LSymbolDash [Double]+ -- ^ The dash style for symbols (alternating stroke, space lengths+ -- in pixels).+ --+ -- @since 0.4.0.0+ | LSymbolDashOffset Double+ -- ^ The pixel offset at which to start drawing the symbol dash array.+ --+ -- @since 0.4.0.0+ | LSymbolFillColor Color+ -- ^ The fill color of the legend symbol.+ --+ -- @since 0.4.0.0+ | LSymbolOffset Double+ -- ^ The horizontal pixel offset for legend symbols.+ --+ -- @since 0.4.0.0+ | LSymbolOpacity Opacity+ -- ^ The opacity of the legend symbols.+ --+ -- @since 0.4.0.0+ | LSymbolSize Double+ -- ^ The size of the legend symbol, in pixels.+ --+ -- @since 0.4.0.0+ | LSymbolStrokeColor Color+ -- ^ The edge color of the legend symbol.+ --+ -- @since 0.4.0.0+ | LSymbolStrokeWidth Double+ -- ^ The width of the sumbol's stroke.+ --+ -- @since 0.4.0.0+ | LSymbolType Symbol+ -- ^ @since 0.4.0.0+ | LTickCount Double+ -- ^ The desired number of tick values for quantitative legends.+ | LTickMinStep Double+ -- ^ The minimum desired step between legend ticks, in terms of the scale+ -- domain values.+ --+ -- @since 0.4.0.0+ | LTitle T.Text+ | LNoTitle+ -- ^ Draw no title.+ --+ -- @since 0.4.0.0+ | LTitleAlign HAlign+ -- ^ @since 0.4.0.0+ | LTitleAnchor APosition+ -- ^ @since 0.4.0.0+ | LTitleBaseline VAlign+ -- ^ @since 0.4.0.0+ | LTitleColor Color+ -- ^ @since 0.4.0.0+ | LTitleFont T.Text+ -- ^ @since 0.4.0.0+ | LTitleFontSize Double+ -- ^ @since 0.4.0.0+ | LTitleFontStyle T.Text+ -- ^ @since 0.4.0.0+ | LTitleFontWeight FontWeight+ -- ^ @since 0.4.0.0+ | LTitleLimit Double+ -- ^ The maximum allowed pixel width of the legend title.+ --+ -- @since 0.4.0.0+ | LTitleOpacity Opacity+ -- ^ Opacity of the legend title.+ --+ -- @since 0.4.0.0+ | LTitleOrient Side+ -- ^ Orientation of the legend title.+ --+ -- @since 0.4.0.0+ | LTitlePadding Double+ -- ^ The padding, in pixels, between title and legend.+ --+ -- @since 0.4.0.0+ | LType LegendType+ -- ^ The type of the legend.+ | LValues LegendValues+ -- ^ Explicitly set the visible legend values.+ | LeX Double+ -- ^ Custom x position, in pixels, for the legend when 'LOrient' is set to 'LONone'.+ --+ -- @since 0.4.0.0+ | LeY Double+ -- ^ Custom y position, in pixels, for the legend when 'LOrient' is set to 'LONone'.+ --+ -- @since 0.4.0.0+ | LZIndex ZIndex+ -- ^ The z-index at which to draw the legend.++legendProperty :: LegendProperty -> LabelledSpec+legendProperty (LClipHeight x) = "clipHeight" .= x+legendProperty (LColumnPadding x) = "columnPadding" .= x+legendProperty (LColumns n) = "columns" .= n+legendProperty (LCornerRadius x) = "cornerRadius" .= x+legendProperty (LDirection o) = "direction" .= orientationSpec o+legendProperty (LFillColor s) = "fillColor" .= s+legendProperty (LFormat s) = "format" .= s+legendProperty LFormatAsNum = "formatType" .= fromT "number"+legendProperty LFormatAsTemporal = "formatType" .= fromT "time"+legendProperty (LGradientLength x) = "gradientLength" .= x+legendProperty (LGradientOpacity x) = "gradientOpacity" .= x+legendProperty (LGradientStrokeColor s) = "gradientStrokeColor" .= s+legendProperty (LGradientStrokeWidth x) = "gradientStrokeWidth" .= x+legendProperty (LGradientThickness x) = "gradientThickness" .= x+legendProperty (LGridAlign ga) = "gridAlign" .= compositionAlignmentSpec ga+legendProperty (LLabelAlign ha) = "labelAlign" .= hAlignLabel ha+legendProperty (LLabelBaseline va) = "labelBaseline" .= vAlignLabel va+legendProperty (LLabelColor s) = "labelColor" .= s+legendProperty (LLabelFont s) = "labelFont" .= s+legendProperty (LLabelFontSize x) = "labelFontSize" .= x+legendProperty (LLabelFontStyle s) = "labelFontStyle" .= s+legendProperty (LLabelFontWeight fw) = "labelFontWeight" .= fontWeightSpec fw+legendProperty (LLabelLimit x) = "labelLimit" .= x+legendProperty (LLabelOffset x) = "labelOffset" .= x+legendProperty (LLabelOpacity x) = "labelOpacity" .= x+legendProperty (LLabelOverlap strat) = "labelOverlap" .= overlapStrategyLabel strat+legendProperty (LLabelPadding x) = "labelPadding" .= x+legendProperty (LLabelSeparation x) = "labelSeparation" .= x+legendProperty (LOffset x) = "offset" .= x+legendProperty (LOrient orl) = "orient" .= legendOrientLabel orl+legendProperty (LPadding x) = "padding" .= x+legendProperty (LRowPadding x) = "rowPadding" .= x+legendProperty (LStrokeColor s) = "strokeColor" .= s++legendProperty (LSymbolDash ds) = "symbolDash" .= ds+legendProperty (LSymbolDashOffset x) = "symbolDashOffset" .= x+legendProperty (LSymbolFillColor s) = "symbolFillColor" .= s+legendProperty (LSymbolOffset x) = "symbolOffset" .= x+legendProperty (LSymbolOpacity x) = "symbolOpacity" .= x+legendProperty (LSymbolSize x) = "symbolSize" .= x+legendProperty (LSymbolStrokeColor s) = "symbolStrokeColor" .= s+legendProperty (LSymbolStrokeWidth x) = "symbolStrikeWidth" .= x+legendProperty (LSymbolType sym) = "symbolType" .= symbolLabel sym+legendProperty (LTickCount x) = "tickCount" .= x+legendProperty (LTickMinStep x) = "tickMinStep" .= x+legendProperty (LTitle s) = "title" .= s+legendProperty LNoTitle = "title" .= A.Null+legendProperty (LTitleAlign ha) = "titleAlign" .= hAlignLabel ha+legendProperty (LTitleAnchor anc) = "titleAnchor" .= anchorLabel anc+legendProperty (LTitleBaseline va) = "titleBaseline" .= vAlignLabel va+legendProperty (LTitleColor s) = "titleColor" .= s+legendProperty (LTitleFont s) = "titleFont" .= s+legendProperty (LTitleFontSize x) = "titleFontSize" .= x+legendProperty (LTitleFontStyle s) = "titleFontStyle" .= s+legendProperty (LTitleFontWeight fw) = "titleFontWeight" .= fontWeightSpec fw+legendProperty (LTitleLimit x) = "titleLimit" .= x+legendProperty (LTitleOpacity x) = "titleOpacity" .= x+legendProperty (LTitleOrient orient) = "titleOrient" .= sideLabel orient+legendProperty (LTitlePadding x) = "titlePadding" .= x+legendProperty (LType lType) = "type" .= legendLabel lType+legendProperty (LValues vals) =+ let ls = case vals of+ LNumbers xs -> map toJSON xs+ LDateTimes dts -> map (object . map dateTimeProperty) dts+ LStrings ss -> map toJSON ss+ in "values" .= ls+legendProperty (LeX x) = "legendX" .= x+legendProperty (LeY x) = "legendY" .= x+legendProperty (LZIndex z) = "zindex" .= z+++-- | A list of data values suitable for setting legend values, used with+-- 'LValues'.+++data LegendValues+ = LDateTimes [[DateTime]]+ | LNumbers [Double]+ | LStrings [T.Text]+++-- | Specify the padding dimensions in pixel units.++data Padding+ = PSize Double+ -- ^ Use the same padding on all four edges of the container.+ | PEdges Double Double Double Double+ -- ^ Specify the padding for the left, top, right, and bottom edges.+++paddingSpec :: Padding -> VLSpec+paddingSpec (PSize p) = toJSON p+paddingSpec (PEdges l t r b) =+ object [ "left" .= l+ , "top" .= t+ , "right" .= r+ , "bottom" .= b+ ]+++-- | The properties of a point marker on a line or area mark.+-- For use with 'MPoint'.+--+-- @since 0.4.0.0++data PointMarker+ = PMTransparent+ -- ^ A transparent marker is used, which can be useful for+ -- interactive selections.+ | PMNone+ -- ^ No marker to be shown.+ | PMMarker [MarkProperty]+ -- ^ The properties of the marks to be shown at the points.+ --+ -- Use an empty list to use a filled point with default properties.++-- An empty object has the same meaning as true, so there is no real need to+-- treat 'PMMarker []' specially, but I don't think it complicates things+-- here.+--+pointMarkerSpec :: PointMarker -> VLSpec+pointMarkerSpec PMTransparent = "transparent"+pointMarkerSpec PMNone = toJSON False+pointMarkerSpec (PMMarker []) = toJSON True+pointMarkerSpec (PMMarker mps) = object (map markProperty mps)+++{-|++Types of geographic map projection. These are based on a subset of those provided+by the <https://github.com/d3/d3-geo d3-geo library>. For details of available+projections see the+<https://vega.github.io/vega-lite/docs/projection.html#projection-types Vega-Lite documentation>.+-}++-- based on schema 3.3.0 #/definitions/ProjectionType++data Projection+ = Albers+ -- ^ An Albers equal-area conic map projection.+ | AlbersUsa+ -- ^ An Albers USA map projection that combines continental USA with+ -- Alaska and Hawaii. Unlike other projection types, this remains+ -- unaffected by 'PrRotate'.+ | AzimuthalEqualArea+ -- ^ An azimuthal equal area map projection.+ | AzimuthalEquidistant+ -- ^ An azimuthal equidistant map projection.+ | ConicConformal+ -- ^ A conformal conic map projection.+ | ConicEqualArea+ -- ^ An equal area conic map projection.+ | ConicEquidistant+ -- ^ An equidistant conic map projection.+ | Custom T.Text+ -- ^ Specify the name of the custom D3 prohection to use. See the+ -- <https://vega.github.io/vega/docs/projections/#register Vega API>+ -- for more information.+ --+ -- An example: @Custom "winkle3"@+ | Equirectangular+ -- ^ An equirectangular map projection that maps longitude to x and latitude to y.+ -- While showing less area distortion towards the poles than the default 'Mercator'+ -- projection, it is neither equal-area nor conformal.+ | Gnomonic+ -- ^ A gnomonic map projection.+ | Identity+ -- ^ The identiy projection. This can be combined with 'PrReflectX' and+ -- 'PrReflectY' in the list of projection properties.+ --+ -- @since 0.4.0.0+ | Mercator+ -- ^ A Mercator map projection. This is the default projection of longitude, latitude+ -- values if no projection is set explicitly. It preserves shape (local angle) and+ -- lines of equal angular bearing remain parallel straight lines. The area is+ -- /significantly/ enlarged towards the poles.+ | Orthographic+ -- ^ An orthographic map projection.+ | Stereographic+ -- ^ A stereographic map projection.+ | TransverseMercator+ -- ^ A transverse Mercator map projection.+++projectionLabel :: Projection -> T.Text+projectionLabel Albers = "albers"+projectionLabel AlbersUsa = "albersUsa"+projectionLabel AzimuthalEqualArea = "azimuthalEqualArea"+projectionLabel AzimuthalEquidistant = "azimuthalEquidistant"+projectionLabel ConicConformal = "conicConformal"+projectionLabel ConicEqualArea = "conicEqualarea"+projectionLabel ConicEquidistant = "conicEquidistant"+projectionLabel (Custom pName) = pName+projectionLabel Equirectangular = "equirectangular"+projectionLabel Gnomonic = "gnomonic"+projectionLabel Identity = "identity"+projectionLabel Mercator = "mercator"+projectionLabel Orthographic = "orthographic"+projectionLabel Stereographic = "stereographic"+projectionLabel TransverseMercator = "transverseMercator"+++-- | Specifies a clipping rectangle for defining+-- the clip extent of a map projection.++data ClipRect+ = NoClip+ -- ^ No clipping it to be applied.+ | LTRB Double Double Double Double+ -- ^ The left, top, right, and bottom extents, in pixels,+ -- of a rectangular clip.+++-- | Specifies the alignment of compositions. It is used with:+-- 'align', 'alignRC', 'LeGridAlign', and 'LGridAlign'.+--+-- @since 0.4.0.0++data CompositionAlignment+ = CANone+ -- ^ Flow layout is used, where adjacent subviews are placed one after+ -- another.+ | CAEach+ -- ^ Each row and column may be of a variable size.+ | CAAll+ -- ^ All the rows and columns are of the same size (this is based on the+ -- maximum subview size).+++compositionAlignmentSpec :: CompositionAlignment -> VLSpec+compositionAlignmentSpec CANone = "none"+compositionAlignmentSpec CAEach = "each"+compositionAlignmentSpec CAAll = "all"+++{-|++Properties for customising a geospatial projection that converts longitude,latitude+pairs into planar @(x,y)@ coordinate pairs for rendering and query. For details see the+<https://vega.github.io/vega-lite/docs/projection.html Vega-Lite documentation>.++This type has been changed in the @0.4.0.0@ release so that all constructors+start with @Pr@ rather than @P@ (and so provide some differentiation to the+'PositionChannel' constructors).++-}++-- based on schema 3.3.0 #/definitions/Projection++data ProjectionProperty+ = PrType Projection+ -- ^ The type of the map projection.+ | PrClipAngle (Maybe Double)+ -- ^ The clipping circle angle in degrees. A value of @Nothing@ will switch to+ -- antimeridian cutting rather than small-circle clipping.+ | PrClipExtent ClipRect+ -- ^ Projection’s viewport clip extent to the specified bounds in pixels.+ | PrCenter Double Double+ -- ^ Projection’s center as longitude and latitude in degrees.+ | PrScale Double+ -- ^ The projection's zoom scale, which if set, overrides automatic scaling of a+ -- geo feature to fit within the viewing area.+ --+ -- @since 0.4.0.0+ | PrTranslate Double Double+ -- ^ A projection’s panning translation, which if set, overrides automatic positioning+ -- of a geo feature to fit within the viewing area+ --+ -- Note that the prefix is @Pr@ and not @P@, to match the Elm API.+ --+ -- @since 0.4.0.0+ | PrRotate Double Double Double+ -- ^ A projection’s three-axis rotation angle. The order is @lambda@ @phi@ @gamma@,+ -- and specifies the rotation angles in degrees about each spherical axis.+ | PrPrecision Double+ -- ^ Threshold for the projection’s adaptive resampling in pixels, and corresponds to the+ -- Douglas–Peucker distance. If precision is not specified, the projection’s current+ -- resampling precision of 0.707 is used.+ --+ -- Version 3.3.0 of the Vega-Lite spec claims this should be output as a string,+ -- but it is written out as a number since the+ -- [spec is in error](https://github.com/vega/vega-lite/issues/5190).+ | PrReflectX Bool+ -- ^ Reflect the x-coordinates after performing an identity projection. This+ -- creates a left-right mirror image of the geoshape marks when subject to an+ -- identity projection with 'Identity'.+ --+ -- @since 0.4.0.0+ | PrReflectY Bool+ -- ^ Reflect the y-coordinates after performing an identity projection. This+ -- creates a left-right mirror image of the geoshape marks when subject to an+ -- identity projection with 'Identity'.+ --+ -- @since 0.4.0.0+ | PrCoefficient Double+ -- ^ The @Hammer@ map projection coefficient.+ | PrDistance Double+ -- ^ The @Satellite@ map projection distance.+ | PrFraction Double+ -- ^ The @Bottomley@ map projection fraction.+ | PrLobes Int+ -- ^ Number of lobes in lobed map projections such as the @Berghaus star@.+ | PrParallel Double+ -- ^ Parallel for map projections such as the @Armadillo@.+ | PrRadius Double+ -- ^ Radius value for map projections such as the @Gingery@.+ | PrRatio Double+ -- ^ Ratio value for map projections such as the @Hill@.+ | PrSpacing Double+ -- ^ Spacing value for map projections such as the @Lagrange@.+ | PrTilt Double+ -- ^ @Satellite@ map projection tilt.+++projectionProperty :: ProjectionProperty -> LabelledSpec+projectionProperty (PrType proj) = "type" .= projectionLabel proj+projectionProperty (PrClipAngle numOrNull) = "clipAngle" .= maybe A.Null toJSON numOrNull+projectionProperty (PrClipExtent rClip) =+ ("clipExtent", case rClip of+ NoClip -> A.Null+ LTRB l t r b -> toJSON (map toJSON [l, t, r, b])+ )+projectionProperty (PrCenter lon lat) = "center" .= [lon, lat]+projectionProperty (PrScale sc) = "scale" .= sc+projectionProperty (PrTranslate tx ty) = "translate" .= [tx, ty]+projectionProperty (PrRotate lambda phi gamma) = "rotate" .= [lambda, phi, gamma]+projectionProperty (PrPrecision pr) = "precision" .= pr -- the 3.3.0 spec says this is a string, but that's wrong, See https://github.com/vega/vega-lite/issues/5190+projectionProperty (PrReflectX b) = "reflectX" .= b+projectionProperty (PrReflectY b) = "reflectY" .= b+projectionProperty (PrCoefficient x) = "coefficient" .= x+projectionProperty (PrDistance x) = "distance" .= x+projectionProperty (PrFraction x) = "fraction" .= x+projectionProperty (PrLobes n) = "lobes" .= n+projectionProperty (PrParallel x) = "parallel" .= x+projectionProperty (PrRadius x) = "radius" .= x+projectionProperty (PrRatio x) = "ratio" .= x+projectionProperty (PrSpacing x) = "spacing" .= x+projectionProperty (PrTilt x) = "tilt" .= x+++{-|++Sets the cartographic projection used for geospatial coordinates. A projection+defines the mapping from @(longitude,latitude)@ to an @(x,y)@ plane used for rendering.+This is useful when using the 'Geoshape' mark. For further details see the+<https://vega.github.io/vega-lite/docs/projection.html Vega-Lite documentation>.++@+'projection' [ 'PrType' 'Orthographic', 'PrRotate' (-40) 0 0 ]+@+-}+projection :: [ProjectionProperty] -> PropertySpec+projection pProps = (VLProjection, object (map projectionProperty pProps))+++{-|++Properties for customising the colors of a range. The parameter should be a+named color scheme such as @\"accent\"@ or @\"purpleorange-11\"@. For details see the+<https://vega.github.io/vega/docs/schemes/#scheme-properties Vega-Lite documentation>.+-}+data RangeConfig+ = RCategory T.Text+ | RDiverging T.Text+ | RHeatmap T.Text+ | ROrdinal T.Text+ | RRamp T.Text+ | RSymbol T.Text+++rangeConfigProperty :: RangeConfig -> LabelledSpec+rangeConfigProperty rangeCfg =+ let (l, n) = case rangeCfg of+ RCategory nme -> ("category", nme)+ RDiverging nme -> ("diverging", nme)+ RHeatmap nme -> ("heatmap", nme)+ ROrdinal nme -> ("ordinal", nme)+ RRamp nme -> ("ramp", nme)+ RSymbol nme -> ("symbol", nme)++ in l .= object [schemeProperty n []]+++{-|++Scale configuration property. These are used to configure all scales.+For more details see the+<https://vega.github.io/vega-lite/docs/scale.html#scale-config Vega-Lite documentation>.++-}++data ScaleConfig+ = SCBandPaddingInner Double+ -- ^ Default inner padding for x and y band-ordinal scales.+ | SCBandPaddingOuter Double+ -- ^ Default outer padding for x and y band-ordinal scales.+ | SCBarBandPaddingInner Double+ -- ^ Default inner padding for x and y band-ordinal scales of 'Bar' marks.+ --+ -- @since 0.4.0.0+ | SCBarBandPaddingOuter Double+ -- ^ Default outer padding for x and y band-ordinal scales of 'Bar' marks.+ --+ -- @since 0.4.0.0+ | SCRectBandPaddingInner Double+ -- ^ Default inner padding for x and y band-ordinal scales of 'Rect' marks.+ --+ -- @since 0.4.0.0+ | SCRectBandPaddingOuter Double+ -- ^ Default outer padding for x and y band-ordinal scales of 'Rect' marks.+ --+ -- @since 0.4.0.0+ | SCClamp Bool+ -- ^ Whether or not by default values that exceed the data domain are clamped to+ -- the min/max range value.+ | SCMaxBandSize Double+ -- ^ Default maximum value for mapping quantitative fields to a bar's+ -- size/bandSize.+ | SCMinBandSize Double+ -- ^ Default minimum value for mapping quantitative fields to a bar's+ -- size/bandSize.+ | SCMaxFontSize Double+ -- ^ Default maximum value for mapping a quantitative field to a text+ -- mark's size.+ | SCMinFontSize Double+ -- ^ Default minimum value for mapping a quantitative field to a text+ -- mark's size.+ | SCMaxOpacity Opacity+ -- ^ Default maximum opacity for mapping a field to opacity.+ | SCMinOpacity Opacity+ -- ^ Default minimum opacity for mapping a field to opacity.+ | SCMaxSize Double+ -- ^ Default maximum size for point-based scales.+ | SCMinSize Double+ -- ^ Default minimum size for point-based scales.+ | SCMaxStrokeWidth Double+ -- ^ Default maximum stroke width for rule, line and trail marks.+ | SCMinStrokeWidth Double+ -- ^ Default minimum stroke width for rule, line and trail marks.+ | SCPointPadding Double+ -- ^ Default padding for point-ordinal scales.+ | SCRangeStep (Maybe Double)+ -- ^ Default range step for band and point scales when the mark is not text.+ | SCRound Bool+ -- ^ Are numeric values are rounded to integers when scaling? Useful+ -- for snapping to the pixel grid.+ | SCTextXRangeStep Double+ -- ^ Default range step for x band and point scales of text marks.+ | SCUseUnaggregatedDomain Bool+ -- ^ Whether or not to use the source data range before aggregation.+++scaleConfigProperty :: ScaleConfig -> LabelledSpec+scaleConfigProperty (SCBandPaddingInner x) = "bandPaddingInner" .= x+scaleConfigProperty (SCBandPaddingOuter x) = "bandPaddingOuter" .= x+scaleConfigProperty (SCBarBandPaddingInner x) = "barBandPaddingInner" .= x+scaleConfigProperty (SCBarBandPaddingOuter x) = "barBandPaddingOuter" .= x+scaleConfigProperty (SCRectBandPaddingInner x) = "rectBandPaddingInner" .= x+scaleConfigProperty (SCRectBandPaddingOuter x) = "rectBandPaddingOuter" .= x+scaleConfigProperty (SCClamp b) = "clamp" .= b+scaleConfigProperty (SCMaxBandSize x) = "maxBandSize" .= x+scaleConfigProperty (SCMinBandSize x) = "minBandSize" .= x+scaleConfigProperty (SCMaxFontSize x) = "maxFontSize" .= x+scaleConfigProperty (SCMinFontSize x) = "minFontSize" .= x+scaleConfigProperty (SCMaxOpacity x) = "maxOpacity" .= x+scaleConfigProperty (SCMinOpacity x) = "minOpacity" .= x+scaleConfigProperty (SCMaxSize x) = "maxSize" .= x+scaleConfigProperty (SCMinSize x) = "minSize" .= x+scaleConfigProperty (SCMaxStrokeWidth x) = "maxStrokeWidth" .= x+scaleConfigProperty (SCMinStrokeWidth x) = "minStrokeWidth" .= x+scaleConfigProperty (SCPointPadding x) = "pointPadding" .= x+scaleConfigProperty (SCRangeStep numOrNull) = "rangeStep" .= maybe A.Null toJSON numOrNull+scaleConfigProperty (SCRound b) = "round" .= b+scaleConfigProperty (SCTextXRangeStep x) = "textXRangeStep" .= x+scaleConfigProperty (SCUseUnaggregatedDomain b) = "useUnaggregatedDomain" .= b+++-- | Indicates the type of selection to be generated by the user.++data Selection+ = Single+ -- ^ Allows one mark at a time to be selected.+ | Multi+ -- ^ Allows multiple items to be selected (e.g. with+ -- shift-click).+ | Interval+ -- ^ Allows a bounding rectangle to be dragged by the user,+ -- selecting all items which intersect it.+++selectionLabel :: Selection -> T.Text+selectionLabel Single = "single"+selectionLabel Multi = "multi"+selectionLabel Interval = "interval"+++{-|++Properties for customising the nature of the selection. See the+<https://vega.github.io/vega-lite/docs/selection.html#selection-properties Vega-Lite documentation>+for details.++For use with 'select' and 'SelectionStyle'.+-}+data SelectionProperty+ = Empty+ -- ^ Make a selection empty by default when nothing selected.+ | BindScales+ -- ^ Enable two-way binding between a selection and the scales used+ -- in the same view. This is commonly used for zooming and panning+ -- by binding selection to position scaling:+ --+ -- @sel = 'selection' . 'select' \"mySelection\" 'Interval' ['BindScales']@+ | On T.Text+ -- ^ [Vega event stream selector](https://vega.github.io/vega/docs/event-streams/#selector)+ -- that triggers a selection, or the empty string (which sets the property to @false@).+ | Clear T.Text+ -- ^ [Vega event stream selector](https://vega.github.io/vega/docs/event-streams/#selector)+ -- that can clear a selection. For example, to allow a zoomed/panned view to be reset+ -- on shift-click:+ --+ -- @+ -- 'selection'+ -- . 'select' \"myZoomPan\"+ -- 'Interval'+ -- ['BindScales', 'Clear' \"click[event.shiftKey]\"]+ -- @+ --+ -- To remove the default clearing behaviour of a selection, provide an empty string+ -- rather than an event stream selector.+ --+ -- @since 0.4.0.0+ | Translate T.Text+ -- ^ Translation selection transformation used for panning a view. See the+ -- [Vega-Lite translate documentation](https://vega.github.io/vega-lite/docs/translate.html).+ | Zoom T.Text+ -- ^ Zooming selection transformation used for zooming a view. See the+ -- [Vega-Lite zoom documentation](https://vega.github.io/vega-lite/docs/zoom.html).+ | Fields [T.Text]+ -- ^ Field names for projecting a selection.+ | Encodings [Channel]+ -- ^ Encoding channels that form a named selection.+ --+ -- For example, to __project__ a selection across all items that+ -- share the same value in the color channel:+ --+ -- @sel = 'selection' . 'select' \"mySelection\" 'Multi' ['Encodings' ['ChColor']]@+ | SInit [(T.Text, DataValue)]+ -- ^ Initialise one or more selections with values from bound fields.+ -- See also 'SInitInterval'.+ --+ -- For example,+ --+ -- @+ -- 'selection'+ -- . 'select' \"CylYr\"+ -- 'Single'+ -- [ 'Fields' [\"Cylinders\", \"Year\"]+ -- , 'SInit'+ -- [ (\"Cylinders\", 'Number' 4)+ -- , (\"Year\", 'Number' 1977)+ -- ]+ -- , 'Bind'+ -- [ 'IRange' \"Cylinders\" ['InMin' 3, 'InMax' 8, 'InStep' 1]+ -- , 'IRange' \"Year\" ['InMin' 1969, 'InMax' 1981, 'InStep' 1]+ -- ]+ -- ]+ -- @+ --+ -- @since 0.4.0.0+ | SInitInterval (Maybe (DataValue, DataValue)) (Maybe (DataValue, DataValue))+ -- ^ Initialize the domain extent of an interval selection. See+ -- also 'SInit'.+ --+ -- The parameters refer to the x and y axes, given in the order+ -- @(minimum, maximum)@ for each axis. If an axis is set to+ -- @Nothing@ then the selection is projected over that+ -- dimension. At least one of the two arguments should be+ -- set (i.e. not @Nothing@).+ --+ -- @+ -- 'select' \"mySelection\"+ -- 'Interval'+ -- [ 'SInitInterval'+ -- (Just ( 'DateTime' ['DTYear' 2013]+ -- , 'DateTime' ['DTYear' 2015]+ -- )+ -- (Just ('Number' 40, 'Number' 80))+ -- ]+ -- @+ --+ -- @since 0.4.0.0+ | ResolveSelections SelectionResolution+ -- ^ Strategy that determines how selections' data queries are resolved when applied+ -- in a filter transform, conditional encoding rule, or scale domain.+ | SelectionMark [SelectionMarkProperty]+ -- ^ Appearance of an interval selection mark (dragged rectangle).+ | Bind [Binding]+ -- ^ Binding to some input elements as part of a named selection.+ --+ -- The followig example allows a selection to be based on a+ -- drop-down list of options:+ --+ -- @+ -- sel = 'selection'+ -- . 'select' \"mySelection\"+ -- 'Single'+ -- ['Fields' [\"crimeType\"]+ -- , 'Bind' ['ISelect' \"crimeType\"+ -- ['InOptions'+ -- [ \"Anti-social behaviour\"+ -- , \"Criminal damage and arson\"+ -- , \"Drugs\"+ -- , \"Robbery\"+ -- , \"Vehicle crime\"+ -- ]+ -- ]+ -- ]+ -- ]+ -- @+ | Nearest Bool+ -- ^ Whether or not a selection should capture nearest marks to a pointer+ -- rather than an exact position match.+ | Toggle T.Text+ -- ^ Predicate expression that determines a toggled selection. See the+ -- [Vega-Lite toggle documentation](https://vega.github.io/vega-lite/docs/toggle.html).+++selectionProperty :: SelectionProperty -> LabelledSpec+selectionProperty (Fields fNames) = "fields" .= map toJSON fNames+selectionProperty (Encodings channels) = "encodings" .= map (toJSON . channelLabel) channels+selectionProperty (SInit iVals) = "init" .= object (map (second dataValueSpec) iVals)+-- This is invalid according to the specification+selectionProperty (SInitInterval Nothing Nothing) = "init" .= A.Null+selectionProperty (SInitInterval mx my) =+ let conv (_, Nothing) = Nothing+ conv (lbl, (Just (lo, hi))) = Just (lbl .= [ dataValueSpec lo, dataValueSpec hi ])++ in "init" .= object (mapMaybe conv (zip ["x", "y"] [mx, my]))++selectionProperty (On e) = "on" .= e+selectionProperty (Clear e) = "clear" .= if T.null e then toJSON False else toJSON e+selectionProperty Empty = "empty" .= fromT "none"+selectionProperty (ResolveSelections res) = "resolve" .= selectionResolutionLabel res+selectionProperty (SelectionMark markProps) = "mark" .= object (map selectionMarkProperty markProps)+selectionProperty BindScales = "bind" .= fromT "scales"+selectionProperty (Bind binds) = "bind" .= object (map bindingSpec binds)+selectionProperty (Nearest b) = "nearest" .= b+selectionProperty (Toggle expr) = "toggle" .= expr+selectionProperty (Translate e) = "translate" .= if T.null e then toJSON False else toJSON e+selectionProperty (Zoom e) = "zoom" .= if T.null e then toJSON False else toJSON e+++-- | Indicates a channel type to be used in a resolution specification.++-- assuming this is based on schema 3.3.0 #/definitions/SingleDefUnitChannel++data Channel+ = ChX+ | ChY+ | ChX2+ | ChY2+ | ChLongitude+ -- ^ @since 0.4.0.0+ | ChLongitude2+ -- ^ @since 0.4.0.0+ | ChLatitude+ -- ^ @since 0.4.0.0+ | ChLatitude2+ -- ^ @since 0.4.0.0+ | ChColor+ | ChFill+ -- ^ @since 0.3.0.0+ | ChFillOpacity+ -- ^ @since 0.4.0.0+ | ChHref+ -- ^ @since 0.4.0.0+ | ChKey+ -- ^ @since 0.4.0.0+ | ChStroke+ -- ^ @since 0.3.0.0+ | ChStrokeOpacity+ -- ^ @since 0.4.0.0+ | ChStrokeWidth+ -- ^ @since 0.4.0.0+ | ChOpacity+ | ChShape+ | ChSize+ | ChText+ -- ^ @since 0.4.0.0+ | ChTooltip+ -- ^ @since 0.4.0.0+++channelLabel :: Channel -> T.Text+channelLabel ChX = "x"+channelLabel ChY = "y"+channelLabel ChX2 = "x2"+channelLabel ChY2 = "y2"+channelLabel ChLongitude = "longitude"+channelLabel ChLatitude = "latitude"+channelLabel ChLongitude2 = "longitude2"+channelLabel ChLatitude2 = "latitude2"+channelLabel ChColor = "color"+channelLabel ChFill = "fill"+channelLabel ChStroke = "stroke"+channelLabel ChStrokeWidth = "strokeWidth"+channelLabel ChShape = "shape"+channelLabel ChSize = "size"+channelLabel ChFillOpacity = "fillOpacity"+channelLabel ChStrokeOpacity = "strokeOpacity"+channelLabel ChOpacity = "opacity"+channelLabel ChText = "text"+channelLabel ChTooltip = "tooltip"+channelLabel ChHref = "href"+channelLabel ChKey = "key"+++{-|++Determines how selections in faceted or repeated views are resolved. See the+<https://vega.github.io/vega-lite/docs/selection.html#resolve Vega-Lite documentation>+for details.++For use with 'ResolveSelections'.++-}+data SelectionResolution+ = Global+ -- ^ One selection available across all subviews (default).+ | Union+ -- ^ Each subview contains its own brush and marks are selected if they lie+ -- within /any/ of these individual selections.+ | Intersection+ -- ^ Each subview contains its own brush and marks are selected if they lie+ -- within /all/ of these individual selections.+++selectionResolutionLabel :: SelectionResolution -> T.Text+selectionResolutionLabel Global = "global"+selectionResolutionLabel Union = "union"+selectionResolutionLabel Intersection = "intersect"+++{-|++Properties for customising the appearance of an interval selection mark (dragged+rectangle). For details see the+<https://vega.github.io/vega-lite/docs/selection.html#interval-mark Vega-Lite documentation>.++-}+data SelectionMarkProperty+ = SMFill T.Text+ | SMFillOpacity Opacity+ | SMStroke T.Text+ | SMStrokeOpacity Opacity+ | SMStrokeWidth Double+ | SMStrokeDash [Double]+ | SMStrokeDashOffset Double+++selectionMarkProperty :: SelectionMarkProperty -> LabelledSpec+selectionMarkProperty (SMFill colour) = "fill" .= colour+selectionMarkProperty (SMFillOpacity x) = "fillOpacity" .= x+selectionMarkProperty (SMStroke colour) = "stroke" .= colour+selectionMarkProperty (SMStrokeOpacity x) = "strokeOpacity" .= x+selectionMarkProperty (SMStrokeWidth x) = "strokeWidth" .= x+selectionMarkProperty (SMStrokeDash xs) = "strokeDash" .= xs+selectionMarkProperty (SMStrokeDashOffset x) = "strokeDashOffset" .= x+++{-|++GUI Input properties. The type of relevant property will depend on the type of+input element selected. For example an @InRange@ (slider) can have numeric min,+max and step values; @InSelect@ (selector) has a list of selection label options.+For details see the+<https://vega.github.io/vega/docs/signals/#bind Vega input element binding documentation>.++The @debounce@ property, available for all input types allows a delay in input event+handling to be added in order to avoid unnecessary event broadcasting. The @Element@+property is an optional CSS selector indicating the parent element to which the+input element should be added. This allows the option of the input element to be+outside the visualization container.+-}++-- based on schema 3.3.0 #/definitions/BindRange+-- or #/definitions/InputBinding++-- placeholder is in InputBinding+-- debounce is in BindCheckbox / BindRadioSelect / BindRange / InputBinding+-- element is in BindCheckbox / BindRadioSelect / BindRange / InputBinding++-- but InputBinding doesn't have min/max/others++data InputProperty+ = Debounce Double+ | Element T.Text+ | InOptions [T.Text]+ | InMin Double+ | InMax Double+ | InName T.Text+ | InStep Double+ | InPlaceholder T.Text+++inputProperty :: InputProperty -> LabelledSpec+inputProperty (Debounce x) = "debounce" .= x+inputProperty (Element el) = "element" .= el -- #/definitions/Element+inputProperty (InOptions opts) = "options" .= map toJSON opts+inputProperty (InMin x) = "min" .= x+inputProperty (InMax x) = "max" .= x+inputProperty (InName s) = "name" .= s+inputProperty (InStep x) = "step" .= x+inputProperty (InPlaceholder el) = "placeholder" .= toJSON el+++{-|++Describes the binding property of a selection based on some HTML input element+such as a checkbox or radio button. For details see the+<https://vega.github.io/vega-lite/docs/bind.html#scale-binding Vega-Lite documentation>+and the+<https://vega.github.io/vega/docs/signals/#bind Vega input binding documentation>.+-}+data Binding+ = IRange T.Text [InputProperty]+ -- ^ Range slider input element that can bound to a named field value.+ | ICheckbox T.Text [InputProperty]+ -- ^ Checkbox input element that can bound to a named field value.+ | IRadio T.Text [InputProperty]+ -- ^ Radio box input element that can bound to a named field value.+ | ISelect T.Text [InputProperty]+ -- ^ Select input element that can bound to a named field value.+ | IText T.Text [InputProperty]+ -- ^ Text input element that can bound to a named field value.+ | INumber T.Text [InputProperty]+ -- ^ Number input element that can bound to a named field value.+ | IDate T.Text [InputProperty]+ -- ^ Date input element that can bound to a named field value.+ | ITime T.Text [InputProperty]+ -- ^ Time input element that can bound to a named field value.+ | IMonth T.Text [InputProperty]+ -- ^ Month input element that can bound to a named field value.+ | IWeek T.Text [InputProperty]+ -- ^ Week input element that can bound to a named field value.+ | IDateTimeLocal T.Text [InputProperty]+ -- ^ Local time input element that can bound to a named field value.+ | ITel T.Text [InputProperty]+ -- ^ Telephone number input element that can bound to a named field value.+ | IColor T.Text [InputProperty]+ -- ^ Color input element that can bound to a named field value.+++bindingSpec :: Binding -> LabelledSpec+bindingSpec bnd =+ let (lbl, input, ps) = case bnd of+ IRange label props -> (label, fromT "range", props)+ ICheckbox label props -> (label, "checkbox", props)+ IRadio label props -> (label, "radio", props)+ ISelect label props -> (label, "select", props)+ IText label props -> (label, "text", props)+ INumber label props -> (label, "number", props)+ IDate label props -> (label, "date", props)+ ITime label props -> (label, "time", props)+ IMonth label props -> (label, "month", props)+ IWeek label props -> (label, "week", props)+ IDateTimeLocal label props -> (label, "datetimelocal", props)+ ITel label props -> (label, "tel", props)+ IColor label props -> (label, "color", props)++ in (lbl, object (("input" .= input) : map inputProperty ps))+++-- | Indicates the anchor position for text.++data APosition+ = AStart+ -- ^ The start of the text.+ | AMiddle+ -- ^ The middle of the text.+ | AEnd+ -- ^ The end of the text.+++anchorLabel :: APosition -> T.Text+anchorLabel AStart = "start"+anchorLabel AMiddle = "middle"+anchorLabel AEnd = "end"+++{-|++Title configuration properties. These are used to configure the default style+of all titles within a visualization.+For further details see the+<https://vega.github.io/vega-lite/docs/title.html#config Vega-Lite documentation>.+-}+data TitleConfig+ = TAnchor APosition+ -- ^ Default anchor position when placing titles.+ | TAngle Angle+ -- ^ Default angle when orientating titles.+ | TBaseline VAlign+ -- ^ Default vertical alignment when placing titles.+ | TColor Color+ -- ^ Default color when showing titles.+ | TFont T.Text+ -- ^ Default font when showing titles.+ | TFontSize Double+ -- ^ Default font size when showing titles.+ | TFontStyle T.Text+ -- ^ Defaylt font style when showing titles.+ --+ -- @since 0.4.0.0+ | TFontWeight FontWeight+ -- ^ Default font weight when showing titles.+ | TFrame TitleFrame+ -- ^ Default title position anchor.+ --+ -- @since 0.4.0.0+ | TLimit Double+ -- ^ Default maximum length, in pixels, of titles.+ | TOffset Double+ -- ^ Default offset, in pixels, of titles relative to the chart body.+ | TOrient Side+ -- ^ Default placement of titles relative to the chart body.+ | TStyle [T.Text]+ -- ^ A list of named styles to apply. A named style can be specified+ -- via 'NamedStyle' or 'NamedStyles'. Later styles in the list will+ -- override earlier ones if there is a conflict in any of the+ -- properties.+ --+ -- @since 0.4.0.0+ | TZIndex ZIndex+ -- ^ Drawing order of a title relative to the other chart elements.+ --+ -- @since 0.4.0.0++titleConfigSpec :: TitleConfig -> LabelledSpec+titleConfigSpec (TAnchor an) = "anchor" .= anchorLabel an+titleConfigSpec (TAngle x) = "angle" .= x+titleConfigSpec (TBaseline va) = "baseline" .= vAlignLabel va+titleConfigSpec (TColor clr) = "color" .= clr+titleConfigSpec (TFont fnt) = "font" .= fnt+titleConfigSpec (TFontSize x) = "fontSize" .= x+titleConfigSpec (TFontStyle s) = "fontStyle" .= s+titleConfigSpec (TFontWeight w) = "fontWeight" .= fontWeightSpec w+titleConfigSpec (TFrame tf) = "frame" .= titleFrameSpec tf+titleConfigSpec (TLimit x) = "limit" .= x+titleConfigSpec (TOffset x) = "offset" .= x+titleConfigSpec (TOrient sd) = "orient" .= sideLabel sd+titleConfigSpec (TStyle [style]) = "style" .= style -- not really needed+titleConfigSpec (TStyle styles) = "style" .= styles+titleConfigSpec (TZIndex z) = "zindex" .= z++-- | Specifies how the title anchor is positioned relative to the frame.+--+-- @since 0.4.0.0+data TitleFrame+ = FrBounds+ -- ^ The position is relative to the full bounding box.+ | FrGroup+ -- ^ The pistion is relative to the group width / height.++titleFrameSpec :: TitleFrame -> VLSpec+titleFrameSpec FrBounds = "bounds"+titleFrameSpec FrGroup = "group"+++-- | The properties for a single view or layer background.+--+-- @since 0.4.0.0++data ViewBackground+ = VBStyle [T.Text]+ -- ^ A list of named styles to apply. A named style can be specified+ -- via 'NamedStyle' or 'NamedStyles'. Later styles in the list will+ -- override earlier ones if there is a conflict in any of the mark+ -- properties.+ | VBCornerRadius Double+ -- ^ The radius in pixels of rounded corners.+ | VBFill (Maybe T.Text)+ -- ^ Fill color.+ | VBFillOpacity Opacity+ -- ^ Fill opacity.+ | VBOpacity Opacity+ -- ^ Overall opacity.+ | VBStroke (Maybe T.Text)+ -- ^ The stroke color for a line around the background. If @Nothing@ then+ -- no line is drawn.+ | VBStrokeOpacity Opacity+ -- ^ The opacity of the line around the background, if drawn.+ | VBStrokeWidth Double+ -- ^ The width of the line around the background, if drawn.+ | VBStrokeCap StrokeCap+ -- ^ The cap line-ending for the line around the background, if drawn.+ | VBStrokeDash [Double]+ -- ^ The dash style of the line around the background, if drawn.+ | VBStrokeDashOffset Double+ -- ^ The dash offset of the line around the background, if drawn.+ | VBStrokeJoin StrokeJoin+ -- ^ The line-joining style of the line around the background, if drawn.+ | VBStrokeMiterLimit Double+ -- ^ The mitre limit at which to bevel the line around the background, if drawn.+++viewBackgroundSpec :: ViewBackground -> LabelledSpec+viewBackgroundSpec (VBStyle [style]) = "style" .= style -- special case singleton+viewBackgroundSpec (VBStyle styles) = "style" .= styles+viewBackgroundSpec (VBCornerRadius r) = "cornerRadius" .= r+viewBackgroundSpec (VBFill (Just s)) = "fill" .= s+viewBackgroundSpec (VBFill Nothing) = "fill" .= A.Null+viewBackgroundSpec (VBFillOpacity x) = "fillOpacity" .= x+viewBackgroundSpec (VBOpacity x) = "opacity" .= x+viewBackgroundSpec (VBStroke (Just s)) = "stroke" .= s+viewBackgroundSpec (VBStroke Nothing) = "stroke" .= A.Null+viewBackgroundSpec (VBStrokeOpacity x) = "strokeOpacity" .= x+viewBackgroundSpec (VBStrokeCap cap) = "strokeCap" .= strokeCapLabel cap+viewBackgroundSpec (VBStrokeJoin jn) = "strokeJoin" .= strokeJoinLabel jn+viewBackgroundSpec (VBStrokeWidth x) = "strokeWidth" .= x+viewBackgroundSpec (VBStrokeDash xs) = "strokeDash" .= xs+viewBackgroundSpec (VBStrokeDashOffset x) = "strokeDashOffset" .= x+viewBackgroundSpec (VBStrokeMiterLimit x) = "strokeMiterLimit" .= x+++-- | The background style of a single view or layer in a view composition.+--+-- @since 0.4.0.0++viewBackground :: [ViewBackground] -> PropertySpec+viewBackground vbs = (VLViewBackground, object (map viewBackgroundSpec vbs))+++{-|++View configuration property. These are used to configure the style of a single+view within a visualization such as its size and default fill and stroke colors.+For further details see the+<https://vega.github.io/vega-lite/docs/spec.html#config Vega-Lite documentation>.++This type has been changed in the @0.4.0.0@ release to use a consistent+naming scheme for the constructors (everything starts with @View@). Prior to+this release only @ViewWidth@ and @ViewHeight@ were named this way. There+are also five new constructors.++-}++-- based on schema 3.3.0 #/definitions/ViewConfig++data ViewConfig+ = ViewWidth Double+ -- ^ The default width of the single plot or each plot in a trellis plot when the+ -- visualization has a continuous (non-ordinal) scale or when the+ -- 'SRangeStep'/'ScRangeStep' is @Nothing@ for an ordinal scale (x axis).+ | ViewHeight Double+ -- ^ The default height of the single plot or each plot in a trellis plot when the+ -- visualization has a continuous (non-ordinal) scale or when the+ -- 'SRangeStep'/'ScRangeStep' is @Nothing@ for an ordinal scale (y axis).+ | ViewClip Bool+ -- ^ Should the view be clipped?+ | ViewCornerRadius Double+ -- ^ The radius, in pixels, of rounded rectangle corners.+ --+ -- The default is @0@.+ --+ -- @since 0.4.0.0+ | ViewFill (Maybe T.Text)+ -- ^ The fill color.+ | ViewFillOpacity Opacity+ -- ^ The fill opacity.+ | ViewOpacity Opacity+ -- ^ The overall opacity.+ --+ -- The default is @0.7@ for non-aggregate plots with 'Point', 'Tick',+ -- 'Circle', or 'Square' marks or layered 'Bar' charts, and @1@+ -- otherwise.+ --+ -- @since 0.4.0.0+ | ViewStroke (Maybe T.Text)+ -- ^ The stroke color.+ | ViewStrokeCap StrokeCap+ -- ^ The stroke cap for line-ending style.+ --+ -- @since 0.4.0.0+ | ViewStrokeDash [Double]+ -- ^ The stroke dash style. It is defined by an alternating 'on-off'+ -- sequence of line lengths, in pixels.+ | ViewStrokeDashOffset Double+ -- ^ Number of pixels before the first line dash is drawn.+ | ViewStrokeJoin StrokeJoin+ -- ^ The stroke line-join method.+ --+ -- @since 0.4.0.0+ | ViewStrokeMiterLimit Double+ -- ^ The miter limit at which to bevel a line join.+ --+ -- @since 0.4.0.0+ | ViewStrokeOpacity Opacity+ -- ^ The stroke opacity.+ | ViewStrokeWidth Double+ -- ^ The stroke width, in pixels.+++viewConfigProperty :: ViewConfig -> LabelledSpec+viewConfigProperty (ViewWidth x) = "width" .= x+viewConfigProperty (ViewHeight x) = "height" .= x+viewConfigProperty (ViewClip b) = "clip" .= b+viewConfigProperty (ViewCornerRadius x) = "cornerRadius" .= x+viewConfigProperty (ViewFill ms) = "fill" .= maybe A.Null toJSON ms+viewConfigProperty (ViewFillOpacity x) = "fillOpacity" .= x+viewConfigProperty (ViewOpacity x) = "opacity" .= x+viewConfigProperty (ViewStroke ms) = "stroke" .= maybe A.Null toJSON ms+viewConfigProperty (ViewStrokeCap sc) = "strokeCap" .= strokeCapLabel sc+viewConfigProperty (ViewStrokeDash xs) = "strokeDash" .= xs+viewConfigProperty (ViewStrokeDashOffset x) = "strokeDashOffset" .= x+viewConfigProperty (ViewStrokeJoin sj) = "strokeJoin" .= strokeJoinLabel sj+viewConfigProperty (ViewStrokeMiterLimit x) = "strokeMiterLimit" .= x+viewConfigProperty (ViewStrokeOpacity x) = "strokeOpacity" .= x+viewConfigProperty (ViewStrokeWidth x) = "strokeWidth" .= x+++{-|++Type of configuration property to customise. See the+<https://vega.github.io/vega-lite/docs/config.html Vega-Lite documentation>+for details.++-}++-- based on schema 3.3.0 #/definitions/Config+--+-- TODO:+-- Bar - change to BarConfig rather than MarkProperty?+-- BoxplotStyle BoxPlotConfig+-- Concat CompositionConfig+-- ErrorBand ErrorBandCOnfig+-- ErrorBar ErrorBarCOnfig+-- Facet takes CompositionConfig not FacetConfig+-- HeaderColumn takes HeaderConfig, just as HeaderStyle does+-- HeaderFacet ditto+-- HeaderRow ditto+-- LineStyle takes LineConfig not MarkConfig+-- TextStyle takes TextConfig not MarkConfig+-- TickStyle takes TickConfig not MarkConfig+-- TrailStyle takes LineConfig not MarkConfig+--++data ConfigurationProperty+ = AreaStyle [MarkProperty]+ -- ^ The default appearance of area marks.+ | Autosize [Autosize]+ -- ^ The default sizing of visualizations.+ | Axis [AxisConfig]+ -- ^ The default appearance of axes.+ | AxisBand [AxisConfig]+ -- ^ The default appearance of axes with band scaling.+ | AxisBottom [AxisConfig]+ -- ^ The default appearance of the bottom-side axes.+ | AxisLeft [AxisConfig]+ -- ^ The default appearance of the left-side axes.+ | AxisRight [AxisConfig]+ -- ^ The default appearance of the right-side axes.+ | AxisTop [AxisConfig]+ -- ^ The default appearance of the top-side axes.+ | AxisX [AxisConfig]+ -- ^ The default appearance of the X axes.+ | AxisY [AxisConfig]+ -- ^ The default appearance of the Y axes.+ | Background T.Text+ -- ^ The default background color of visualizations.+ | BarStyle [MarkProperty]+ -- ^ The default appearance of bar marks.+ | CircleStyle [MarkProperty]+ -- ^ The default appearance of circle marks.+ | ConcatStyle [ConcatConfig]+ -- ^ The default appearance of concatenated layouts.+ --+ -- @since 0.4.0.0+ | CountTitle T.Text+ -- ^ The default title style for count fields.+ | FacetStyle [FacetConfig]+ -- ^ The default appearance of facet layouts.+ --+ -- @since 0.4.0.0+ | FieldTitle FieldTitleProperty+ -- ^ The default title-generation style for fields.+ | GeoshapeStyle [MarkProperty]+ -- ^ The default appearance of geoshape marks.+ --+ -- @since 0.4.0.0+ | HeaderStyle [HeaderProperty]+ -- ^ The default appearance of facet headers.+ --+ -- @since 0.4.0.0+ | Legend [LegendConfig]+ -- ^ The default appearance of legends.+ | LineStyle [MarkProperty]+ -- ^ The default appearance of line marks.+ | MarkStyle [MarkProperty]+ -- ^ The default mark appearance.+ | NamedStyle T.Text [MarkProperty]+ -- ^ The default appearance of a single named style.+ | NamedStyles [(T.Text, [MarkProperty])]+ -- ^ The default appearance of a list of named styles.+ --+ -- @since 0.4.0.0+ | NumberFormat T.Text+ -- ^ The default number formatting for axis and text labels.+ | Padding Padding+ -- ^ The default padding in pixels from the edge of the of visualization+ -- to the data rectangle.+ | PointStyle [MarkProperty]+ -- ^ The default appearance of point marks.+ | Projection [ProjectionProperty]+ -- ^ The default style of map projections.+ | Range [RangeConfig]+ -- ^ The default range properties used when scaling.+ | RectStyle [MarkProperty]+ -- ^ The default appearance of rectangle marks.+ | RemoveInvalid Bool+ -- ^ The default handling of invalid (@null@ and @NaN@) values. If @True@,+ -- invalid values are skipped or filtered out when represented as marks.+ | RuleStyle [MarkProperty]+ -- ^ The default appearance of rule marks.+ | Scale [ScaleConfig] -- TODO: rename ScaleStyle+ -- ^ The default properties used when scaling.+ | SelectionStyle [(Selection, [SelectionProperty])]+ -- ^ The default appearance of selection marks.+ | SquareStyle [MarkProperty]+ -- ^ the default appearance of square marks+ | Stack StackOffset+ -- ^ The default stack offset style for stackable marks.+ --+ -- Changed from @StackProperty@ in version @0.4.0.0@.+ | TextStyle [MarkProperty]+ -- ^ The default appearance of text marks.+ | TickStyle [MarkProperty]+ -- ^ The default appearance of tick marks.+ | TimeFormat T.Text+ -- ^ The default time format for axis and legend labels.+ | TitleStyle [TitleConfig]+ -- ^ The default appearance of visualization titles.+ | TrailStyle [MarkProperty]+ -- ^ The default style of trail marks.+ --+ -- @since 0.4.0.0+ | View [ViewConfig]+ -- ^ The default single view style.++configProperty :: ConfigurationProperty -> LabelledSpec+configProperty (Autosize aus) = "autosize" .= object (map autosizeProperty aus)+configProperty (Background bg) = "background" .= bg+configProperty (CountTitle ttl) = "countTitle" .= ttl+configProperty (ConcatStyle cps) = "concat" .= object (map concatConfigProperty cps)+configProperty (FieldTitle ftp) = "fieldTitle" .= fieldTitleLabel ftp+configProperty (RemoveInvalid b) = "invalidValues" .= if b then "filter" else A.Null+configProperty (NumberFormat fmt) = "numberFormat" .= fmt+configProperty (Padding pad) = "padding" .= paddingSpec pad+configProperty (TimeFormat fmt) = "timeFormat" .= fmt+configProperty (Axis acs) = "axis" .= object (map axisConfigProperty acs)+configProperty (AxisX acs) = "axisX" .= object (map axisConfigProperty acs)+configProperty (AxisY acs) = "axisY" .= object (map axisConfigProperty acs)+configProperty (AxisLeft acs) = "axisLeft" .= object (map axisConfigProperty acs)+configProperty (AxisRight acs) = "axisRight" .= object (map axisConfigProperty acs)+configProperty (AxisTop acs) = "axisTop" .= object (map axisConfigProperty acs)+configProperty (AxisBottom acs) = "axisBottom" .= object (map axisConfigProperty acs)+configProperty (AxisBand acs) = "axisBand" .= object (map axisConfigProperty acs)+configProperty (Legend lcs) = "legend" .= object (map legendConfigProperty lcs)+configProperty (MarkStyle mps) = mprops_ "mark" mps+configProperty (Projection pps) = "projection" .= object (map projectionProperty pps)+configProperty (AreaStyle mps) = mprops_ "area" mps+configProperty (BarStyle mps) = mprops_ "bar" mps+configProperty (CircleStyle mps) = mprops_ "circle" mps+configProperty (FacetStyle fps) = "facet" .= object (map facetConfigProperty fps)+configProperty (GeoshapeStyle mps) = mprops_ "geoshape" mps+configProperty (HeaderStyle hps) = header_ hps+configProperty (LineStyle mps) = mprops_ "line" mps+configProperty (PointStyle mps) = mprops_ "point" mps+configProperty (RectStyle mps) = mprops_ "rect" mps+configProperty (RuleStyle mps) = mprops_ "rule" mps+configProperty (SquareStyle mps) = mprops_ "square" mps+configProperty (TextStyle mps) = mprops_ "text" mps+configProperty (TickStyle mps) = mprops_ "tick" mps+configProperty (TitleStyle tcs) = "title" .= object (map titleConfigSpec tcs)+configProperty (NamedStyle nme mps) = "style" .= object [mprops_ nme mps]+configProperty (NamedStyles styles) =+ let toStyle = uncurry mprops_+ in "style" .= object (map toStyle styles)+configProperty (Scale scs) = scaleConfig_ scs+configProperty (Stack so) = stackOffset so+configProperty (Range rcs) = "range" .= object (map rangeConfigProperty rcs)+configProperty (SelectionStyle selConfig) =+ let selProp (sel, sps) = selectionLabel sel .= object (map selectionProperty sps)+ in "selection" .= object (map selProp selConfig)+configProperty (TrailStyle mps) = mprops_ "trail" mps+configProperty (View vcs) = "view" .= object (map viewConfigProperty vcs)+++{-|++Axis configuration options for customising all axes. See the+<https://vega.github.io/vega-lite/docs/axis.html#general-config Vega-Lite documentation>+for more details.++The @TitleMaxLength@ constructor was removed in release @0.4.0.0@. The+@TitleLimit@ constructor should be used instead.++-}+data AxisConfig+ = BandPosition Double+ -- ^ The default axis band position.+ | Domain Bool+ -- ^ Should the axis domain be displayed?+ | DomainColor Color+ -- ^ The axis domain color.+ | DomainDash [Double]+ -- ^ The dash style of the domain (alternating stroke, space lengths+ -- in pixels).+ --+ -- @since 0.4.0.0+ | DomainDashOffset Double+ -- ^ The pixel offset at which to start drawing the domain dash array.+ --+ -- @since 0.4.0.0+ | DomainOpacity Opacity+ -- ^ The axis domain opacity.+ --+ -- @since 0.4.0.0+ | DomainWidth Double+ -- ^ The width of the axis domain.+ | Grid Bool+ -- ^ Should an axis grid be displayed?+ | GridColor Color+ -- ^ The color for the grid.+ | GridDash [Double]+ -- ^ The dash style of the grid (alternating stroke, space lengths+ -- in pixels).+ | GridDashOffset Double+ -- ^ The pixel offset at which to start drawing the grid dash array.+ --+ -- @since 0.4.0.0+ | GridOpacity Opacity+ -- ^ The opacity of the grid.+ | GridWidth Double+ -- ^ The width of the grid lines.+ | Labels Bool+ -- ^ Should labels be added to an axis?+ | LabelAlign HAlign+ -- ^ The horizontal alignment for labels.+ --+ -- @since 0.4.0.0+ | LabelAngle Angle+ -- ^ The angle at which to draw labels.+ | LabelBaseline VAlign+ -- ^ The vertical alignment for labels.+ --+ -- @since 0.4.0.0+ | LabelNoBound+ -- ^ No boundary overlap check is applied to labels. This is the+ -- default behavior.+ --+ -- See also 'LabelBound' and 'LabelBoundValue'.+ --+ -- @since 0.4.0.0+ | LabelBound+ -- ^ Labels are hidden if they exceed the axis range by more than 1+ -- pixel.+ --+ -- See also 'LabelNoBound' and 'LabelBoundValue'.+ --+ -- @since 0.4.0.0+ | LabelBoundValue Double+ -- ^ Labels are hidden if they exceed the axis range by more than+ -- the given number of pixels.+ --+ -- See also 'LabelNoBound' and 'LabelBound'.+ --+ -- @since 0.4.0.0+ | LabelColor Color+ -- ^ The label color.+ | LabelNoFlush+ -- ^ The labels are not aligned flush to the scale. This is the+ -- default for non-continuous X scales.+ --+ -- See also 'LabelFlush' and 'LabelFlushValue'.+ --+ -- @since 0.4.0.0+ | LabelFlush+ -- ^ The first and last axis labels are aligned flush to the scale+ -- range.+ --+ -- See also 'LabelNoFlush' and 'LabelFlushValue'.+ --+ -- @since 0.4.0.0+ | LabelFlushValue Double+ -- ^ The labels are aligned flush, and the parameter determines+ -- the extra offset, in pixels, to apply to the first and last+ -- labels. This can help the labels better group (visually) with+ -- the corresponding axis ticks.+ --+ -- See also 'LabelNoFlush' and 'LabelFlush'.+ --+ -- @since 0.4.0.0+ | LabelFlushOffset Double+ -- ^ The number of pixels to offset flush-adjusted labels.+ --+ -- @since 0.4.0.0+ | LabelFont T.Text+ -- ^ The font for the label.+ | LabelFontSize Double+ -- ^ The font size of the label.+ | LabelFontStyle T.Text+ -- ^ The font style of the label.+ --+ -- @since 0.4.0.0+ | LabelFontWeight FontWeight+ -- ^ The font weight of the label.+ --+ -- @since 0.4.0.0+ | LabelLimit Double+ -- ^ The maximum width of a label, in pixels.+ | LabelOpacity Opacity+ -- ^ The opacity of the label.+ --+ -- @since 0.4.0.0+ | LabelOverlap OverlapStrategy+ -- ^ How should overlapping labels be displayed?+ | LabelPadding Double+ -- ^ The padding, in pixels, between the label and the axis.+ | LabelSeparation Double+ -- ^ The minimum separation, in pixels, between label bounding boxes+ -- for them to be considered non-overlapping. This is ignored if+ -- the 'LabelOverlap' strategy is 'ONone'.+ --+ -- @since 0.4.0.0+ | MaxExtent Double+ -- ^ The maximum extent, in pixels, that axis ticks and labels should use.+ -- This determines a maxmium offset value for axis titles.+ | MinExtent Double+ -- ^ The minimum extent, in pixels, that axis ticks and labels should use.+ -- This determines a minmium offset value for axis titles.+ | NoTitle+ -- ^ Do not draw a title for this axis.+ --+ -- @since 0.4.0.0+ | Orient Side+ -- ^ The orientation of the axis.+ --+ -- @since 0.4.0.0+ | ShortTimeLabels Bool+ -- ^ Should an axis use short time labels (abbreviated month and week-day names)?+ | Ticks Bool+ -- ^ Should tick marks be drawn on an axis?+ | TickColor Color+ -- ^ The color of the ticks.+ | TickDash [Double]+ -- ^ The dash style of the ticks (alternating stroke, space lengths+ -- in pixels).+ | TickDashOffset Double+ -- ^ The pixel offset at which to start drawing the tick dash array.+ --+ -- @since 0.4.0.0+ | TickExtra Bool+ -- ^ Should an extra axis tick mark be added for the initial position of+ -- the axis?+ --+ -- @since 0.4.0.0+ | TickOffset Double+ -- ^ The position offset, in pixels, to apply to ticks, labels, and grid lines.+ --+ -- @since 0.4.0.0+ | TickOpacity Opacity+ -- ^ The opacity of the ticks.+ --+ -- @since 0.4.0.0+ | TickRound Bool+ -- ^ Should pixel position values be rounded to the nearest integer?+ | TickSize Double+ -- ^ The size of the tick marks in pixels.+ | TickWidth Double+ -- ^ The width of the tick marks in pixels.+ | TitleAlign HAlign+ -- ^ The horizontal alignment of the axis title.+ | TitleAnchor APosition+ -- ^ The text anchor position for placing axis titles.+ --+ -- @since 0.4.0.0+ | TitleAngle Angle+ -- ^ The angle of the axis title.+ | TitleBaseline VAlign+ -- ^ The vertical alignment of the axis title.+ | TitleColor Color+ -- ^ The color of the axis title.+ | TitleFont T.Text+ -- ^ The font for the axis title.+ | TitleFontSize Double+ -- ^ The font size of the axis title.+ | TitleFontStyle T.Text+ -- ^ The font style of the axis title.+ --+ -- @since 0.4.0.0+ | TitleFontWeight FontWeight+ -- ^ The font weight of the axis title.+ | TitleLimit Double+ -- ^ The maximum allowed width of the axis title, in pixels.+ | TitleOpacity Opacity+ -- ^ The opacity of the axis title.+ --+ -- @since 0.4.0.0+ | TitlePadding Double+ -- ^ The padding, in pixels, between title and axis.+ | TitleX Double+ -- ^ The X coordinate of the axis title, relative to the axis group.+ | TitleY Double+ -- ^ The Y coordinate of the axis title, relative to the axis group.+++axisConfigProperty :: AxisConfig -> LabelledSpec+axisConfigProperty (BandPosition x) = "bandPosition" .= x+axisConfigProperty (Domain b) = "domain" .= b+axisConfigProperty (DomainColor c) = "domainColor" .= c+axisConfigProperty (DomainDash ds) = "domainDash" .= ds+axisConfigProperty (DomainDashOffset x) = "domainDashOffset" .= x+axisConfigProperty (DomainOpacity x) = "domainOpacity" .= x+axisConfigProperty (DomainWidth w) = "domainWidth" .= w+axisConfigProperty (Grid b) = "grid" .= b+axisConfigProperty (GridColor c) = "gridColor" .= c+axisConfigProperty (GridDash ds) = "gridDash" .= ds+axisConfigProperty (GridDashOffset x) = "gridDashOffset" .= x+axisConfigProperty (GridOpacity o) = "gridOpacity" .= o+axisConfigProperty (GridWidth x) = "gridWidth" .= x+axisConfigProperty (Labels b) = "labels" .= b+axisConfigProperty (LabelAlign ha) = "labelAlign" .= hAlignLabel ha+axisConfigProperty (LabelAngle angle) = "labelAngle" .= angle+axisConfigProperty (LabelBaseline va) = "labelBaseline" .= vAlignLabel va+axisConfigProperty LabelNoBound = "labelBound" .= False+axisConfigProperty LabelBound = "labelBound" .= True+axisConfigProperty (LabelBoundValue x) = "labelBound" .= x+axisConfigProperty LabelNoFlush = "labelFlush" .= False+axisConfigProperty LabelFlush = "labelFlush" .= True+axisConfigProperty (LabelFlushValue x) = "labelFlush" .= x+axisConfigProperty (LabelFlushOffset x) = "labelFlushOffset" .= x+axisConfigProperty (LabelColor c) = "labelColor" .= c+axisConfigProperty (LabelFont f) = "labelFont" .= f+axisConfigProperty (LabelFontSize x) = "labelFontSize" .= x+axisConfigProperty (LabelFontStyle s) = "labelFontStyle" .= s+axisConfigProperty (LabelFontWeight fw) = "labelFontWeight" .= fontWeightSpec fw+axisConfigProperty (LabelLimit x) = "labelLimit" .= x+axisConfigProperty (LabelOpacity x) = "labelOpacity" .= x+axisConfigProperty (LabelOverlap strat) = "labelOverlap" .= overlapStrategyLabel strat+axisConfigProperty (LabelPadding pad) = "labelPadding" .= pad+axisConfigProperty (LabelSeparation x) = "labelSeparation" .= x+axisConfigProperty (MaxExtent n) = "maxExtent" .= n+axisConfigProperty (MinExtent n) = "minExtent" .= n+axisConfigProperty NoTitle = "title" .= A.Null+axisConfigProperty (Orient orient) = "orient" .= sideLabel orient+axisConfigProperty (ShortTimeLabels b) = "shortTimeLabels" .= b+axisConfigProperty (Ticks b) = "ticks" .= b+axisConfigProperty (TickColor c) = "tickColor" .= c+axisConfigProperty (TickDash ds) = "tickDash" .= ds+axisConfigProperty (TickDashOffset x) = "tickDashOffset" .= x+axisConfigProperty (TickExtra b) = "tickExtra" .= b+axisConfigProperty (TickOffset x) = "tickOffset" .= x+axisConfigProperty (TickOpacity x) = "tickOpacity" .= x+axisConfigProperty (TickRound b) = "tickRound" .= b+axisConfigProperty (TickSize x) = "tickSize" .= x+axisConfigProperty (TickWidth x) = "tickWidth" .= x+axisConfigProperty (TitleAlign algn) = "titleAlign" .= hAlignLabel algn+axisConfigProperty (TitleAnchor a) = "titleAnchor" .= anchorLabel a+axisConfigProperty (TitleAngle x) = "titleAngle" .= x+axisConfigProperty (TitleBaseline va) = "titleBaseline" .= vAlignLabel va+axisConfigProperty (TitleColor c) = "titleColor" .= c+axisConfigProperty (TitleFont f) = "titleFont" .= f+axisConfigProperty (TitleFontSize x) = "titleFontSize" .= x+axisConfigProperty (TitleFontStyle s) = "titleFontStyle" .= s+axisConfigProperty (TitleFontWeight w) = "titleFontWeight" .= fontWeightSpec w+axisConfigProperty (TitleLimit x) = "titleLimit" .= x+axisConfigProperty (TitleOpacity x) = "titleOpacity" .= x+axisConfigProperty (TitlePadding x) = "titlePadding" .= x+axisConfigProperty (TitleX x) = "titleX" .= x+axisConfigProperty (TitleY y) = "titleY" .= y+++{-|++Used for creating logical compositions. For example++@+'color'+ [ 'MSelectionCondition' (Or ('SelectionName' "alex") (SelectionName "morgan"))+ ['MAggregate' 'Count', 'MName' "*", 'MmType' 'Quantitative']+ ['MString' "gray"]+ ]+@++Logical compositions can be nested to any level as shown in this example++@+'Not' ('And' ('Expr' "datum.IMDB_Rating === null") ('Expr' "datum.Rotten_Tomatoes_Rating === null") )+@+-}+data BooleanOp+ = Expr T.Text+ -- ^ Expression that should evaluate to either true or false.+ -- Can use any valid+ -- [Vega expression](https://vega.github.io/vega/docs/expressions/).+ | FilterOp Filter+ -- ^ Convert a 'Filter' into a 'BooleanOp' so that it may be used as+ -- part of a more complex expression.+ --+ -- For example (using 'Data.Function.&' to apply 'FilterOp' to a filter):+ --+ -- @+ -- trans = 'transform'+ -- . 'filter' ('FCompose'+ -- ('And'+ -- ('FValid' "IMDB_Rating" & 'FilterOp')+ -- ('FValid' "Rotten_Tomatoes_Rating" & 'FilterOp')+ -- )+ -- )+ -- @+ --+ -- @since 0.4.0.0+ | FilterOpTrans MarkChannel Filter+ -- ^ Combine a data-transformation operation with a filter before+ -- converting into a boolean operation. This can be useful when+ -- working with dates, such as the following exampe, which aggregates+ -- a set of dates into years, and filters only those years between+ -- 2010 and 2017 (inclusive). The final expression is converted+ -- back into a 'BooleanOp' with 'FCompose' (combined using+ -- 'Data.Function.&').+ --+ -- @+ -- 'filter' ('FRange' "date" ('DateRange' ['DTYear' 2010] ['DTYear' 2017])+ -- & 'FilterOpTrans' ('MTimeUnit' 'Year')+ -- & 'FCompose'+ -- )+ -- @+ --+ -- @since 0.4.0.0+ | Selection T.Text -- TODO: rename Selected since collides with Selection type+ -- ^ Interactive selection that will be true or false as part of+ -- a logical composition. For example: to filter a dataset so+ -- that only items selected interactively and that have a+ -- weight of more than 30:+ --+ -- @+ -- 'transform'+ -- . 'filter' ('FCompose' ('And' ('Selection' "brush") ('Expr' "datum.weight > 30")))+ -- @+ | SelectionName T.Text+ -- ^ Name a selection that is used as part of a conditional encoding.+ --+ -- @+ -- 'color'+ -- [ 'MSelectionCondition' ('SelectionName' \"myBrush\")+ -- ['MName' \"myField\", 'MmType' 'Nominal']+ -- ['MString' \"grey\"]+ -- ]+ -- @+ | And BooleanOp BooleanOp+ -- ^ Apply an \'and\' Boolean operation as part of a logical composition.+ --+ -- @+ -- 'And' ('Expr' "datum.IMDB_Rating === null") ('Expr' "datum.Rotten_Tomatoes_Rating === null")+ -- @+ | Or BooleanOp BooleanOp+ -- ^ Apply an \'or\' Boolean operation as part of a logical composition.+ | Not BooleanOp+ -- ^ Negate the given expression.+ --+ -- @+ -- 'Not' ('And' ('Expr' "datum.IMDB_Rating === null") ('Expr' "datum.Rotten_Tomatoes_Rating === null"))+ -- @++booleanOpSpec :: BooleanOp -> VLSpec+booleanOpSpec (Expr expr) = toJSON expr+booleanOpSpec (FilterOp f) = filterSpec f+booleanOpSpec (FilterOpTrans tr f) = trFilterSpec tr f+booleanOpSpec (SelectionName selName) = toJSON selName+booleanOpSpec (Selection sel) = object ["selection" .= sel]+booleanOpSpec (And operand1 operand2) = object ["and" .= [booleanOpSpec operand1, booleanOpSpec operand2]]+booleanOpSpec (Or operand1 operand2) = object ["or" .= [booleanOpSpec operand1, booleanOpSpec operand2]]+booleanOpSpec (Not operand) = object ["not" .= booleanOpSpec operand]+++{-|++Type of filtering operation. See the+<https://vega.github.io/vega-lite/docs/filter.html Vega-Lite documentation>+for details.++These can also be included into a 'BooleanOp' expression using 'FilterOp'+and 'FilterOpTrans'+(as of version @0.4.0.0@).++-}+data Filter+ = FEqual T.Text DataValue+ -- ^ Filter a data stream so that only data in a given field equal to+ -- the given value are used.+ | FLessThan T.Text DataValue+ -- ^ Filter a data stream so that only data in a given field less than the given+ -- value are used.+ --+ -- @since 0.4.0.0+ | FLessThanEq T.Text DataValue+ -- ^ Filter a data stream so that only data in a given field less than,+ -- or equal to, the given value are used.+ --+ -- @since 0.4.0.0+ | FGreaterThan T.Text DataValue+ -- ^ Filter a data stream so that only data in a given field greater than the given+ -- value are used.+ --+ -- @since 0.4.0.0+ | FGreaterThanEq T.Text DataValue+ -- ^ Filter a data stream so that only data in a given field greater than,+ -- or equal to, the given value are used.+ --+ -- @since 0.4.0.0+ | FExpr T.Text+ -- ^ Filter a data stream so that only data that satisfy the given predicate+ -- expression are used.+ | FCompose BooleanOp+ -- ^ Build up a filtering predicate through logical composition such+ -- as 'And' and 'Or'.+ --+ -- The following fgragment will apply a filter to identify only+ -- those items selected interactively and that represent ages+ -- over 65:+ --+ -- @+ -- trans = 'transform'+ -- . 'filter'+ -- ('FCompose'+ -- ('And' ('Selection' "brush") ('Expr' "datum.age > 65"))+ -- )+ -- @+ | FSelection T.Text+ -- ^ Filter a data stream so that only data in a given field that are+ -- within the given interactive selection are used.+ --+ -- @+ -- sel = 'selection' . 'select' \"myBrush\" 'Interval' ['Encodings' ['ChX']]+ -- trans = 'transform' . 'filter' ('FSelection' \"myBrush\")+ -- @+ | FOneOf T.Text DataValues+ -- ^ Filter a data stream so that only data in a given field contained in the given+ -- list of values are used.+ | FRange T.Text FilterRange+ -- ^ Filter a data stream so that only data in a given field+ -- that are within the given range are used.+ --+ -- For example:+ --+ -- @+ -- 'filter' ('FRange' "date" ('DateRange' ['DTYear' 2006] ['DTYear' 2016])+ -- @+ --+ -- See 'FilterOpTrans' for more use cases.+ | FValid T.Text+ -- ^ Filter a data stream so that only valid data (i.e. not null or NaN) in a given+ -- field are used.+ --+ -- @since 0.4.0.0+++fop_ :: T.Text -> T.Text -> DataValue -> [LabelledSpec]+fop_ field label val = [field_ field, label .= dataValueSpec val]++filterProperty :: Filter -> [LabelledSpec]++filterProperty (FEqual field val) = fop_ field "equal" val+filterProperty (FLessThan field val) = fop_ field "lt" val+filterProperty (FLessThanEq field val) = fop_ field "lte" val+filterProperty (FGreaterThan field val) = fop_ field "gt" val+filterProperty (FGreaterThanEq field val) = fop_ field "gte" val++filterProperty (FSelection selName) = ["selection" .= selName]++filterProperty (FRange field vals) =+ let ans = case vals of+ NumberRange mn mx -> map toJSON [mn, mx]+ DateRange dMin dMax -> [process dMin, process dMax]++ process [] = A.Null+ process dts = object (map dateTimeProperty dts)++ in [field_ field, "range" .= ans]++filterProperty (FOneOf field vals) =+ let ans = case vals of+ Numbers xs -> map toJSON xs+ DateTimes dts -> map (object . map dateTimeProperty) dts+ Strings ss -> map toJSON ss+ Booleans bs -> map toJSON bs++ in [field_ field, "oneOf" .= ans]++filterProperty (FValid field) = [field_ field, "valid" .= True]+filterProperty _ = [] -- ignore FExpr and FCompose+++filterSpec :: Filter -> VLSpec+filterSpec (FExpr expr) = toJSON expr+filterSpec (FCompose boolExpr) = booleanOpSpec boolExpr+filterSpec f = object (filterProperty f)++trFilterSpec :: MarkChannel -> Filter -> VLSpec+trFilterSpec _ (FExpr expr) = toJSON expr+trFilterSpec _ (FCompose boolExpr) = booleanOpSpec boolExpr+trFilterSpec mchan fi = object (markChannelProperty mchan <> filterProperty fi)+++{-|++A pair of filter range data values. The first argument is the inclusive minimum+vale to accept and the second the inclusive maximum.+-}+data FilterRange+ = NumberRange Double Double+ | DateRange [DateTime] [DateTime]+++{-|++Specifies the type and content of geometry specifications for programatically+creating GeoShapes. These can be mapped to the+<https://tools.ietf.org/html/rfc7946#section-3.1 GeoJson geometry object types>+where the pluralised type names refer to their @Multi@ prefixed equivalent in the+GeoJSON specification.+-}+data Geometry+ = GeoPoint Double Double+ -- ^ The GeoJson geometry @point@ type.+ | GeoPoints [(Double, Double)]+ -- ^ The GeoJson geometry @multi-point@ type.+ | GeoLine [(Double, Double)]+ -- ^ The GeoJson geometry @line@ type.+ | GeoLines [[(Double, Double)]]+ -- ^ The GeoJson geometry @multi-line@ type.+ | GeoPolygon [[(Double, Double)]]+ -- ^ The GeoJson geometry @polygon@ type.+ | GeoPolygons [[[(Double, Double)]]]+ -- ^ The GeoJson geometry @multi-polygon@ type.+++{-|++Specifies a geometric object to be used in a geoShape specification. The first+parameter is the geometric type, the second an optional list of properties to be+associated with the object.++@+'geometry' ('GeoPolygon' [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 59 ) ] ]) []+@+-}+geometry :: Geometry -> [(T.Text, DataValue)] -> VLSpec+geometry gType properties =+ object ([ ("type", fromT "Feature")+ , ("geometry", geometryTypeSpec gType) ]+ <> if null properties+ then []+ else [("properties",+ object (map (second dataValueSpec) properties))]+ )+++geometryTypeSpec :: Geometry -> VLSpec+geometryTypeSpec gType =+ let toCoords :: [(Double, Double)] -> VLSpec+ toCoords = toJSON -- rely on Aeson converting a pair to a 2-element list++ toCoordList :: [[(Double, Double)]] -> VLSpec+ toCoordList = toJSON . map toCoords -- this is just toJSON isn't it?++ -- can we replace this infinite tower of toJSON calls with one toJSON call?+ (ptype, cs) = case gType of+ GeoPoint x y -> ("Point", toJSON [x, y])+ GeoPoints coords -> ("MultiPoint", toCoords coords)+ GeoLine coords -> ("LineString", toCoords coords)+ GeoLines coords -> ("MultiLineString", toCoordList coords)+ GeoPolygon coords -> ("Polygon", toCoordList coords)+ GeoPolygons ccoords -> ("MultiPolygon", toJSON (map toCoordList ccoords))++ in object [("type", ptype), ("coordinates", cs)]+++{-|++Generate a data source that is a sphere for bounding global geographic data.+The sphere will be subject to whatever projection is specified for the view.++@+'toVegaLite'+ [ 'sphere'+ , 'projection' [ 'PrType' 'Orthographic' ]+ , 'mark' 'Geoshape' [ 'MFill' "aliceblue" ]+ ]+@++@since 0.4.0.0+-}+sphere :: Data+sphere = (VLData, object ["sphere" .= True])+++{-|++Generate a grid of lines of longitude (meridians) and latitude+(parallels).++@+let proj = 'projection' [ 'PrType' 'Orthographic' ]+ sphereSpec = 'asSpec' [ 'sphere'+ , 'mark' 'Geoshape' [ 'MFill' "aliceblue" ] ]+ gratSpec =+ 'asSpec'+ [ 'graticule' [ 'GrStep' (5, 5) ]+ , 'mark' 'Geoshape' [ 'MFilled' False, 'MStrokeWidth' 0.3 ]+ ]+in 'toVegaLite' [ proj, 'layer' [ sphereSpec, gratSpec ] ]+@++@since 0.4.0.0++-}+graticule ::+ [GraticuleProperty] -- ^ An empty list uses the default parameters+ -> Data+graticule [] = (VLData, object ["graticule" .= True])+graticule grProps =+ (VLData, object ["graticule" .= object (map graticuleProperty grProps)])+++{-|++Determine the properties of graticules. See the+<https://vega.github.io/vega-lite/docs/data.html#graticule Vega-Lite documentation> for details.++@since 0.4.0.0++-}+data GraticuleProperty+ = GrExtent (Double, Double) (Double, Double)+ -- ^ Define the extent of both the major and minor graticules.+ -- The range is given as longitude, latitude pairs of the+ -- minimum and then maximum extent. The units are degrees.+ | GrExtentMajor (Double, Double) (Double, Double)+ -- ^ As @GrExtent@ but for the major graticule lines only.+ | GrExtentMinor (Double, Double) (Double, Double)+ -- ^ As @GrExtent@ but for the minor graticule lines only.+ | GrStep (Double, Double)+ -- ^ The step angles for the graticule lines, given as a longitude,+ -- latitude pair defining the EW and NS intervals respectively.+ -- The units are degrees.+ --+ -- By default major graticule lines extend to both poles but the+ -- minor lines stop at ±80 degrees latitude.+ | GrStepMajor (Double, Double)+ -- ^ As @GrStep@ but for the major graticule lines only.+ --+ -- The default is @(90, 360)@.+ | GrStepMinor (Double, Double)+ -- ^ As @GrStep@ but for the minor graticule lines only.+ --+ -- The default is @(10, 10)@.+ | GrPrecision Double+ -- ^ The precision of the graticule. The units are degrees.+ -- A smaller value reduces visual artifacts (steps) but takes longer+ -- to render.+ --+ -- The default is @2.5@.+++graticuleProperty :: GraticuleProperty -> LabelledSpec+graticuleProperty (GrExtent (lng1, lat1) (lng2, lat2)) =+ "extent" .= [[lng1, lat1], [lng2, lat2]]+graticuleProperty (GrExtentMajor (lng1, lat1) (lng2, lat2)) =+ "extentMajor" .= [[lng1, lat1], [lng2, lat2]]+graticuleProperty (GrExtentMinor (lng1, lat1) (lng2, lat2)) =+ "extentMinor" .= [[lng1, lat1], [lng2, lat2]]+graticuleProperty (GrStep (lng, lat)) = "step" .= [lng, lat]+graticuleProperty (GrStepMajor (lng, lat)) = "stepMajor" .= [lng, lat]+graticuleProperty (GrStepMinor (lng, lat)) = "stepMinor" .= [lng, lat]+graticuleProperty (GrPrecision x) = "precision" .= x+++{-|++Indicates whether or not a scale domain should be independent of others in a+composite visualization. See the+<https://vega.github.io/vega-lite/docs/resolve.html Vega-Lite documentation> for+details.++For use with 'Resolve'.++-}+data Resolution+ = Shared+ | Independent+++resolutionLabel :: Resolution -> T.Text+resolutionLabel Shared = "shared"+resolutionLabel Independent = "independent"+++{-|++Used to determine how a channel's axis, scale or legend domains should be resolved+if defined in more than one view in a composite visualization. See the+<https://vega.github.io/vega-lite/docs/resolve.html Vega-Lite documentation>+for details.+-}+data Resolve+ = RAxis [(Channel, Resolution)]+ | RLegend [(Channel, Resolution)]+ | RScale [(Channel, Resolution)]+++resolveProperty :: Resolve -> LabelledSpec+resolveProperty res =+ let (nme, rls) = case res of+ RAxis chRules -> ("axis", chRules)+ RLegend chRules -> ("legend", chRules)+ RScale chRules -> ("scale", chRules)++ ans = map (\(ch, rule) -> (channelLabel ch .= resolutionLabel rule)) rls+ in (nme, object ans)+++{-|++Represents a facet header property. For details, see the+<https://vega.github.io/vega-lite/docs/facet.html#header Vega-Lite documentation>.++Labels refer to the title of each sub-plot in a faceted view and+title is the overall title of the collection.++-}++-- TODO: should there be a HLabelBaseline, HTitleFontStyle, ...?+-- However, the following covers the vega-lite 3.3.0 schema++data HeaderProperty+ = HFormat T.Text+ -- ^ [Formatting pattern](https://vega.github.io/vega-lite/docs/format.html) for+ -- facet header (title) values. To distinguish between formatting as numeric values+ -- and data/time values, additionally use 'HFormatAsNum' or 'HFormatAsTemporal'.+ | HFormatAsNum+ -- ^ Facet headers should be formatted as numbers. Use a+ -- [d3 numeric format string](https://github.com/d3/d3-format#locale_format)+ -- with 'HFormat'.+ --+ -- @since 0.4.0.0+ | HFormatAsTemporal+ -- ^ Facet headers should be formatted as dates or times. Use a+ -- [d3 date/time format string](https://github.com/d3/d3-time-format#locale_format)+ -- with 'HFormat'.+ --+ -- @since 0.4.0.0+ | HTitle T.Text+ -- ^ The title for the facets.+ | HNoTitle+ -- ^ Draw no title for the facets.+ --+ -- @since 0.4.0.0+ | HLabelAlign HAlign+ -- ^ The horizontal alignment of the labels.+ --+ -- @since 0.4.0.0+ | HLabelAnchor APosition+ -- ^ The anchor position for the labels.+ --+ -- @since 0.4.0.0+ | HLabelAngle Angle+ -- ^ The angle to draw the labels.+ --+ -- @since 0.4.0.0+ | HLabelColor Color+ -- ^ The color of the labels.+ --+ -- @since 0.4.0.0+ | HLabelFont T.Text+ -- ^ The font for the labels.+ --+ -- @since 0.4.0.0+ | HLabelFontSize Double+ -- ^ The font size for the labels.+ --+ -- @since 0.4.0.0+ | HLabelLimit Double+ -- ^ The maximum length of each label.+ --+ -- @since 0.4.0.0+ | HLabelOrient Side+ -- ^ The position of the label relative to its sub-plot.+ --+ -- @since 0.4.0.0+ | HLabelPadding Double+ -- ^ The spacing in pixels between the label and its sub-plot.+ --+ -- @since 0.4.0.0+ | HTitleAlign HAlign+ -- ^ The horizontal alignment of the title.+ --+ -- @since 0.4.0.0+ | HTitleAnchor APosition+ -- ^ The anchor position for the title.+ --+ -- @since 0.4.0.0+ | HTitleAngle Angle+ -- ^ The angle to draw the title.+ --+ -- @since 0.4.0.0+ | HTitleBaseline VAlign+ -- ^ The vertical alignment of the title.+ --+ -- @since 0.4.0.0+ | HTitleColor Color+ -- ^ The color of the title.+ --+ -- @since 0.4.0.0+ | HTitleFont T.Text+ -- ^ The font for the title.+ --+ -- @since 0.4.0.0+ | HTitleFontSize Double+ -- ^ The font size for the title.+ --+ -- @since 0.4.0.0+ | HTitleFontWeight T.Text+ -- ^ The font weight for the title.+ --+ -- @since 0.4.0.0+ | HTitleLimit Double+ -- ^ The maximum length of the title.+ --+ -- @since 0.4.0.0+ | HTitleOrient Side+ -- ^ The position of the title relative to the sub-plots.+ --+ -- @since 0.4.0.0+ | HTitlePadding Double+ -- ^ The spacing in pixels between the title and the labels.+ --+ -- @since 0.4.0.0+++headerProperty :: HeaderProperty -> LabelledSpec+headerProperty (HFormat fmt) = "format" .= fmt+headerProperty HFormatAsNum = "formatType" .= fromT "number"+headerProperty HFormatAsTemporal = "formatType" .= fromT "time"+headerProperty (HTitle ttl) = "title" .= ttl+headerProperty HNoTitle = "title" .= A.Null+headerProperty (HLabelAlign ha) = "labelAlign" .= hAlignLabel ha+headerProperty (HLabelAnchor a) = "labelAnchor" .= anchorLabel a+headerProperty (HLabelAngle x) = "labelAngle" .= x+headerProperty (HLabelColor s) = "labelColor" .= s+headerProperty (HLabelFont s) = "labelFont" .= s+headerProperty (HLabelFontSize x) = "labelFontSize" .= x+headerProperty (HLabelLimit x) = "labelLimit" .= x+headerProperty (HLabelOrient orient) = "labelOrient" .= sideLabel orient+headerProperty (HLabelPadding x) = "labelPadding" .= x+headerProperty (HTitleAlign ha) = "titleAlign" .= hAlignLabel ha+headerProperty (HTitleAnchor a) = "titleAnchor" .= anchorLabel a+headerProperty (HTitleAngle x) = "titleAngle" .= x+headerProperty (HTitleBaseline va) = "titleBaseline" .= vAlignLabel va+headerProperty (HTitleColor s) = "titleColor" .= s+headerProperty (HTitleFont s) = "titleFont" .= s+headerProperty (HTitleFontWeight s) = "titleFontWeight" .= s+headerProperty (HTitleFontSize x) = "titleFontSize" .= x+headerProperty (HTitleLimit x) = "titleLimit" .= x+headerProperty (HTitleOrient orient) = "titleOrient" .= sideLabel orient+headerProperty (HTitlePadding x) = "titlePadding" .= x+++-- | Types of hyperlink channel property used for linking marks or text to URLs.++data HyperlinkChannel+ = HName T.Text+ -- ^ Field used for encoding with a hyperlink channel.+ | HRepeat Arrangement+ -- ^ Reference in a hyperlink channel to a field name generated by 'repeatFlow'+ -- or 'repeat'. The parameter identifies whether reference is being made to+ -- fields that are to be arranged in columns, in rows, or a with a flow layout.+ | HmType Measurement+ -- ^ Level of measurement when encoding with a hyperlink channel.+ | HBin [BinProperty]+ -- ^ Discretize numeric values into bins when encoding with a hyperlink channel.+ | HBinned+ -- ^ Indicate that data encoded with a hyperlink channel are already binned.+ --+ -- @since 0.4.0.0+ | HAggregate Operation+ -- ^ Compute aggregate summary statistics for a field to be encoded with a+ -- hyperlink channel.+ | HTimeUnit TimeUnit+ | HSelectionCondition BooleanOp [HyperlinkChannel] [HyperlinkChannel]+ -- ^ Make a hyperlink channel conditional on interactive selection. The first parameter+ -- provides the selection to evaluate, the second the encoding to apply if the hyperlink+ -- has been selected, the third the encoding if it is not selected.+ | HDataCondition [(BooleanOp, [HyperlinkChannel])] [HyperlinkChannel]+ -- ^ Make a hyperlink channel conditional on one or more predicate expressions. The first+ -- parameter is a list of tuples each pairing an expression to evaluate with the encoding+ -- if that expression is @True@. The second is the encoding if none of the expressions+ -- evaluate as @True@.+ --+ -- The arguments to this constructor have changed in @0.4.0.0@+ -- to support multiple expressions.+ | HString T.Text+ -- ^ Literal string value when encoding with a hyperlink channel.++hyperlinkChannelProperty :: HyperlinkChannel -> [LabelledSpec]+hyperlinkChannelProperty (HName s) = [field_ s]+hyperlinkChannelProperty (HRepeat arr) = ["field" .= object [repeat_ arr]]+hyperlinkChannelProperty (HmType t) = [mtype_ t]+hyperlinkChannelProperty (HBin bps) = [bin bps]+hyperlinkChannelProperty HBinned = [binned_]+hyperlinkChannelProperty (HSelectionCondition selName ifClause elseClause) =+ selCond_ hyperlinkChannelProperty selName ifClause elseClause+hyperlinkChannelProperty (HDataCondition tests elseClause) =+ dataCond_ hyperlinkChannelProperty tests elseClause+hyperlinkChannelProperty (HTimeUnit tu) = [timeUnit_ tu]+hyperlinkChannelProperty (HAggregate op) = [aggregate_ op]+hyperlinkChannelProperty (HString s) = [value_ s]+++----++{-|++Create a pair of continuous domain to color mappings suitable for customising+ordered scales. The first parameter is a tuple representing the mapping of the lowest+numeric value in the domain to its equivalent color; the second tuple the mapping+of the highest numeric value to color. If the domain contains any values between+these lower and upper bounds they are interpolated according to the scale's interpolation+function. This is a convenience function equivalent to specifying separate 'SDomain'+and 'SRange' lists and is safer as it guarantees a one-to-one correspondence between+domain and range values.++@+'color'+ [ 'MName' "year"+ , 'MmType' 'Ordinal'+ , 'MScale' (domainRangeMap (1955, \"rgb(230,149,156)\") (2000, \"rgb(145,26,36)\"))+ ]+@+-}++domainRangeMap :: (Double, T.Text) -> (Double, T.Text) -> [ScaleProperty]+domainRangeMap lowerMap upperMap =+ let (domain, range) = unzip [lowerMap, upperMap]+ in [SDomain (DNumbers domain), SRange (RStrings range)]+++{-|++Create a set of discrete domain to color mappings suitable for customising categorical+scales. The first item in each tuple should be a domain value and the second the+color value with which it should be associated. It is a convenience function equivalent+to specifying separate 'SDomain' and 'SRange' lists and is safer as it guarantees+a one-to-one correspondence between domain and range values.++@+'color'+ [ 'MName' "weather"+ , 'MmType' Nominal+ , 'MScale' (+ categoricalDomainMap+ [ ( "sun", "yellow" )+ , ( "rain", "blue" )+ , ( "fog", "grey" )+ ]+ )+ ]+@+-}++categoricalDomainMap :: [(T.Text, T.Text)] -> [ScaleProperty]+categoricalDomainMap scaleDomainPairs =+ let (domain, range) = unzip scaleDomainPairs+ in [SDomain (DStrings domain), SRange (RStrings range)]+++{-|++Create a list of fields to use in set of repeated small multiples. The list of+fields named here can be referenced in an encoding with @'PRepeat' 'Column'@+or @'PRepeat' 'Row'@.++-}+data RepeatFields+ = RowFields [T.Text]+ | ColumnFields [T.Text]+++repeatFieldsProperty :: RepeatFields -> LabelledSpec+repeatFieldsProperty rfs =+ let (nme, vs) = case rfs of+ RowFields fields -> ("row", fields)+ ColumnFields fields -> ("column", fields)++ in nme .= map toJSON vs+++{-|++Types of facet channel property used for creating a composed facet view of small+multiples.++-}++-- based on schema 3.3.0 #/definitions/FacetFieldDef++data FacetChannel+ = FName T.Text+ -- ^ The name of the field from which to pull a data value.+ | FmType Measurement+ -- ^ The encoded field's type of measurement.+ | FAggregate Operation+ -- ^ Aggregation function for the field.+ | FBin [BinProperty]+ -- ^ Describe how to bin quantitative fields, or whether the+ -- channels are already binned.+ | FHeader [HeaderProperty]+ -- ^ The properties of a facet's header.+ | FSort [SortProperty]+ -- ^ Sort order for the encoded field.+ --+ -- @since 0.4.0.0+ | FTimeUnit TimeUnit+ -- ^ The time-unit for a temporal field.+ | FTitle T.Text+ -- ^ The title for the field.+ --+ -- @since 0.4.0.0+ | FNoTitle+ -- ^ Draw no title.+ --+ -- @since 0.4.0.0++facetChannelProperty :: FacetChannel -> LabelledSpec+facetChannelProperty (FName s) = field_ s+facetChannelProperty (FmType measure) = mtype_ measure+facetChannelProperty (FAggregate op) = aggregate_ op+facetChannelProperty (FBin bps) = bin bps+facetChannelProperty (FHeader hps) = header_ hps+facetChannelProperty (FSort sps) = sort_ sps+facetChannelProperty (FTitle s) = "title" .= s+facetChannelProperty FNoTitle = "title" .= A.Null+facetChannelProperty (FTimeUnit tu) = timeUnit_ tu+++{-|++Configuration options for faceted views, used with 'FacetStyle'.++See the+<https://vega.github.io/vega-lite/docs/facet.html#facet-configuration Vega-Lite facet config documentation>.++@since 0.4.0.0++-}+data FacetConfig+ = FColumns Int+ -- ^ The maximum number of columns to use in a faceted-flow layout.+ | FSpacing Double+ -- ^ The spacing in pixels between sub-views in a faceted composition.+++facetConfigProperty :: FacetConfig -> LabelledSpec+facetConfigProperty (FColumns n) = "columns" .= n+facetConfigProperty (FSpacing x) = "spacing" .= x+++-- | Types of text channel property used for displaying text as part of the visualization.++-- Basing the following partly on vega-lite-3.3.0.json / TextFieldDef+-- but that doesn't seem to be sufficient.++data TextChannel+ = TName T.Text+ -- ^ Name of the field used for encoding with a text channel.+ | TAggregate Operation+ -- ^ Compute some aggregate summary statistics for a field to be encoded with a+ -- text channel. The type of aggregation is determined by the given operation+ -- parameter.+ | TBin [BinProperty]+ -- ^ Discretize numeric values into bins when encoding with a text channel.+ | TBinned+ -- ^ Indicate that data encoded with a text channel are already binned.+ --+ -- @since 0.4.0.0+ | TDataCondition [(BooleanOp, [TextChannel])] [TextChannel]+ -- ^ Make a text channel conditional on one or more predicate expressions. The first+ -- parameter is a list of tuples each pairing an expression to evaluate with the encoding+ -- if that expression is @True@. The second is the encoding if none of the expressions+ -- evaluate as @True@.+ --+ -- The arguments to this constructor have changed in @0.4.0.0@+ -- to support multiple expressions.+ | TFormat T.Text+ -- ^ [Formatting pattern](https://vega.github.io/vega-lite/docs/format.html)+ -- for text marks. To distinguish between formatting as numeric values and data/time+ -- values, additionally use 'TFormatAsNum' or 'TFormatAsTemporal'.+ | TFormatAsNum+ -- ^ The text marks should be formatted as numbers. Use a+ -- [d3 numeric format string](https://github.com/d3/d3-format#locale_format)+ -- with 'TFormat'.+ --+ -- @since 0.4.0.0+ | TFormatAsTemporal+ -- ^ The text marks should be formatted as dates or times. Use a+ -- [d3 date/time format string](https://github.com/d3/d3-time-format#locale_format)+ -- with 'TFormat'.+ --+ -- @since 0.4.0.0+ | TmType Measurement+ -- ^ Level of measurement when encoding with a text channel.+ | TRepeat Arrangement+ -- ^ Reference in a text channel to a field name generated by 'repeatFlow'+ -- or 'repeat'. The parameter identifies whether reference is being made to+ -- fields that are to be arranged in columns, in rows, or a with a flow layout.+ | TSelectionCondition BooleanOp [TextChannel] [TextChannel]+ -- ^ Make a text channel conditional on interactive selection. The first parameter+ -- is a selection condition to evaluate; the second the encoding to apply if that+ -- selection is true; the third parameter is the encoding if the selection is false.+ | TTitle T.Text+ -- ^ Title of a field when encoding with a text or tooltip channel.+ --+ -- @since 0.4.0.0+ | TNoTitle+ -- ^ Display no title.+ --+ -- @since 0.4.0.0+ | TTimeUnit TimeUnit+ -- ^ Time unit aggregation of field values when encoding with a text channel.+++textChannelProperty :: TextChannel -> [LabelledSpec]+textChannelProperty (TName s) = [field_ s]+textChannelProperty (TAggregate op) = [aggregate_ op]+textChannelProperty (TBin bps) = [bin bps]+textChannelProperty TBinned = [binned_]+textChannelProperty (TFormat fmt) = ["format" .= fmt]+textChannelProperty TFormatAsNum = ["formatType" .= fromT "number"]+textChannelProperty TFormatAsTemporal = ["formatType" .= fromT "time"]+textChannelProperty (TmType measure) = [mtype_ measure]+textChannelProperty (TRepeat arr) = ["field" .= object [repeat_ arr]]+textChannelProperty (TTitle s) = ["title" .= s]+textChannelProperty TNoTitle = ["title" .= A.Null]+textChannelProperty (TTimeUnit tu) = [timeUnit_ tu]+textChannelProperty (TDataCondition tests elseClause) =+ dataCond_ textChannelProperty tests elseClause+textChannelProperty (TSelectionCondition selName ifClause elseClause) =+ selCond_ textChannelProperty selName ifClause elseClause+++-- | Properties of an ordering channel used for sorting data fields.++data OrderChannel+ = OName T.Text+ | ORepeat Arrangement+ -- ^ Reference in an order channel to a field name generated by 'repeatFlow'+ -- or 'repeat'. The parameter identifies whether reference is being made to+ -- fields that are to be arranged in columns, in rows, or a with a flow layout.+ | OmType Measurement+ | OBin [BinProperty]+ | OAggregate Operation+ | OTimeUnit TimeUnit+ | OSort [SortProperty]+++orderChannelProperty :: OrderChannel -> LabelledSpec+orderChannelProperty (OName s) = field_ s+orderChannelProperty (ORepeat arr) = "field" .= object [repeat_ arr]+orderChannelProperty (OmType measure) = mtype_ measure+orderChannelProperty (OBin bps) = bin bps+orderChannelProperty (OAggregate op) = aggregate_ op+orderChannelProperty (OTimeUnit tu) = timeUnit_ tu+orderChannelProperty (OSort ops) = sort_ ops+++-- | Level of detail channel properties used for creating a grouped channel encoding.++data DetailChannel+ = DName T.Text+ | DmType Measurement+ | DBin [BinProperty]+ | DTimeUnit TimeUnit+ | DAggregate Operation+++detailChannelProperty :: DetailChannel -> LabelledSpec+detailChannelProperty (DName s) = field_ s+detailChannelProperty (DmType t) = mtype_ t+detailChannelProperty (DBin bps) = bin bps+detailChannelProperty (DTimeUnit tu) = timeUnit_ tu+detailChannelProperty (DAggregate op) = aggregate_ op+++{-|++Provides details of the mapping between a row or column and its field+definitions in a set of faceted small multiples. For details see the+<https://vega.github.io/vega-lite/docs/facet.html#mapping Vega-Lite documentation>.+-}+data FacetMapping+ = ColumnBy [FacetChannel]+ | RowBy [FacetChannel]+++facetMappingProperty :: FacetMapping -> LabelledSpec+facetMappingProperty (RowBy fFields) =+ "row" .= object (map facetChannelProperty fFields)+facetMappingProperty (ColumnBy fFields) =+ "column" .= object (map facetChannelProperty fFields)+++{-|++Create a single global configuration from a list of configuration specifications.+Configurations are applied to all relevant items in the specification. See the+<https://vega.github.io/vega-lite/docs/config.html Vega-Lite documentation> for+more details.++The following example would make axis lines (domain) 2 pixels wide,+remove the border rectangle and require interactive selection of items+to use a double-click:++@+config =+ 'configure'+ . 'configuration' ('Axis' [ 'DomainWidth' 1 ])+ . 'configuration' ('View' [ 'ViewStroke' (Just "transparent") ])+ . 'configuration' ('SelectionStyle' [ ( 'Single', [ 'On' \"dblclick\" ] ) ])+@+-}+configure :: [LabelledSpec] -> PropertySpec+configure configs = (VLConfig, object configs)+++-- | Alignment to apply to grid rows and columns generated by a composition+-- operator. This version sets the same alignment for rows and columns.+--+-- See also 'alignRC'.+--+-- @since 0.4.0.0++align :: CompositionAlignment -> PropertySpec+align algn = (VLAlign, compositionAlignmentSpec algn)+++-- | Similar to 'align' but with independent alignments for rows and columns.+--+-- See also 'align'.+--+-- @since 0.4.0.0++alignRC ::+ CompositionAlignment -- ^ Row alignment+ -> CompositionAlignment -- ^ Column alignment+ -> PropertySpec+alignRC alRow alCol =+ (VLSpacing, object [ "row" .= compositionAlignmentSpec alRow+ , "col" .= compositionAlignmentSpec alCol+ ])+++-- | Spacing between sub-views in a composition operator.+--+-- See also 'spacingRC'.+--+-- @since 0.4.0.0++spacing ::+ Double -- ^ Spacing in pixels.+ -> PropertySpec+spacing sp = (VLSpacing, toJSON sp)+++-- | Set the spacing between the rows and columns.+--+-- See also 'spacing'.+--+-- @since 0.4.0.0++spacingRC ::+ Double -- ^ Spacing between rows (in pixels).+ -> Double -- ^ Spacing between columns (in pixels).+ -> PropertySpec+spacingRC spRow spCol = (VLSpacing, object ["row" .= spRow, "column" .= spCol])+++-- | Are sub-views in a composition operator centred relative to their respective+-- rows and columns?+--+-- See also 'centerRC'.+--+-- @since 0.4.0.0++center :: Bool -> PropertySpec+center c = (VLCenter, toJSON c)+++-- | Are sub-views in a composition operator centred relative to their respective+-- rows and columns?+--+-- See also 'center'.+--+-- @since 0.4.0.0++centerRC ::+ Bool -- ^ Are rows to be centered?+ -> Bool -- ^ Are columns to be centered?+ -> PropertySpec+centerRC cRow cCol = (VLCenter, object ["row" .= cRow, "col" .= cCol])+++-- | This is used with 'bounds' to define the extent of a sub plot.+--+-- @since 0.4.0.0++data Bounds+ = Full+ -- ^ Bounds calculation should use the entire plot area (including axes, title,+ -- and legend).+ | Flush+ -- ^ Bounds calculation should take only the specified width and height values for+ -- a sub-view. Useful when attempting to place sub-plots without axes or legends into+ -- a uniform grid structure.+++boundsSpec :: Bounds -> VLSpec+boundsSpec Full = "full"+boundsSpec Flush = "flush"+++{-|++Bounds calculation method to use for determining the extent of a sub-plot in+a composed view.++@since 0.4.0.0+-}+bounds :: Bounds -> PropertySpec+bounds bnds = (VLBounds, boundsSpec bnds)+++{-|++The list of specifications to be juxtaposed horizontally in a flow+layout of views.++The number of columns in the flow layout can be set with 'columns'+and, if not specified, will default to a single row of unlimited columns.++@+let dvals = 'dataSequenceAs' 0 6.28 0.1 \"x\"+ trans = 'transform'+ . 'calculateAs' \"sin(datum.x)\" \"sinX\"+ . 'calculateAs' \"cos(datum.x)\" \"cosX\"+ enc = 'encoding'+ . 'position' 'X' ['PName' \"x\", 'PmType' 'Quantitative']+ encCos = enc . 'position' 'Y' ['PName' \"cosX\", 'PmType' 'Quantitative']+ encSin = enc . 'position' 'Y' ['PName' \"sinX\", 'PmType' 'Quantitative']++in toVegaLite [ dvals+ , trans []+ , 'vlConcat' [ 'asSpec' [encCos [], 'mark' 'Line' []]+ , 'asSpec' [encSin [], 'mark' 'Line' []]+ ]+ ]+@++This is named @concat@ in Elm VegaLite but has been renamed here+to avoid conflicting with the Prelude.++@since 0.4.0.0++-}+vlConcat :: [VLSpec] -> PropertySpec+vlConcat specs = (VLConcat, toJSON specs)+++{-|++Defines the fields that will be used to facet a view in rows or columns to create+a set of small multiples. This is used where the encoding of the visualization in small+multiples is identical, but data for each is grouped by the given fields. When+creating a faceted view in this way you also need to define a full specification+to apply to each of those facets using 'asSpec'.++See the+<https://vega.github.io/vega-lite/docs/facet.html Vega-Lite documentation>+for further details.++@+'toVegaLite'+ [ facet [ 'RowBy' [ 'FName' \"Month\", 'FmType' 'Ordinal' ]+ , 'ColumnBy' [ 'FName' \"Week\", 'FmType' 'Ordinal' ]+ ]+ , 'specification' spec+ ]+@++See also 'facetFlow'.++-}++facet :: [FacetMapping] -> PropertySpec+facet fMaps = (VLFacet, object (map facetMappingProperty fMaps))+++{-|++Facet a view to create small multiples in a flow layout. Used when the encoding+of the visualization in small multiples is identical, but data for each is grouped+by the given fields. When creating a faceted view in this way you also need to+define a full specification to apply to each of those facets using 'asSpec'.++Small multiples will be laid out from left to right, moving on to new rows only+if the number of plots exceeds an optional column limit (specified via 'columns').++@+'toVegaLite'+ [ facetFlow [ 'FName' \"Origin\", 'FmType' 'Nominal' ]+ , 'specification' spec+ ]+@++See also 'facet'.++@since 0.4.0.0+-}+facetFlow :: [FacetChannel] -> PropertySpec+facetFlow fFields = (VLFacet, object (map facetChannelProperty fFields))+++{-|++Overrides the default height of the visualization. If not specified the height+will be calculated based on the content of the visualization. See+'autosize' for customization of the content sizing relative to this+setting.++@+'toVegaLite'+ [ 'height' 300+ , 'dataFromUrl' "data/population.json" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+height :: Double -> PropertySpec+height h = (VLHeight, toJSON h)+++{-|++Configuration options for concatenated views, used with 'ConcatStyle'.++@since 0.4.0.0++-}+data ConcatConfig+ = ConcatColumns Int+ -- ^ The maximum number of columns to use in a concatenated flow layout.+ | ConcatSpacing Double+ -- ^ The spacing in pixels between sub-views in a concatenated view.+++concatConfigProperty :: ConcatConfig -> LabelledSpec+concatConfigProperty (ConcatColumns n) = "columns" .= n+concatConfigProperty (ConcatSpacing x) = "spacing" .= x+++{-|++Assigns a list of specifications to be juxtaposed horizontally in a visualization.++@+'toVegaLite'+ [ 'dataFromUrl' "data/driving.json" []+ , hConcat [ spec1, spec2 ]+ ]+@+-}+hConcat :: [VLSpec] -> PropertySpec+hConcat specs = (VLHConcat, toJSON specs)+++{-|++Assigns a list of specifications to superposed layers in a visualization.++@+'toVegaLite' ['dataFromUrl' "data/driving.json" [], layer [spec1, spec2]]+@++A complete example showing @layer@ in use:++@+let dvals = 'dataFromColumns' []+ . 'dataColumn' \"x\" ('Numbers' [1, 2, 3, 4, 5])+ . 'dataColumn' \"a\" ('Numbers' [28, 91, 43, 55, 81])+ enc = 'encoding'+ . 'position' 'X' ['PName' \"x\", 'PmType' 'Ordinal']+ . 'position' 'Y' ['PName' \"a\", 'PmType' 'Quantitative']+ . 'text' ['TName' \"a\", 'TmType' 'Nominal']++ in 'toVegaLite' [ dvals []+ , enc []+ , 'layer' [ 'asSpec' ['mark' 'Bar' []]+ , 'asSpec' ['mark' 'Text' ['MdY' (-8)]]+ ]+ ]+@++-}+layer :: [VLSpec] -> PropertySpec+layer specs = (VLLayer, toJSON specs)+++{-|++Provides an optional name to be associated with the visualization.++@+'toVegaLite'+ [ 'name' \"PopGrowth\"+ , 'dataFromUrl' \"data/population.json\" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+name :: T.Text -> PropertySpec+name s = (VLName, toJSON s)+++{-|++Set the padding around the visualization in pixel units. The way padding is+interpreted will depend on the 'autosize' properties. See the+<https://vega.github.io/vega-lite/docs/spec.html#top-level-specifications Vega-Lite documentation>+for details.++@+'toVegaLite'+ [ 'width' 500+ , 'padding' ('PEdges' 20 10 5 15)+ , 'dataFromUrl' "data/population.json" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+padding :: Padding -> PropertySpec+padding pad = (VLPadding, paddingSpec pad)+++{-|++Define the fields that will be used to compose rows and columns of a+set of small multiples. This is used where the encoding of the+visualization in small multiples is largely identical, but the data+field used in each might vary. When a list of fields is identified+with @repeat@ you also need to define a full specification to apply to+each of those fields using 'asSpec'.++Unlike __faceting__, which creates multiple charts based on different values of a+single field, __repeating__ uses a different field for each chart.++See the+<https://vega.github.io/vega-lite/docs/repeat.html Vega-Lite documentation>+for further details.++@+'toVegaLite'+ [ 'repeat' ['ColumnFields' [\"Cat\", \"Dog\", \"Fish\"]]+ , 'specification' ('asSpec' spec)+ ]+@++See also 'repeatFlow'.++-}++repeat :: [RepeatFields] -> PropertySpec+repeat fields = (VLRepeat, object (map repeatFieldsProperty fields))+++{-|++Define the fields that will be used to compose a flow layout of a set of+small multiples. Used when the encoding is largely identical, but the data field+used in each might vary. When a list of fields is identified with @repeatFlow@ you also+need to define a full specification to apply to each of those fields using 'asSpec'.++Small multiples will be laid out from left to right, moving on to new rows only+if the number of plots exceeds an optional column limit (specified via 'columns').++@+'toVegaLite'+ [ 'repeatFlow' [ \"Cat\", \"Dog\", \"Fish\" ]+ , 'specification' ('asSpec' spec)+ ]+@++See also 'repeat'.++@since 0.4.0.0++-}+repeatFlow :: [T.Text] -> PropertySpec+repeatFlow fields = (VLRepeat, toJSON fields)+++{-|++Determine whether scales, axes or legends in composite views should+share channel encodings. This allows, for example, two different color+encodings to be created in a layered view, which otherwise by default+would share color channels between layers. Each resolution rule should+be in a tuple pairing the channel to which it applies and the rule+type.++@+let res = 'resolve'+ . 'resolution' ('RLegend' [('ChColor', 'Independent')])++in 'toVegaLite'+ [ 'dataFromUrl' \"data/movies.json\" []+ , 'vConcat' [heatSpec, barSpec]+ , res []+ ]+@++For more information see the+<https://vega.github.io/vega-lite/docs/resolve.html Vega-Lite documentation>.++@+let dvals = 'dataFromColumns' []+ . 'dataColumn' "x" ('Numbers' [1, 2, 3, 4, 5])+ . 'dataColumn' "a" ('Numbers' [28, 91, 43, 55, 81])+ . 'dataColumn' "b" ('Numbers' [17, 22, 28, 30, 40])+ encBar = 'encoding'+ . 'position' 'X' ['PName' \"x\", 'PmType' 'Quantitative']+ . 'position' 'Y' ['PName' \"a\", 'PmType' 'Quantitative']+ specBar = 'asSpec' ['mark' 'Bar' [], encBar []]+ encLine = 'encoding'+ . 'position' 'X' ['PName' \"x\", 'PmType' 'Quantitative']+ . 'position' 'Y' ['PName' \"b\", 'PmType' 'Quantitative']+ specLine = 'asSpec' ['mark' 'Line' ['MColor' \"firebrick\"], encLine []]+ res = 'resolve'+ . 'resolution' ('RScale' [('ChY', 'Independent')])++in 'toVegaLite' [dvals [], res [], 'layer' [specBar, specLine]]+@++-}+resolve :: [LabelledSpec] -> PropertySpec+resolve res = (VLResolve, object res)+++{-|++Create a full selection specification from a list of selections. For details+see the+<https://vega.github.io/vega-lite/docs/selection.html Vega-Lite documentation>.++@+sel =+ 'selection'+ . 'select' \"view\" 'Interval' ['BindScales'] []+ . 'select' \"myBrush\" 'Interval' []+ . 'select' \"myPaintbrush\" 'Multi' ['On' \"mouseover\", 'Nearest' True]+@++-}++selection :: [LabelledSpec] -> PropertySpec+selection sels = (VLSelection, object sels)+++{-|++Defines a specification object for use with faceted and repeated small multiples.++@+'toVegaLite'+ [ 'facet' [ 'RowBy' [ 'FName' \"Origin\", 'FmType' 'Nominal' ] ]+ , 'specification' spec+ ]+@+-}+specification :: VLSpec -> PropertySpec+specification spec = (VLSpecification, spec)+++{-|++Create a single transform from a list of transformation+specifications. Note that the order of transformations can be+important, especially if labels created with 'calculateAs',+'timeUnitAs', and 'binAs' are used in other transformations. Using+the functional composition pipeline idiom (as example below) allows+you to provide the transformations in the order intended in a clear+manner.++@+'transform'+ . 'filter' ('FExpr' "datum.year == 2010")+ . 'calculateAs' "datum.sex == 2 ? \'Female\' : \'Male\'" "gender"+@++The supported transformations include: 'aggregate', 'binAs',+'calculateAs', 'impute', 'joinAggregate', 'lookup', 'lookupAs',+'flattenAs', 'foldAs', 'stack', 'timeUnitAs', and 'window'.++-}++transform :: [LabelledSpec] -> PropertySpec+transform transforms =+ let js = if null transforms then A.Null else toJSON (map assemble transforms)++ -- use the same approach as Elm of encoding the spec, then decoding it,+ -- rather than inspecting the structure of the JSON+ --+ assemble :: LabelledSpec -> VLSpec+ assemble (str, val) =++ let dval = decode (encode val) :: Maybe A.Value+ in case str of+ "aggregate" ->+ case dval of+ Just (A.Array vs) | V.length vs == 2 -> object [ ("aggregate", vs V.! 0)+ , ("groupby", vs V.! 1) ]+ _ -> A.Null++ "bin" ->+ case dval of+ Just (A.Array vs) | V.length vs == 3 -> object [ ("bin", vs V.! 0)+ , ("field", vs V.! 1)+ , ("as", vs V.! 2) ]+ _ -> A.Null++ "calculate" ->+ case dval of+ Just (A.Array vs) | V.length vs == 2 -> object [ ("calculate", vs V.! 0)+ , ("as", vs V.! 1) ]+ _ -> A.Null+++ "impute" ->+ case dval of+ Just (A.Array vs) | V.length vs == 8 ->+ let [imp, key, frameObj, keyValsObj, keyValsSequenceObj, methodObj, groupbyObj, valueObj] = V.toList vs++ addField _ A.Null = []+ addField f v = [(f, v)]++ ols = [ ("impute", imp)+ , ("key", key) ]+ <> addField "frame" frameObj+ <> addField "keyvals" keyValsObj+ <> addField "keyvals" keyValsSequenceObj+ <> addField "method" methodObj+ <> addField "groupby" groupbyObj+ <> addField "value" valueObj++ in object ols+ _ -> A.Null++ "lookup" ->+ case dval of+ Just (A.Array vs) | V.length vs == 4 -> object [ ("lookup", vs V.! 0)+ , ("from",+ object [ ("data", vs V.! 1)+ , ("key", vs V.! 2)+ , ("fields", vs V.! 3) ] )+ ]+ _ -> A.Null++ "lookupAs" ->+ case dval of+ Just (A.Array vs) | V.length vs == 4 -> object [ ("lookup", vs V.! 0)+ , ("from",+ object [ ("data", vs V.! 1)+ , ("key", vs V.! 2) ] )+ , ("as", vs V.! 3) ]+ _ -> A.Null++ "flattenAs" ->+ case dval of+ Just (A.Array vs) | V.length vs == 2 -> object [ ("flatten", vs V.! 0)+ , ("as", vs V.! 1) ]+ _ -> A.Null++ "foldAs" ->+ case dval of+ Just (A.Array vs) | V.length vs == 3 -> object [ ("fold", vs V.! 0)+ , ("as", toJSON [vs V.! 1, vs V.! 2]) ]+ _ -> A.Null++ "stack" ->+ case dval of+ Just (A.Array vs) | V.length vs == 6 ->+ let [field, grp, start, end, offsetObj, sortObj] = V.toList vs++ addField _ A.Null = []+ addField f v = [(f, v)]++ ols = [ ("stack", field)+ , ("groupby", grp)+ , ("as", toJSON [start, end]) ]+ <> addField "offset" offsetObj+ <> addField "sort" sortObj++ in object ols+ _ -> A.Null++ "timeUnit" ->+ case dval of+ Just (A.Array vs) | V.length vs == 3 -> object [ ("timeUnit", vs V.! 0)+ , ("field", vs V.! 1)+ , ("as", vs V.! 2) ]+ _ -> A.Null++ "window" ->+ case dval of+ Just (A.Array vs) | V.length vs == 5 ->+ let [winObj, frameObj, peersObj, groupbyObj, sortObj] = V.toList vs++ addField _ A.Null = []+ addField f v = [(f, v)]++ ols = [("window", winObj)]+ <> addField "frame" frameObj+ <> addField "ignorePeers" peersObj+ <> addField "groupby" groupbyObj+ <> addField "sort" sortObj++ in object ols+ _ -> A.Null++ "joinaggregate" ->+ case dval of+ Just (A.Array vs) | V.length vs == 5 ->+ let [joinObjs, frameObj, peersObj, groupbyObj, sortObj] = V.toList vs++ addField _ A.Null = []+ addField f v = [(f, v)]++ ols = [("joinaggregate", joinObjs)]+ <> addField "frame" frameObj+ <> addField "ignorePeers" peersObj+ <> addField "groupby" groupbyObj+ <> addField "sort" sortObj++ in object ols+ _ -> A.Null++ _ -> object [(str, val)]++ in (VLTransform, js)+++{-|++Assigns a list of specifications to be juxtaposed vertically in a visualization.++@+'toVegaLite'+ [ 'dataFromUrl' "data/driving.json" []+ , 'vConcat' [ spec1, spec2 ]+ ]+@+-}+vConcat :: [VLSpec] -> PropertySpec+vConcat specs = (VLVConcat, toJSON specs)+++{-|++Override the default width of the visualization. If not specified the width+will be calculated based on the content of the visualization. See+'autosize' for customization of the content sizing relative to this+setting.++@+'toVegaLite'+ [ 'width' 500+ , 'dataFromUrl' "data/population.json" []+ , 'mark' 'Bar' []+ , enc []+ ]+@+-}+width :: Double -> PropertySpec+width w = (VLWidth, toJSON w)+++-- | Properties for a window transform.+--+-- @since 0.4.0.0++data WindowProperty+ = WFrame (Maybe Int) (Maybe Int)+ -- ^ Moving window for use by a window transform. When a number is+ -- given, via @Just@, then it indicates the offset from the current+ -- data object. A @Nothing@ indicates an un-bounded number of rows+ -- preceding or following the current data object.+ | WIgnorePeers Bool+ -- ^ Should the sliding window in a window transform ignore peer+ -- values (those considered identical by the sort criteria).+ | WGroupBy [T.Text]+ -- ^ The fields for partitioning data objects in a window transform+ -- into separate windows. If not specified, all points will be in a+ -- single group.+ | WSort [SortField]+ -- ^ Comparator for sorting data objects within a window transform.+++-- This is different to how Elm's VegaLite handles this (as of version 1.12.0)+-- Helpers for windowPropertySpec++-- allowNull :: A.ToJSON a => Maybe a -> VLSpec+allowNull :: Maybe Int -> VLSpec+allowNull (Just a) = toJSON a+allowNull Nothing = A.Null++wpFrame , wpIgnorePeers, wpGroupBy, wpSort :: WindowProperty -> Maybe VLSpec+wpFrame (WFrame m1 m2) = Just (toJSON [allowNull m1, allowNull m2])+wpFrame _ = Nothing++wpIgnorePeers (WIgnorePeers b) = Just (toJSON b)+wpIgnorePeers _ = Nothing++wpGroupBy (WGroupBy fs) = Just (toJSON fs)+wpGroupBy _ = Nothing++wpSort (WSort sfs) = Just (toJSON (map sortFieldSpec sfs))+wpSort _ = Nothing++windowPropertySpec :: [WindowProperty] -> [VLSpec]+windowPropertySpec wps =+ let frms = mapMaybe wpFrame wps+ ips = mapMaybe wpIgnorePeers wps+ gps = mapMaybe wpGroupBy wps+ sts = mapMaybe wpSort wps++ fromSpecs [spec] = spec+ fromSpecs _ = A.Null++ in map fromSpecs [frms, ips, gps, sts]+++-- | How should the field be sorted when performing a window transform.+--+-- @since 0.4.00++data SortField+ = WAscending T.Text+ -- ^ Sort the field into ascending order.+ | WDescending T.Text+ -- ^ Sort the field into descending order.+++sortFieldSpec :: SortField -> VLSpec+sortFieldSpec (WAscending f) = object [field_ f, order_ "ascending"]+sortFieldSpec (WDescending f) = object [field_ f, order_ "descending"]+++-- | Window transformations.+--+-- @since 0.4.0.0++data Window+ = WAggregateOp Operation+ -- ^ An aggregrate operation to be used in a window transformation.+ | WOp WOperation+ -- ^ Window-specific operation to be used in a window transformation.+ | WParam Int+ -- ^ Numeric parameter for window-only operations that can be parameterised+ -- ('Ntile', 'Lag', 'Lead' and 'NthValue').+ | WField T.Text+ -- ^ Field for which to compute a window operation. Not needed for operations+ -- that do not apply to fields such as 'Count', 'Rank', and 'DenseRank'.+++windowFieldProperty :: Window -> LabelledSpec+windowFieldProperty (WAggregateOp op) = "op" .= operationSpec op+windowFieldProperty (WOp op) = "op" .= wOperationLabel op+windowFieldProperty (WParam n) = "param" .= n+windowFieldProperty (WField f) = field_ f+++-- | Window-specific operation for transformations (for use with 'WOp').+--+-- @since 0.4.0.0++data WOperation+ = RowNumber+ -- ^ Assign consecutive row number to values in a data object to be applied in a window transform.+ | Rank+ -- ^ Rank function to be applied in a window transform.+ | DenseRank+ -- ^ Dense rank function to be applied in a window transform.+ | PercentRank+ -- ^ Percentile of values in a sliding window to be applied in a window transform.+ | CumeDist+ -- ^ Cumulative distribution function to be applied in a window transform.+ | Ntile+ -- ^ Value preceding the current object in a sliding window to be applied in a window transform.+ | Lag+ -- ^ Value preceding the current object in a sliding window to be applied in a window transform.+ | Lead+ -- ^ Value following the current object in a sliding window to be applied in a window transform.+ | FirstValue+ -- ^ First value in a sliding window to be applied in a window transform.+ | LastValue+ -- ^ Last value in a sliding window to be applied in a window transform.+ | NthValue+ -- ^ Nth value in a sliding window to be applied in a window transform.+++wOperationLabel :: WOperation -> T.Text+wOperationLabel RowNumber = "row_number"+wOperationLabel Rank = "rank"+wOperationLabel DenseRank = "dense_rank"+wOperationLabel PercentRank = "percent_rank"+wOperationLabel CumeDist = "cume_dist"+wOperationLabel Ntile = "ntile"+wOperationLabel Lag = "lag"+wOperationLabel Lead = "lead"+wOperationLabel FirstValue = "first_value"+wOperationLabel LastValue = "last_value"+wOperationLabel NthValue = "nth_value"+++{-|++Defines a set of named aggregation transformations to be used when encoding+channels. This is useful when, for example, you wish to apply the same transformation+to a number of channels but do not want to define it each time. For further details+see the+<https://vega.github.io/vega-lite/docs/aggregate.html#aggregate-op-def Vega-Lite documentation>.++@+'transform'+ . 'aggregate'+ [ 'opAs' 'Min' "people" "lowerBound", 'opAs' 'Max' "people" "upperBound" ]+ [ "age" ]+@++See also 'joinAggregate'.++-}+aggregate ::+ [VLSpec]+ -- ^ The named aggregation operations to apply.+ -> [T.Text]+ -- ^ The \"group by\" fields.+ -> BuildLabelledSpecs+aggregate ops groups ols =+ let ags = toJSON [toJSON ops, toJSON (map toJSON groups)]+ in ("aggregate", ags) : ols+++{-|++Aggregation transformations to be used when encoding channels. Unlike+'aggregate', this transformation joins the results to the input data.+Can be helpful for creating derived values that combine raw data with some aggregate+measure, such as percentages of group totals. The first parameter is a list+of the named aggregation operations to apply. The second is a list of possible+window aggregate field properties, such as a field to group by when aggregating.+The third parameter is a list of transformations to which this is added.++@+'transform'+ . 'joinAggregate'+ [ 'opAs' 'Mean' "rating" "avYearRating" ]+ [ 'WGroupBy' [ "year" ] ]+ . 'filter' ('FExpr' "(datum.rating - datum.avYearRating) > 3"))+@++For details, see the+<https://vega.github.io/vega-lite/docs/joinaggregate.html Vega-Lite join aggregate documentation>.++See also 'aggregate'.++@since 0.4.0.0+-}++joinAggregate ::+ [VLSpec]+ -> [WindowProperty]+ -> BuildLabelledSpecs+joinAggregate ops wProps ols =+ let ags = toJSON ops : windowPropertySpec wProps+ in ("joinaggregate", toJSON ags) : ols+++{-|++Window transform for performing calculations over sorted groups of+data objects such as ranking, lead/lag analysis, running sums and averages.++The first parameter is a list of tuples each comprising a window transform field+definition and an output name. The second is the window transform definition.++@+'transform'+ . 'window' [ ( [ 'WAggregateOp' 'Sum', 'WField' "Time" ], "TotalTime" ) ]+ [ 'WFrame' Nothing Nothing ]+@++@since 0.4.0.0++-}+window ::+ [([Window], T.Text)]+ -- ^ The window-transform definition and associated output name.+ -> [WindowProperty]+ -- ^ The window transform.+ -> BuildLabelledSpecs+window wss wProps ols =+ let args = toJSON wargs : windowPropertySpec wProps+ wargs = map winFieldDef wss+ winFieldDef (ws, out) = object ("as" .= out : map windowFieldProperty ws)+ in ("window" .= toJSON args) : ols+++{-|++Randomly sample rows from a data source up to a given maximum.++For example, the following randomly samples 50 values from a sine curve:++@+ dvals = 'dataSequenceAs' 0 13 0.001 \"x\"+ trans = 'transform'+ . 'calculateAs' \"sin(datum.x)\" \"y\"+ . 'sample' 50+@++@since 0.4.0.0++-}++sample :: Int -> BuildLabelledSpecs+sample maxSize ols = ("sample" .= maxSize) : ols+++{-|++Create a named binning transformation that may be referenced in other Transformations+or encodings. See the+<https://vega.github.io/vega-lite/docs/bin.html Vega-Lite documentation> for+more details. Note that usually, direct binning within an encoding is preferred+over this form of bin transformation.++@+'transform'+ . 'binAs' [ 'MaxBins' 3 ] \"IMDB_Rating\" \"ratingGroup\"+@+-}+binAs ::+ [BinProperty]+ -- ^ An empty list means that the default binning is used (that is, the+ -- @bin@ field will be set to @true@ in the Vega-Lite specification).+ -> T.Text+ -- ^ The field to bin.+ -> T.Text+ -- ^ The label for the binned data.+ -> BuildLabelledSpecs+binAs bProps field label ols =+ let js = if null bProps+ then [toJSON True, toJSON field, toJSON label]+ else [object (map binProperty bProps), toJSON field, toJSON label]+ in ("bin" .= js) : ols+++{-|++Creates a new data field based on calculations from existing fields and values.++See the <https://vega.github.io/vega-lite/docs/calculate.html Vega-Lite documentation>+for further details.++@+'transform' . 'calculateAs' "datum.sex == 2 ? \'F\' : \'M\'" "gender"+@+-}+calculateAs ::+ T.Text+ -- ^ The calculation to perform, supporting the+ -- [Vega-Lite expression syntax](https://vega.github.io/vega/docs/expressions/).+ -> T.Text+ -- ^ The field to assign the new values.+ -> BuildLabelledSpecs+calculateAs expr label ols = ("calculate" .= [expr, label]) : ols+++{-|++Encode a color channel.++@+'color' [ 'MName' \"Species\", 'MmType' 'Nominal' ] []+@++Encoding a color channel will generate a legend by default. To stop the legend+appearing, just supply an empty list of legend properties to 'MLegend':++@+'color' [ 'MName' \"Species\", 'MmType' 'Nominal', 'MLegend' [] ] []+@+-}+color ::+ [MarkChannel]+ -- ^ The color-encoding options.+ -> BuildLabelledSpecs+color markProps ols = mchan_ "color" markProps : ols+++{-|++Encodes a new facet to be arranged in columns. See the+<https://vega.github.io/vega-lite/docs/facet.html#facet-row-and-column-encoding-channels Vega-Lite column documentation>.++Note that when faceting, dimensions specified with 'width' and 'height'+refer to the individual faceted plots, not the overall visualization.++@+let dvals = 'dataFromUrl' \"crimeData.csv\"+ enc = 'encoding'+ . 'position' 'X' ['PName' \"month\", 'PmType' 'Temporal']+ . 'position' 'Y' ['PName' \"reportedCrimes\", 'PmType' 'Quantitative'+ , 'PAggregate' 'Sum']+ . 'column' ['FName' \"crimeType\", 'FmType' 'Nominal']++ in 'toVegaLite' ['width' 100, dvals [], 'mark' 'Bar' [], enc [] ]+@+-}+column ::+ [FacetChannel]+ -- ^ The list of properties that define the faceting channel. At a minimum+ -- this should include the data field ('FName') and its measurement type+ -- ('FmType').+ -> BuildLabelledSpecs+column fFields ols =+ ("column" .= object (map facetChannelProperty fFields)) : ols+++{-|++The maximum number of columns to include in a view composition flow+layout. If the number of faceted small multiples exceeds this number,+flow moves to the next row. Only applies to flow layouts generated by+'vlConcat', 'facetFlow', and 'repeatFlow'.++@since 0.4.0.0++-}++columns ::+ Natural+ -- ^ A value of 0 means that a single row will be used (which is also+ -- the default behavior).+ -> PropertySpec+columns cols = (VLColumns, toJSON cols)+++{-|++Defines a single configuration option to be applied globally across the visualization.+The first parameter identifies the type of configuration, the second a list of previous+configurations to which this one may be added.++@+'configuration' ('Axis' [ 'DomainWidth' 4 ]) []+@+-}+configuration :: ConfigurationProperty -> BuildLabelledSpecs+configuration cfg ols = configProperty cfg : ols+++{-|++Encode a \"level of detail\" channel. This provides a way of grouping by a field+but unlike, say 'color', all groups have the same visual properties.++See the+<https://vega.github.io/vega-lite/docs/encoding.html#detail Vega-Lite documentation>+for details.++@+'detail' ['DName' \"Species\", 'DmType' 'Nominal'] []+@+-}+detail ::+ [DetailChannel]+ -- ^ The field to group.+ -> BuildLabelledSpecs+detail detailProps ols =+ ("detail" .= object (map detailChannelProperty detailProps)) : ols+++{-|++Encode a fill channel. This acts in a similar way to encoding by 'color' but+only affects the interior of closed shapes. The first parameter is a list of mark+channel properties that characterise the way a data field is encoded by fill.+The second parameter is a list of any previous channels to which this fill channel+should be added.++@+'fill' [ 'MName' \"Species\", 'MmType' 'Nominal' ] []+@++Note that if both @fill@ and 'color' encodings are specified, @fill@ takes precedence.++-}++fill :: [MarkChannel] -> BuildLabelledSpecs+fill markProps ols = mchan_ "fill" markProps : ols+++{-|++Encode a fill opacity channel. This acts in a similar way to encoding by 'opacity'+but only affects the interior of closed shapes. If both @fillOpacity@ and 'opacity'+encodings are specified, @fillOpacity@ takes precedence.++See also 'fill'.++@since 0.4.0.0+-}++fillOpacity :: [MarkChannel] -> BuildLabelledSpecs+fillOpacity markProps ols = mchan_ "fillOpacity" markProps : ols+++{-|++Adds the given filter operation a list of transformations that may be applied+to a channel or field.++@+'transform'+ . 'filter' ('FEqual' \"Animal\" ('Str' \"Cat\"))+@++Filter operations can combine selections and data predicates with 'BooleanOp'+expressions (and as of @0.4.0.0@, 'FilterOp' and 'FilterOpTrans'+can be used to lift the 'Filter' type into boolean expressions):++@+'transform'+ . 'filter' ('FCompose' ('And' ('Expr' "datum.Weight_in_lbs > 3000") ('Selection' "brush")))+@++The [Vega-Lite expression documentation](https://vega.github.io/vega/docs/expressions/)+describes the supported format (e.g. the requirement to precede column names+with @"datum."@).++-}+filter :: Filter -> BuildLabelledSpecs+filter f ols = ("filter" .= filterSpec f) : ols++++{-|++Map array-valued fields to a set of individual data objects, one per array entry.++See also 'flattenAs'.++@since 0.4.0.0++-}++flatten :: [T.Text] -> BuildLabelledSpecs+flatten fields ols = ("flatten" .= fields) : ols+++{-|++Similar to 'flatten' but allows the new output fields to be named.++@since 0.4.0.0++-}++flattenAs ::+ [T.Text]+ -> [T.Text]+ -- ^ The names of the output fields.+ -> BuildLabelledSpecs+flattenAs fields names ols = ("flattenAs" .= [fields, names]) : ols+++{-|++Perform a /gather/ operation to /tidy/ a table. Collapse multiple data fields+into two new data fields: @key@ containing the original data field names and @value@+containing the corresponding data values. This performs the same function as the+<https://tidyr.tidyverse.org/dev/articles/pivot.html pivot_longer> and+<https://tidyr.tidyverse.org/reference/gather.html gather>+operations in the R tidyverse.++See also 'foldAs'.++@+dvals =+ 'dataFromColumns' []+ . 'dataColumn' \"city\" ('Strings' [ \"Bristol\", \"Sheffield\", \"Glasgow\" ])+ . 'dataColumn' \"temp2017\" ('Numbers' [ 12, 11, 7 ])+ . 'dataColumn' \"temp2018\" ('Numbers' [ 14, 13, 10 ])++trans =+ 'transform'+ . 'fold' [ \"temp2017\", \"temp2018\" ]++enc =+ 'encoding'+ . 'position' 'X' [ 'PName' \"key\", 'PmType' 'Nominal' ]+ . 'position' 'Y' [ 'PName' \"city\", 'PmType' 'Nominal' ]+ . 'size' [ 'MName' \"value\", 'MmType' 'Quantitative' ]+@++@since 0.4.0.0+-}++fold :: [T.Text] -> BuildLabelledSpecs+fold fields ols = ("fold" .= fields) : ols+++{-|++A 'fold' where the @key@ and @value@ fields can be renamed.++@since 0.4.0.0++-}++foldAs ::+ [T.Text]+ -> T.Text+ -- ^ The name for the @key@ field.+ -> T.Text+ -- ^ The name for the @value@ field.+ -> BuildLabelledSpecs+foldAs fields keyName valName ols =+ ("foldAs" .= [toJSON fields, fromT keyName, fromT valName]) : ols+++{-|++Encode a hyperlink channel.++@+'encoding'+ . 'hyperlink' [ 'HName' \"Species\", 'HmType' 'Nominal' ]+@++@+'encoding'+ . 'hyperlink' [ 'HString' \"http://www.imdb.com\" ]+@++For further details see the+<https://vega.github.io/vega-lite/docs/encoding.html#href Vega-Lite documentation>.++-}+hyperlink ::+ [HyperlinkChannel]+ -- ^ The properties for the hyperlink channel.+ -> BuildLabelledSpecs+hyperlink hyperProps ols =+ ("href" .= object (concatMap hyperlinkChannelProperty hyperProps)) : ols+++{-|++Perform a lookup of named fields between two data sources. This allows+you to find values in one data source based on the values in another+(like a relational join).++Unlike 'lookupAs', this function will only return the specific fields+named in the fourth parameter. If you wish to return the entire set of+fields in the secondary data source as a single object, use+'lookupAs'.++See the <https://vega.github.io/vega-lite/docs/lookup.html Vega-Lite documentation>+for further details.++The following would return the values in the @age@ and @height@ fields from+@lookup_people.csv@ for all rows where the value in the @name@ column in that+file matches the value of @person@ in the primary data source.++@+trans = 'transform'+ . 'lookup' \"person\" ('dataFromUrl' \"data/lookup_people.csv\" []) \"name\" [\"age\", \"height\"]+@+-}+lookup ::+ T.Text+ -- ^ The field in the primary data structure acting as the key.+ -> Data+ -- ^ The secondary data source (e.g. the return from the data-generating+ -- functions such as 'dataFromUrl').+ -> T.Text+ -- ^ The name of the field in the secondary data source to match against+ -- the primary key.+ -> [T.Text]+ -- ^ The list of fields to store when the keys match.+ -> BuildLabelledSpecs+lookup key1 (_, spec) key2 fields ols =+ let js = [toJSON key1, spec, toJSON key2, toJSON (map toJSON fields)]+ in ("lookup" .= js) : ols+++{-|++Perform an object lookup between two data sources. This allows you to+find values in one data source based on the values in another (like a+relational join). Unlike 'lookup', this function returns the entire+set of field values from the secondary data source when keys+match. Those fields are stored as an object with the name provided in+the fourth parameter.++In the following example, @personDetails@ would reference all the+field values in @lookup_people.csv@ for each row where the value in+the @name@ column in that file matches the value of @person@ in the+primary data source.++@+'transform'+ . 'lookupAs' "person" ('dataFromUrl' "data/lookup_people.csv" []) "name" "personDetails"+@++If the data contained columns called @age@ and @height@ then they would+then be accessed as @personDetails.age@ and @personDetails.height@ - for+example:++@+'encoding'+ . 'position' X ['PName' "personDetails.age", 'PmType' 'Temporal', 'PTimeUnit' 'Year', 'PTitle' \"Age\"]+ . 'position' Y ['PName' "personDetails.height", 'PmType' 'Quantitative', 'PTitle' \"Height\"]+@++See the+<https://vega.github.io/vega-lite/docs/lookup.html Vega-Lite documentation>+for further details.++-}+lookupAs ::+ T.Text+ -- ^ The field in the primary data structure acting as the key.+ -> Data+ -- ^ The secondary data source (e.g. the return from the data-generating+ -- functions such as 'dataFromUrl').+ -> T.Text+ -- ^ The name of the field in the secondary data source to match against+ -- the primary key.+ -> T.Text+ -- ^ The field name for the new data.+ -> BuildLabelledSpecs+lookupAs key1 (_, spec) key2 asName ols =+ ("lookupAs" .= [toJSON key1, spec, toJSON key2, toJSON asName]) : ols+++-- | This is used with `impute` and `PImpute`.+--+-- @since 0.4.0.0++data ImputeProperty+ = ImFrame (Maybe Int) (Maybe Int)+ -- ^ 1d window over which data imputation values are generated. The two+ -- parameters should either be @Just@ a number indicating the offset from the current+ -- data object, or @Nothing@ to indicate unbounded rows preceding or following the+ -- current data object.+ | ImKeyVals DataValues+ -- ^ Key values to be considered for imputation.+ | ImKeyValSequence Double Double Double+ -- ^ Key values to be considered for imputation as a sequence of numbers between+ -- a start (first parameter), to less than an end (second parameter) in steps of+ -- the third parameter.+ | ImMethod ImMethod+ -- ^ How is the imputed value constructed.+ --+ -- When using @ImMethod 'ImValue'@, the replacement value is+ -- set with 'ImNewValue'.+ | ImGroupBy [T.Text]+ -- ^ Allow imputing of missing values on a per-group basis. For use with the impute+ -- transform only and not a channel encoding.+ | ImNewValue DataValue+ -- ^ The replacement value (when using @ImMethod 'ImValue'@).+++imputeProperty :: ImputeProperty -> LabelledSpec+imputeProperty (ImFrame m1 m2) = "frame" .= map allowNull [m1, m2]+imputeProperty (ImKeyVals dVals) = "keyvals" .= dataValuesSpecs dVals+imputeProperty (ImKeyValSequence start stop step) =+ "keyvals" .= object ["start" .= start, "stop" .= stop, "step" .= step]+imputeProperty (ImMethod method) = "method" .= imMethodLabel method+imputeProperty (ImNewValue dVal) = "value" .= dataValueSpec dVal+imputeProperty (ImGroupBy _) = "groupby" .= A.Null+++imputePropertySpecFrame, imputePropertySpecKeyVals,+ imputePropertySpecKeyValSequence, imputePropertySpecGroupBy,+ imputePropertySpecMethod, imputePropertySpecValue :: ImputeProperty -> Maybe VLSpec++imputePropertySpecFrame (ImFrame m1 m2) = Just (toJSON (map allowNull [m1, m2]))+imputePropertySpecFrame _ = Nothing++imputePropertySpecKeyVals (ImKeyVals dVals) = Just (toJSON (dataValuesSpecs dVals))+imputePropertySpecKeyVals _ = Nothing++imputePropertySpecKeyValSequence (ImKeyValSequence start stop step) =+ let obj = ["start" .= start, "stop" .= stop, "step" .= step]+ in Just (object obj)+imputePropertySpecKeyValSequence _ = Nothing++imputePropertySpecGroupBy (ImGroupBy fields) = Just (toJSON fields)+imputePropertySpecGroupBy _ = Nothing++imputePropertySpecMethod (ImMethod method) = Just (toJSON (imMethodLabel method))+imputePropertySpecMethod _ = Nothing++imputePropertySpecValue (ImNewValue dVal) = Just (dataValueSpec dVal)+imputePropertySpecValue _ = Nothing++++-- | Imputation method to use when replacing values.+--+-- @since 0.4.0.0++data ImMethod+ = ImMin+ -- ^ Use the minimum value.+ | ImMax+ -- ^ Use the maximum value.+ | ImMean+ -- ^ Use the mean value.+ | ImMedian+ -- ^ Use the median value.+ | ImValue+ -- ^ Use a replacement value (set with @ImNewValue@).+++imMethodLabel :: ImMethod -> T.Text+imMethodLabel ImMin = "min"+imMethodLabel ImMax = "max"+imMethodLabel ImMean = "mean"+imMethodLabel ImMedian = "median"+imMethodLabel ImValue = "value"++{-|++Impute missing data values.++The following example creates a value for @b@, set to the+mean of existing @b@ values with @c=1@, for the \"missing\" coordinate+of (@a=30@, @c=1@):++@+let dvals = 'dataFromColumns' []+ . 'dataColumn' "a" ('Numbers' [0, 0, 10, 10, 20, 20, 30])+ . 'dataColumn' "b" ('Numbers' [28, 91, 43, 55, 81, 53, 19])+ . 'dataColumn' "c" ('Numbers' [0, 1, 0, 1, 0, 1, 0])++ trans = 'transform'+ . 'impute' "b" "a" ['ImMethod' 'ImMean', 'ImGroupBy' ["c"]]++ enc = 'encoding'+ . 'position' 'X' ['PName' \"a\", 'PmType' 'Quantitative']+ . 'position' 'Y' ['PName' \"b\", 'PmType' 'Quantitative']+ . 'color' ['MName' \"c\", 'MmType' 'Nominal']++ in 'toVegaLite' [dvals [], trans [], enc [], 'mark' 'Line' []]+@++@since 0.4.0.0+-}++impute ::+ T.Text+ -- ^ The data field to process.+ -> T.Text+ -- ^ The key field to uniquely identify data objects within a group.+ -> [ImputeProperty]+ -- ^ Define how the imputation works.+ -> BuildLabelledSpecs+impute fields key imProps ols =+ let ags = [ fromT fields, fromT key+ , toSpec (mapMaybe imputePropertySpecFrame imProps)+ , toSpec (mapMaybe imputePropertySpecKeyVals imProps)+ , toSpec (mapMaybe imputePropertySpecKeyValSequence imProps)+ , toSpec (mapMaybe imputePropertySpecMethod imProps)+ , toSpec (mapMaybe imputePropertySpecGroupBy imProps)+ , toSpec (mapMaybe imputePropertySpecValue imProps) ]++ toSpec [x] = x+ toSpec _ = A.Null++ in ("impute", toJSON ags) : ols+++{-|++Encode an opacity channel. The first parameter is a list of mark+channel properties that characterise the way a data field is encoded+by opacity. The second parameter is a list of any previous channels to+which this opacity channel should be added.++@+'opacity' [ 'MName' \"Age\", 'MmType' 'Quantitative' ] []+@++See also 'fillOpacity'.++-}++opacity :: [MarkChannel] -> BuildLabelledSpecs+opacity markProps ols = mchan_ "opacity" markProps : ols+++{-|++Encode an order channel.++@+enc =+ 'encoding'+ . 'position' 'X' [ 'PName' "miles", 'PmType' 'Quantitative' ]+ . 'position' 'Y' [ 'PName' "gas", 'PmType' 'Quantitative' ]+ . 'order' [ 'OName' "year", 'OmType' 'Temporal', 'OSort' ['Descending'] ]+@+-}+order ::+ [OrderChannel]+ -- ^ The order-encoding options.+ -> BuildLabelledSpecs+order oDefs ols =+ ("order" .= object (map orderChannelProperty oDefs)) : ols+++{-|++Encode a position channel.++@+enc =+ 'encoding'+ . 'position' 'X' [ 'PName' \"Animal\", 'PmType' 'Ordinal' ]+@++Encoding by position will generate an axis by default. To prevent the axis from+appearing, simply provide an empty list of axis properties to 'PAxis':++@+enc =+ 'encoding'+ . 'position' 'X' [ 'PName' \"Animal\", 'PmType' 'Ordinal', 'PAxis' [] ]+@+-}+position ::+ Position+ -- ^ The channel to encode.+ -> [PositionChannel]+ -- ^ The options for the channel; this will usually include the name ('PName')+ -- and measurement type ('PmType'), but can be a reference to a row or+ -- column repeat field.+ -> BuildLabelledSpecs+position pos pDefs ols =+ let defs = object (map positionChannelProperty pDefs)+ in (positionLabel pos, defs) : ols+++{-|++Define a single resolution option to be applied when scales, axes or legends+in composite views share channel encodings. This allows, for example, two different+color encodings to be created in a layered view, which otherwise by default would+share color channels between layers. Each resolution rule should be in a tuple+pairing the channel to which it applies and the rule type.++@+'resolve'+ . resolution ('RScale' [ ( 'ChY', 'Independent' ) ])+@+-}+resolution :: Resolve -> BuildLabelledSpecs+resolution res ols = resolveProperty res : ols+++{-|++Encode a new facet to be arranged in rows.++See the+<https://vega.github.io/vega-lite/docs/facet.html#facet-row-and-column-encoding-channels Vega-Lite row documentation>.++Note that when faceting, dimensions specified with 'width' and 'height'+refer to the individual faceted plots, not the whole visualization.++@+let dvals = 'dataFromUrl' \"crimeData.csv\"+ enc = 'encoding'+ . 'position' 'X' ['PName' \"month\", 'PmType' 'Temporal']+ . 'position' 'Y' ['PName' \"reportedCrimes\"+ , 'PmType' 'Quantitative'+ , 'PAggregate' 'Sum'+ , 'PAxis' ['AxNoTitle']+ ]+ . 'row' ['FName' \"crimeType\", 'FmType' 'Nominal']++in 'toVegaLite' ['height' 80, dvals [], 'mark' 'Bar' [], enc []]+@++-}+row ::+ [FacetChannel]+ -- ^ The facet properties for the channel; this should include the name of+ -- the field ('FName') and its measurement type ('FmType').+ -> BuildLabelledSpecs+row fFields ols = ("row" .= object (map facetChannelProperty fFields)) : ols+++{-|++Create a single named selection that may be applied to a data query or transformation.++@+sel =+ 'selection'+ . 'select' "view" 'Interval' [ 'BindScales' ] []+ . 'select' "myBrush" 'Interval' []+ . 'select' "myPaintbrush" 'Multi' [ 'On' "mouseover", 'Nearest' True ]+@++-}+select ::+ T.Text+ -- ^ The name given to the selection.+ -> Selection+ -- ^ The type of the selection.+ -> [SelectionProperty]+ -- ^ What options are applied to the selection.+ -> BuildLabelledSpecs+select nme sType options ols =+ let selProps = ("type" .= selectionLabel sType) : map selectionProperty options+ in (nme .= object selProps) : ols+++{-|++Encode a shape channel.++@+'shape' [ 'MName' \"Species\", 'MmType' 'Nominal' ] []+@+-}+shape ::+ [MarkChannel]+ -- ^ What data values are used to control the shape parameters of the mark.+ -> BuildLabelledSpecs+shape markProps ols = mchan_ "shape" markProps : ols+++{-|++Encode a size channel.++@+'size' [ 'MName' \"Age\", 'MmType' 'Quantitative' ] []+@+-}+size ::+ [MarkChannel]+ -- ^ What data values are used to control the size parameters of the mark.+ -> BuildLabelledSpecs+size markProps ols = mchan_ "size" markProps : ols+++{-|++Encode a stroke channel. This acts in a similar way to encoding by 'color' but+only affects the exterior boundary of marks.++@+'stroke' [ 'MName' \"Species\", 'MmType' 'Nominal' ] []+@++Note that if both @stroke@ and 'color' encodings are specified, @stroke@ takes+precedence.++-}+stroke ::+ [MarkChannel]+ -- ^ What data values are used to control the stoke parameters of the mark.+ -> BuildLabelledSpecs+stroke markProps ols = mchan_ "stroke" markProps : ols+++{-|++Encode a stroke opacity channel. This acts in a similar way to encoding by+'opacity' but only affects the exterior boundary of marks. If both 'opacity' and+@strokeOpacity@ are specified, @strokeOpacity@ takes precedence for stroke encoding.++@since 0.4.0.0++-}++strokeOpacity ::+ [MarkChannel]+ -- ^ What data values are used to control the stoke opacity parameters of the mark.+ -> BuildLabelledSpecs+strokeOpacity markProps ols = mchan_ "strokeOpacity" markProps : ols+++{-|++Encode a stroke width channel.++@since 0.4.0.0++-}++strokeWidth ::+ [MarkChannel]+ -- ^ What data values are used to control the stoke width parameters of the mark.+ -> BuildLabelledSpecs+strokeWidth markProps ols = mchan_ "strokeWidth" markProps : ols+++{-|++Encode a text channel. See the+<https://vega.github.io/vega-lite/docs/encoding.html#text Vega-Lite documentation>+for further details on the text and tooltip channels and+<https://vega.github.io/vega-lite/docs/format.html Vega-Lite formatting documentation>+for formatting the appearance of the text.++@+'encoding'+ . 'position' 'X' [ 'PName' "miles", 'PmType' 'Quantitative' ]+ . 'position' 'Y' [ 'PName' "gas", 'PmType' 'Quantitative' ]+ . 'text' [ 'TName' "miles", 'TmType' 'Quantitative' ]+@+-}+text ::+ [TextChannel]+ -- ^ What data values are used to control the text parameters.+ -> BuildLabelledSpecs+text tDefs ols =+ ("text" .= object (concatMap textChannelProperty tDefs)) : ols+++{-|++Creates a new data field based on the given temporal binning. Unlike the+direct encoding binning, this transformation is named and so can be referred+to in multiple encodings. Note though that usually it is easer to apply the temporal+binning directly as part of the encoding as this will automatically format the+temporal axis. See the+<https://vega.github.io/vega-lite/docs/timeunit.html#transform Vega-Lite documentation>+for further details.++The following example takes a temporal dataset and encodes daily totals from it+grouping by month:++@+trans = 'transform' . 'timeUnitAs' 'Month' \"date\" \"monthly\"++enc = 'encoding'+ . 'position' 'X' [ 'PName' \"date\", 'PmType' 'Temporal', 'PTimeUnit' 'Day' ]+ . 'position' 'Y' [ 'PAggregate' 'Sum', 'PmType' 'Quantitative' ]+ . 'detail' [ 'DName' \"monthly\", 'DmType' 'Temporal' ]+@+-}+timeUnitAs ::+ TimeUnit+ -- ^ The width of each bin.+ -> T.Text+ -- ^ The field to bin.+ -> T.Text+ -- ^ The name of the binned data created by this routine.+ -> BuildLabelledSpecs+timeUnitAs tu field label ols =+ ("timeUnit" .= [timeUnitLabel tu, field, label]) : ols+++{-|++Encode a tooltip channel. See the+<https://vega.github.io/vega-lite/docs/encoding.html#text Vega-Lite documentation>+for further details on the text and tooltip channels and+<https://vega.github.io/vega-lite/docs/format.html Vega-Lite formatting documentation>+for formatting the appearance of the text.++@+enc = 'encoding'+ . 'position' 'X' [ 'PName' \"Horsepower\", 'PmType' 'Quantitative' ]+ . 'position' 'Y' [ 'PName' \"Miles_per_Gallon\", 'PmType' 'Quantitative' ]+ . 'tooltip' [ 'TName' \"Year\", 'TmType' 'Temporal', 'TFormat' "%Y" ]+@++To encode multiple tooltip values with a mark, use 'tooltips'.++-}+tooltip ::+ [TextChannel]+ -- ^ The properties for the channel.+ -> BuildLabelledSpecs+tooltip tDefs ols =+ ("tooltip" .= object (concatMap textChannelProperty tDefs)) : ols++{-|++Encode a tooltip channel using multiple data fields.++@since 0.3.0.0++@+'encoding'+ . 'position' 'X' [ 'PName' \"Horsepower\", 'PmType' 'Quantitative' ]+ . 'position' 'Y' [ 'PName' \"Miles_per_Gallon\", 'PmType' 'Quantitative' ]+ . 'tooltips' [ [ 'TName' \"Year\", 'TmType' 'Temporal', 'TFormat' "%Y" ]+ , [ 'TName' \"Month\", 'TmType' 'Temporal', 'TFormat' "%Y" ] ]+@+-}+tooltips ::+ [[TextChannel]]+ -- ^ A separate list of properties for each channel.+ -> BuildLabelledSpecs+tooltips tDefs ols =+ ("tooltip" .= toJSON (map (object . (concatMap textChannelProperty)) tDefs)) : ols+++-- | This is used with 'MTooltip'.+--+-- @since 0.4.0.0++data TooltipContent+ = TTEncoding+ -- ^ Tooltips are generated by the encoding (this is the default).+ --+ -- For example:+ --+ -- @'mark' 'Circle' ['MTooltip' 'TTEncoding']@+ | TTData+ -- ^ Tooltips are generated by all fields in the underlying data.+ --+ -- For example:+ --+ -- @'mark' 'Circle' ['MTooltip' 'TTData']@+ | TTNone+ -- ^ Disable tooltips.+ --+ -- For example:+ --+ -- @'mark' 'Circle' ['MTooltip' 'TTNone']@+++-- Note that TTNone is special cased by markProperty+ttContentLabel :: TooltipContent -> T.Text+ttContentLabel TTEncoding = "encoding"+ttContentLabel TTData = "data"+ttContentLabel TTNone = "null"
@@ -5,4 +5,4 @@ extra-deps: [] -resolver: lts-11.19+resolver: lts-14.1
@@ -0,0 +1,193 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite AxisTests.elm in the 2.0 development version+--+module AxisTests (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("axis1", axis1)+ , ("axis2", axis2)+ , ("axis3", axis3)+ , ("axis4", axis4)+ , ("axis5", axis5)+ , ("axis6", axis6)+ -- , ("axis7", axis7) require AxLabelExpr support (VL 4)+ -- , ("axis8", axis8) require AxLabelExpr support (VL 4)+ , ("zorder", zorder)+ ]+++-- We do not provide these in hvega, so define them here to make copying+-- the Elm tests over easier.+--+pOrdinal, pQuant, pTemporal :: PositionChannel+pOrdinal = PmType Ordinal+pQuant = PmType Quantitative+pTemporal = PmType Temporal++pName :: T.Text -> PositionChannel+pName = PName+++simpleData :: [DataColumn] -> Data+simpleData =+ let xvals = map fromIntegral xs+ xs = [1::Int .. 100]+ in dataFromColumns []+ . dataColumn "x" (Numbers xvals)+ . dataColumn "catX" (Strings (map (T.pack . show) xs))+ . dataColumn "y" (Numbers xvals)+++temporalData :: [DataColumn] -> Data+temporalData =+ let dates = [ "2019-01-01 09:00:00"+ , "2019-01-02 09:00:00"+ , "2019-01-03 09:00:00"+ , "2019-01-04 09:00:00"+ , "2019-01-05 09:00:00"+ , "2019-01-06 09:00:00"+ , "2019-01-07 09:00:00"+ , "2019-01-08 09:00:00"+ , "2019-01-09 09:00:00"+ , "2019-01-10 09:00:00"+ , "2019-01-11 09:00:00"+ , "2019-01-12 09:00:00"+ ]++ xs = map fromIntegral [1::Int .. 12]++ in dataFromColumns []+ . dataColumn "date" (Strings dates)+ . dataColumn "y" (Numbers xs)+++axis1 :: VegaLite+axis1 =+ let enc = encoding+ . position X [ pName "x", pQuant ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++axis2 :: VegaLite+axis2 =+ let enc = encoding+ . position X [ pName "catX", pOrdinal ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++axis3 :: VegaLite+axis3 =+ let enc = encoding+ . position X [ pName "date", pTemporal ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++axis4 :: VegaLite+axis4 =+ let enc = encoding+ . position X [ pName "x"+ , pQuant+ , PAxis [AxValues (Numbers [1, 25, 39, 90])]+ ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++axis5 :: VegaLite+axis5 =+ let enc = encoding+ . position X [ pName "catX"+ , pOrdinal+ , PAxis [AxValues (Strings ["1", "25", "39", "dummy", "90"])]+ ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++axis6 :: VegaLite+axis6 =+ let enc = encoding+ . position X [ pName "date"+ , pTemporal+ , PAxis [AxValues (DateTimes axDates)]+ ]+ . position Y [ pName "y", pQuant ]++ axDates = [ [DTYear 2019, DTMonth Jan, DTDate 4 ]+ , [DTYear 2019, DTMonth Jan, DTDate 8 ]+ , [DTYear 2019, DTMonth Jan, DTDate 20 ]+ ]+ + in + toVegaLite [ temporalData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++{-+axis7 :: VegaLite+axis7 =+ let enc = encoding+ . position X [ pName "x"+ , pQuant+ , PAxis [AxLabelExpr "datum.value / 100"]+ ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]+++axis8 :: VegaLite+axis8 =+ let enc = encoding+ . position X [ pName "catX"+ , pOrdinal+ , PAxis [AxLabelExpr "'number' + datum.label"]+ ]+ . position Y [ pName "y", pQuant ]+ in+ toVegaLite [ simpleData [], enc [], mark Line [ MPoint (PMMarker []) ] ]++-}+++-- From+-- https://github.com/gicentre/elm-vegalite/issues/15#issuecomment-524527125+--+zorder :: VegaLite+zorder =+ let dcols = dataFromColumns []+ . dataColumn "x" (Numbers [ 20, 10 ])+ . dataColumn "y" (Numbers [ 10, 20 ])+ . dataColumn "cat" (Strings [ "a", "b" ])++ axis lbl z = [ PName lbl, PmType Quantitative, PAxis [ AxZIndex z ] ]+ enc = encoding+ . position X (axis "x" 2)+ . position Y (axis "y" 1)+ . color [ MName "cat", MmType Nominal, MLegend [] ]++ cfg = configure+ . configuration (Axis [ GridWidth 8 ])+ . configuration (AxisX [ GridColor "red" ])+ . configuration (AxisY [ GridColor "blue" ])++ in toVegaLite [ cfg []+ , dcols []+ , enc []+ , mark Circle [ MSize 5000, MOpacity 1 ]+ ]
@@ -0,0 +1,253 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ColorTests.elm as of version 1.12.0+--+-- The following tests do not meet the VegaLite spec (v3.3.0):+-- interp1 -- SInterpolate should only accept Rgb/CubeHelix[Long]+-- interp2+-- interp3+-- interp4+-- interp5+--++module ColorTests (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("defContinuous", defContinuous)+ , ("defOrdinal", defOrdinal)+ , ("defNominal", defNominal)+ , ("namedContinuous1", namedContinuous1)+ , ("namedContinuous2", namedContinuous2)+ , ("namedContinuous3", namedContinuous3)+ , ("namedContinuous4", namedContinuous4)+ , ("customContinuous", customContinuous)+ , ("customDiscrete", customDiscrete)+ , ("scale1", scale1)+ , ("scale3", scale3)+ , ("scale4", scale4)+ , ("scale5", scale5)+ , ("scale6", scale6)+ , ("scale7", scale7)+ , ("scale8", scale8)+ , ("interp1", interp1)+ , ("interp2", interp2)+ , ("interp3", interp3)+ , ("interp4", interp4)+ , ("interp5", interp5)+ , ("interp6", interp6)+ , ("interp7", interp7)+ , ("gamma1", gamma1)+ , ("gamma2", gamma2)+ , ("gamma3", gamma3)+ , ("gamma4", gamma4)+ , ("gamma5", gamma5)+ ]+++chart :: T.Text -> ([a] -> [LabelledSpec]) -> VegaLite+chart desText enc =+ let des = description desText++ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ trans =+ transform+ . calculateAs "(datum.Acceleration - 15.52)/2.80" "accelerationZScore"++ fullEnc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . size [ MNumber 60 ]+ . opacity [ MNumber 1 ]+ . enc+ in+ toVegaLite [ des, dataVals [], trans [], mark Circle [], fullEnc [] ]+++defContinuous :: VegaLite+defContinuous =+ chart "Default continuous colour scales."+ (color [ MName "Acceleration", MmType Quantitative ])+++defOrdinal :: VegaLite+defOrdinal =+ chart "Default ordinal colour scales."+ (color [ MName "Cylinders", MmType Ordinal ])+++defNominal :: VegaLite+defNominal =+ chart "Default nominal colour scales."+ (color [ MName "Origin", MmType Nominal ])+++namedContinuous1 :: VegaLite+namedContinuous1 =+ chart "Continuous colour scale based on named vega schame. Should use the entire plasma colour scheme."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SScheme "plasma" [] ] ])+++namedContinuous2 :: VegaLite+namedContinuous2 =+ chart "Continuous colour scale based on named vega schame. Should use the upper half of the plasma colour scheme."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SScheme "plasma" [ 0.5, 1 ] ] ])+++namedContinuous3 :: VegaLite+namedContinuous3 =+ chart "Continuous colour scale based on named vega schame. Should use the flipped plasma colour scheme (i.e. red to orange)."+ (color [ MName "Acceleration"+ , MmType Quantitative+ , MScale [ SScheme "plasma" [] ]+ , MSort [ Descending ]+ ])+++namedContinuous4 :: VegaLite+namedContinuous4 =+ chart "Continuous colour scale based on named vega schame. Should use the first half of the flipped plasma colour scheme (i.e. red to orange)."+ (color [ MName "Acceleration"+ , MmType Quantitative+ , MScale [ SScheme "plasma" [ 0, 0.5 ] ]+ , MSort [ Descending ]+ ])+++customContinuous :: VegaLite+customContinuous =+ chart "Custom continuous colour scheme (red to blue ramp)."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SRange (RStrings [ "#f33", "#33f" ]) ] ])+++customDiscrete :: VegaLite+customDiscrete =+ chart "Custom discrete colours (red, green, blue)."+ (color [ MName "Origin", MmType Nominal, MScale [ SRange (RStrings [ "#e33", "#3a3", "#33d" ]) ] ])+++scale1 :: VegaLite+scale1 =+ chart "Linear (default) colour scale."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++{- ScSequential has been removed from hvega, with the suggstion to use ScLinear instead,+ which is tested in scale1. This is left in mainly to explain the test numbering.+scale2 :: VegaLite+scale2 =+ chart "Sequential (deprecated) colour scale."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SType ScSequential, SRange (RStrings [ "yellow", "red" ]) ] ])+-}++scale3 :: VegaLite+scale3 =+ chart "Power colour scale with default (1) exponent."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SType ScPow, SRange (RStrings [ "yellow", "red" ]) ] ])++scale4 :: VegaLite+scale4 =+ chart "Cubic Power colour scale."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SType ScPow, SExponent 3, SRange (RStrings [ "yellow", "red" ]) ] ])++scale5 :: VegaLite+scale5 =+ chart "Square root colour scale."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SType ScSqrt, SRange (RStrings [ "yellow", "red" ]) ] ])+++scale6 :: VegaLite+scale6 =+ chart "Log colour scale."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SType ScLog, SRange (RStrings [ "yellow", "red" ]) ] ])++scale7 :: VegaLite+scale7 =+ chart "SymLog colour scale with default slope constant (1)."+ (color [ MName "accelerationZScore", MmType Quantitative, MScale [ SType ScSymLog, SRange (RStrings [ "yellow", "red" ]) ] ])++scale8 :: VegaLite+scale8 =+ chart "SymLog colour scale with slope constant of 0.01."+ (color [ MName "accelerationZScore", MmType Quantitative, MScale [ SType ScSymLog, SConstant 0.01, SRange (RStrings [ "yellow", "red" ]) ] ])++interp1 :: VegaLite+interp1 =+ chart "HSL interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate Hsl, SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++interp2 :: VegaLite+interp2 =+ chart "HSL-long interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate HslLong, SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++interp3 :: VegaLite+interp3 =+ chart "Lab interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate Lab, SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++interp4 :: VegaLite+interp4 =+ chart "HCL interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate Hcl, SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++interp5 :: VegaLite+interp5 =+ chart "HCL-long interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate HclLong, SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++interp6 :: VegaLite+interp6 =+ chart "cube-helix interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelix 1), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++interp7 :: VegaLite+interp7 =+ chart "cube-helix-long interpolation."+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelixLong 1), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++gamma1 :: VegaLite+gamma1 =+ chart "cube-helix-long interpolation, gamma of -0.1"+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelixLong (-0.1)), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++gamma2 :: VegaLite+gamma2 =+ chart "cube-helix-long interpolation, gamma of 0"+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelixLong 0), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++gamma3 :: VegaLite+gamma3 =+ chart "cube-helix-long interpolation with default gamma value of 1"+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelixLong 1), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++gamma4 :: VegaLite+gamma4 =+ chart "cube-helix-long interpolation, gamma of 2"+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelixLong 2), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+++gamma5 :: VegaLite+gamma5 =+ chart "cube-helix-long interpolation, gamma of 10"+ (color [ MName "Acceleration", MmType Quantitative, MScale [ SInterpolate (CubeHelixLong 10), SType ScLinear, SRange (RStrings [ "yellow", "red" ]) ] ])+
@@ -0,0 +1,203 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite CompositeTests.elm as of version 1.12.0+--+module CompositeTests (testSpecs) where++import qualified Data.Text as T++import Data.Monoid ((<>))++import Graphics.Vega.VegaLite+++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("boxplot1", boxplot1)+ , ("boxplot2", boxplot2)+ , ("boxplot3", boxplot3)+ , ("errorband1", errorband1)+ , ("errorband2", errorband2)+ , ("errorbar1", errorbar1)+ , ("errorbar2", errorbar2)+ , ("errorbar3", errorbar3)+ ]++bPlot :: MarkErrorExtent -> VegaLite+bPlot ext =+ let+ pop =+ dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []++ enc =+ encoding+ . position X [ PName "age", PmType Ordinal ]+ . position Y [ PName "people", PmType Quantitative, PAxis [ AxTitle "Population" ] ]+ in+ toVegaLite [ pop, mark Boxplot [ MExtent ext ], enc [] ]++boxplot1 :: VegaLite+boxplot1 = bPlot ExRange++boxplot2 :: VegaLite+boxplot2 = bPlot (IqrScale 2)++boxplot3 :: VegaLite+boxplot3 =+ let+ pop =+ dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []++ enc =+ encoding+ . position X [ PName "age", PmType Ordinal ]+ . position Y [ PName "people", PmType Quantitative, PAxis [ AxTitle "Population" ] ]+ in+ toVegaLite+ [ pop+ , mark Boxplot+ [ MExtent (IqrScale 0.5)+ , MBox [ MColor "firebrick" ]+ , MOutliers [ MColor "black", MStrokeWidth 0.3, MSize 10 ]+ , MMedian [ MSize 18, MFill "black", MStrokeWidth 0 ]+ , MRule [ MStrokeWidth 0.4 ]+ , MTicks [ MSize 8 ]+ ]+ , enc []+ ]+++-- Note: at present only called with ci or stdev arguments++eBand :: T.Text -> VegaLite+eBand ext =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ label =+ case ext of+ "ci" ->+ "(95% CI)"++ "stdev" ->+ "(1 stdev)"++ "stderr" ->+ "(1 std Error)"++ "range" ->+ "(min to max)"++ _ ->+ "(IQR)"++ summary =+ case ext of+ "ci" ->+ ConfidenceInterval++ "stdev" ->+ StdDev++ "stderr" ->+ StdErr++ {-+ "range" ->+ ExRange+ -}+ + _ ->+ Iqr++ enc =+ encoding+ . position X [ PName "Year", PmType Temporal, PTimeUnit Year ]+ . position Y+ [ PName "Miles_per_Gallon"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PTitle ("Miles per Gallon " <> label)+ ]++ mopts = [ MExtent summary, MInterpolate Monotone, MBorders [] ]+ in+ toVegaLite [ cars+ , mark ErrorBand mopts+ , enc [] ]+++errorband1 :: VegaLite+errorband1 =+ eBand "ci"+++errorband2 :: VegaLite+errorband2 =+ eBand "stdev"+++eBar :: MarkErrorExtent -> VegaLite+eBar ext =+ let+ barley =+ dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []++ enc =+ encoding+ . position X [ PName "yield", PmType Quantitative+ , PScale [ SZero False ] ]+ . position Y+ [ PName "variety"+ , PmType Ordinal+ ]++ mopts = [ MExtent ext, MTicks [ MStroke "blue" ] ]+ + in+ toVegaLite [ barley+ , mark ErrorBar mopts+ , enc [] ]+++errorbar1 :: VegaLite+errorbar1 =+ eBar ConfidenceInterval+++errorbar2 :: VegaLite+errorbar2 =+ eBar StdDev+++errorbar3 :: VegaLite+errorbar3 =+ let+ des =+ description "Error bars with color encoding"++ specErrorBars =+ asSpec [ mark ErrorBar [ MTicks [] ], encErrorBars [] ]++ encErrorBars =+ encoding+ . position X [ PName "yield", PmType Quantitative+ , PScale [ SZero False ] ]+ . position Y [ PName "variety", PmType Ordinal ]+ . color [ MString "#4682b4" ]++ specPoints =+ asSpec [ mark Point [ MFilled True, MColor "black" ], encPoints [] ]++ encPoints =+ encoding+ . position X [ PName "yield", PmType Quantitative+ , PAggregate Mean ]+ . position Y [ PName "variety", PmType Ordinal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []+ , layer [ specErrorBars, specPoints ]+ ]
@@ -0,0 +1,269 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ConditionalTests.elm as of version 1.12.0+--+module ConditionalTests (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("markCondition1", markCondition1)+ , ("markCondition2", markCondition2)+ , ("selectionCondition1", selectionCondition1)+ , ("selectionCondition2", selectionCondition2)+ , ("selectionCondition3", selectionCondition3)+ , ("selectionCondition4", selectionCondition4)+ , ("selectionCondition5", selectionCondition5)+ , ("bindScales1", bindScales1)+ , ("bindScales2", bindScales2)+ ]+ +markCondition1 :: VegaLite+markCondition1 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []++ config =+ configure+ . configuration (RemoveInvalid False)++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative ]+ . color+ [ MDataCondition+ [ ( Or (Expr "datum.IMDB_Rating === null")+ (Expr "datum.Rotten_Tomatoes_Rating === null")+ , [ MString "#ddd" ]+ )+ ]+ [ MString "#0099ee" ]+ ]+ in+ toVegaLite [ config [], dataVals, mark Point [], enc [] ]+++markCondition2 :: VegaLite+markCondition2 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "value" (Numbers [ 10, 20, 30, 40, 50, 60 ])++ enc =+ encoding+ . position X [ PName "value", PmType Ordinal ]+ . color+ [ MDataCondition+ [ ( Expr "datum.value < 40", [ MString "blue" ] )+ , ( Expr "datum.value < 50", [ MString "red" ] )+ , ( Expr "datum.value < 60", [ MString "yellow" ] )+ ]+ [ MString "black" ]+ ]+ in+ toVegaLite [ width 400, dataVals [], mark Circle [ MSize 800 ], enc [] ]++selectionCondition1 :: VegaLite+selectionCondition1 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ sel =+ selection+ . select "alex"+ Interval+ [ On "[mousedown[!event.shiftKey], mouseup] > mousemove"+ , Translate "[mousedown[!event.shiftKey], mouseup] > mousemove"+ ]+ . select "morgan"+ Interval+ [ On "[mousedown[event.shiftKey], mouseup] > mousemove"+ , Translate "[mousedown[event.shiftKey], mouseup] > mousemove"+ , SelectionMark [ SMFill "#fdbb84", SMFillOpacity 0.5, SMStroke "#e34a33" ]+ ]++ enc =+ encoding+ . position Y [ PName "Origin", PmType Ordinal ]+ . position X [ PName "Cylinders", PmType Ordinal ]+ . color [ MAggregate Count, MName "*", MmType Quantitative ]+ in+ toVegaLite+ [ dataVals, sel [], mark Rect [ MCursor CGrab ], enc [] ]+++selectionCondition2 :: VegaLite+selectionCondition2 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ sel =+ selection+ . select "alex"+ Interval+ [ On "[mousedown[!event.shiftKey], mouseup] > mousemove"+ , Translate "[mousedown[!event.shiftKey], mouseup] > mousemove"+ ]+ . select "morgan"+ Interval+ [ On "[mousedown[event.shiftKey], mouseup] > mousemove"+ , Translate "[mousedown[event.shiftKey], mouseup] > mousemove"+ , SelectionMark [ SMFill "#fdbb84", SMFillOpacity 0.5, SMStroke "#e34a33" ]+ ]++ enc =+ encoding+ . position Y [ PName "Origin", PmType Ordinal ]+ . position X [ PName "Cylinders", PmType Ordinal ]+ . color+ [ MSelectionCondition+ (And (SelectionName "alex") (SelectionName "morgan"))+ [ MAggregate Count, MName "*", MmType Quantitative ]+ [ MString "gray" ]+ ]+ in+ toVegaLite+ [ dataVals, sel [], mark Rect [ MCursor CGrab ], enc [] ]+++selectionCondition3 :: VegaLite+selectionCondition3 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ trans =+ transform+ . filter (FCompose (And (Selection "brush") (Expr "datum.Weight_in_lbs > 3000")))++ sel =+ selection+ . select "brush" Interval []++ enc1 =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]++ spec1 =+ asSpec [ sel [], mark Point [], enc1 [] ]++ enc2 =+ encoding+ . position X [ PName "Acceleration", PmType Quantitative, PScale [ SDomain (DNumbers [ 0, 25 ]) ] ]+ . position Y [ PName "Displacement", PmType Quantitative, PScale [ SDomain (DNumbers [ 0, 500 ]) ] ]++ spec2 =+ asSpec [ trans [], mark Point [], enc2 [] ]+ in+ toVegaLite+ [ dataVals, vConcat [ spec1, spec2 ] ]+++selectionCondition4 :: VegaLite+selectionCondition4 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ sel =+ selection+ . select "mySelection"+ Interval+ [ Clear ""+ , On "[mousedown[!event.shiftKey], mouseup] > mousemove"+ , Translate "[mousedown[!event.shiftKey], mouseup] > mousemove"+ ]++ enc =+ encoding+ . position Y [ PName "Origin", PmType Ordinal ]+ . position X [ PName "Cylinders", PmType Ordinal ]+ . color+ [ MSelectionCondition+ (SelectionName "mySelection")+ [ MAggregate Count, MName "*", MmType Quantitative ]+ [ MString "gray" ]+ ]+ in+ toVegaLite+ [ dataVals, sel [], mark Rect [ MCursor CGrab ], enc [] ]+++selectionCondition5 :: VegaLite+selectionCondition5 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ sel =+ selection+ . select "mySelection"+ Interval+ [ Clear "mouseup"+ , Empty+ , On "[mousedown[!event.shiftKey], mouseup] > mousemove"+ , Translate "[mousedown[!event.shiftKey], mouseup] > mousemove"+ ]++ enc =+ encoding+ . position Y [ PName "Origin", PmType Ordinal ]+ . position X [ PName "Cylinders", PmType Ordinal ]+ . color+ [ MSelectionCondition+ (SelectionName "mySelection")+ [ MAggregate Count, MName "*", MmType Quantitative ]+ [ MString "gray" ]+ ]+ in+ toVegaLite+ [ dataVals, sel [], mark Rect [ MCursor CGrab ], enc [] ]+++bindScales1 :: VegaLite+bindScales1 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ sel =+ selection+ . select "myZoomPan" Interval [ BindScales ]++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ in+ toVegaLite+ [ width 300, height 300, dataVals [], sel [], mark Circle [], enc [] ]+++bindScales2 :: VegaLite+bindScales2 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ sel =+ selection+ . select "myZoomPan"+ Interval+ [ BindScales, Clear "click[event.shiftKey]" ]++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ in+ toVegaLite+ [ width 300, height 300, dataVals [], sel [], mark Circle [], enc [] ]
@@ -0,0 +1,229 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ConfigTests.elm as of version 1.12.0+--+-- - Padding has been removed as the resulting spec does not validate+-- against v3.3.0+--+-- - the vbTest output is not valid since the spec description says that+-- style can be a string or array-of-strings, but the type is only+-- string.+--++module ConfigTests (testSpecs) where++import Data.Function ((&))+import Graphics.Vega.VegaLite++import Prelude hiding (filter)+++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("default", defaultCfg)+ , ("dark", darkCfg)+ , ("mark1", markCfg1)+ , ("mark2", markCfg2)+ , ("padding", paddingCfg)+ , ("vbTest", vbTest)+ , ("axisCfg1", axisCfg1)+ ]++singleVis :: ([a] -> (VLProperty, VLSpec)) -> VegaLite+singleVis config =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ scatterEnc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Cylinders", MmType Ordinal ]+ . shape [ MName "Origin", MmType Nominal ]+ in+ toVegaLite [ title "Car Scatter" [], config [], cars, width 200, height 200, mark Point [ MSize 100 ], scatterEnc [] ]+++{- TODO: padding causes spec to be invalid -}+compositeVis :: ([a] -> (VLProperty, VLSpec)) -> VegaLite+compositeVis config =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ scatterEnc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Cylinders", MmType Ordinal ]+ . shape [ MName "Origin", MmType Nominal ]++ scatterSpec =+ asSpec [ title "Car Scatter" [], width 200, height 200+ {- , padding (PSize 20) -}+ , mark Point [ MSize 100 ], scatterEnc [] ]++ barEnc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal ]++ streamEnc =+ encoding+ . position X [ PName "Year", PmType Temporal, PTimeUnit Year ]+ . position Y [ PAggregate Count, PmType Quantitative, PStack StCenter, PAxis [] ]+ . color [ MName "Origin", MmType Nominal ]++ barSpec =+ asSpec [ title "Car Histogram" [], width 200, height 200+ {- , padding (PSize 20) -}+ , mark Bar [], barEnc [] ]++ streamSpec =+ asSpec [ title "Car Streamgraph" [], width 200, height 200+ {- , padding (PSize 20) -}+ , mark Area [], streamEnc [] ]++ res =+ resolve+ . resolution (RScale [ ( ChColor, Independent ), ( ChShape, Independent ) ])+ in+ toVegaLite [ config [], cars, hConcat [ scatterSpec, barSpec, streamSpec ], res [] ]+++vbTest :: VegaLite+vbTest =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ scatterEnc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Cylinders", MmType Ordinal ]+ . shape [ MName "Origin", MmType Nominal ]++ barEnc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal ]++ streamEnc =+ encoding+ . position X [ PName "Year", PmType Temporal, PTimeUnit Year ]+ . position Y [ PAggregate Count, PmType Quantitative, PStack StCenter, PAxis [] ]+ . color [ MName "Origin", MmType Nominal ]++ scatterSpec =+ asSpec+ [ title "Car Scatter" [TColor "brown", TFontSize 12]+ , width 200+ , height 200+ , mark Point [ MSize 100 ]+ , scatterEnc []+ ]++ barSpec =+ asSpec+ [ title "Car Histogram" []+ , width 200+ , height 200+ , viewBackground+ [ VBFill (Just "white")+ , VBCornerRadius 18+ , VBStroke (Just "red")+ , VBStrokeWidth 4+ , VBStrokeCap CRound+ , VBStrokeDash [ 10, 10 ]+ , VBStrokeJoin JBevel+ ]+ , mark Bar []+ , barEnc []+ ]++ cfg =+ configure+ . configuration+ (NamedStyles+ [ ( "myStyle", [ MFill "red", MFillOpacity 0.1, MStrokeOpacity 1 ] )+ , ( "mySecondStyle", [ MFill "black", MStroke "blue" ] )+ ]+ )++ streamSpec =+ asSpec+ [ title "Car Streamgraph" []+ , width 200+ , height 200+ , viewBackground [ VBStyle [ "myStyle", "mySecondStyle" ] ]+ , mark Area []+ , streamEnc []+ ]++ res =+ resolve+ . resolution (RScale [ ( ChColor, Independent ), ( ChShape, Independent ) ])+ in+ toVegaLite+ [ cfg []+ , background "yellow"+ , cars+ , hConcat [ scatterSpec, barSpec, streamSpec ]+ , res []+ ]+++defaultCfg :: VegaLite+defaultCfg =+ configure+ & compositeVis++darkCfg :: VegaLite+darkCfg =+ configure+ . configuration (Background "black")+ . configuration (TitleStyle [ TFont "Roboto", TColor "#fff" ])+ . configuration (Axis [ DomainColor "yellow", GridColor "rgb(255,255,200)", GridOpacity 0.2, LabelColor "#fcf", TickColor "white", TitleColor "rgb(200,255,200)", LabelFont "Roboto", TitleFont "Roboto" ])+ . configuration (Legend [ LeFillColor "#333", LeStrokeColor "#444", LeTitleColor "rgb(200,200,200)", LeLabelColor "white", LeSymbolFillColor "red", LeGradientStrokeColor "yellow", LeLabelFont "Roboto", LeTitleFont "Roboto" ])+ & compositeVis+++markCfg1 :: VegaLite+markCfg1 =+ configure+ . configuration (MarkStyle [ MFilled False ])+ & compositeVis+++markCfg2 :: VegaLite+markCfg2 =+ configure+ . configuration (MarkStyle [ MFilled True, MFill "black", MOpacity 1 ])+ . configuration (BarStyle [ MFilled True ])+ . configuration (AreaStyle [ MFilled False ])+ . configuration (PointStyle [ MFilled True, MStroke "white", MStrokeOpacity 0.2 ])+ & compositeVis+++paddingCfg :: VegaLite+paddingCfg =+ configure+ . configuration (Autosize [ AFit ])+ . configuration (Padding (PEdges 90 60 30 0))+ & singleVis+++axisCfg1 :: VegaLite+axisCfg1 =+ configure+ . configuration (Axis [ TitleFontStyle "italic"+ , TitleFont "serif"+ , LabelFontStyle "bold"+ , LabelFont "serif"+ , TitleAnchor AEnd+ ])+ & singleVis
@@ -0,0 +1,626 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite DataTests.elm as of version 1.12.0+--+module DataTests (testSpecs) where++import qualified Data.Aeson as A+import qualified Data.Text as T++import Data.Aeson ((.=))+import Data.Function ((&))+import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("data1", data1)+ , ("data2", data2)+ , ("data3", data3)+ , ("data4", data4)+ , ("data5", data5)+ , ("data6", data6)+ , ("data7", data7)+ , ("data8", data8)+ , ("data9", data9)+ , ("data10", data10)+ -- , ("data11", data11)+ , ("namedData1", namedData1)+ , ("namedData2", namedData2)+ , ("namedData3", namedData3)+ , ("geodata1", geodata1)+ , ("geodata2", geodata2)+ , ("flatten1", flatten1)+ , ("fold1", fold1)+ , ("impute1", impute1)+ , ("impute2", impute2)+ , ("impute3", impute3)+ , ("impute4", impute4)+ , ("impute5", impute5)+ , ("impute6", impute6)+ , ("impute7", impute7)+ , ("impute8", impute8)+ , ("sample1", sample1)+ , ("bin1", bin1)+ , ("bin2", bin2)+ , ("bin3", bin3)+ , ("sequence1", sequence1)+ , ("sequence2", sequence2)+ , ("filter1", filter1)+ , ("filter2", filter2)+ , ("annotate1", annotate1)+ , ("null1", null1)+ ]+++-- We do not provide these in hvega, so define them here to make copying+-- the Elm tests over easier.+--+pOrdinal, pQuant :: PositionChannel+pOrdinal = PmType Ordinal+pQuant = PmType Quantitative++pName :: T.Text -> PositionChannel+pName = PName+++showData :: (VLProperty, VLSpec) -> VegaLite+showData dvals =+ let+ enc =+ encoding+ . position X [ PName "cat", PmType Nominal ]+ . position Y [ PName "val", PmType Quantitative ]+ in+ toVegaLite [ dvals, enc [], mark Bar [] ]++data1 :: VegaLite+data1 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "cat" (Strings [ "a", "b", "c" ])+ . dataColumn "val" (Numbers [ 10, 18, 12 ])+ in+ showData (dvals [])+++data2 :: VegaLite+data2 =+ let+ dvals =+ dataFromRows []+ . dataRow [ ( "cat", Str "a" ), ( "val", Number 10 ) ]+ . dataRow [ ( "cat", Str "b" ), ( "val", Number 18 ) ]+ . dataRow [ ( "cat", Str "c" ), ( "val", Number 12 ) ]+ in+ showData (dvals [])+++json :: A.Value+json =+ let cv :: String -> Int -> A.Value+ cv c v = A.object [ "cat" .= c, "val" .= v]+ + in A.toJSON [ cv "a" 10+ , cv "b" 18+ , cv "c" 12 ]++ +data3 :: VegaLite+data3 = showData (dataFromJson json [])+++data4 :: VegaLite+data4 =+ showData (dataFromUrl "data/dataTest.csv" [])+++data5 :: VegaLite+data5 =+ showData (dataFromUrl "data/dataTest.tsv" [])+++data6 :: VegaLite+data6 =+ showData (dataFromUrl "data/dataTest.csv" [ DSV ',' ])+++data7 :: VegaLite+data7 =+ showData (dataFromUrl "data/dataTest.json" [])++dataSource :: T.Text -> VegaLite+dataSource dname =+ let+ dataColumns =+ dataFromColumns []+ . dataColumn "cat" (Strings [ "a", "b", "c" ])+ . dataColumn "val" (Numbers [ 10, 18, 12 ])++ dataRows =+ dataFromRows []+ . dataRow [ ( "cat", Str "a" ), ( "val", Number 10 ) ]+ . dataRow [ ( "cat", Str "b" ), ( "val", Number 18 ) ]+ . dataRow [ ( "cat", Str "c" ), ( "val", Number 12 ) ]++ enc =+ encoding+ . position X [ PName "cat", PmType Nominal ]+ . position Y [ PName "val", PmType Quantitative ]+ in+ toVegaLite+ [ datasets+ [ ( "myData1", dataRows [] )+ , ( "myData2", dataColumns [] )+ , ( "myData3", dataFromJson json [] )+ ]+ , dataFromSource dname []+ , enc []+ , mark Bar []+ ]+++data8 :: VegaLite+data8 = dataSource "myData1"+++data9 :: VegaLite+data9 = dataSource "myData2"+++data10 :: VegaLite+data10 = dataSource "myData3"+++{-+-- TODO no arrow support++data11 =+ let+ pollData =+ dataFromUrl "https://gicentre.github.io/data/euPolls.arrow" [ arrow ]++ enc =+ encoding+ . position X [ PName "Answer", PmType Nominal ]+ . position Y [ PName "Percent", PmType Quantitative, pAggregate opMean ]+ . color [ mName "Pollster", MmType Nominal ]+ . column [ fName "Pollster", fMType Nominal ]+ in+ toVegaLite [ pollData, enc [], mark Bar [] ]++-}+++namedData1, namedData2, namedData3 :: VegaLite+namedData1 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ in+ toVegaLite [ dataName "source" (dvals []), enc [], mark Bar [] ]+++namedData2 =+ let+ dvals =+ dataName "myName" (dataFromUrl "data/dataTest.tsv" [])++ enc =+ encoding+ . position X [ PName "cat", PmType Nominal ]+ . position Y [ PName "val", PmType Quantitative ]+ in+ toVegaLite [ dvals, enc [], mark Bar [] ]++namedData3 =+ let+ enc =+ encoding+ . position X [ PName "cat", PmType Nominal ]+ . position Y [ PName "val", PmType Quantitative ]+ in+ toVegaLite [ dataName "source" (dataFromColumns [] []), enc [], mark Bar [] ]+++geodata1 :: VegaLite+geodata1 =+ toVegaLite+ [ width 700+ , height 500+ , configure $ configuration (View [ ViewStroke Nothing ]) []+ , dataFromUrl "https://vega.github.io/vega-lite/data/londonBoroughs.json" [ TopojsonFeature "boroughs" ]+ , mark Geoshape []+ , encoding $ color [ MName "id", MmType Nominal ] []+ ]++geodata2 :: VegaLite+geodata2 =+ let+ geojson =+ geoFeatureCollection+ [ geometry (GeoPolygon [ [ ( -3, 52 ), ( 4, 52 ), ( 4, 45 ), ( -3, 45 ), ( -3, 52 ) ] ]) [ ( "Region", Str "Southsville" ) ]+ , geometry (GeoPolygon [ [ ( -3, 59 ), ( 4, 59 ), ( 4, 52 ), ( -3, 52 ), ( -3, 59 ) ] ]) [ ( "Region", Str "Northerton" ) ]+ ]+ in+ toVegaLite+ [ width 300+ , height 400+ , configure $ configuration (View [ ViewStroke Nothing ]) []+ , dataFromJson geojson [ JSON "features" ]+ , projection [ PrType Orthographic ]+ , encoding (color [ MName "properties.Region", MmType Nominal, MLegend [ LNoTitle ] ] [])+ , mark Geoshape []+ ]++flatten1 :: VegaLite+flatten1 =+ let+ dvals =+ dataFromJson+ (A.toJSON (map A.object+ [ [ ( "key" .= ("alpha" :: String) )+ , ( "foo" .= [ 1 :: Int, 2 ] )+ , ( "bar" .= [ "A" :: String, "B" ] )+ ]+ , [ ( "key" .= ("beta" :: String) )+ , ( "foo" .= [ 3 :: Int, 4, 5 ] )+ , ( "bar" .= [ "C" :: String, "D" ] )+ ]+ ])+ )++ trans =+ transform+ . flattenAs [ "foo", "bar" ] [ "quant", "cat" ]++ enc =+ encoding+ . position X [ PName "quant", PmType Quantitative ]+ . position Y [ PName "cat", PmType Nominal ]+ . color [ MName "key", MmType Nominal ]+ in+ toVegaLite [ dvals [], trans [], mark Circle [], enc [] ]+++fold1 :: VegaLite+fold1 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "country" (Strings [ "USA", "Canada" ])+ . dataColumn "gold" (Numbers [ 10, 7 ])+ . dataColumn "silver" (Numbers [ 20, 26 ])++ trans =+ transform+ . foldAs [ "gold", "silver" ] "k" "v"++ enc =+ encoding+ . column [ FName "k", FmType Nominal ]+ . position X [ PName "country", PmType Nominal ]+ . position Y [ PName "v", PmType Quantitative ]+ . color [ MName "country", MmType Nominal ]+ in+ toVegaLite [ dvals [], trans [], mark Bar [], enc [] ]+++imputeData :: [DataColumn] -> Data+imputeData =+ dataFromColumns []+ . dataColumn "a" (Numbers [ 0, 0, 1, 1, 2, 2, 3 ])+ . dataColumn "b" (Numbers [ 28, 91, 43, 55, 81, 53, 19 ])+ . dataColumn "c" (Numbers [ 0, 1, 0, 1, 0, 1, 0 ])+++impute1, impute2, impute3, impute4, impute5, impute6, impute7, impute8 :: VegaLite++impute1 =+ let+ trans =+ transform+ . impute "b" "a" [ ImNewValue (Number 0), ImGroupBy [ "c" ] ]++ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], trans [], mark Line [], enc [] ]+++impute2 =+ let+ trans =+ transform+ . impute "b" "a" [ ImMethod ImMean, ImGroupBy [ "c" ], ImFrame (Just (-2)) (Just 2) ]++ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], trans [], mark Line [], enc [] ]+++impute3 =+ let+ trans =+ transform+ . impute "b" "a" [ ImNewValue (Number 100), ImGroupBy [ "c" ], ImKeyValSequence 1 4 1 ]++ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], trans [], mark Line [], enc [] ]+++impute4 =+ let+ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative, PImpute [ ImNewValue (Number 0) ] ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], mark Line [], enc [] ]+++impute5 =+ let+ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative, PImpute [ ImMethod ImMean ] ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], mark Line [], enc [] ]+++impute6 =+ let+ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative, PImpute [ ImMethod ImMean, ImFrame (Just (-2)) (Just 2) ] ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], mark Line [], enc [] ]+++impute7 =+ let+ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative, PImpute [ ImNewValue (Number 100)+ , ImKeyVals (Numbers [ 4 ]) ] ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], mark Line [], enc [] ]+++impute8 =+ let+ enc =+ encoding+ . position X [ PName "a", PmType Quantitative, PScale [ SNice (NTickCount 1) ] ]+ . position Y [ PName "b", PmType Quantitative, PImpute [ ImNewValue (Number 100)+ , ImKeyValSequence 4 6 1 ] ]+ . color [ MName "c", MmType Nominal ]+ in+ toVegaLite [ imputeData [], mark Line [], enc [] ]+++sample1 :: VegaLite+sample1 =+ let+ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ trans =+ transform+ . sample 200++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]++ spec1 =+ asSpec [ mark Point [], enc [] ]++ spec2 =+ asSpec [ mark Point [], trans [], enc [] ]+ in+ toVegaLite [ dvals, hConcat [ spec1, spec2 ] ]+++bin1 :: VegaLite+bin1 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "bin_start" (Numbers [ 8, 10, 12, 14, 16, 18, 20, 22 ])+ . dataColumn "bin_end" (Numbers [ 10, 12, 14, 16, 18, 20, 22, 24 ])+ . dataColumn "count" (Numbers [ 7, 29, 71, 127, 94, 54, 17, 5 ])++ enc =+ encoding+ . position X [ PName "bin_start", PmType Quantitative+ , PBinned+ , PAxis [ AxTickMinStep 2 ] ]+ . position X2 [ PName "bin_end" ]+ . position Y [ PName "count", PmType Quantitative ]+ in+ toVegaLite [ dvals [], enc [], mark Bar [] ]+++bin2 :: VegaLite+bin2 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "x" (Numbers [ 10.6, 12.1, 9.4, 11.5, 12.6, 10.7, 11.6, 7.7, 12, 10.6, 16.5, 8.7, 7.6, 10.2, 10, 9.8, 11, 9, 10.4, 11.6, 11.2, 11.1, 11.7, 12.1, 9.9, 8.9, 10.9, 14.6, 11.4, 12.1 ])++ enc =+ encoding+ . position X [ PName "x", pQuant, PBin [] ]+ . position Y [ PAggregate Count, pQuant ]+ in+ toVegaLite [ width 300, dvals [], enc [], mark Bar [] ]+++bin3 :: VegaLite+bin3 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "x" (Numbers [ 10.6, 12.1, 9.4, 11.5, 12.6, 10.7, 11.6, 7.7, 12, 10.6, 16.5, 8.7, 7.6, 10.2, 10, 9.8, 11, 9, 10.4, 11.6, 11.2, 11.1, 11.7, 12.1, 9.9, 8.9, 10.9, 14.6, 11.4, 12.1, 12.2, 11.3, 13.1, 14.3, 9.8, 12.7, 9.2, 8.7, 11.3, 6.5, 11.1, 8.9, 11.8, 10.5, 12.8, 11.1, 11.2, 7, 12.4, 11.3, 8.3, 12.4, 12.1, 9.4, 8.6, 11.1, 8.9, 8.4, 10.5, 9.9, 6.5, 8.2, 12.7, 7.7, 11.1, 8.1, 8.1, 10.7, 9.8, 11.2, 11.2 ])++ enc =+ encoding+ . position X [ PName "x", pQuant, PBin [ BinAnchor 0.5 ] ]+ . position Y [ PAggregate Count, pQuant ]+ in+ toVegaLite [ width 300, dvals [], enc [], mark Bar [] ]+++sequence1 :: VegaLite+sequence1 =+ let+ dvals =+ dataSequence 0 12.7 0.1++ trans =+ transform+ . calculateAs "sin(datum.data)" "v"++ enc =+ encoding+ . position X [ PName "data", PmType Quantitative ]+ . position Y [ PName "v", PmType Quantitative ]+ in+ toVegaLite [ dvals, trans [], enc [], mark Line [] ]+++sequence2 :: VegaLite+sequence2 =+ let+ dvals =+ dataSequenceAs 0 12.7 0.1 "u"++ trans =+ transform+ . calculateAs "sin(datum.u)" "v"++ enc =+ encoding+ . position X [ PName "u", PmType Quantitative ]+ . position Y [ PName "v", PmType Quantitative ]+ in+ toVegaLite [ dvals, trans [], enc [], mark Line [] ]+++filter1 :: VegaLite+filter1 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ trans =+ transform+ . filter (FExpr "datum.a == 'A' || datum.a == 'C' || datum.a == 'E'")++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ in+ toVegaLite [ dvals [], trans [], enc [], mark Bar [] ]+++filter2 :: VegaLite+filter2 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ trans =+ transform+ . filter+ (Or+ (Or (FEqual "a" (Str "A") & FilterOp)+ (FEqual "a" (Str "C") & FilterOp)+ )+ (FEqual "a" (Str "E") & FilterOp)+ & FCompose+ )++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ in+ toVegaLite [ dvals [], trans [], enc [], mark Bar [] ]+++annotate1 :: VegaLite+annotate1 =+ let+ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81 ])++ enc =+ encoding+ . position X [ pName "a", pOrdinal ]+ . position Y [ pName "b", pQuant ]++ specBars =+ asSpec [ enc [], mark Bar [] ]++ specText =+ asSpec [ noData, mark Text [ MText "Test" ] ]+ in+ toVegaLite [ dvals [], layer [ specBars, specText ] ]+++-- See https://vega.github.io/vega-lite/examples/line_skip_invalid_mid_overlay.html+null1 :: VegaLite+null1 =+ toVegaLite [ mark Line [MPoint (PMMarker [])]+ , encoding+ . position X [pName "x", pQuant]+ . position Y [pName "y", pQuant]+ $ []+ , dataFromRows []+ . dataRow [("x", Number 1), ("y", Number 10)]+ . dataRow [("x", Number 2), ("y", Number 30)]+ . dataRow [("x", Number 3), ("y", NullValue)]+ . dataRow [("x", Number 4), ("y", Number 15)]+ . dataRow [("x", Number 5), ("y", NullValue)]+ . dataRow [("x", Number 6), ("y", Number 40)]+ . dataRow [("x", Number 7), ("y", Number 20)]+ $ []+ ]
@@ -0,0 +1,107 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite FillStrokeTests.elm as of version 1.12.0+--+-- Note that fill1, stroke1, and combined1 generate invalid Vega-Lite+-- since they create empty objects for the fill or stroke fields,+-- and that is not valid. I am leaving this as is for now.+--+module FillStrokeTests (testSpecs) where++-- import qualified Data.Text as T++import Graphics.Vega.VegaLite hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("default", defChart)+ , ("fill1", fill1)+ , ("fill2", fill2)+ , ("fill3", fill3)+ , ("stroke1", stroke1)+ , ("stroke2", stroke2)+ , ("stroke3", stroke3)+ , ("combined1", combined1)+ , ("combined2", combined2)+ , ("combined3", combined3)+ , ("geo1", geo1)+ , ("geo2", geo2)+ ]++encChart :: ([a] -> [LabelledSpec]) -> VegaLite+encChart extraEnc =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "x" (Numbers [ 10, 20, 30, 36 ])+ . dataColumn "y" (Numbers [ 1, 2, 3, 4 ])+ . dataColumn "val" (Numbers [ 1, 2, 3, 4 ])+ . dataColumn "cat" (Strings [ "a", "b", "c", "d" ])++ enc =+ encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative ]+ . color [ MName "cat", MmType Nominal ]+ . size [ MNumber 2000 ]+ . extraEnc+ in+ toVegaLite [ width 200, height 200, dataVals [], enc [],+ mark Circle [ MStroke "black" ] ]+++defChart :: VegaLite+defChart = encChart (const [])++fill1, fill2, fill3 :: VegaLite+fill1 = encChart (fill []) -- this produces invalid output+fill2 = encChart (fill [ MName "y", MmType Ordinal ])+fill3 = encChart (fill [ MString "red" ])++stroke1, stroke2, stroke3 :: VegaLite+stroke1 = encChart (stroke []) -- this produces invalid output+stroke2 = encChart (stroke [ MName "y", MmType Ordinal ])+stroke3 = encChart (stroke [ MString "red" ])++combined1, combined2, combined3 :: VegaLite+combined1 = encChart (stroke [] . fill [])+combined2 = encChart (stroke [ MName "y", MmType Ordinal ] . fill [ MString "red" ])+combined3 = encChart (stroke [ MString "red" ] . fill [ MName "y", MmType Ordinal ])++geo1 :: VegaLite+geo1 =+ let+ geojson =+ geoFeatureCollection+ [ geometry (GeoPolygon [ [ ( -2, 58 ), ( 3, 58 ), ( 3, 53 ), ( -2, 53 ), ( -2, 58 ) ] ]) []+ , geometry (GeoLine [ ( 4, 52 ), ( 4, 59 ), ( -3, 59 ) ]) []+ ]+ in+ toVegaLite+ [ width 300+ , height 300+ , dataFromJson geojson []+ , mark Geoshape []+ ]++geo2 :: VegaLite+geo2 =+ let+ geojson =+ geoFeatureCollection+ [ geometry (GeoPolygon [ [ ( -2, 58 ), ( 3, 58 ), ( 3, 53 ), ( -2, 53 ), ( -2, 58 ) ] ]) []+ , geometry (GeoLine [ ( 4, 52 ), ( 4, 59 ), ( -3, 59 ) ]) []+ ]++ -- NOTE: There is a bug in Vega-Lite that prevents nested geometry from being read correctly.+ enc =+ encoding . color [ MName "features.geometry.type",+ MmType Nominal ]+ in+ toVegaLite+ [ width 300+ , height 300+ , enc []+ , dataFromJson geojson []+ , mark Geoshape []+ ]
@@ -0,0 +1,448 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryAdvanced.elm (from development of version+-- 1.13.0)+--+module Gallery.Advanced (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("advanced1", advanced1)+ , ("advanced2", advanced2)+ , ("advanced3", advanced3)+ , ("advanced4", advanced4)+ , ("advanced5", advanced5)+ , ("advanced6", advanced6)+ , ("advanced7", advanced7)+ , ("advanced8", advanced8)+ , ("advanced9", advanced9)+ ]+++advanced1 :: VegaLite+advanced1 =+ let+ desc =+ description "Calculation of percentage of total"++ dvals =+ dataFromColumns []+ . dataColumn "Activity" (Strings [ "Sleeping", "Eating", "TV", "Work", "Exercise" ])+ . dataColumn "Time" (Numbers [ 8, 2, 4, 8, 2 ])++ trans =+ transform+ . window+ [ ( [ WAggregateOp Sum, WField "Time" ], "TotalTime" ) ]+ [ WFrame Nothing Nothing ]+ . calculateAs "datum.Time/datum.TotalTime * 100" "PercentOfTotal"++ enc =+ encoding+ . position X [ PName "PercentOfTotal", PmType Quantitative, PAxis [ AxTitle "% of total time" ] ]+ . position Y [ PName "Activity", PmType Nominal, PScale [ SRangeStep (Just 12) ] ]+ in+ toVegaLite+ [ desc, dvals [], trans [], mark Bar [], enc [] ]+++advanced2 :: VegaLite+advanced2 =+ let+ desc =+ description "Calculation of difference from average"++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ trans =+ transform+ . filter (FExpr "isValid(datum.IMDB_Rating)")+ . window [ ( [ WAggregateOp Mean, WField "IMDB_Rating" ], "AverageRating" ) ]+ [ WFrame Nothing Nothing ]+ . filter (FExpr "(datum.IMDB_Rating - datum.AverageRating) > 2.5")++ barEnc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [ AxTitle "IMDB Rating" ] ]+ . position Y [ PName "Title", PmType Ordinal ]++ barSpec =+ asSpec [ mark Bar [], barEnc [] ]++ ruleEnc =+ encoding+ . position X [ PName "AverageRating", PAggregate Mean, PmType Quantitative ]++ ruleSpec =+ asSpec [ mark Rule [ MColor "red" ], ruleEnc [] ]+ in+ toVegaLite+ [ desc, dvals [], trans [], layer [ barSpec, ruleSpec ] ]+++advanced3 :: VegaLite+advanced3 =+ let+ desc =+ description "Calculation of difference from annual average"++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"+ [ Parse [ ( "Release_Date", FoDate "%d-%b-%y" ) ] ]++ trans =+ transform+ . filter (FExpr "isValid(datum.IMDB_Rating)")+ . timeUnitAs Year "Release_Date" "year"+ . window [ ( [ WAggregateOp Mean, WField "IMDB_Rating" ], "AverageYearRating" ) ]+ [ WGroupBy [ "year" ], WFrame Nothing Nothing ]+ . filter (FExpr "(datum.IMDB_Rating - datum.AverageYearRating) > 2.5")++ barEnc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [ AxTitle "IMDB Rating" ] ]+ . position Y [ PName "Title", PmType Ordinal ]++ barSpec =+ asSpec [ mark Bar [ MClip True ], barEnc [] ]++ tickEnc =+ encoding+ . position X [ PName "AverageYearRating", PmType Quantitative ]+ . position Y [ PName "Title", PmType Ordinal ]+ . color [ MString "red" ]++ tickSpec =+ asSpec [ mark Tick [], tickEnc [] ]+ in+ toVegaLite [ desc, dvals, trans [], layer [ barSpec, tickSpec ] ]+++advanced4 :: VegaLite+advanced4 =+ let+ desc =+ description "A scatterplot showing each movie in the database and the difference from the average movie rating."++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ trans =+ transform+ . filter (FExpr "isValid(datum.IMDB_Rating)")+ . filter (FRange "Release_Date" (DateRange [] [ DTYear 2019 ]))+ . window [ ( [ WAggregateOp Mean, WField "IMDB_Rating" ], "AverageRating" ) ]+ [ WFrame Nothing Nothing ]+ . calculateAs "datum.IMDB_Rating - datum.AverageRating" "RatingDelta"++ enc =+ encoding+ . position X [ PName "Release_Date", PmType Temporal ]+ . position Y+ [ PName "RatingDelta"+ , PmType Quantitative+ , PAxis [ AxTitle "Residual" ]+ ]+ in+ toVegaLite+ [ desc+ , dvals []+ , trans []+ , enc []+ , mark Point [ MStrokeWidth 0.3, MOpacity 0.3 ]+ ]+++advanced5 :: VegaLite+advanced5 =+ let+ des =+ description "Line chart showing ranks over time for thw World Cup 2018 Group F teams"++ dvals =+ dataFromColumns []+ . dataColumn "team" (Strings [ "Germany", "Mexico", "South Korea", "Sweden", "Germany", "Mexico", "South Korea", "Sweden", "Germany", "Mexico", "South Korea", "Sweden" ])+ . dataColumn "matchday" (Numbers [ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ])+ . dataColumn "point" (Numbers [ 0, 3, 0, 3, 3, 6, 0, 3, 3, 6, 3, 6 ])+ . dataColumn "diff" (Numbers [ -1, 1, -1, 1, 0, 2, -2, 0, -2, -1, 0, 3 ])++ trans =+ transform+ . window [ ( [ WOp Rank ], "rank" ) ]+ [ WSort [ WDescending "point", WDescending "diff" ], WGroupBy [ "matchday" ] ]++ enc =+ encoding+ . position X [ PName "matchday", PmType Ordinal ]+ . position Y [ PName "rank", PmType Ordinal ]+ . color [ MName "team", MmType Nominal, MScale teamColours ]++ teamColours =+ categoricalDomainMap+ [ ( "Germany", "black" )+ , ( "Mexico", "#127153" )+ , ( "South Korea", "#c91a3c" )+ , ( "Sweden", "#0c71ab" )+ ]+ in+ toVegaLite+ [ des+ , title "World Cup 2018: Group F Rankings" [ TFrame FrBounds, TFontStyle "italic" ]+ , dvals []+ , trans []+ , enc []+ , mark Line [ MOrient Vertical ]+ ]+++advanced6 :: VegaLite+advanced6 =+ let+ des =+ description "Waterfall chart of monthly profit and loss"++ dvals =+ dataFromColumns []+ . dataColumn "label" (Strings [ "Begin", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "End" ])+ . dataColumn "amount" (Numbers [ 4000, 1707, -1425, -1030, 1812, -1067, -1481, 1228, 1176, 1146, 1205, -1388, 1492, 0 ])++ trans =+ transform+ . window [ ( [ WAggregateOp Sum, WField "amount" ], "sum" ) ] []+ . window [ ( [ WOp Lead, WField "label" ], "lead" ) ] []+ . calculateAs "datum.lead === null ? datum.label : datum.lead" "lead"+ . calculateAs "datum.label === 'End' ? 0 : datum.sum - datum.amount" "previous_sum"+ . calculateAs "datum.label === 'End' ? datum.sum : datum.amount" "amount"+ . calculateAs "(datum.label !== 'Begin' && datum.label !== 'End' && datum.amount > 0 ? '+' : '') + datum.amount" "text_amount"+ . calculateAs "(datum.sum + datum.previous_sum) / 2" "center"+ . calculateAs "datum.sum < datum.previous_sum ? datum.sum : ''" "sum_dec"+ . calculateAs "datum.sum > datum.previous_sum ? datum.sum : ''" "sum_inc"++ enc =+ encoding+ . position X [ PName "label", PmType Ordinal, PSort [], PTitle "Months" ]++ enc1 =+ encoding+ . position Y [ PName "previous_sum", PmType Quantitative, PTitle "Amount" ]+ . position Y2 [ PName "sum" ]+ . color+ [ MDataCondition+ [ ( Expr "datum.label === 'Begin' || datum.label === 'End'", [ MString "#f7e0b6" ] )+ , ( Expr "datum.sum < datum.previous_sum", [ MString "#f78a64" ] )+ ]+ [ MString "#93c4aa" ]+ ]++ spec1 =+ asSpec [ enc1 [], mark Bar [ MSize 45 ] ]++ enc2 =+ encoding+ . position X2 [ PName "lead" ]+ . position Y [ PName "sum", PmType Quantitative ]++ spec2 =+ asSpec+ [ enc2 []+ , mark Rule+ [ MColor "#404040"+ , MOpacity 1+ , MStrokeWidth 2+ , MXOffset (-22.5)+ , MX2Offset 22.5+ ]+ ]++ enc3 =+ encoding+ . position Y [ PName "sum_inc", PmType Quantitative ]+ . text [ TName "sum_inc", TmType Nominal ]++ spec3 =+ asSpec+ [ enc3 []+ , mark Text+ [ MdY (-8)+ , MFontWeight Bold+ , MColor "#404040"+ ]+ ]++ enc4 =+ encoding+ . position Y [ PName "sum_dec", PmType Quantitative ]+ . text [ TName "sum_dec", TmType Nominal ]++ spec4 =+ asSpec+ [ enc4 []+ , mark Text+ [ MdY 8+ , MBaseline AlignTop+ , MFontWeight Bold+ , MColor "#404040"+ ]+ ]++ enc5 =+ encoding+ . position Y [ PName "center", PmType Quantitative ]+ . text [ TName "text_amount", TmType Nominal ]+ . color+ [ MDataCondition+ [ ( Expr "datum.label === 'Begin' || datum.label === 'End'"+ , [ MString "#725a30" ]+ )+ ]+ [ MString "white" ]+ ]++ spec5 =+ asSpec [ enc5 [], mark Text [ MBaseline AlignMiddle, MFontWeight Bold ] ]+ in+ toVegaLite+ [ des+ , width 800+ , height 450+ , dvals []+ , trans []+ , enc []+ , layer [ spec1, spec2, spec3, spec4, spec5 ]+ ]+++advanced7 :: VegaLite+advanced7 =+ let+ des =+ description "Using the lookup transform to combine data"++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/lookup_groups.csv"++ trans =+ transform+ . lookup "person"+ (dataFromUrl "https://vega.github.io/vega-lite/data/lookup_people.csv" [])+ "name"+ [ "age", "height" ]++ enc =+ encoding+ . position X [ PName "group", PmType Ordinal ]+ . position Y [ PName "age", PmType Quantitative, PAggregate Mean ]+ in+ toVegaLite [ des, dvals [], trans [], enc [], mark Bar [] ]+++advanced8 :: VegaLite+advanced8 =+ let+ des =+ description "Parallel coordinates plot with manual generation of parallel axes"++ cfg =+ configure+ . configuration (View [ ViewStroke Nothing ])+ . configuration (AxisX [ Domain False, LabelAngle 0, TickColor "#ccc" ])+ . configuration+ (NamedStyles+ [ ( "label", [ MBaseline AlignMiddle, MAlign AlignRight, MdX (-5), MTooltip TTNone ] )+ , ( "tick", [ MOrient Horizontal, MTooltip TTNone ] )+ ]+ )++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/iris.json"++ trans =+ transform+ . window [ ( [ WAggregateOp Count ], "index" ) ] []+ . fold [ "petalLength", "petalWidth", "sepalLength", "sepalWidth" ]+ . joinAggregate [ opAs Min "value" "min", opAs Max "value" "max" ] [ WGroupBy [ "key" ] ]+ . calculateAs "(datum.value - datum.min) / (datum.max-datum.min)" "normVal"+ . calculateAs "(datum.min + datum.max) / 2" "mid"++ fields = ["petalLength", "petalWidth", "sepalLength", "sepalWidth"]+ encLine =+ encoding+ . position X [ PName "key", PmType Nominal ]+ . position Y [ PName "normVal", PmType Quantitative, PAxis [] ]+ . color [ MName "species", MmType Nominal ]+ . detail [ DName "index", DmType Nominal ]+ . tooltips (map (\n -> [TName n, TmType Quantitative]) fields)++ specLine =+ asSpec [ encLine [], mark Line [ MOpacity 0.3 ] ]++ encAxis =+ encoding+ . position X [ PName "key", PmType Nominal, PAxis [ AxNoTitle ] ]+ . detail [ DAggregate Count, DmType Quantitative ]++ specAxis =+ asSpec [ encAxis [], mark Rule [ MColor "#ccc" ] ]++ encAxisLabelsTop =+ encoding+ . position X [ PName "key", PmType Nominal ]+ . position Y [ PNumber 0 ]+ . text [ TName "max", TmType Quantitative, TAggregate Max ]++ specAxisLabelsTop =+ asSpec [ encAxisLabelsTop [], mark Text [ MStyle [ "label" ] ] ]++ encAxisLabelsMid =+ encoding+ . position X [ PName "key", PmType Nominal ]+ . position Y [ PNumber 150 ]+ . text [ TName "mid", TmType Quantitative, TAggregate Min ]++ specAxisLabelsMid =+ asSpec [ encAxisLabelsMid [], mark Text [ MStyle [ "label" ] ] ]++ encAxisLabelsBot =+ encoding+ . position X [ PName "key", PmType Nominal ]+ . position Y [ PHeight ]+ . text [ TName "min", TmType Quantitative, TAggregate Min ]++ specAxisLabelsBot =+ asSpec [ encAxisLabelsBot [], mark Text [ MStyle [ "label" ] ] ]+ in+ toVegaLite+ [ des+ , cfg []+ , width 600+ , height 300+ , dvals []+ , trans []+ , layer [ specLine, specAxis, specAxisLabelsTop, specAxisLabelsMid, specAxisLabelsBot ]+ ]+++advanced9 :: VegaLite+advanced9 =+ let+ desc =+ description "Production budget of the film with highest US Gross in each major genre."++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ enc =+ encoding+ . position X+ [ PName "Production_Budget"+ , PmType Quantitative+ , PAggregate (ArgMax (Just "US_Gross"))+ ]+ . position Y [ PName "Major_Genre", PmType Nominal ]+ in+ toVegaLite [ desc, dvals [], enc [], mark Bar [] ]
@@ -0,0 +1,263 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryArea.elm (from development of version+-- 1.13.0)+--+module Gallery.Area (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("area1", area1)+ , ("area2", area2)+ , ("area3", area3)+ , ("area4", area4)+ , ("area5", area5)+ , ("area6", area6)+ , ("area7", area7)+ ]++area1 :: VegaLite+area1 =+ let+ des =+ description "Unemployment over time (area chart)"++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonth, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "count", PmType Quantitative, PAggregate Sum, PAxis [ AxTitle "Count" ] ]+ in+ toVegaLite+ [ des+ , width 300+ , height 200+ , dataFromUrl "https://vega.github.io/vega-lite/data/unemployment-across-industries.json" []+ , mark Area []+ , enc []+ ]+++area2 :: VegaLite+area2 =+ let+ des =+ description "Area chart with overlaid lines and point markers"++ trans =+ transform . filter (FExpr "datum.symbol === 'GOOG'")++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , trans []+ , mark Area [ MPoint (PMMarker []), MLine (LMMarker []) ]+ , enc []+ ]+++area3 :: VegaLite+area3 =+ let+ des =+ description "Unemployment across industries as a stacked area chart."++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonth, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "count", PmType Quantitative, PAggregate Sum ]+ . color [ MName "series", MmType Nominal, MScale [ SScheme "category20b" [] ] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/unemployment-across-industries.json" []+ , mark Area []+ , enc []+ ]+++area4 :: VegaLite+area4 =+ let+ des =+ description "Unemployment across industries as a normalised area chart."++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonth, PAxis [ AxDomain False, AxFormat "%Y" ] ]+ . position Y [ PName "count", PmType Quantitative, PAggregate Sum, PAxis [], PStack StNormalize ]+ . color [ MName "series", MmType Nominal, MScale [ SScheme "category20b" [] ] ]+ in+ toVegaLite+ [ des+ , width 300+ , height 200+ , dataFromUrl "https://vega.github.io/vega-lite/data/unemployment-across-industries.json" []+ , mark Area []+ , enc []+ ]+++area5 :: VegaLite+area5 =+ let+ des =+ description "Unemployment across industries as a streamgraph (centred, stacked area chart)."++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonth, PAxis [ AxDomain False, AxFormat "%Y" ] ]+ . position Y [ PName "count", PmType Quantitative, PAggregate Sum, PAxis [], PStack StCenter ]+ . color [ MName "series", MmType Nominal, MScale [ SScheme "category20b" [] ] ]+ in+ toVegaLite+ [ des+ , width 300+ , height 200+ , dataFromUrl "https://vega.github.io/vega-lite/data/unemployment-across-industries.json" []+ , mark Area []+ , enc []+ ]+++area6 :: VegaLite+area6 =+ let+ des =+ description "Horizon chart with 2 layers. (See https://idl.cs.washington.edu/papers/horizon/ for more details on horizon charts.)"++ dvals =+ dataFromColumns []+ . dataColumn "x" (Numbers [1..20])+ . dataColumn "y" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52, 48, 24, 49, 87, 66, 17, 27, 68, 16, 49, 15 ])++ trans =+ transform . calculateAs "datum.y - 50" "ny"++ encX =+ encoding . position X [ PName "x", PmType Quantitative, PScale [ SZero False, SNice (IsNice False) ] ]++ encLower =+ encoding+ . position Y [ PName "y", PmType Quantitative, PScale [ SDomain (DNumbers [ 0, 50 ]) ] ]+ . opacity [ MNumber 0.6 ]++ specLower =+ asSpec [ mark Area [ MClip True ], encLower [] ]++ encUpper =+ encoding+ . position Y [ PName "ny", PmType Quantitative, PScale [ SDomain (DNumbers [ 0, 50 ]) ], PAxis [ AxTitle "y" ] ]+ . opacity [ MNumber 0.3 ]++ specUpper =+ asSpec [ trans [], mark Area [ MClip True ], encUpper [] ]++ config =+ configure+ . configuration (AreaStyle [ MInterpolate Monotone, MOrient Vertical ])+ in+ toVegaLite [ des, width 300, height 50, dvals [], encX [], layer [ specLower, specUpper ], config [] ]+++area7 :: VegaLite+area7 =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ trans =+ transform+ . aggregate [ opAs Count "" "count_*" ] [ "Origin", "Cylinders" ]+ . stack "count_*"+ []+ "stack_count_Origin1"+ "stack_count_Origin2"+ [ StOffset StNormalize, StSort [ WAscending "Origin" ] ]+ . window+ [ ( [ WAggregateOp Min, WField "stack_count_Origin1" ], "x" )+ , ( [ WAggregateOp Max, WField "stack_count_Origin2" ], "x2" )+ , ( [ WOp DenseRank ], "rank_Cylinders" )+ , ( [ WAggregateOp Distinct, WField "Cylinders" ], "distinct_Cylinders" )+ ]+ [ WFrame Nothing Nothing, WGroupBy [ "Origin" ], WSort [ WAscending "Cylinders" ] ]+ . window+ [ ( [ WOp DenseRank ], "rank_Origin" ) ]+ [ WFrame Nothing Nothing, WSort [ WAscending "Origin" ] ]+ . stack "count_*"+ [ "Origin" ]+ "y"+ "y2"+ [ StOffset StNormalize, StSort [ WAscending "Cylinders" ] ]+ . calculateAs "datum.y + (datum.rank_Cylinders - 1) * datum.distinct_Cylinders * 0.01 / 3" "ny"+ . calculateAs "datum.y2 + (datum.rank_Cylinders - 1) * datum.distinct_Cylinders * 0.01 / 3" "ny2"+ . calculateAs "datum.x + (datum.rank_Origin - 1) * 0.01" "nx"+ . calculateAs "datum.x2 + (datum.rank_Origin - 1) * 0.01" "nx2"+ . calculateAs "(datum.nx+datum.nx2)/2" "xc"+ . calculateAs "(datum.ny+datum.ny2)/2" "yc"++ enc1 =+ encoding+ . position X+ [ PName "xc"+ , PmType Quantitative+ , PAggregate Min+ , PTitle "Origin"+ , PAxis [ AxOrient STop ]+ ]+ . color [ MName "Origin", MmType Nominal, MLegend [] ]+ . text [ TName "Origin", TmType Nominal ]++ spec1 =+ asSpec [ mark Text [ MBaseline AlignMiddle, MAlign AlignCenter ], enc1 [] ]++ enc2 =+ encoding+ . position X [ PName "nx", PmType Quantitative, PAxis [] ]+ . position X2 [ PName "nx2" ]+ . position Y [ PName "ny", PmType Quantitative, PAxis [] ]+ . position Y2 [ PName "ny2" ]+ . color [ MName "Origin", MmType Nominal, MLegend [] ]+ . opacity [ MName "Cylinders", MmType Quantitative, MLegend [] ]+ . tooltips+ [ [ TName "Origin", TmType Nominal ]+ , [ TName "Cylinders", TmType Quantitative ]+ ]++ spec2 =+ asSpec [ mark Rect [], enc2 [] ]++ enc3 =+ encoding+ . position X [ PName "xc", PmType Quantitative, PAxis [] ]+ . position Y [ PName "yc", PmType Quantitative, PAxis [ AxTitle "Cylinders" ] ]+ . text [ TName "Cylinders", TmType Nominal ]++ spec3 =+ asSpec [ mark Text [ MBaseline AlignMiddle ], enc3 [] ]++ cfg =+ configure+ . configuration (View [ ViewStroke Nothing ])+ . configuration (Axis [ Domain False, Ticks False, Labels False, Grid False ])+ . configuration (ConcatStyle [ ConcatSpacing 10 ])++ res =+ resolve+ . resolution (RScale [ ( ChX, Shared ) ])+ in+ toVegaLite+ [ cfg []+ , res []+ , cars+ , trans []+ , vConcat [ spec1, asSpec [ layer [ spec2, spec3 ] ] ]+ ]
@@ -0,0 +1,447 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryBar.elm (from development of version+-- 1.13.0)+--+module Gallery.Bar (testSpecs) where++import Graphics.Vega.VegaLite++import qualified Data.Text as T++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("bar1", bar1)+ , ("bar2", bar2)+ , ("bar3", bar3)+ , ("bar4", bar4)+ , ("bar5", bar5)+ , ("bar6", bar6)+ , ("bar7", bar7)+ , ("bar8", bar8)+ , ("bar9", bar9)+ , ("bar10", bar10)+ , ("bar11", bar11)+ , ("bar12", bar12)+ , ("bar13", bar13)+ , ("bar14", bar14)+ ]+++bar1 :: VegaLite+bar1 =+ let+ des =+ description "A simple bar chart with embedded data."++ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ in+ toVegaLite [ des, dvals [], mark Bar [], enc [] ]++bar2 :: VegaLite+bar2 =+ let+ des =+ description "Simple histogram of IMDB ratings."++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Bar [ MBinSpacing 0 ]+ , enc []+ ]+++bar3 :: VegaLite+bar3 =+ let+ des =+ description "A bar chart showing the US population distribution of age groups in 2000."++ trans =+ transform . filter (FExpr "datum.year == 2000")++ enc =+ encoding+ . position X [ PName "people", PmType Quantitative, PAggregate Sum, PAxis [ AxTitle "population" ] ]+ . position Y [ PName "age", PmType Ordinal, PScale [ SRangeStep (Just 17) ], PSort [ Descending ] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []+ , mark Bar []+ , trans []+ , enc []+ ]+++bar4 :: VegaLite+bar4 =+ let+ des =+ description "Grouped bar chart showing population structure by age and gender."++ trans =+ transform+ . filter (FExpr "datum.year == 2000")+ . calculateAs "datum.sex == 2 ? 'Female' : 'Male'" "gender"++ enc =+ encoding+ . position X [ PName "gender", PmType Nominal, PScale [ SRangeStep (Just 12) ], PAxis [ AxNoTitle ] ]+ . position Y [ PName "people", PmType Quantitative, PAggregate Sum, PAxis [ AxTitle "population", AxGrid False ] ]+ . column [ FName "age", FmType Ordinal ]+ . color [ MName "gender", MmType Nominal, MScale [ SRange (RStrings [ "#EA98D2", "#659CCA" ]) ] ]++ config =+ configure+ . configuration (Axis [ DomainWidth 1 ])+ . configuration (View [ ViewStroke Nothing ])+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []+ , mark Bar []+ , trans []+ , enc []+ , config []+ ]+++bar5 :: VegaLite+bar5 =+ let+ des =+ description "Seattle weather stacked bar chart"++ weatherColors =+ categoricalDomainMap+ [ ( "sun", "#e7ba52" )+ , ( "fog", "#c7c7c7" )+ , ( "drizzle", "#aec7ea" )+ , ( "rain", "#1f77b4" )+ , ( "snow", "#9467bd" )+ ]++ enc =+ encoding+ . position X [ PName "date", PmType Ordinal, PTimeUnit Month, PAxis [ AxTitle "Month of the year" ] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ . color+ [ MName "weather"+ , MmType Nominal+ , MScale weatherColors+ , MLegend [ LTitle "Weather type" ]+ ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , mark Bar []+ , enc []+ ]+++bar6 :: VegaLite+bar6 =+ let+ des =+ description "Barley crop yields as a horizontal stacked bar chart"++ enc =+ encoding+ . position X [ PName "yield", PmType Quantitative, PAggregate Sum ]+ . position Y [ PName "variety", PmType Nominal ]+ . color [ MName "site", MmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []+ , mark Bar []+ , enc []+ ]+++bar7 :: VegaLite+bar7 =+ let+ des =+ description "Population structure as a normalised stacked bar chart."++ trans =+ transform+ . filter (FExpr "datum.year == 2000")+ . calculateAs "datum.sex == 2 ? 'Female' : 'Male'" "gender"++ enc =+ encoding+ . position X [ PName "age", PmType Ordinal, PScale [ SRangeStep (Just 17) ] ]+ . position Y [ PName "people", PmType Quantitative, PAggregate Sum, PAxis [ AxTitle "Population" ], PStack StNormalize ]+ . color [ MName "gender", MmType Nominal, MScale [ SRange (RStrings [ "#EA98D2", "#659CCA" ]) ] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []+ , trans []+ , mark Bar []+ , enc []+ ]+++bar8 :: VegaLite+bar8 =+ let+ des =+ description "A simple bar chart with ranged data (aka Gantt Chart)."++ dvals =+ dataFromColumns []+ . dataColumn "task" (Strings [ "A", "B", "C" ])+ . dataColumn "start" (Numbers [ 1, 3, 8 ])+ . dataColumn "end" (Numbers [ 3, 8, 10 ])++ enc =+ encoding+ . position Y [ PName "task", PmType Ordinal ]+ . position X [ PName "start", PmType Quantitative ]+ . position X2 [ PName "end" ]+ in+ toVegaLite [ des, dvals [], mark Bar [], enc [] ]+++bar9 :: VegaLite+bar9 =+ let+ des =+ description "A bar chart that directly encodes color names in the data."++ dvals =+ dataFromColumns []+ . dataColumn "color" (Strings [ "red", "green", "blue" ])+ . dataColumn "b" (Numbers [ 28, 55, 43 ])++ enc =+ encoding+ . position X [ PName "color", PmType Nominal ]+ . position Y [ PName "b", PmType Quantitative ]+ . color [ MName "color", MmType Nominal, MScale [] ]+ in+ toVegaLite [ des, dvals [], mark Bar [], enc [] ]+++bar10 :: VegaLite+bar10 =+ let+ des =+ description "Layered bar chart showing the US population distribution of age groups and gender in 2000."++ trans =+ transform+ . filter (FExpr "datum.year == 2000")+ . calculateAs "datum.sex == 2 ? 'Female' : 'Male'" "gender"++ enc =+ encoding+ . position X [ PName "age", PmType Ordinal, PScale [ SRangeStep (Just 17) ] ]+ . position Y [ PName "people", PmType Quantitative, PAggregate Sum, PAxis [ AxTitle "Population" ], PStack NoStack ]+ . color [ MName "gender", MmType Nominal, MScale [ SRange (RStrings [ "#e377c2", "#1f77b4" ]) ] ]+ . opacity [ MNumber 0.7 ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []+ , trans []+ , mark Bar []+ , enc []+ ]+++bar11 :: VegaLite+bar11 =+ let+ des =+ description "A diverging stacked bar chart for sentiments towards a set of eight questions, displayed as percentages with neutral responses straddling the 0% mark."++ dvals =+ dataFromColumns []+ . dataColumn "question" (Strings [ "Q1", "Q1", "Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q2", "Q2", "Q3", "Q3", "Q3", "Q3", "Q3", "Q4", "Q4", "Q4", "Q4", "Q4", "Q5", "Q5", "Q5", "Q5", "Q5", "Q6", "Q6", "Q6", "Q6", "Q6", "Q7", "Q7", "Q7", "Q7", "Q7", "Q8", "Q8", "Q8", "Q8", "Q8" ])+ . dataColumn "type" (Strings [ "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree", "Strongly disagree", "Disagree", "Neither agree nor disagree", "Agree", "Strongly agree" ])+ . dataColumn "value" (Numbers [ 24, 294, 594, 1927, 376, 2, 2, 0, 7, 11, 2, 0, 2, 4, 2, 0, 2, 1, 7, 6, 0, 1, 3, 16, 4, 1, 1, 2, 9, 3, 0, 0, 1, 4, 0, 0, 0, 0, 0, 2 ])+ . dataColumn "percentage" (Numbers [ 0.7, 9.1, 18.5, 59.9, 11.7, 18.2, 18.2, 0, 63.6, 0, 20, 0, 20, 40, 20, 0, 12.5, 6.3, 43.8, 37.5, 0, 4.2, 12.5, 66.7, 16.7, 6.3, 6.3, 12.5, 56.3, 18.8, 0, 0, 20, 80, 0, 0, 0, 0, 0, 100 ])+ . dataColumn "percentage_start" (Numbers [ -19.1, -18.4, -9.2, 9.2, 69.2, -36.4, -18.2, 0, 0, 63.6, -30, -10, -10, 10, 50, -15.6, -15.6, -3.1, 3.1, 46.9, -10.4, -10.4, -6.3, 6.3, 72.9, -18.8, -12.5, -6.3, 6.3, 62.5, -10, -10, -10, 10, 90, 0, 0, 0, 0, 0 ])+ . dataColumn "percentage_end" (Numbers [ -18.4, -9.2, 9.2, 69.2, 80.9, -18.2, 0, 0, 63.6, 63.6, -10, -10, 10, 50, 70, -15.6, -3.1, 3.1, 46.9, 84.4, -10.4, -6.3, 6.3, 72.9, 89.6, -12.5, -6.3, 6.3, 62.5, 81.3, -10, -10, 10, 90, 90, 0, 0, 0, 0, 100 ])++ enc =+ encoding+ . position X [ PName "percentage_start", PmType Quantitative, PAxis [ AxTitle "Percentage" ] ]+ . position X2 [ PName "percentage_end" ]+ . position Y [ PName "question", PmType Nominal, PAxis [ AxTitle "Question", AxOffset 5, AxTicks False, AxMinExtent 60, AxDomain False ] ]+ . color+ [ MName "type"+ , MmType Nominal+ , MLegend [ LTitle "Response" ]+ , MScale (SType ScOrdinal+ : categoricalDomainMap+ [ ( "Strongly disagree", "#c30d24" )+ , ( "Disagree", "#f3a583" )+ , ( "Neither agree nor disagree", "#cccccc" )+ , ( "Agree", "#94c6da" )+ , ( "Strongly agree", "#1770ab" )+ ]+ )+ ]+ in+ toVegaLite [ des, dvals [], mark Bar [], enc [] ]+++bar12 :: VegaLite+bar12 =+ let+ des =+ description "A simple bar chart with embedded data labels."++ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C" ])+ . dataColumn "b" (Numbers [ 28, 55, 43 ])++ enc =+ encoding+ . position X [ PName "b", PmType Quantitative ]+ . position Y [ PName "a", PmType Ordinal ]++ specBar =+ asSpec [mark Bar [] ]++ specText =+ asSpec [ mark Text [ MStyle [ "label" ] ], encoding (text [ TName "b", TmType Quantitative ] []) ]++ config =+ configure . configuration (NamedStyle "label" [ MAlign AlignLeft, MBaseline AlignMiddle, MdX 3 ])+ in+ toVegaLite [ des, dvals [], enc [], layer [ specBar, specText ], config [] ]+++toRows :: T.Text -> [( T.Text, Int )] -> [DataRow] -> [DataRow]+toRows country animalFreqs oldRows =+ let+ toRow animal n =+ dataRow+ [ ( "country", Str country )+ , ( "animal", Str animal )+ , ( "col", Number (fromIntegral n) )+ ]++ fToCol ( animal, f ) =+ foldr (toRow animal) [] [1 .. f]++ newRows = concatMap fToCol animalFreqs+ + in oldRows ++ newRows+++bar13 :: VegaLite+bar13 =+ let+ cow =+ "M4 -2c0 0 0.9 -0.7 1.1 -0.8c0.1 -0.1 -0.1 0.5 -0.3 0.7c-0.2 0.2 1.1 1.1 1.1 1.2c0 0.2 -0.2 0.8 -0.4 0.7c-0.1 0 -0.8 -0.3 -1.3 -0.2c-0.5 0.1 -1.3 1.6 -1.5 2c-0.3 0.4 -0.6 0.4 -0.6 0.4c0 0.1 0.3 1.7 0.4 1.8c0.1 0.1 -0.4 0.1 -0.5 0c0 0 -0.6 -1.9 -0.6 -1.9c-0.1 0 -0.3 -0.1 -0.3 -0.1c0 0.1 -0.5 1.4 -0.4 1.6c0.1 0.2 0.1 0.3 0.1 0.3c0 0 -0.4 0 -0.4 0c0 0 -0.2 -0.1 -0.1 -0.3c0 -0.2 0.3 -1.7 0.3 -1.7c0 0 -2.8 -0.9 -2.9 -0.8c-0.2 0.1 -0.4 0.6 -0.4 1c0 0.4 0.5 1.9 0.5 1.9l-0.5 0l-0.6 -2l0 -0.6c0 0 -1 0.8 -1 1c0 0.2 -0.2 1.3 -0.2 1.3c0 0 0.3 0.3 0.2 0.3c0 0 -0.5 0 -0.5 0c0 0 -0.2 -0.2 -0.1 -0.4c0 -0.1 0.2 -1.6 0.2 -1.6c0 0 0.5 -0.4 0.5 -0.5c0 -0.1 0 -2.7 -0.2 -2.7c-0.1 0 -0.4 2 -0.4 2c0 0 0 0.2 -0.2 0.5c-0.1 0.4 -0.2 1.1 -0.2 1.1c0 0 -0.2 -0.1 -0.2 -0.2c0 -0.1 -0.1 -0.7 0 -0.7c0.1 -0.1 0.3 -0.8 0.4 -1.4c0 -0.6 0.2 -1.3 0.4 -1.5c0.1 -0.2 0.6 -0.4 0.6 -0.4z"++ pig =+ "M1.2 -2c0 0 0.7 0 1.2 0.5c0.5 0.5 0.4 0.6 0.5 0.6c0.1 0 0.7 0 0.8 0.1c0.1 0 0.2 0.2 0.2 0.2c0 0 -0.6 0.2 -0.6 0.3c0 0.1 0.4 0.9 0.6 0.9c0.1 0 0.6 0 0.6 0.1c0 0.1 0 0.7 -0.1 0.7c-0.1 0 -1.2 0.4 -1.5 0.5c-0.3 0.1 -1.1 0.5 -1.1 0.7c-0.1 0.2 0.4 1.2 0.4 1.2l-0.4 0c0 0 -0.4 -0.8 -0.4 -0.9c0 -0.1 -0.1 -0.3 -0.1 -0.3l-0.2 0l-0.5 1.3l-0.4 0c0 0 -0.1 -0.4 0 -0.6c0.1 -0.1 0.3 -0.6 0.3 -0.7c0 0 -0.8 0 -1.5 -0.1c-0.7 -0.1 -1.2 -0.3 -1.2 -0.2c0 0.1 -0.4 0.6 -0.5 0.6c0 0 0.3 0.9 0.3 0.9l-0.4 0c0 0 -0.4 -0.5 -0.4 -0.6c0 -0.1 -0.2 -0.6 -0.2 -0.5c0 0 -0.4 0.4 -0.6 0.4c-0.2 0.1 -0.4 0.1 -0.4 0.1c0 0 -0.1 0.6 -0.1 0.6l-0.5 0l0 -1c0 0 0.5 -0.4 0.5 -0.5c0 -0.1 -0.7 -1.2 -0.6 -1.4c0.1 -0.1 0.1 -1.1 0.1 -1.1c0 0 -0.2 0.1 -0.2 0.1c0 0 0 0.9 0 1c0 0.1 -0.2 0.3 -0.3 0.3c-0.1 0 0 -0.5 0 -0.9c0 -0.4 0 -0.4 0.2 -0.6c0.2 -0.2 0.6 -0.3 0.8 -0.8c0.3 -0.5 1 -0.6 1 -0.6z"++ sheep =+ "M-4.1 -0.5c0.2 0 0.2 0.2 0.5 0.2c0.3 0 0.3 -0.2 0.5 -0.2c0.2 0 0.2 0.2 0.4 0.2c0.2 0 0.2 -0.2 0.5 -0.2c0.2 0 0.2 0.2 0.4 0.2c0.2 0 0.2 -0.2 0.4 -0.2c0.1 0 0.2 0.2 0.4 0.1c0.2 0 0.2 -0.2 0.4 -0.3c0.1 0 0.1 -0.1 0.4 0c0.3 0 0.3 -0.4 0.6 -0.4c0.3 0 0.6 -0.3 0.7 -0.2c0.1 0.1 1.4 1 1.3 1.4c-0.1 0.4 -0.3 0.3 -0.4 0.3c-0.1 0 -0.5 -0.4 -0.7 -0.2c-0.3 0.2 -0.1 0.4 -0.2 0.6c-0.1 0.1 -0.2 0.2 -0.3 0.4c0 0.2 0.1 0.3 0 0.5c-0.1 0.2 -0.3 0.2 -0.3 0.5c0 0.3 -0.2 0.3 -0.3 0.6c-0.1 0.2 0 0.3 -0.1 0.5c-0.1 0.2 -0.1 0.2 -0.2 0.3c-0.1 0.1 0.3 1.1 0.3 1.1l-0.3 0c0 0 -0.3 -0.9 -0.3 -1c0 -0.1 -0.1 -0.2 -0.3 -0.2c-0.2 0 -0.3 0.1 -0.4 0.4c0 0.3 -0.2 0.8 -0.2 0.8l-0.3 0l0.3 -1c0 0 0.1 -0.6 -0.2 -0.5c-0.3 0.1 -0.2 -0.1 -0.4 -0.1c-0.2 -0.1 -0.3 0.1 -0.4 0c-0.2 -0.1 -0.3 0.1 -0.5 0c-0.2 -0.1 -0.1 0 -0.3 0.3c-0.2 0.3 -0.4 0.3 -0.4 0.3l0.2 1.1l-0.3 0l-0.2 -1.1c0 0 -0.4 -0.6 -0.5 -0.4c-0.1 0.3 -0.1 0.4 -0.3 0.4c-0.1 -0.1 -0.2 1.1 -0.2 1.1l-0.3 0l0.2 -1.1c0 0 -0.3 -0.1 -0.3 -0.5c0 -0.3 0.1 -0.5 0.1 -0.7c0.1 -0.2 -0.1 -1 -0.2 -1.1c-0.1 -0.2 -0.2 -0.8 -0.2 -0.8c0 0 -0.1 -0.5 0.4 -0.8z"++ des =+ description "Isotype bar chart inspired by this Only An Ocean Between, 1943. Population Live Stock, p.13."++ config =+ configure+ . configuration (View [ ViewStroke Nothing ])++ dvals =+ dataFromRows []+ . toRows "Great Britain" [ ( "cattle", 3 ), ( "pigs", 2 ), ( "sheep", 10 ) ]+ . toRows "United States" [ ( "cattle", 9 ), ( "pigs", 6 ), ( "sheep", 7 ) ]++ enc =+ encoding+ . position X [ PName "col", PmType Ordinal, PAxis [] ]+ . position Y [ PName "animal", PmType Ordinal, PAxis [] ]+ . row [ FName "country", FmType Nominal, FHeader [ HNoTitle ] ]+ . shape+ [ MName "animal"+ , MmType Nominal+ , MScale+ (categoricalDomainMap+ [ ( "person", "circle" )+ , ( "cattle", cow )+ , ( "pigs", pig )+ , ( "sheep", sheep )+ ]+ )+ , MLegend []+ ]+ . color+ [ MName "animal"+ , MmType Nominal+ , MLegend []+ , MScale + (categoricalDomainMap+ [ ( "person", "rgb(162,160,152)" )+ , ( "cattle", "rgb(194,81,64)" )+ , ( "pigs", "rgb(93,93,93)" )+ , ( "sheep", "rgb(91,131,149)" )+ ]+ )+ ]+ . opacity [ MNumber 1 ]+ . size [ MNumber 200 ]+ in+ toVegaLite [ des, config [], width 800, height 200, dvals [], mark Point [ MFilled True ], enc [] ]+++bar14 :: VegaLite+bar14 =+ let+ des =+ description "Isotype bar chart using emojis for symbols"++ config =+ configure+ . configuration (View [ ViewStroke Nothing ])++ dvals =+ dataFromRows []+ . toRows "Great Britain" [ ( "cattle", 3 ), ( "pigs", 2 ), ( "sheep", 10 ) ]+ . toRows "United States" [ ( "cattle", 9 ), ( "pigs", 6 ), ( "sheep", 7 ) ]++ trans =+ transform+ . calculateAs "{'cattle': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum.animal]" "emoji"+ . window [ ( [ WOp Rank ], "rank" ) ] [ WGroupBy [ "country", "animal" ] ]++ enc =+ encoding+ . position X [ PName "rank", PmType Ordinal, PAxis [] ]+ . position Y [ PName "animal", PmType Nominal, PAxis [], PSort [] ]+ . row [ FName "country", FmType Nominal, FHeader [ HNoTitle ] ]+ . text [ TName "emoji", TmType Nominal ]+ . size [ MNumber 65 ]+ in+ toVegaLite [ des, config [], width 800, height 200, dvals [], trans [], mark Text [ MBaseline AlignMiddle ], enc [] ]
@@ -0,0 +1,243 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryDist.elm (from development of version+-- 1.13.0)+--+module Gallery.Dist (testSpecs) where++import Graphics.Vega.VegaLite++-- import qualified Data.Text as T++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("dist1", dist1)+ , ("dist2", dist2)+ , ("dist3", dist3)+ , ("dist4", dist4)+ , ("dist5", dist5)+ ]+++dist1 :: VegaLite+dist1 =+ let+ des =+ description "Simple histogram of IMDB ratings."++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Bar [ MBinSpacing 0 ]+ , enc []+ ]+++dist2 :: VegaLite+dist2 =+ let+ des =+ description "Cumulative frequency distribution"++ trans =+ transform+ . window [ ( [ WAggregateOp Count, WField "count" ], "cumulativeCount" ) ]+ [ WSort [ WAscending "IMDB_Rating" ], WFrame Nothing (Just 0) ]++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "cumulativeCount", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , trans []+ , mark Area []+ , enc []+ ]+++dist3 :: VegaLite+dist3 =+ let+ des =+ description "A layered histogram and cumulative histogram."++ trans =+ transform+ . binAs [] "IMDB_Rating" "bin_IMDB_Rating"+ . aggregate+ [ opAs Count "" "count" ]+ [ "bin_IMDB_Rating", "bin_IMDB_Rating_end" ]+ . filter (FExpr "datum.bin_IMDB_Rating !== null")+ . window [ ( [ WAggregateOp Sum, WField "count" ], "cumulativeCount" ) ]+ [ WSort [ WAscending "bin_IMDB_Rating" ], WFrame Nothing (Just 0) ]++ enc =+ encoding+ . position X+ [ PName "bin_IMDB_Rating"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ AxTitle "IMDB rating" ]+ ]+ . position X2 [ PName "bin_IMDB_Rating_end" ]++ cdEnc =+ encoding+ . position Y [ PName "cumulativeCount", PmType Quantitative ]++ specCumulative =+ asSpec [ cdEnc [], mark Bar [] ]++ dEnc =+ encoding+ . position Y [ PName "count", PmType Quantitative ]++ specDist =+ asSpec [ dEnc [], mark Bar [ MColor "yellow", MOpacity 0.5 ] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , trans []+ , layer [ specCumulative, specDist ]+ , enc []+ ]+++dist4 :: VegaLite+dist4 =+ let+ des =+ description "A vertical 2D box plot showing median, min, and max in the US population distribution of age groups in 2000."++ trans =+ transform+ . aggregate+ [ opAs Min "people" "lowerWhisker"+ , opAs Q1 "people" "lowerBox"+ , opAs Median "people" "midBox"+ , opAs Q3 "people" "upperBox"+ , opAs Max "people" "upperWhisker"+ ]+ [ "age" ]++ encAge =+ encoding . position X [ PName "age", PmType Ordinal ]++ encLWhisker =+ encoding+ . position Y [ PName "lowerWhisker", PmType Quantitative, PAxis [ AxTitle "Population" ] ]+ . position Y2 [ PName "lowerBox" ]++ specLWhisker =+ asSpec [mark Rule [ MStyle [ "boxWhisker" ] ], encLWhisker [] ]++ encUWhisker =+ encoding+ . position Y [ PName "upperBox", PmType Quantitative ]+ . position Y2 [ PName "upperWhisker" ]++ specUWhisker =+ asSpec [mark Rule [ MStyle [ "boxWhisker" ] ], encUWhisker [] ]++ encBox =+ encoding+ . position Y [ PName "lowerBox", PmType Quantitative ]+ . position Y2 [ PName "upperBox" ]+ . size [ MNumber 5 ]++ specBox =+ asSpec [mark Bar [ MStyle [ "box" ] ], encBox [] ]++ encBoxMid =+ encoding+ . position Y [ PName "midBox", PmType Quantitative ]+ . color [ MString "white" ]+ . size [ MNumber 5 ]++ specBoxMid =+ asSpec [mark Tick [ MStyle [ "boxMid" ] ], encBoxMid [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []+ , trans []+ , encAge []+ , layer [ specLWhisker, specUWhisker, specBox, specBoxMid ]+ ]+++dist5 :: VegaLite+dist5 =+ let+ des =+ description "A Tukey box plot showing median and interquartile range in the US population distribution of age groups in 2000. This isn't strictly a Tukey box plot as the IQR extends beyond the min/max values for some age cohorts."++ trans =+ transform+ . aggregate+ [ opAs Q1 "people" "lowerBox"+ , opAs Q3 "people" "upperBox"+ , opAs Median "people" "midBox"+ ]+ [ "age" ]+ . calculateAs "datum.upperBox - datum.lowerBox" "IQR"+ . calculateAs "datum.upperBox + datum.IQR * 1.5" "upperWhisker"+ . calculateAs "max(0,datum.lowerBox - datum.IQR *1.5)" "lowerWhisker"++ encAge =+ encoding . position X [ PName "age", PmType Ordinal ]++ encLWhisker =+ encoding+ . position Y [ PName "lowerWhisker", PmType Quantitative, PAxis [ AxTitle "Population" ] ]+ . position Y2 [ PName "lowerBox" ]++ specLWhisker =+ asSpec [mark Rule [ MStyle [ "boxWhisker" ] ], encLWhisker [] ]++ encUWhisker =+ encoding+ . position Y [ PName "upperBox", PmType Quantitative ]+ . position Y2 [ PName "upperWhisker" ]++ specUWhisker =+ asSpec+ [mark Rule [ MStyle [ "boxWhisker" ] ], encUWhisker [] ]++ encBox =+ encoding+ . position Y [ PName "lowerBox", PmType Quantitative ]+ . position Y2 [ PName "upperBox" ]+ . size [ MNumber 5 ]++ specBox =+ asSpec [mark Bar [ MStyle [ "box" ] ], encBox [] ]++ encBoxMid =+ encoding+ . position Y [ PName "midBox", PmType Quantitative ]+ . color [ MString "white" ]+ . size [ MNumber 5 ]++ specBoxMid =+ asSpec+ [mark Tick [ MStyle [ "boxMid" ] ], encBoxMid [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []+ , trans []+ , encAge []+ , layer [ specLWhisker, specUWhisker, specBox, specBoxMid ]+ ]
@@ -0,0 +1,198 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryError.elm (from development of version+-- 1.13.0)+--+module Gallery.Error (testSpecs) where++import Graphics.Vega.VegaLite++-- import qualified Data.Text as T++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("error1", error1)+ , ("error2", error2)+ , ("error3", error3)+ , ("error4", error4)+ ]+++error1 :: VegaLite+error1 =+ let+ des =+ description "Error bars showing confidence intervals"++ encVariety =+ encoding . position Y [ PName "variety", PmType Ordinal ]++ encPoints =+ encoding+ . position X+ [ PName "yield"+ , PmType Quantitative+ , PAggregate Mean+ , PScale [ SZero False ]+ , PAxis [ AxTitle "Barley Yield" ]+ ]+ . color [ MString "black" ]++ specPoints =+ asSpec [ mark Point [ MFilled True ], encPoints [] ]++ encCIs =+ encoding+ . position X [ PName "yield", PmType Quantitative, PAggregate CI0 ]+ . position X2 [ PName "yield", PAggregate CI1 ]++ specCIs =+ asSpec [ mark Rule [], encCIs [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []+ , encVariety []+ , layer [ specPoints, specCIs ]+ ]+++error2 :: VegaLite+error2 =+ let+ des =+ description "Error bars showing standard deviations"++ trans =+ transform+ . aggregate [ opAs Mean "yield" "mean", opAs Stdev "yield" "stdev" ] [ "variety" ]+ . calculateAs "datum.mean-datum.stdev" "lower"+ . calculateAs "datum.mean+datum.stdev" "upper"++ encVariety =+ encoding . position Y [ PName "variety", PmType Ordinal ]++ encMeans =+ encoding+ . position X+ [ PName "mean"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ AxTitle "Barley Yield" ]+ ]+ . color [ MString "black" ]++ specMeans =+ asSpec [ mark Point [ MFilled True ], encMeans [] ]++ encStdevs =+ encoding+ . position X [ PName "upper", PmType Quantitative ]+ . position X2 [ PName "lower" ]++ specStdevs =+ asSpec [ mark Rule [], encStdevs [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []+ , trans []+ , encVariety []+ , layer [ specMeans, specStdevs ]+ ]+++error3 :: VegaLite+error3 =+ let+ des =+ description "Line chart with confidence interval band."++ encTime =+ encoding . position X [ PName "Year", PmType Temporal, PTimeUnit Year ]++ encBand =+ encoding+ . position Y+ [ PName "Miles_per_Gallon"+ , PmType Quantitative+ , PAggregate CI0+ , PAxis [ AxTitle "Miles/Gallon" ]+ ]+ . position Y2+ [ PName "Miles_per_Gallon"+ , PAggregate CI1+ ]+ . opacity [ MNumber 0.3 ]++ specBand =+ asSpec [ mark Area [], encBand [] ]++ encLine =+ encoding+ . position Y+ [ PName "Miles_per_Gallon"+ , PmType Quantitative+ , PAggregate Mean+ ]++ specLine =+ asSpec [ mark Line [], encLine [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , encTime []+ , layer [ specBand, specLine ]+ ]+++error4 :: VegaLite+error4 =+ let+ des =+ description "A scatterplot showing horsepower and miles per gallon for various cars with a global mean and standard deviation overlay."++ encPoints =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]++ specPoints =+ asSpec [ mark Point [], encPoints [] ]++ trans =+ transform+ . aggregate+ [ opAs Mean "Miles_per_Gallon" "mean_MPG"+ , opAs Stdev "Miles_per_Gallon" "dev_MPG"+ ]+ []+ . calculateAs "datum.mean_MPG+datum.dev_MPG" "upper"+ . calculateAs "datum.mean_MPG-datum.dev_MPG" "lower"++ encMean =+ encoding . position Y [ PName "mean_MPG", PmType Quantitative ]++ specMean =+ asSpec [ mark Rule [], encMean [] ]++ encRect =+ encoding+ . position Y [ PName "lower", PmType Quantitative ]+ . position Y2 [ PName "upper" ]+ . opacity [ MNumber 0.2 ]++ specRect =+ asSpec [ mark Rect [], encRect [] ]++ specSpread =+ asSpec [ trans [], layer [ specMean, specRect ] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , layer [ specPoints, specSpread ]+ ]
@@ -0,0 +1,206 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryFacet.elm (from development of version+-- 1.13.0)+--+module Gallery.Facet (testSpecs) where++import Graphics.Vega.VegaLite++-- import qualified Data.Text as T++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("facet1", facet1)+ , ("facet2", facet2)+ , ("facet3", facet3)+ , ("facet4", facet4)+ , ("facet5", facet5)+ , ("facet6", facet6)+ , ("facet7", facet7)+ ]+++facet1 :: VegaLite+facet1 =+ let+ des =+ description "A trellis bar chart showing the US population distribution of age groups and gender in 2000"++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/population.json"++ trans =+ transform+ . filter (FExpr "datum.year == 2000")+ . calculateAs "datum.sex == 2 ? 'Female' : 'Male'" "gender"++ enc =+ encoding+ . position X [ PName "age", PmType Ordinal, PScale [ SRangeStep (Just 17) ] ]+ . position Y [ PName "people", PmType Quantitative, PAggregate Sum, PAxis [ AxTitle "Population" ] ]+ . color [ MName "gender", MmType Nominal, MScale [ SRange (RStrings [ "#EA98D2", "#659CCA" ]) ] ]+ . row [ FName "gender", FmType Nominal ]+ in+ toVegaLite [ des, dvals [], trans [], mark Bar [], enc [] ]+++facet2 :: VegaLite+facet2 =+ let+ des =+ description "Barley crop yields in 1931 and 1932 shown as stacked bar charts"++ enc =+ encoding+ . position X [ PName "yield", PmType Quantitative, PAggregate Sum ]+ . position Y [ PName "variety", PmType Nominal ]+ . color [ MName "site", MmType Nominal ]+ . column [ FName "year", FmType Ordinal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []+ , mark Bar []+ , enc []+ ]+++facet3 :: VegaLite+facet3 =+ let+ des =+ description "Scatterplots of movie takings vs profits for different MPAA ratings"++ enc =+ encoding+ . position X [ PName "Worldwide_Gross", PmType Quantitative ]+ . position Y [ PName "US_DVD_Sales", PmType Quantitative ]+ . column [ FName "MPAA_Rating", FmType Ordinal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Point []+ , enc []+ ]+++facet4 :: VegaLite+facet4 =+ let+ des =+ description "Disitributions of car engine power for different countries of origin"++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative, PBin [ MaxBins 15 ] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ . row [ FName "Origin", FmType Ordinal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Bar []+ , enc []+ ]+++facet5 :: VegaLite+facet5 =+ let+ des =+ description "Anscombe's Quartet"++ enc =+ encoding+ . position X [ PName "X", PmType Quantitative, PScale [ SZero False ] ]+ . position Y [ PName "Y", PmType Quantitative, PScale [ SZero False ] ]+ . opacity [ MNumber 1 ]+ . column [ FName "Series", FmType Ordinal ]+ in+ toVegaLite [ des, dataFromUrl "https://vega.github.io/vega-lite/data/anscombe.json" [], mark Circle [], enc [] ]+++facet6 :: VegaLite+facet6 =+ let+ des =+ description "The Trellis display by Becker et al. helped establish small multiples as a 'powerful mechanism for understanding interactions in studies of how a response depends on explanatory variables'"++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/barley.json"++ enc =+ encoding+ . position X+ [ PName "yield"+ , PmType Quantitative+ , PAggregate Median+ , PScale [ SZero False ]+ ]+ . position Y+ [ PName "variety"+ , PmType Ordinal+ , PScale [ SRangeStep (Just 12) ]+ , PSort [ ByChannel ChX, Descending ]+ ]+ . color [ MName "year", MmType Nominal ]+ in+ toVegaLite+ [ des+ , dvals []+ , columns 2+ , facetFlow+ [ FName "site"+ , FmType Ordinal+ , FSort [ ByFieldOp "yield" Median ]+ , FHeader [ HNoTitle ]+ ]+ , specification (asSpec [ enc [], mark Point [] ])+ ]+++facet7 :: VegaLite+facet7 =+ let+ des =+ description "Stock prices of five large companies as a small multiples of area charts"++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv"++ enc =+ encoding+ . position X+ [ PName "date"+ , PmType Temporal+ , PAxis [ AxFormat "%Y", AxNoTitle, AxGrid False ]+ ]+ . position Y+ [ PName "price"+ , PmType Quantitative+ , PAxis [ AxNoTitle, AxGrid False ]+ ]+ . color+ [ MName "symbol"+ , MmType Nominal+ , MLegend []+ ]+ . row+ [ FName "symbol"+ , FmType Nominal+ , FHeader [ HTitle "Stock price", HLabelAngle 0 ]+ ]++ res =+ resolve+ . resolution (RScale [ ( ChY, Independent ) ])++ cfg =+ configure+ . configuration (View [ ViewStroke Nothing ])+ in+ toVegaLite [ des, width 300, height 50, cfg [], res [], dvals [], mark Area [], enc [] ]
@@ -0,0 +1,385 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryGeo.elm (from development of version+-- 1.13.0)+--+module Gallery.Geo (testSpecs) where++import Graphics.Vega.VegaLite++-- import qualified Data.Text as T++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("geo1", geo1)+ , ("geo2", geo2)+ , ("geo3", geo3)+ , ("geo4", geo4)+ , ("geo5", geo5)+ , ("geo6", geo6)+ , ("geo7", geo7)+ , ("geo8", geo8)+ , ("geo9", geo9)+ ]+++{-| No borders around maps+-}+cfg :: [LabelledSpec] -> ( VLProperty, VLSpec )+cfg =+ configure+ . configuration (View [ ViewStroke Nothing ])+++geo1 :: VegaLite+geo1 =+ let+ countyData =+ dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json"+ [ TopojsonFeature "counties" ]++ unemploymentData =+ dataFromUrl "https://vega.github.io/vega-lite/data/unemployment.tsv" []++ trans =+ transform+ . lookup "id" unemploymentData "id" [ "rate" ]++ proj =+ projection [ PrType AlbersUsa ]++ enc =+ encoding+ . color [ MName "rate", MmType Quantitative, MSort [ Descending ] ]+ in+ toVegaLite [ cfg [], width 500, height 300, countyData, proj, trans [], enc [], mark Geoshape [] ]+++geo2 :: VegaLite+geo2 =+ let+ enc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . size [ MNumber 1 ]+ . color [ MName "digit", MmType Nominal ]+ in+ toVegaLite+ [ cfg []+ , description "US zip codes: One dot per zipcode colored by first digit"+ , width 500+ , height 300+ , projection [ PrType AlbersUsa ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/zipcodes.csv" []+ , transform (calculateAs "substring(datum.zip_code, 0, 1)" "digit" [])+ , mark Circle []+ , enc []+ ]+++geo3 :: VegaLite+geo3 =+ let+ des =+ description "One dot per airport in the US overlayed on geoshape"++ backdropSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]+ , mark Geoshape []+ , encoding (color [ MString "#eee" ] [])+ ]++ overlayEnc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . size [ MNumber 5 ]+ . color [ MString "steelblue" ]++ overlaySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" []+ , mark Circle []+ , overlayEnc []+ ]+ in+ toVegaLite+ [ cfg []+ , des+ , width 500+ , height 300+ , projection [ PrType AlbersUsa ]+ , layer [ backdropSpec, overlaySpec ]+ ]+++geo4 :: VegaLite+geo4 =+ let+ backdropSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]+ , mark Geoshape []+ , encoding (color [ MString "#eee" ] [])+ ]++ airportsEnc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . size [ MNumber 5 ]+ . color [ MString "gray" ]++ airportsSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" []+ , mark Circle []+ , airportsEnc []+ ]++ trans =+ transform+ . filter (FEqual "origin" (Str "SEA"))+ . lookup "origin" (dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" []) "iata" [ "latitude", "longitude" ]+ . calculateAs "datum.latitude" "origin_latitude"+ . calculateAs "datum.longitude" "origin_longitude"+ . lookup "destination" (dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" []) "iata" [ "latitude", "longitude" ]+ . calculateAs "datum.latitude" "dest_latitude"+ . calculateAs "datum.longitude" "dest_longitude"++ flightsEnc =+ encoding+ . position Longitude [ PName "origin_longitude", PmType Quantitative ]+ . position Latitude [ PName "origin_latitude", PmType Quantitative ]+ . position Longitude2 [ PName "dest_longitude" ]+ . position Latitude2 [ PName "dest_latitude" ]++ flightsSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/flights-airport.csv" []+ , trans []+ , mark Rule []+ , flightsEnc []+ ]+ in+ toVegaLite+ [ cfg []+ , description "Rules (line segments) connecting SEA to every airport reachable via direct flight"+ , width 800+ , height 500+ , projection [ PrType AlbersUsa ]+ , layer [ backdropSpec, airportsSpec, flightsSpec ]+ ]+++geo5 :: VegaLite+geo5 =+ let+ enc =+ encoding+ . shape [ MName "geo", MmType GeoFeature ]+ . color [ MRepeat Row, MmType Quantitative, MSort [ Descending ] ]++ spec =+ asSpec+ [ width 500+ , height 300+ , dataFromUrl "https://vega.github.io/vega-lite/data/population_engineers_hurricanes.csv" []+ , transform (lookupAs "id" (dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]) "id" "geo" [])+ , projection [ PrType AlbersUsa ]+ , mark Geoshape []+ , enc []+ ]+ in+ toVegaLite+ [ cfg []+ , description "Population per state, engineers per state, and hurricanes per state"+ , repeat [ RowFields [ "population", "engineers", "hurricanes" ] ]+ , resolve (resolution (RScale [ ( ChColor, Independent ) ]) [])+ , specification spec+ ]+++geo6 :: VegaLite+geo6 =+ let+ des =+ description "US state capitals overlayed on map of the US"++ backdropSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]+ , mark Geoshape []+ , encoding (color [ MString "#ccc" ] [])+ ]++ overlayEnc =+ encoding+ . position Longitude [ PName "lon", PmType Quantitative ]+ . position Latitude [ PName "lat", PmType Quantitative ]+ . text [ TName "city", TmType Nominal ]++ overlaySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/us-state-capitals.json" []+ , mark Text []+ , overlayEnc []+ ]+ in+ toVegaLite+ [ cfg []+ , des+ , width 800+ , height 500+ , projection [ PrType AlbersUsa ]+ , layer [ backdropSpec, overlaySpec ]+ ]+++geo7 :: VegaLite+geo7 =+ let+ backdropSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]+ , mark Geoshape []+ , encoding (color [ MString "#eee" ] [])+ ]++ airportsEnc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . size [ MNumber 5 ]+ . color [ MString "gray" ]++ airportsSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" []+ , mark Circle []+ , airportsEnc []+ ]++ itinerary =+ dataFromColumns []+ . dataColumn "airport" (Strings [ "SEA", "SFO", "LAX", "LAS", "DFW", "DEN", "ORD", "JFK", "ATL" ])+ . dataColumn "order" (Numbers [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ])++ trans =+ transform+ . lookup "airport" (dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" []) "iata" [ "latitude", "longitude" ]++ flightsEnc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . order [ OName "order", OmType Ordinal ]++ flightsSpec =+ asSpec+ [ itinerary []+ , trans []+ , mark Line []+ , flightsEnc []+ ]+ in+ toVegaLite+ [ cfg []+ , description "Line drawn between airports in the U.S. simulating a flight itinerary"+ , width 800+ , height 500+ , projection [ PrType AlbersUsa ]+ , layer [ backdropSpec, airportsSpec, flightsSpec ]+ ]+++geo8 :: VegaLite+geo8 =+ let+ enc =+ encoding+ . shape [ MName "geo", MmType GeoFeature ]+ . color [ MName "pct", MmType Quantitative, MSort [ Descending ] ]+ . row [ FName "group", FmType Nominal ]+ in+ toVegaLite+ [ cfg []+ , description "Income in the U.S. by state, faceted over income brackets"+ , width 500+ , height 300+ , dataFromUrl "https://vega.github.io/vega-lite/data/income.json" []+ , transform (lookupAs "id" (dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]) "id" "geo" [])+ , projection [ PrType AlbersUsa ]+ , mark Geoshape []+ , enc []+ ]+++geo9 :: VegaLite+geo9 =+ let+ tubeLineColors =+ categoricalDomainMap+ [ ( "Bakerloo", "rgb(137,78,36)" )+ , ( "Central", "rgb(220,36,30)" )+ , ( "Circle", "rgb(255,206,0)" )+ , ( "District", "rgb(1,114,41)" )+ , ( "DLR", "rgb(0,175,173)" )+ , ( "Hammersmith & City", "rgb(215,153,175)" )+ , ( "Jubilee", "rgb(106,114,120)" )+ , ( "Metropolitan", "rgb(114,17,84)" )+ , ( "Northern", "rgb(0,0,0)" )+ , ( "Piccadilly", "rgb(0,24,168)" )+ , ( "Victoria", "rgb(0,160,226)" )+ , ( "Waterloo & City", "rgb(106,187,170)" )+ ]++ polySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/londonBoroughs.json" [ TopojsonFeature "boroughs" ]+ , mark Geoshape [ MStroke "rgb(251,247,238)", MStrokeWidth 2 ]+ , encoding (color [ MString "#ddc" ] [])+ ]++ labelEnc =+ encoding+ . position Longitude [ PName "cx", PmType Quantitative ]+ . position Latitude [ PName "cy", PmType Quantitative ]+ . text [ TName "bLabel", TmType Nominal ]+ . size [ MNumber 8 ]+ . opacity [ MNumber 0.6 ]++ trans =+ transform+ . calculateAs "indexof (datum.name,' ') > 0 ? substring(datum.name,0,indexof(datum.name, ' ')) : datum.name" "bLabel"++ labelSpec =+ asSpec [ dataFromUrl "https://vega.github.io/vega-lite/data/londonCentroids.json" [], trans [], mark Text [], labelEnc [] ]++ tubeEnc =+ encoding+ . color+ [ MName "id"+ , MmType Nominal+ , MLegend [ LNoTitle, LOrient LOBottomRight, LOffset 0 ]+ , MScale tubeLineColors+ ]++ routeSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/londonTubeLines.json" [ TopojsonFeature "line" ]+ , mark Geoshape [ MFilled False, MStrokeWidth 2 ]+ , tubeEnc []+ ]+ in+ toVegaLite+ [ cfg []+ , description "Geographic position of London underground lines"+ , width 700+ , height 500+ , layer [ polySpec, labelSpec, routeSpec ]+ ]
@@ -0,0 +1,483 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryInteraction.elm (from development of version+-- 1.13.0)+--+module Gallery.Interaction (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("interaction1", interaction1)+ , ("interaction2", interaction2)+ , ("interaction3", interaction3)+ , ("interaction4", interaction4)+ , ("interaction5", interaction5)+ , ("interaction6", interaction6)+ , ("interaction7", interaction7)+ , ("interaction8", interaction8)+ , ("interaction9", interaction9)+ , ("interaction10", interaction10)+ , ("interaction11a", interaction11a)+ , ("interaction11b", interaction11b)+ , ("interaction11c", interaction11c)+ , ("interaction11d", interaction11d)+ ]+++pQuant :: T.Text -> [PositionChannel]+pQuant n = [ PName n, PmType Quantitative ]+++interaction1 :: VegaLite+interaction1 =+ let+ des =+ description "A bar chart with highlighting on hover and selecting on click. Inspired by Tableau's interaction style."++ config =+ configure+ . configuration (Scale [ SCBandPaddingInner 0.2 ])++ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ sel =+ selection+ . select "highlight" Single [ On "mouseover", Empty ]+ . select "select" Multi []++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ . fillOpacity [ MSelectionCondition (SelectionName "select") [ MNumber 1 ] [ MNumber 0.3 ] ]+ . strokeWidth+ [ MDataCondition+ [ ( And (Selection "select") (Expr "length(data(\"select_store\"))"), [ MNumber 2 ] )+ , ( Selection "highlight", [ MNumber 1 ] )+ ]+ [ MNumber 0 ]+ ]+ in+ toVegaLite+ [ des+ , config []+ , dvals []+ , sel []+ , mark Bar [ MFill "#4C78A8", MStroke "black", MCursor CPointer ]+ , enc []+ ]+++interaction2 :: VegaLite+interaction2 =+ let+ des =+ description "Scatterplot with external links and tooltips"++ trans =+ transform+ . calculateAs "'https://www.google.com/search?q=' + datum.Name" "url"++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal ]+ . tooltip [ TName "Name", TmType Nominal ]+ . hyperlink [ HName "url", HmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , trans []+ , mark Point []+ , enc []+ ]+++interaction3 :: VegaLite+interaction3 =+ let+ des =+ description "Drag out a rectangular brush to highlight points"++ sel =+ selection . select "myBrush" Interval []++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName "myBrush")+ [ MName "Cylinders", MmType Ordinal ]+ [ MString "grey" ]+ ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point []+ , sel []+ , enc []+ ]+++interaction4 :: VegaLite+interaction4 =+ let+ des =+ description "Area chart with rectangular brush"++ trans =+ transform+ . filter (FSelection "myBrush")++ sel =+ selection . select "myBrush" Interval [ Encodings [ ChX ] ]++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonth ]+ . position Y [ PName "count", PmType Quantitative, PAggregate Sum ]++ specBackground =+ asSpec [ mark Area [], sel [] ]++ specHighlight =+ asSpec [ mark Area [ MColor "goldenrod" ], trans [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/unemployment-across-industries.json" []+ , enc []+ , layer [ specBackground, specHighlight ]+ ]+++interaction5 :: VegaLite+interaction5 =+ let+ des =+ description "Mouse over individual points or select multiple points with the shift key"++ sel =+ selection . select "myPaintbrush" Multi [ On "mouseover", Nearest True ]++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . size+ [ MSelectionCondition (SelectionName "myPaintbrush")+ [ MNumber 300 ]+ [ MNumber 50 ]+ ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point []+ , sel []+ , enc []+ ]+++interaction6 :: VegaLite+interaction6 =+ let+ des =+ description "Drag to pan. Zoom in or out with mousewheel/zoom gesture."++ sel =+ selection . select "myGrid" Interval [ BindScales ]++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative, PScale [ SDomain (DNumbers [ 75, 150 ]) ] ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative, PScale [ SDomain (DNumbers [ 20, 40 ]) ] ]+ . size [ MName "Cylinders", MmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Circle []+ , sel []+ , enc []+ ]+++interaction7 :: VegaLite+interaction7 =+ let+ des =+ description "Drag the sliders to highlight points"++ trans =+ transform+ . calculateAs "year(datum.Year)" "Year"++ sel1 =+ selection+ . select "CylYr"+ Single+ [ Fields [ "Cylinders", "Year" ]+ , SInit [ ( "Cylinders", Number 4 ), ( "Year", Number 1977 ) ]+ , Bind+ [ IRange "Cylinders" [ InName "Cylinders ", InMin 3, InMax 8, InStep 1 ]+ , IRange "Year" [ InName "Year ", InMin 1969, InMax 1981, InStep 1 ]+ ]+ ]++ encPosition =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]++ enc1 =+ encoding+ . color+ [ MSelectionCondition (SelectionName "CylYr")+ [ MName "Origin", MmType Nominal ]+ [ MString "grey" ]+ ]++ spec1 =+ asSpec [ sel1 [], mark Circle [], enc1 [] ]++ trans2 =+ transform+ . filter (FSelection "CylYr")++ enc2 =+ encoding+ . color [ MName "Origin", MmType Nominal ]+ . size [ MNumber 100 ]++ spec2 =+ asSpec [ trans2 [], mark Circle [], enc2 [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , trans []+ , encPosition []+ , layer [ spec1, spec2 ]+ ]+++interaction8 :: VegaLite+interaction8 =+ let+ des =+ description "Drag over bars to update selection average"++ sel =+ selection . select "myBrush" Interval [ Encodings [ ChX ] ]++ encPosition =+ encoding . position Y [ PName "precipitation", PmType Quantitative, PAggregate Mean ]++ enc1 =+ encoding+ . position X [ PName "date", PmType Ordinal, PTimeUnit Month ]+ . opacity+ [ MSelectionCondition (SelectionName "myBrush")+ [ MNumber 1 ]+ [ MNumber 0.7 ]+ ]++ spec1 =+ asSpec [ sel [], mark Bar [], enc1 [] ]++ trans =+ transform+ . filter (FSelection "myBrush")++ enc2 =+ encoding+ . color [ MString "firebrick" ]+ . size [ MNumber 3 ]++ spec2 =+ asSpec [ des, trans [], mark Rule [], enc2 [] ]+ in+ toVegaLite+ [ dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , encPosition []+ , layer [ spec1, spec2 ]+ ]+++interaction9 :: VegaLite+interaction9 =+ let+ desc =+ description "Displays tooltips for all stock prices of the hovered time"++ enc1 =+ encoding+ . position X [ PName "date", PmType Temporal ]+ . position Y [ PName "price", PmType Quantitative ]+ . color [ MName "symbol", MmType Nominal ]++ spec1 =+ asSpec+ [ enc1 []+ , layer+ [ asSpec [ mark Line [] ]+ , asSpec [ mark Point [], sel1_2 [], enc1_2 [] ]+ ]+ ]++ enc1_2 =+ encoding+ . opacity [ MSelectionCondition (Expr "myTooltip") [ MNumber 1 ] [ MNumber 0 ] ]++ sel1_2 =+ selection+ . select "myTooltip"+ Single+ [ Nearest True+ , On "mouseover"+ , Encodings [ ChX ]+ , Empty+ ]++ spec2 =+ asSpec [ trans2 [], layer [ spec2_1, spec2_2 ] ]++ trans2 =+ transform . filter (FSelection "myTooltip")++ spec2_1 =+ asSpec [ mark Rule [ MColor "gray" ], enc2_1 [] ]++ enc2_1 =+ encoding . position X [ PName "date", PmType Temporal ]++ spec2_2 =+ asSpec [ mark Text [ MAlign AlignLeft, MdX 5, MdY (-5) ], enc2_2 [] ]++ enc2_2 =+ encoding+ . position X [ PName "date", PmType Temporal ]+ . position Y [ PName "price", PmType Quantitative ]+ . text [ TName "price", TmType Quantitative ]+ . color [ MName "symbol", MmType Nominal ]+ in+ toVegaLite+ [ width 800+ , height 400+ , desc+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" [ Parse [ ( "date", FoDate "" ) ] ]+ , layer [ spec1, spec2 ]+ ]+++interaction10 :: VegaLite+interaction10 =+ let+ desc =+ description "Multi Series Line Chart with Tooltip"++ config =+ configure+ . configuration (AxisY [ MinExtent 30 ])++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonthDate ]+ . tooltips+ [ [ TName "date", TmType Temporal, TTimeUnit YearMonthDate ]+ , [ TName "temp_max", TmType Quantitative ]+ , [ TName "temp_min", TmType Quantitative ]+ ]++ enc1 =+ encoding+ . position Y [ PName "temp_max", PmType Quantitative ]++ spec1 =+ asSpec [ mark Line [ MColor "orange" ], enc1 [] ]++ enc2 =+ encoding+ . position Y [ PName "temp_min", PmType Quantitative ]++ spec2 =+ asSpec [ mark Line [ MColor "red" ], enc2 [] ]++ sel =+ selection+ . select "hover" Single [ On "mouseover", Empty ]++ enc3 =+ encoding+ . color+ [ MSelectionCondition (Not (SelectionName "hover"))+ [ MString "transparent" ]+ []+ ]++ spec3 =+ asSpec [ sel [], mark Rule [], enc3 [] ]+ in+ toVegaLite+ [ config []+ , desc+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , enc []+ , layer [ spec1, spec2, spec3 ]+ ]+++-- From https://vega.github.io/vega-lite/examples/interactive_brush.html+-- and added to test SInitInterval+--+initInterval :: Maybe (DataValue, DataValue) -> Maybe (DataValue, DataValue) -> VegaLite+initInterval mx my =+ let desc = "Drag out a rectangular brush to hughlight points."++ sel = selection+ . select "brush" Interval [ SInitInterval mx my ]++ enc = encoding+ . position X (pQuant "Horsepower")+ . position Y (pQuant "Miles_per_Gallon")+ . color [ MSelectionCondition+ (SelectionName "brush")+ [ MName "Cylinders", MmType Ordinal ]+ [ MString "grey" ]+ ]++ in toVegaLite+ [ description desc+ , dataFromUrl "data/cars.json" []+ , mark Point []+ , enc []+ , sel []+ ]+++xInit, yInit :: (DataValue, DataValue)+xInit = (Number 55, Number 160)+yInit = (Number 13, Number 37)++-- Note: interaction11a is invalid according to the Vega Lite 3.4.0+-- specification.+--+interaction11a, interaction11b, interaction11c, interaction11d :: VegaLite+interaction11a = initInterval Nothing Nothing+interaction11b = initInterval (Just xInit) Nothing+interaction11c = initInterval Nothing (Just yInit)+interaction11d = initInterval (Just xInit) (Just yInit)
@@ -0,0 +1,330 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryLabel.elm (from development of version+-- 1.13.0)+--+module Gallery.Label (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("label1", label1)+ , ("label2", label2)+ , ("label3", label3)+ , ("label4", label4)+ , ("label5", label5)+ , ("label6", label6)+ , ("label7", label7)+ ]++label1 :: VegaLite+label1 =+ let+ des =+ description "A simple bar chart with embedded data labels"++ dvals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C" ])+ . dataColumn "b" (Numbers [ 28, 55, 43 ])++ enc =+ encoding+ . position X [ PName "b", PmType Quantitative ]+ . position Y [ PName "a", PmType Ordinal ]++ specBar =+ asSpec [ mark Bar [] ]++ specText =+ asSpec [ mark Text [ MStyle [ "label" ] ], encoding (text [ TName "b", TmType Quantitative ] []) ]++ config =+ configure . configuration (NamedStyle "label" [ MAlign AlignLeft, MBaseline AlignMiddle, MdX 3 ])+ in+ toVegaLite [ des, dvals [], enc [], layer [ specBar, specText ], config [] ]+++label2 :: VegaLite+label2 =+ let+ des =+ description "Layering text over 'heatmap'"++ encPosition =+ encoding+ . position X [ PName "Cylinders", PmType Ordinal ]+ . position Y [ PName "Origin", PmType Ordinal ]++ encRect =+ encoding+ . color [ MName "*", MmType Quantitative, MAggregate Count ]++ specRect =+ asSpec [ mark Rect [], encRect [] ]++ encText =+ encoding+ . color [ MString "white" ]+ . text [ TName "*", TmType Quantitative, TAggregate Count ]++ specText =+ asSpec [ mark Text [], encText [] ]++ config =+ configure+ . configuration (Scale [ SCBandPaddingInner 0, SCBandPaddingOuter 0 ])+ . configuration (TextStyle [ MBaseline AlignMiddle ])+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , encPosition []+ , layer [ specRect, specText ]+ , config []+ ]+++label3 :: VegaLite+label3 =+ let+ des =+ description "Carbon dioxide in the atmosphere."++ trans =+ transform+ . calculateAs "year(datum.Date)" "year"+ . calculateAs "month(datum.Date)" "month"+ . calculateAs "floor(datum.year / 10)" "decade"+ . calculateAs "(datum.year % 10) + (datum.month / 12)" "scaled_date"++ encPosition =+ encoding+ . position X+ [ PName "scaled_date"+ , PmType Quantitative+ , PAxis [ AxTitle "Year into decade"+ , AxTickCount 10+ , AxValues (Numbers [1, 2, 3, 4, 5, 6, 7, 8, 9])+ ]+ ]+ . position Y+ [ PName "CO2"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ AxTitle "CO2 concentration in ppm" ]+ ]++ encLine =+ encoding+ . color [ MName "decade", MmType Nominal, MLegend [] ]++ specLine =+ asSpec [ mark Line [ MOrient Vertical ], encLine [] ]++ transTextMin =+ transform+ . aggregate [ opAs (ArgMin Nothing) "scaled_date" "aggregated" ] [ "decade" ]+ . calculateAs "datum.aggregated.scaled_date" "scaled_date"+ . calculateAs "datum.aggregated.CO2" "CO2"++ encTextMin =+ encoding+ . text [ TName "aggregated.year", TmType Nominal ]++ specTextMin =+ asSpec [ transTextMin [], mark Text [ MAlign AlignLeft, MBaseline AlignTop, MdX 3, MdY 1 ], encTextMin [] ]++ transTextMax =+ transform+ . aggregate [ opAs (ArgMax Nothing) "scaled_date" "aggregated" ] [ "decade" ]+ . calculateAs "datum.aggregated.scaled_date" "scaled_date"+ . calculateAs "datum.aggregated.CO2" "CO2"++ encTextMax =+ encoding+ . text [ TName "aggregated.year", TmType Nominal ]++ specTextMax =+ asSpec [ transTextMax [], mark Text [ MAlign AlignLeft, MBaseline AlignBottom, MdX 3, MdY 1 ], encTextMax [] ]++ config =+ configure . configuration (View [ ViewStroke Nothing ])+ in+ toVegaLite+ [ des+ , config []+ , width 800+ , height 500+ , dataFromUrl "https://vega.github.io/vega-lite/data/co2-concentration.csv" [ Parse [ ( "Date", FoUtc "%Y-%m-%d" ) ] ]+ , trans []+ , encPosition []+ , layer [ specLine, specTextMin, specTextMax ]+ ]+++label4 :: VegaLite+label4 =+ let+ des =+ description "Bar chart that highlights values beyond a threshold. The PM2.5 value of Beijing observed 15 days, highlighting the days when PM2.5 level is hazardous to human health. Data source https://chartaccent.github.io/chartaccent.html"++ dvals =+ dataFromColumns []+ . dataColumn "Day" (Numbers (map fromIntegral [1::Int .. 15]))+ . dataColumn "Value" (Numbers [ 54.8, 112.1, 63.6, 37.6, 79.7, 137.9, 120.1, 103.3, 394.8, 199.5, 72.3, 51.1, 112.0, 174.5, 130.5 ])++ encBar =+ encoding+ . position X [ PName "Day", PmType Ordinal, PAxis [ AxLabelAngle 0 ] ]+ . position Y [ PName "Value", PmType Quantitative ]++ specBar =+ asSpec [ mark Bar [], encBar [] ]++ trans =+ transform+ . filter (FExpr "datum.Value >= 300")+ . calculateAs "300" "baseline"++ encUpperBar =+ encoding+ . position X [ PName "Day", PmType Ordinal, PAxis [ AxLabelAngle 0 ] ]+ . position Y [ PName "baseline", PmType Quantitative ]+ . position Y2 [ PName "Value" ]+ . color [ MString "#e45755" ]++ specUpperBar =+ asSpec [ trans [], mark Bar [], encUpperBar [] ]++ layer0 =+ asSpec [ dvals [], layer [ specBar, specUpperBar ] ]++ thresholdData =+ dataFromRows []+ . dataRow [ ( "ThresholdValue", Number 300 ), ( "Threshold", Str "hazardous" ) ]++ specRule =+ asSpec [ mark Rule [], encRule [] ]++ encRule =+ encoding+ . position Y [ PName "ThresholdValue", PmType Quantitative ]++ specText =+ asSpec [ mark Text [ MAlign AlignRight, MdX (-2), MdY (-4) ], encText [] ]++ encText =+ encoding+ . position X [ PWidth ]+ . position Y [ PName "ThresholdValue", PmType Quantitative, PAxis [ AxTitle "PM2.5 Value" ] ]+ . text [ TName "Threshold", TmType Ordinal ]++ layer1 =+ asSpec [ thresholdData [], layer [ specRule, specText ] ]+ in+ toVegaLite [ des, layer [ layer0, layer1 ] ]+++label5 :: VegaLite+label5 =+ let+ des =+ description "Monthly precipitation with mean value overlay"++ encBar =+ encoding+ . position X [ PName "date", PmType Ordinal, PTimeUnit Month ]+ . position Y [ PName "precipitation", PmType Quantitative, PAggregate Mean ]++ specBar =+ asSpec [ mark Bar [], encBar [] ]++ encLine =+ encoding+ . position Y [ PName "precipitation", PmType Quantitative, PAggregate Mean ]+ . color [ MString "red" ]+ . size [ MNumber 3 ]++ specLine =+ asSpec [ mark Rule [], encLine [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , layer [ specBar, specLine ]+ ]+++label6 :: VegaLite+label6 =+ let+ des =+ description "Histogram with global mean overlay"++ encBars =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [], PAxis [] ]+ . position Y [ PmType Quantitative, PAggregate Count ]++ specBars =+ asSpec [ mark Bar [], encBars [] ]++ encMean =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAggregate Mean ]+ . color [ MString "red" ]+ . size [ MNumber 5 ]++ specMean =+ asSpec [ mark Rule [], encMean [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , layer [ specBars, specMean ]+ ]+++label7 :: VegaLite+label7 =+ let+ des =+ description "The population of the German city of Falkensee over time with annotated time periods highlighted"++ dvals =+ dataFromColumns [ Parse [ ( "year", FoDate "%Y" ) ] ]+ . dataColumn "year" (Strings [ "1875", "1890", "1910", "1925", "1933", "1939", "1946", "1950", "1964", "1971", "1981", "1985", "1989", "1990", "1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014" ])+ . dataColumn "population" (Numbers [ 1309, 1558, 4512, 8180, 15915, 24824, 28275, 29189, 29881, 26007, 24029, 23340, 22307, 22087, 22139, 22105, 22242, 22801, 24273, 25640, 27393, 29505, 32124, 33791, 35297, 36179, 36829, 37493, 38376, 39008, 39366, 39821, 40179, 40511, 40465, 40905, 41258, 41777 ])++ highlights =+ dataFromColumns [ Parse [ ( "start", FoDate "%Y" ), ( "end", FoDate "%Y" ) ] ]+ . dataColumn "start" (Strings [ "1933", "1948" ])+ . dataColumn "end" (Strings [ "1945", "1989" ])+ . dataColumn "event" (Strings [ "Nazi Rule", "GDR (East Germany)" ])++ encRects =+ encoding+ . position X [ PName "start", PmType Temporal, PTimeUnit Year, PAxis [] ]+ . position X2 [ PName "end", PTimeUnit Year ]+ . color [ MName "event", MmType Nominal ]++ specRects =+ asSpec [ highlights [], mark Rect [], encRects [] ]++ encPopulation =+ encoding+ . position X [ PName "year", PmType Temporal, PTimeUnit Year, PAxis [ AxNoTitle ] ]+ . position Y [ PName "population", PmType Quantitative ]+ . color [ MString "#333" ]++ specLine =+ asSpec [ mark Line [], encPopulation [] ]++ specPoints =+ asSpec [ mark Point [], encPopulation [] ]+ in+ toVegaLite [ des, width 500, dvals [], layer [ specRects, specLine, specPoints ] ]
@@ -0,0 +1,433 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryLayer.elm (from development of version+-- 1.13.0)+--+module Gallery.Layer (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)++import Data.Aeson (Value, (.=), object, toJSON)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("layer1", layer1)+ , ("layer2", layer2)+ , ("layer3", layer3)+ , ("layer4", layer4)+ , ("layer5", layer5)+ , ("layer6", layer6)+ , ("layer7", layer7)+ ]++layer1 :: VegaLite+layer1 =+ let+ des =+ description "A candlestick chart inspired by Protovis (http://mbostock.github.io/protovis/ex/candlestick.html)"++ dvals =+ dataFromColumns []+ . dataColumn "date" (Strings [ "01-Jun-2009", "02-Jun-2009", "03-Jun-2009", "04-Jun-2009", "05-Jun-2009", "08-Jun-2009", "09-Jun-2009", "10-Jun-2009", "11-Jun-2009", "12-Jun-2009", "15-Jun-2009", "16-Jun-2009", "17-Jun-2009", "18-Jun-2009", "19-Jun-2009", "22-Jun-2009", "23-Jun-2009", "24-Jun-2009", "25-Jun-2009", "26-Jun-2009", "29-Jun-2009", "30-Jun-2009" ])+ . dataColumn "open" (Numbers [ 28.7, 30.04, 29.62, 31.02, 29.39, 30.84, 29.77, 26.9, 27.36, 28.08, 29.7, 30.81, 31.19, 31.54, 29.16, 30.4, 31.3, 30.58, 29.45, 27.09, 25.93, 25.36 ])+ . dataColumn "high" (Numbers [ 30.05, 30.13, 31.79, 31.02, 30.81, 31.82, 29.77, 29.74, 28.11, 28.5, 31.09, 32.75, 32.77, 31.54, 29.32, 32.05, 31.54, 30.58, 29.56, 27.22, 27.18, 27.38 ])+ . dataColumn "low" (Numbers [ 28.45, 28.3, 29.62, 29.92, 28.85, 26.41, 27.79, 26.9, 26.81, 27.73, 29.64, 30.07, 30.64, 29.6, 27.56, 30.3, 27.83, 28.79, 26.3, 25.76, 25.29, 25.02 ])+ . dataColumn "close" (Numbers [ 30.04, 29.63, 31.02, 30.18, 29.62, 29.77, 28.27, 28.46, 28.11, 28.15, 30.81, 32.68, 31.54, 30.03, 27.99, 31.17, 30.58, 29.05, 26.36, 25.93, 25.35, 26.35 ])+ . dataColumn "signal" (Strings [ "short", "short", "short", "short", "short", "short", "short", "short", "short", "short", "long", "short", "short", "short", "short", "short", "short", "long", "long", "long", "long", "long" ])+ . dataColumn "ret" (Numbers [ -4.89396411092985, -0.322580645161295, 3.68663594470045, 4.51010886469673, 6.08424336973478, 1.2539184952978, -5.02431118314424, -5.46623794212217, -8.3743842364532, -5.52763819095477, 3.4920634920635, 0.155038759689914, 5.82822085889571, 8.17610062893082, 8.59872611464968, 15.4907975460123, 11.7370892018779, -10.4234527687296, 0, 0, 5.26315789473684, 6.73758865248228 ])++ trans =+ transform . calculateAs "datum.open > datum.close" "isIncrease"++ encLine =+ encoding+ . position X+ [ PName "date"+ , PmType Temporal+ , PTimeUnit YearMonthDate+ , PScale [ SDomain (DDateTimes [ [ DTMonth May, DTDate 31, DTYear 2009 ], [ DTMonth Jul, DTDate 1, DTYear 2009 ] ]) ]+ , PAxis [ AxTitle "Date in 2009", AxFormat "%m/%d" ]+ ]+ . position Y [ PName "low", PmType Quantitative, PScale [ SZero False ] ]+ . position Y2 [ PName "high" ]+ . color [ MName "isIncrease", MmType Nominal, MLegend [], MScale [ SRange (RStrings [ "#ae1325", "#06982d" ]) ] ]++ specLine =+ asSpec [ mark Rule [], encLine [] ]++ encBar =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit YearMonthDate ]+ . position Y [ PName "open", PmType Quantitative ]+ . position Y2 [ PName "close" ]+ . size [ MNumber 5 ]+ . color [ MName "isIncrease", MmType Nominal, MLegend [] ]++ specBar =+ asSpec [ mark Bar [], encBar [] ]+ in+ toVegaLite [ des, width 320, dvals [], trans [], layer [ specLine, specBar ] ]+++layer2 :: VegaLite+layer2 =+ let+ des =+ description "A ranged dot plot that uses 'layer' to convey changing life expectancy for the five most populous countries (between 1955 and 2000)."++ trans =+ transform+ . filter (FOneOf "country" (Strings [ "China", "India", "United States", "Indonesia", "Brazil" ]))+ . filter (FOneOf "year" (Numbers [ 1955, 2000 ]))++ encCountry =+ encoding+ . position Y+ [ PName "country"+ , PmType Nominal+ , PAxis [ AxTitle "Country", AxOffset 5, AxTicks False, AxMinExtent 70, AxDomain False ]+ ]++ encLine =+ encoding+ . position X [ PName "life_expect", PmType Quantitative ]+ . detail [ DName "country", DmType Nominal ]+ . color [ MString "#db646f" ]++ specLine =+ asSpec [ mark Line [], encLine [] ]++ encPoints =+ encoding+ . position X [ PName "life_expect", PmType Quantitative, PAxis [ AxTitle "Life Expectancy (years)" ] ]+ . color [ MName "year", MmType Ordinal, MScale (domainRangeMap ( 1955, "#e6959c" ) ( 2000, "#911a24" )), MLegend [ LTitle "Year" ] ]+ . size [ MNumber 100 ]+ . opacity [ MNumber 1 ]++ specPoints =+ asSpec [ mark Point [ MFilled True ], encPoints [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/countries.json" []+ , trans []+ , encCountry []+ , layer [ specLine, specPoints ]+ ]+++layer3 :: VegaLite+layer3 =+ let+ des =+ description "Bullet chart"++ conf =+ configure . configuration (TickStyle [ MThickness 2 ])++ row_ :: T.Text -> [Double] -> [Double] -> Double -> Value+ row_ ttl ranges measures marker =+ object+ [ "title" .= ttl+ , "ranges" .= ranges+ , "measures" .= measures+ , "markers" .= [ marker ]+ ]++ dvals =+ dataFromJson+ (toJSON+ [ row_ "Revenue" [ 150, 225, 300 ] [ 220, 270 ] 250+ , row_ "Profit" [ 20, 25, 30 ] [ 21, 23 ] 26+ , row_ "Order size" [ 350, 500, 600 ] [ 100, 320 ] 550+ , row_ "New customers" [ 1400, 2000, 2500 ] [ 1000, 1650 ] 2100+ , row_ "Satisfaction" [ 3.5, 4.25, 5 ] [ 3.2, 4.7 ] 4.4+ ]+ )++ fac =+ facet [ RowBy [ FName "title", FmType Ordinal, FHeader [ HLabelAngle 30, HNoTitle ] ] ]++ res =+ resolve . resolution (RScale [ ( ChX, Independent ) ])++ enc1 =+ encoding+ . position X+ [ PName "ranges[2]"+ , PmType Quantitative+ , PScale [ SNice (IsNice False) ]+ , PAxis [ AxNoTitle ]+ ]++ spec1 =+ asSpec [ mark Bar [ MColor "#eee" ], enc1 [] ]++ enc2 =+ encoding . position X [ PName "ranges[1]", PmType Quantitative ]++ spec2 =+ asSpec [ mark Bar [ MColor "#ddd" ], enc2 [] ]++ enc3 =+ encoding . position X [ PName "ranges[0]", PmType Quantitative ]++ spec3 =+ asSpec [ mark Bar [ MColor "#ccc" ], enc3 [] ]++ enc4 =+ encoding . position X [ PName "measures[1]", PmType Quantitative ]++ spec4 =+ asSpec [ mark Bar [ MColor "lightsteelblue", MSize 10 ], enc4 [] ]++ enc5 =+ encoding . position X [ PName "measures[0]", PmType Quantitative ]++ spec5 =+ asSpec [ mark Bar [ MColor "steelblue", MSize 10 ], enc5 [] ]++ enc6 =+ encoding . position X [ PName "markers[0]", PmType Quantitative ]++ spec6 =+ asSpec [ mark Tick [ MColor "black" ], enc6 [] ]+ in+ toVegaLite+ [ des+ , conf []+ , dvals []+ , fac+ , res []+ , specification (asSpec [ layer [ spec1, spec2, spec3, spec4, spec5, spec6 ] ])+ ]+++layer4 :: VegaLite+layer4 =+ let+ des =+ description "Layered bar/line chart with dual axes"++ encTime =+ encoding . position X [ PName "date", PmType Ordinal, PTimeUnit Month ]++ encBar =+ encoding+ . position Y [ PName "precipitation", PmType Quantitative, PAggregate Mean, PAxis [ AxGrid False ] ]++ specBar =+ asSpec [ mark Bar [], encBar [] ]++ encLine =+ encoding+ . position Y [ PName "temp_max", PmType Quantitative, PAggregate Mean, PAxis [ AxGrid False ], PScale [ SZero False ] ]+ . color [ MString "firebrick" ]++ specLine =+ asSpec [ mark Line [], encLine [] ]++ res =+ resolve+ . resolution (RScale [ ( ChY, Independent ) ])+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , encTime []+ , layer [ specBar, specLine ]+ , res []+ ]++layer5 :: VegaLite+layer5 =+ let+ des =+ description "Horizon chart with 2 layers. (See https://idl.cs.washington.edu/papers/horizon/ for more details on horizon charts.)"++ dvals =+ dataFromColumns []+ . dataColumn "x" (Numbers (map fromIntegral [1::Int .. 20]))+ . dataColumn "y" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52, 48, 24, 49, 87, 66, 17, 27, 68, 16, 49, 15 ])++ trans =+ transform . calculateAs "datum.y - 50" "ny"++ encX =+ encoding . position X [ PName "x", PmType Quantitative, PScale [ SZero False, SNice (IsNice False) ] ]++ encLower =+ encoding+ . position Y [ PName "y", PmType Quantitative, PScale [ SDomain (DNumbers [ 0, 50 ]) ] ]+ . opacity [ MNumber 0.6 ]++ specLower =+ asSpec [ mark Area [ MClip True ], encLower [] ]++ encUpper =+ encoding+ . position Y [ PName "ny", PmType Quantitative, PScale [ SDomain (DNumbers [ 0, 50 ]) ], PAxis [ AxTitle "y" ] ]+ . opacity [ MNumber 0.3 ]++ specUpper =+ asSpec [ trans [], mark Area [ MClip True ], encUpper [] ]++ config =+ configure+ . configuration (AreaStyle [ MInterpolate Monotone, MOrient Vertical ])+ in+ toVegaLite+ [ des+ , width 300+ , height 50+ , dvals []+ , encX []+ , layer [ specLower, specUpper ]+ , config []+ ]+++layer6 :: VegaLite+layer6 =+ let+ enc1 =+ encoding+ . position Y [ PName "record.low", PmType Quantitative, PScale [ SDomain (DNumbers [ 10, 70 ]) ], PAxis [ AxTitle "Temperature (F)" ] ]+ . position Y2 [ PName "record.high" ]+ . position X [ PName "id", PmType Ordinal, PAxis [ AxTitle "Day" ] ]+ . size [ MNumber 20 ]+ . color [ MString "#ccc" ]++ spec1 =+ asSpec [ mark Bar [], enc1 [] ]++ enc2 =+ encoding+ . position Y [ PName "normal.low", PmType Quantitative ]+ . position Y2 [ PName "normal.high" ]+ . position X [ PName "id", PmType Ordinal ]+ . size [ MNumber 20 ]+ . color [ MString "#999" ]++ spec2 =+ asSpec [ mark Bar [], enc2 [] ]++ enc3 =+ encoding+ . position Y [ PName "actual.low", PmType Quantitative ]+ . position Y2 [ PName "actual.high" ]+ . position X [ PName "id", PmType Ordinal ]+ . size [ MNumber 12 ]+ . color [ MString "#000" ]++ spec3 =+ asSpec [ mark Bar [], enc3 [] ]++ enc4 =+ encoding+ . position Y [ PName "forecast.low.low", PmType Quantitative ]+ . position Y2 [ PName "forecast.low.high" ]+ . position X [ PName "id", PmType Ordinal ]+ . size [ MNumber 12 ]+ . color [ MString "#000" ]++ spec4 =+ asSpec [ mark Bar [], enc4 [] ]++ enc5 =+ encoding+ . position Y [ PName "forecast.low.high", PmType Quantitative ]+ . position Y2 [ PName "forecast.high.low" ]+ . position X [ PName "id", PmType Ordinal ]+ . size [ MNumber 3 ]+ . color [ MString "#000" ]++ spec5 =+ asSpec [ mark Bar [], enc5 [] ]++ enc6 =+ encoding+ . position Y [ PName "forecast.high.low", PmType Quantitative ]+ . position Y2 [ PName "forecast.high.high" ]+ . position X [ PName "id", PmType Ordinal ]+ . size [ MNumber 12 ]+ . color [ MString "#000" ]++ spec6 =+ asSpec [ mark Bar [], enc6 [] ]++ enc7 =+ encoding+ . position X+ [ PName "id"+ , PmType Ordinal+ , PAxis+ [ AxDomain False+ , AxTicks False+ , AxLabels False+ , AxTitle "Day"+ , AxTitlePadding 25+ , AxOrient STop+ ]+ ]+ . text [ TName "day", TmType Nominal ]++ spec7 =+ asSpec [ mark Text [ MAlign AlignCenter, MdY (-105) ], enc7 [] ]+ in+ toVegaLite+ [ description "A layered bar chart with floating bars representing weekly weather data"+ , title "Weekly Weather Observations and Predictions" []+ , width 250+ , height 200+ , dataFromUrl "https://vega.github.io/vega-lite/data/weather.json" []+ , layer [ spec1, spec2, spec3, spec4, spec5, spec6, spec7 ]+ ]+++-- From+-- https://vega.github.io/vega-lite/examples/layer_line_rolling_mean_point_raw.html+-- but slightly adjusted, to use ZIndex on one of the axes.+--+layer7 :: VegaLite+layer7 =+ let desc = "Plot showing a 30 day rolling average with raw values in the background."++ wtrans = window+ [([WAggregateOp Mean, WField "temp_max"], "rolling_mean")]+ [WFrame (Just (-15)) (Just 15)]++ allPoints = [ mark Point [MOpacity 0.3]+ , encoding+ . position X [ PName "date"+ , PmType Temporal+ , PTitle "Date"+ , PAxis [ AxZIndex 1+ , AxGridColor "orange"+ , AxGridOpacity 0.8+ ]+ ]+ . position Y [PName "temp_max", PmType Quantitative, PTitle "Max Temperature"]+ $ []+ ]+ avgPoints = [ mark Line [MColor "red", MSize 3]+ , encoding+ . position X [PName "date", PmType Temporal]+ . position Y [PName "rolling_mean", PmType Quantitative]+ $ []+ ]++ layers = map asSpec [allPoints, avgPoints]++ in toVegaLite+ [ description desc+ , height 300+ , width 400+ , dataFromUrl "data/seattle-weather.csv" []+ , transform (wtrans [])+ , layer layers+ ]
@@ -0,0 +1,370 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryLine.elm (from development of version+-- 1.13.0)+--+module Gallery.Line (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)+++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("line1", line1)+ , ("line2", line2)+ , ("line3", line3)+ , ("line4", line4)+ , ("line5", line5)+ , ("line6", line6)+ , ("line7", line7)+ , ("line8", line8)+ , ("line9", line9)+ , ("line10", line10)+ , ("line11", line11)+ , ("line12", line12)+ ]+++line1 :: VegaLite+line1 =+ let+ des =+ description "Google's stock price over time."++ trans =+ transform . filter (FExpr "datum.symbol === 'GOOG'")++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , trans []+ , mark Line []+ , enc []+ ]+++line2 :: VegaLite+line2 =+ let+ des =+ description "Google's stock price over time with point markers."++ trans =+ transform . filter (FExpr "datum.symbol === 'GOOG'")++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , trans []+ , mark Line [ MColor "green", MPoint (PMMarker [ MColor "purple" ]) ]+ , enc []+ ]+++line3 :: VegaLite+line3 =+ let+ des =+ description "Stock prices of 5 tech companies over time."++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ . color [ MName "symbol", MmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , mark Line []+ , enc []+ ]+++line4 :: VegaLite+line4 =+ let+ des =+ description "Slope graph showing the change in yield for different barley sites. It shows the error in the year labels for the Morris site."++ enc =+ encoding+ . position X [ PName "year", PmType Ordinal, PScale [ SRangeStep (Just 50), SPadding 0.5 ] ]+ . position Y [ PName "yield", PmType Quantitative, PAggregate Median ]+ . color [ MName "site", MmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/barley.json" []+ , mark Line []+ , enc []+ ]+++line5 :: VegaLite+line5 =+ let+ des =+ description "Google's stock price over time (quantized as a step-chart)."++ trans =+ transform . filter (FExpr "datum.symbol === 'GOOG'")++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , trans []+ , mark Line [ MInterpolate StepAfter ]+ , enc []+ ]+++line6 :: VegaLite+line6 =+ let+ des =+ description "Google's stock price over time (smoothed with monotonic interpolation)."++ trans =+ transform . filter (FExpr "datum.symbol === 'GOOG'")++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , trans []+ , mark Line [ MInterpolate Monotone ]+ , enc []+ ]+++line7 :: VegaLite+line7 =+ let+ des =+ description "A connected scatterplot can be created by customizing line order and adding point marker in the line mark definition."++ enc =+ encoding+ . position X [ PName "miles", PmType Quantitative, PScale [ SZero False ] ]+ . position Y [ PName "gas", PmType Quantitative, PScale [ SZero False ] ]+ . order [ OName "year", OmType Temporal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/driving.json" []+ , enc []+ , mark Line [ MPoint (PMMarker []) ]+ ]+++line8 :: VegaLite+line8 =+ let+ des =+ description "Stock prices of five tech companies over time double encoding price with vertical position and line thickness."++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ . size [ MName "price", MmType Quantitative ]+ . color [ MName "symbol", MmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , mark Trail []+ , enc []+ ]+++line9 :: VegaLite+line9 =+ let+ des =+ description "Line chart with markers and invalid values."++ dvals =+ dataFromColumns []+ . dataColumn "x" (Numbers [ 1, 2, 3, 4, 5, 6, 7 ])+ . dataColumn "y" (Numbers [ 10, 30, 0 / 0, 15, 0 / 0, 40, 20 ])++ enc =+ encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dvals []+ , mark Line [ MPoint (PMMarker []) ]+ , enc []+ ]+++line10 :: VegaLite+line10 =+ let+ des =+ description "Carbon dioxide in the atmosphere."++ trans =+ transform+ . calculateAs "year(datum.Date)" "year"+ . calculateAs "month(datum.Date)" "month"+ . calculateAs "floor(datum.year / 10)" "decade"+ . calculateAs "(datum.year % 10) + (datum.month / 12)" "scaled_date"++ encPosition =+ encoding+ . position X+ [ PName "scaled_date"+ , PmType Quantitative+ , PAxis [ AxTitle "Year into decade"+ , AxTickCount 10+ , AxValues (Numbers [1, 2, 3, 4, 5, 6, 7, 8, 9])+ ]+ ]+ . position Y+ [ PName "CO2"+ , PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ AxTitle "CO2 concentration in ppm" ]+ ]++ encLine =+ encoding+ . color [ MName "decade", MmType Nominal, MLegend [] ]++ specLine =+ asSpec [ mark Line [ MOrient Vertical ], encLine [] ]++ transTextMin =+ transform+ . aggregate [ opAs (ArgMin Nothing) "scaled_date" "aggregated" ] [ "decade" ]+ . calculateAs "datum.aggregated.scaled_date" "scaled_date"+ . calculateAs "datum.aggregated.CO2" "CO2"++ encTextMin =+ encoding+ . text [ TName "aggregated.year", TmType Nominal ]++ specTextMin =+ asSpec [ transTextMin [], mark Text [ MAlign AlignLeft, MBaseline AlignTop, MdX 3, MdY 1 ], encTextMin [] ]++ transTextMax =+ transform+ . aggregate [ opAs (ArgMax Nothing) "scaled_date" "aggregated" ] [ "decade" ]+ . calculateAs "datum.aggregated.scaled_date" "scaled_date"+ . calculateAs "datum.aggregated.CO2" "CO2"++ encTextMax =+ encoding+ . text [ TName "aggregated.year", TmType Nominal ]++ specTextMax =+ asSpec [ transTextMax [], mark Text [ MAlign AlignLeft, MBaseline AlignBottom, MdX 3, MdY 1 ], encTextMax [] ]++ config =+ configure . configuration (View [ ViewStroke Nothing ])+ in+ toVegaLite+ [ des+ , config []+ , width 800+ , height 500+ , dataFromUrl "https://vega.github.io/vega-lite/data/co2-concentration.csv" [ Parse [ ( "Date", FoUtc "%Y-%m-%d" ) ] ]+ , trans []+ , encPosition []+ , layer [ specLine, specTextMin, specTextMax ]+ ]+++line11 :: VegaLite+line11 =+ let+ des =+ description "Line chart showing ranks over time for thw World Cup 2018 Group F teams"++ dvals =+ dataFromColumns []+ . dataColumn "team" (Strings [ "Germany", "Mexico", "South Korea", "Sweden", "Germany", "Mexico", "South Korea", "Sweden", "Germany", "Mexico", "South Korea", "Sweden" ])+ . dataColumn "matchday" (Numbers [ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ])+ . dataColumn "point" (Numbers [ 0, 3, 0, 3, 3, 6, 0, 3, 3, 6, 3, 6 ])+ . dataColumn "diff" (Numbers [ -1, 1, -1, 1, 0, 2, -2, 0, -2, -1, 0, 3 ])++ trans =+ transform+ . window [ ( [ WOp Rank ], "rank" ) ]+ [ WSort [ WDescending "point", WDescending "diff" ], WGroupBy [ "matchday" ] ]++ enc =+ encoding+ . position X [ PName "matchday", PmType Ordinal ]+ . position Y [ PName "rank", PmType Ordinal ]+ . color [ MName "team", MmType Nominal, MScale teamColours ]++ teamColours =+ categoricalDomainMap+ [ ( "Germany", "black" )+ , ( "Mexico", "#127153" )+ , ( "South Korea", "#c91a3c" )+ , ( "Sweden", "#0c71ab" )+ ]+ in+ toVegaLite [ des, dvals [], trans [], enc [], mark Line [ MOrient Vertical ] ]+++line12 :: VegaLite+line12 =+ let+ des =+ description "Plots a function using a generated sequence"++ dvals =+ dataSequenceAs 0 12.7 0.1 "u"++ trans =+ transform+ . calculateAs "sin(datum.u)" "v"+ . calculateAs "cos(datum.u)" "w"++ encSin =+ encoding+ . position X [ PName "u", PmType Quantitative, PTitle "x" ]+ . position Y [ PName "v", PmType Quantitative, PTitle "sin(x)" ]++ specSin =+ asSpec [ encSin [], mark Line [] ]++ encCos =+ encoding+ . position X [ PName "u", PmType Quantitative, PTitle "x" ]+ . position Y [ PName "w", PmType Quantitative, PTitle "cos(x)" ]++ specCos =+ asSpec [ encCos [], mark Line [ MStroke "firebrick" ] ]+ in+ toVegaLite [ des, width 300, height 150, dvals, trans [], layer [ specSin, specCos ] ]
@@ -0,0 +1,467 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryMulti.elm (from development of version+-- 1.13.0)+--+module Gallery.Multi (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("multi1", multi1)+ , ("multi2", multi2)+ , ("multi3", multi3)+ , ("multi4", multi4)+ , ("multi5", multi5)+ , ("multi6", multi6)+ , ("multi7", multi7)+ ]+++multi1 :: VegaLite+multi1 =+ let+ des =+ description "Overview and detail."++ sel =+ selection . select "myBrush" Interval [ Encodings [ ChX ] ]++ enc1 =+ encoding+ . position X+ [ PName "date"+ , PmType Temporal+ , PScale [ SDomain (DSelection "myBrush") ]+ , PAxis [ AxNoTitle ]+ ]+ . position Y [ PName "price", PmType Quantitative ]++ spec1 =+ asSpec [ width 500, mark Area [], enc1 [] ]++ enc2 =+ encoding+ . position X [ PName "date", PmType Temporal, PAxis [ AxFormat "%Y" ] ]+ . position Y+ [ PName "price"+ , PmType Quantitative+ , PAxis [ AxTickCount 3, AxGrid False ]+ ]++ spec2 =+ asSpec [ width 480, height 60, sel [], mark Area [], enc2 [] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/sp500.csv" []+ , vConcat [ spec1, spec2 ]+ ]+++multi2 :: VegaLite+multi2 =+ let+ des =+ description "Cross-filter."++ trans =+ transform+ . calculateAs "hours(datum.date)" "time"++ sel =+ selection . select "myBrush" Interval [ Encodings [ ChX ] ]++ selTrans =+ transform+ . filter (FSelection "myBrush")++ encPosition =+ encoding+ . position X+ [ PRepeat Column+ , PmType Quantitative+ , PBin [ MaxBins 20 ]+ ]+ . position Y [ PAggregate Count, PmType Quantitative ]++ spec1 =+ asSpec [ sel [], mark Bar [] ]++ spec2 =+ asSpec [ selTrans [], mark Bar [], encoding (color [ MString "goldenrod" ] []) ]++ spec =+ asSpec+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/flights-2k.json" [ Parse [ ( "date", FoDate "" ) ] ]+ , trans []+ , encPosition []+ , layer [ spec1, spec2 ]+ ]+ in+ toVegaLite+ [ repeat [ ColumnFields [ "distance", "delay", "time" ] ]+ , specification spec+ ]+++multi3 :: VegaLite+multi3 =+ let+ des =+ description "Scatterplot matrix"++ sel =+ selection+ . select "myBrush"+ Interval+ [ On "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"+ , Translate "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"+ , Zoom "wheel![event.shiftKey]"+ , ResolveSelections Union+ ]+ . select "grid"+ Interval+ [ BindScales+ , Translate "[mousedown[!event.shiftKey], window:mouseup] > window:mousemove!"+ , Zoom "wheel![event.shiftKey]"+ , ResolveSelections Global+ ]++ enc =+ encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName "myBrush")+ [ MName "Origin", MmType Nominal ]+ [ MString "grey" ]+ ]++ spec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point []+ , sel []+ , enc []+ ]+ in+ toVegaLite+ [ des+ , repeat+ [ RowFields [ "Horsepower", "Acceleration", "Miles_per_Gallon" ]+ , ColumnFields [ "Miles_per_Gallon", "Acceleration", "Horsepower" ]+ ]+ , specification spec+ ]+++multi4 :: VegaLite+multi4 =+ let+ des =+ description "A dashboard with cross-highlighting"++ selTrans =+ transform+ . filter (FSelection "myPts")++ encPosition =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [ MaxBins 10 ] ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative, PBin [ MaxBins 10 ] ]++ enc1 =+ encoding+ . color [ MAggregate Count, MmType Quantitative, MLegend [ LNoTitle ] ]++ spec1 =+ asSpec [ width 300, mark Rect [], enc1 [] ]++ enc2 =+ encoding+ . size [ MAggregate Count, MmType Quantitative, MLegend [ LTitle "In Selected Category" ] ]+ . color [ MString "#666" ]++ spec2 =+ asSpec [ selTrans [], mark Point [], enc2 [] ]++ heatSpec =+ asSpec [ encPosition [], layer [ spec1, spec2 ] ]++ sel =+ selection . select "myPts" Single [ Encodings [ ChX ] ]++ barSpec =+ asSpec [ width 420, height 120, mark Bar [], sel [], encBar [] ]++ encBar =+ encoding+ . position X [ PName "Major_Genre", PmType Nominal, PAxis [ AxLabelAngle (-40) ] ]+ . position Y [ PAggregate Count, PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName "myPts")+ [ MString "steelblue" ]+ [ MString "grey" ]+ ]++ config =+ configure . configuration (Range [ RHeatmap "greenblue" ])++ res =+ resolve+ . resolution (RLegend [ ( ChColor, Independent ), ( ChSize, Independent ) ])+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , vConcat [ heatSpec, barSpec ]+ , res []+ , config []+ ]+++multi5 :: VegaLite+multi5 =+ let+ des =+ description "A dashboard with cross-highlighting"++ spec1 =+ asSpec+ [ width 600, height 300, mark Point [], sel1 [], trans1 [], enc1 [] ]++ sel1 =+ selection . select "myBrush" Interval [ Encodings [ ChX ] ]++ trans1 =+ transform . filter (FSelection "myClick")++ weatherColors =+ categoricalDomainMap+ [ ( "sun", "#e7ba52" )+ , ( "fog", "#c7c7c7" )+ , ( "drizzle", "#aec7ea" )+ , ( "rain", "#1f77b4" )+ , ( "snow", "#9467bd" )+ ]++ enc1 =+ encoding+ . position X+ [ PName "date"+ , PmType Temporal+ , PTimeUnit MonthDate+ , PAxis [ AxTitle "Date", AxFormat "%b" ]+ ]+ . position Y+ [ PName "temp_max"+ , PmType Quantitative+ , PScale [ SDomain (DNumbers [ -5, 40 ]) ]+ , PAxis [ AxTitle "Maximum Daily Temperature (C)" ]+ ]+ . color+ [ MSelectionCondition (SelectionName "myBrush")+ [ MName "weather"+ , MTitle "Weather"+ , MmType Nominal+ , MScale weatherColors+ ]+ [ MString "#cfdebe" ]+ ]+ . size+ [ MName "precipitation"+ , MmType Quantitative+ , MScale [ SDomain (DNumbers [ -1, 50 ]) ]+ ]++ spec2 =+ asSpec [ width 600, mark Bar [], sel2 [], trans2 [], enc2 [] ]++ sel2 =+ selection . select "myClick" Multi [ Encodings [ ChColor ] ]++ trans2 =+ transform . filter (FSelection "myBrush")++ enc2 =+ encoding+ . position X [ PAggregate Count, PmType Quantitative ]+ . position Y [ PName "weather", PmType Nominal ]+ . color+ [ MSelectionCondition (SelectionName "myClick")+ [ MName "weather"+ , MmType Nominal+ , MScale weatherColors+ ]+ [ MString "#acbf98" ]+ ]+ in+ toVegaLite+ [ title "Seattle Weather, 2012-2015" []+ , des+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , vConcat [ spec1, spec2 ]+ ]+++multi6 :: VegaLite+multi6 =+ let+ desc =+ description "Drag a rectangular brush to show (first 20) selected points in a table."++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ trans =+ transform+ . window [ ( [ WOp RowNumber ], "rowNumber" ) ] []++ sel =+ selection+ . select "brush" Interval []++ encPoint =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName "brush")+ [ MName "Cylinders", MmType Ordinal ]+ [ MString "grey" ]+ ]++ specPoint =+ asSpec [ sel [], mark Point [], encPoint [] ]++ tableTrans =+ transform+ . filter (FSelection "brush")+ . window [ ( [ WOp Rank ], "rank" ) ] []+ . filter (FLessThan "rank" (Number 20))++ encHPText =+ encoding+ . position Y [ PName "rowNumber", PmType Ordinal, PAxis [] ]+ . text [ TName "Horsepower", TmType Nominal ]++ specHPText =+ asSpec [ title "Engine power" [], tableTrans [], mark Text [], encHPText [] ]++ encMPGText =+ encoding+ . position Y [ PName "rowNumber", PmType Ordinal, PAxis [] ]+ . text [ TName "Miles_per_Gallon", TmType Nominal ]++ specMPGText =+ asSpec [ title "Efficiency (mpg)" [], tableTrans [], mark Text [], encMPGText [] ]++ encOriginText =+ encoding+ . position Y [ PName "rowNumber", PmType Ordinal, PAxis [] ]+ . text [ TName "Origin", TmType Nominal ]++ specOriginText =+ asSpec [ title "Country of origin" [], tableTrans [], mark Text [], encOriginText [] ]++ res =+ resolve+ . resolution (RLegend [ ( ChColor, Independent ) ])++ cfg =+ configure+ . configuration (View [ ViewStroke Nothing ])+ in+ toVegaLite+ [ desc, cfg [], dvals [], trans [], res [], hConcat [ specPoint, specHPText, specMPGText, specOriginText ] ]+++multi7 :: VegaLite+multi7 =+ let+ des =+ description "One dot per airport in the US overlayed on geoshape"++ cfg =+ configure+ . configuration (View [ ViewStroke Nothing ])++ backdropSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "states" ]+ , mark Geoshape [ MFill "#ddd", MStroke "#fff" ]+ ]++ lineTrans =+ transform+ . filter (FSelection "mySelection")+ . lookup "origin"+ (dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" [])+ "iata"+ [ "latitude", "longitude" ]+ . calculateAs "datum.latitude" "oLat"+ . calculateAs "datum.longitude" "oLon"+ . lookup "destination"+ (dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" [])+ "iata"+ [ "latitude", "longitude" ]+ . calculateAs "datum.latitude" "dLat"+ . calculateAs "datum.longitude" "dLon"++ lineEnc =+ encoding+ . position Longitude [ PName "oLon", PmType Quantitative ]+ . position Latitude [ PName "oLat", PmType Quantitative ]+ . position Longitude2 [ PName "dLon" ]+ . position Latitude2 [ PName "dLat" ]++ lineSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/flights-airport.csv" []+ , lineTrans []+ , lineEnc []+ , mark Rule [ MColor "black", MOpacity 0.35 ]+ ]++ airportTrans =+ transform+ . aggregate [ opAs Count "" "routes" ] [ "origin" ]+ . lookup "origin"+ (dataFromUrl "https://vega.github.io/vega-lite/data/airports.csv" [])+ "iata"+ [ "state", "latitude", "longitude" ]+ . filter (FExpr "datum.state !== 'PR' && datum.state !== 'VI'")++ airportEnc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . size [ MName "routes", MmType Quantitative, MScale [ SRange (RNumbers [ 0, 1000 ]) ], MLegend [] ]+ . order [ OName "routes", OmType Quantitative, OSort [ Descending ] ]++ sel =+ selection+ . select "mySelection" Single [ On "mouseover", Nearest True, Empty, Fields [ "origin" ] ]++ airportSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/flights-airport.csv" []+ , airportTrans []+ , sel []+ , mark Circle []+ , airportEnc []+ ]+ in+ toVegaLite+ [ des+ , cfg []+ , width 900+ , height 500+ , projection [ PrType AlbersUsa ]+ , layer [ backdropSpec, lineSpec, airportSpec ]+ ]
@@ -0,0 +1,232 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryRepeat.elm (from development of version+-- 1.13.0)+--+module Gallery.Repeat (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("repeat1", repeat1)+ , ("repeat2", repeat2)+ , ("repeat3", repeat3)+ , ("repeat4", repeat4)+ , ("repeat5", repeat5)+ ]+++repeat1 :: VegaLite+repeat1 =+ let+ des =+ description "Monthly weather information for individual years and overall average for Seatle and New York"++ enc1 =+ encoding+ . position X [ PName "date", PmType Ordinal, PTimeUnit Month ]+ . position Y [ PRepeat Column, PmType Quantitative, PAggregate Mean ]+ . detail [ DName "date", DmType Temporal, DTimeUnit Year ]+ . color [ MName "location", MmType Nominal ]+ . opacity [ MNumber 0.2 ]++ spec1 =+ asSpec [ mark Line [], enc1 [] ]++ enc2 =+ encoding+ . position X [ PName "date", PmType Ordinal, PTimeUnit Month ]+ . position Y [ PRepeat Column, PmType Quantitative, PAggregate Mean ]+ . color [ MName "location", MmType Nominal ]++ spec2 =+ asSpec [ mark Line [], enc2 [] ]++ spec =+ asSpec [ layer [ spec1, spec2 ] ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/weather.csv" []+ , repeat [ ColumnFields [ "temp_max", "precipitation", "wind" ] ]+ , specification spec+ ]+++repeat2 :: VegaLite+repeat2 =+ let+ desc =+ description "Two vertically concatenated charts that show a histogram of precipitation in Seattle and the relationship between min and max temperature"++ trans =+ transform+ . filter (FExpr "datum.location === 'Seattle'")++ enc1 =+ encoding+ . position X [ PName "date", PTimeUnit Month, PmType Ordinal ]+ . position Y [ PName "precipitation", PmType Quantitative, PAggregate Mean ]++ spec1 =+ asSpec [ mark Bar [], enc1 [] ]++ enc2 =+ encoding+ . position X [ PName "temp_min", PmType Quantitative, PBin [] ]+ . position Y [ PName "temp_max", PmType Quantitative, PBin [] ]+ . size [ MAggregate Count, MmType Quantitative ]++ spec2 =+ asSpec [ mark Point [], enc2 [] ]+ in+ toVegaLite+ [ desc+ , trans []+ , dataFromUrl "https://vega.github.io/vega-lite/data/weather.csv" []+ , vConcat [ spec1, spec2 ]+ ]+++repeat3 :: VegaLite+repeat3 =+ let+ des =+ description "Horizontally repeated charts that show the histograms of different parameters of cars in different countries"++ enc =+ encoding+ . position X [ PRepeat Column, PmType Quantitative, PBin [] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ . color [ MName "Origin", MmType Nominal ]++ spec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Bar []+ , enc []+ ]+ in+ toVegaLite+ [ des+ , repeat [ ColumnFields [ "Horsepower", "Miles_per_Gallon", "Acceleration" ] ]+ , specification spec+ ]+++repeat4 :: VegaLite+repeat4 =+ let+ des =+ description "Scatterplot matrix"++ sel =+ selection+ . select "myBrush"+ Interval+ [ On "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"+ , Translate "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"+ , Zoom "wheel![event.shiftKey]"+ , ResolveSelections Union+ ]+ . select "grid"+ Interval+ [ BindScales+ , Translate "[mousedown[!event.shiftKey], window:mouseup] > window:mousemove!"+ , Zoom "wheel![event.shiftKey]"+ , ResolveSelections Global+ ]++ enc =+ encoding+ . position X [ PRepeat Column, PmType Quantitative ]+ . position Y [ PRepeat Row, PmType Quantitative ]+ . color+ [ MSelectionCondition (SelectionName "myBrush")+ [ MName "Origin", MmType Nominal ]+ [ MString "grey" ]+ ]++ spec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point []+ , sel []+ , enc []+ ]+ in+ toVegaLite+ [ des+ , repeat+ [ RowFields [ "Horsepower", "Acceleration", "Miles_per_Gallon" ]+ , ColumnFields [ "Miles_per_Gallon", "Acceleration", "Horsepower" ]+ ]+ , specification spec+ ]+++repeat5 :: VegaLite+repeat5 =+ let+ des =+ description "Marginal histograms show the counts along the x and y dimension"++ config =+ configure+ . configuration (Range [ RHeatmap "greenblue" ])+ . configuration (View [ ViewStroke Nothing ])++ enc1 =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [], PBin [] ]+ . position Y+ [ PAggregate Count+ , PmType Quantitative+ , PScale [ SDomain (DNumbers [ 0, 1000 ]) ]+ , PAxis [ AxNoTitle ]+ ]++ spec1 =+ asSpec [ height 60, mark Bar [], enc1 [] ]++ spec2 =+ asSpec [ spacing 15, bounds Flush, hConcat [ spec2_1, spec2_2 ] ]++ enc2_1 =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [] ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative, PBin [] ]+ . color [ MAggregate Count, MmType Quantitative ]++ spec2_1 =+ asSpec [ mark Rect [], enc2_1 [] ]++ enc2_2 =+ encoding+ . position Y+ [ PName "Rotten_Tomatoes_Rating"+ , PmType Quantitative+ , PBin []+ , PAxis []+ ]+ . position X+ [ PAggregate Count+ , PmType Quantitative+ , PScale [ SDomain (DNumbers [ 0, 1000 ]) ]+ , PAxis [ AxNoTitle ]+ ]++ spec2_2 =+ asSpec [ width 60, mark Bar [], enc2_2 [] ]+ in+ toVegaLite+ [ des+ , spacing 15+ , bounds Flush+ , config []+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , vConcat [ spec1, spec2 ]+ ]
@@ -0,0 +1,279 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryScatter.elm (from development of version+-- 1.13.0)+--+module Gallery.Scatter (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("scatter1", scatter1)+ , ("scatter2", scatter2)+ , ("scatter3", scatter3)+ , ("scatter4", scatter4)+ , ("scatter5", scatter5)+ , ("scatter6", scatter6)+ , ("scatter7", scatter7)+ , ("scatter8", scatter8)+ , ("scatter9", scatter9)+ , ("scatter10", scatter10)+ , ("scatter11", scatter11)+ ]+++scatter1 :: VegaLite+scatter1 =+ let+ des =+ description "A scatterplot showing horsepower and miles per gallon for various cars (via point marks)."++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point [ MTooltip TTData ]+ , enc []+ ]+++scatter2 :: VegaLite+scatter2 =+ let+ des =+ description "Shows the distribution of a single variable (precipitation) using tick marks."++ enc =+ encoding+ . position X [ PName "precipitation", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-weather.csv" []+ , mark Tick []+ , enc []+ ]+++scatter3 :: VegaLite+scatter3 =+ let+ des =+ description "Shows the relationship between horsepower and the number of cylinders using tick marks."++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Cylinders", PmType Ordinal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Tick []+ , enc []+ ]+++scatter4 :: VegaLite+scatter4 =+ let+ des =+ description "A scatterplot showing horsepower and miles per gallon with country of origin double encoded by colour and shape."++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal ]+ . shape [ MName "Origin", MmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point []+ , enc []+ ]+++scatter5 :: VegaLite+scatter5 =+ let+ des =+ description "A binned scatterplot comparing IMDB and Rotten Tomatoes rating with marks sized by number of reviews."++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [ MaxBins 10 ] ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative, PBin [ MaxBins 10 ] ]+ . size [ MAggregate Count, MmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Circle []+ , enc []+ ]+++scatter6 :: VegaLite+scatter6 =+ let+ des =+ description "A bubbleplot showing horsepower on x, miles per gallons on y, and acceleration on size."++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . size [ MName "Acceleration", MmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Point []+ , enc []+ ]+++scatter7 :: VegaLite+scatter7 =+ let+ des =+ description "Scatterplot with Null values in grey"++ config =+ configure+ . configuration (RemoveInvalid False)++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative ]+ . color+ [ MDataCondition+ [ ( Expr "datum.IMDB_Rating === null || datum.Rotten_Tomatoes_Rating === null"+ , [ MString "#ddd" ]+ )+ ]+ [ MString "rgb(76,120,168)" ]+ ]+ in+ toVegaLite+ [ des+ , config []+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Point []+ , enc []+ ]+++scatter8 :: VegaLite+scatter8 =+ let+ des =+ description "A scatterplot showing horsepower and miles per gallon for various cars (via circle marks)."++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Circle []+ , enc []+ ]+++scatter9 :: VegaLite+scatter9 =+ let+ des =+ description "A bubble plot showing the correlation between health and income for 187 countries in the world (modified from an example in Lisa Charlotte Rost's blog post 'One Chart, Twelve Charting Libraries' --http://lisacharlotterost.github.io/2016/05/17/one-chart-code/)."++ enc =+ encoding+ . position X [ PName "income", PmType Quantitative, PScale [ SType ScLog ] ]+ . position Y [ PName "health", PmType Quantitative, PScale [ SZero False ] ]+ . size [ MName "population", MmType Quantitative ]+ . color [ MString "#000" ]++ sel =+ selection . select "view" Interval [ BindScales ]+ in+ toVegaLite+ [ des+ , width 500+ , height 300+ , dataFromUrl "https://vega.github.io/vega-lite/data/gapminder-health-income.csv" []+ , mark Circle []+ , enc []+ , sel []+ ]+++scatter10 :: VegaLite+scatter10 =+ let+ des =+ description "Visualization of global deaths from natural disasters. Copy of chart from https://ourworldindata.org/natural-catastrophes"++ trans =+ transform+ . filter (FExpr "datum.Entity !== 'All natural disasters'")++ enc =+ encoding+ . position X [ PName "Year", PmType Ordinal, PAxis [ AxLabelAngle 0 ] ]+ . position Y [ PName "Entity", PmType Nominal, PAxis [ AxNoTitle ] ]+ . size+ [ MName "Deaths"+ , MmType Quantitative+ , MLegend [ LTitle "Annual Global Deaths" ]+ , MScale [ SRange (RNumbers [ 0, 5000 ]) ]+ ]+ . color [ MName "Entity", MmType Nominal, MLegend [] ]+ in+ toVegaLite+ [ des+ , width 600+ , height 400+ , dataFromUrl "https://vega.github.io/vega-lite/data/disasters.csv" []+ , trans []+ , mark Circle [ MOpacity 0.8, MStroke "black", MStrokeWidth 1 ]+ , enc []+ ]+++scatter11 :: VegaLite+scatter11 =+ let+ des =+ description "A scatterplot showing horsepower and miles per gallon with country of origin double encoded by colour and text symbol."++ trans =+ transform+ . calculateAs "datum.Origin[0]" "OriginInitial"++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal ]+ . text [ TName "OriginInitial", TmType Nominal ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , trans []+ , mark Text []+ , enc []+ ]
@@ -0,0 +1,170 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GalleryTable.elm (from development of version+-- 1.13.0)+--+module Gallery.Table (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter, lookup, repeat)++import Data.Function ((&))++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("table1", table1)+ , ("table2", table2)+ , ("table3", table3)+ , ("table4", table4)+ , ("table5", table5)+ ]+++table1 :: VegaLite+table1 =+ let+ des =+ description "'Table heatmap' showing engine size/power for three countries."++ enc =+ encoding+ . position X [ PName "Cylinders", PmType Ordinal ]+ . position Y [ PName "Origin", PmType Nominal ]+ . color [ MName "Horsepower", MmType Quantitative, MAggregate Mean ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , mark Rect []+ , enc []+ ]+++table2 :: VegaLite+table2 =+ let+ des =+ description "Annual weather 'heatmap'"++ conf =+ configure+ . configuration (View [ ViewStrokeWidth 0 ])+ . configuration (Scale [ SCRangeStep (Just 13) ])+ . configuration (Axis [ Domain False ])++ enc =+ encoding+ . position X [ PName "date", PmType Ordinal, PTimeUnit Date, PAxis [ AxTitle "Day", AxLabelAngle 0, AxFormat "%e" ] ]+ . position Y [ PName "date", PmType Ordinal, PTimeUnit Month, PAxis [ AxTitle "Month" ] ]+ . color [ MName "temp", MmType Quantitative, MAggregate Max, MLegend [ LNoTitle ] ]+ in+ toVegaLite+ [ des+ , conf []+ , dataFromUrl "https://vega.github.io/vega-lite/data/seattle-temps.csv" []+ , mark Rect []+ , enc []+ ]+++table3 :: VegaLite+table3 =+ let+ des =+ description "'Binned heatmap' comparing movie ratings."++ dvals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ trans =+ transform+ . filter+ (FCompose+ (And+ (FValid "IMDB_Rating" & FilterOp)+ (FValid "Rotten_Tomatoes_Rating" & FilterOp)+ )+ )++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PBin [ MaxBins 60 ] ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative, PBin [ MaxBins 40 ] ]+ . color [ MmType Quantitative, MAggregate Count ]++ config =+ configure+ . configuration (Range [ RHeatmap "greenblue" ])+ . configuration (View [ ViewStroke Nothing ])+ in+ toVegaLite+ [ des+ , width 300+ , height 200+ , dvals []+ , trans []+ , mark Rect []+ , enc []+ , config []+ ]+++table4 :: VegaLite+table4 =+ let+ des =+ description "Table bubble plot in the style of a Github punched card."++ enc =+ encoding+ . position X [ PName "time", PmType Ordinal, PTimeUnit Hours ]+ . position Y [ PName "time", PmType Ordinal, PTimeUnit Day ]+ . size [ MName "count", MmType Quantitative, MAggregate Sum ]+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/github.csv" []+ , mark Circle []+ , enc []+ ]+++table5 :: VegaLite+table5 =+ let+ des =+ description "Layering text over 'heatmap'."++ encPosition =+ encoding+ . position X [ PName "Cylinders", PmType Ordinal ]+ . position Y [ PName "Origin", PmType Ordinal ]++ encRect =+ encoding+ . color [ MName "*", MmType Quantitative, MAggregate Count ]++ specRect =+ asSpec [ mark Rect [], encRect [] ]++ encText =+ encoding+ . color [ MString "white" ]+ . text [ TName "*", TmType Quantitative, TAggregate Count ]++ specText =+ asSpec [ mark Text [], encText [] ]++ config =+ configure+ . configuration (Scale [ SCBandPaddingInner 0, SCBandPaddingOuter 0 ])+ . configuration (TextStyle [ MBaseline AlignMiddle ])+ in+ toVegaLite+ [ des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , encPosition []+ , layer [ specRect, specText ]+ , config []+ ]
@@ -0,0 +1,653 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GeoTests.elm as of version 1.12.0+--+module GeoTests (testSpecs) where++import qualified Data.Text as T++import Data.Monoid ((<>))++import Graphics.Vega.VegaLite++import Prelude hiding (filter)+++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("defaultSize1", defaultSize1)+ , ("defaultSize2", defaultSize2)+ , ("choropleth1", choropleth1)+ , ("choropleth2", choropleth2)+ , ("linear1", tubeLines1)+ , ("linear2", tubeLines2)+ , ("linear3", tubeLines3)+ , ("sphere1", sphere1)+ , ("sphere2", sphere2)+ , ("graticule1", graticule1)+ , ("graticule2", graticule2)+ , ("graticule3", graticule3)+ , ("graticule4", graticule4)+ , ("scale1", scale1)+ , ("translate1", translate1)+ , ("mapComp1", mapComp1)+ , ("mapComp2", mapComp2)+ , ("mapComp3", mapComp3)+ , ("mapComp4", mapComp4)+ , ("dotMap1", dotMap1)+ , ("scribbleMap1", scribbleMap1)+ , ("scribbleMap2", scribbleMap2)+ , ("map1d", map1d)+ ]+++{- Some relevant data sources:++ https://github.com/deldersveld/topojson+ https://github.com/topojson/world-atlas+-}+++defaultSize1 :: VegaLite+defaultSize1 =+ toVegaLite+ [ description "Default map size"+ , projection [ PrType AlbersUsa ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "counties" ]+ , mark Geoshape []+ , encoding $ color [ MString "black" ] []+ ]+++defaultSize2 :: VegaLite+defaultSize2 =+ toVegaLite+ [ description "Default map size with view width and height specified in config."+ , configure $ configuration (View [ ViewWidth 500, ViewHeight 300 ]) $ []+ , projection [ PrType AlbersUsa ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/us-10m.json" [ TopojsonFeature "counties" ]+ , mark Geoshape []+ , encoding $ color [ MString "black" ] []+ ]+++choropleth1 :: VegaLite+choropleth1 =+ toVegaLite+ [ width 900+ , height 500+ , configure $ configuration (View [ ViewStroke Nothing ]) []+ , dataFromUrl "https://vega.github.io/vega-lite/data/londonBoroughs.json" [ TopojsonFeature "boroughs" ]+ , mark Geoshape [ MStrokeOpacity 0 ]+ , encoding $ color [ MName "id", MmType Nominal ] []+ ]+++choropleth2 :: VegaLite+choropleth2 =+ let+ trans =+ transform+ . calculateAs "indexof (datum.name,' ') > 0 ? substring(datum.name,0,indexof(datum.name, ' ')) : datum.name" "bLabel"++ polyEnc =+ encoding+ . color [ MName "id", MmType Nominal, MScale boroughColors, MLegend [] ]+ . opacity [ MNumber 1 ]++ polySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/londonBoroughs.json" [ TopojsonFeature "boroughs" ]+ , mark Geoshape [ MStroke "rgb(251,247,238)", MStrokeWidth 2 ]+ , polyEnc []+ ]++ labelEnc =+ encoding+ . position Longitude [ PName "cx", PmType Quantitative ]+ . position Latitude [ PName "cy", PmType Quantitative ]+ . text [ TName "bLabel", TmType Nominal ]++ labelSpec =+ asSpec [ dataFromUrl "https://vega.github.io/vega-lite/data/londonCentroids.json" [], trans [], mark Text [], labelEnc [] ]+ in+ toVegaLite+ [ width 1200+ , height 700+ , configure $ configuration (View [ ViewStroke Nothing ]) []+ , layer [ polySpec, labelSpec ]+ ]+++tubeLines1 :: VegaLite+tubeLines1 =+ toVegaLite+ [ width 700+ , height 500+ , dataFromUrl "https://vega.github.io/vega-lite/data/londonTubeLines.json" [ TopojsonFeature "line" ]+ , mark Geoshape [ MFilled False ]+ , encoding $ color [ MName "id", MmType Nominal ] []+ ]+++tubeLines2 :: VegaLite+tubeLines2 =+ let+ enc =+ encoding+ . color+ [ MName "id"+ , MmType Nominal+ , MLegend [ LNoTitle, LOrient LOBottomRight ]+ , MScale tubeLineColors+ ]+ in+ toVegaLite+ [ width 700+ , height 500+ , configure $ configuration (View [ ViewStroke Nothing ]) []+ , dataFromUrl "https://vega.github.io/vega-lite/data/londonTubeLines.json" [ TopojsonFeature "line" ]+ , mark Geoshape [ MFilled False, MStrokeWidth 2 ]+ , enc []+ ]++tubeLines3 :: VegaLite+tubeLines3 =+ let+ polySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/londonBoroughs.json" [ TopojsonFeature "boroughs" ]+ , mark Geoshape [ MStroke "rgb(251,247,238)", MStrokeWidth 2 ]+ , encoding $ color [ MString "#ddc" ] []+ ]++ labelEnc =+ encoding+ . position Longitude [ PName "cx", PmType Quantitative ]+ . position Latitude [ PName "cy", PmType Quantitative ]+ . text [ TName "bLabel", TmType Nominal ]+ . size [ MNumber 8 ]+ . opacity [ MNumber 0.6 ]++ trans =+ transform+ . calculateAs "indexof (datum.name,' ') > 0 ? substring(datum.name,0,indexof(datum.name, ' ')) : datum.name" "bLabel"++ labelSpec =+ asSpec [ dataFromUrl "https://vega.github.io/vega-lite/data/londonCentroids.json" [], trans [], mark Text [], labelEnc [] ]++ tubeEnc =+ encoding+ . color+ [ MName "id"+ , MmType Nominal+ , MLegend [ LNoTitle, LOrient LOBottomRight, LOffset 0 ]+ , MScale tubeLineColors+ ]++ routeSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/londonTubeLines.json" [ TopojsonFeature "line" ]+ , mark Geoshape [ MFilled False, MStrokeWidth 2 ]+ , tubeEnc []+ ]+ in+ toVegaLite+ [ width 700+ , height 500+ , configure $ configuration (View [ ViewStroke Nothing ]) []+ , layer [ polySpec, labelSpec, routeSpec ]+ ]+++boroughColors :: [ScaleProperty]+boroughColors =+ categoricalDomainMap+ [ ( "Kingston upon Thames", "#9db7b1" )+ , ( "Croydon", "#d4b4e5" )+ , ( "Bromley", "#afb9cb" )+ , ( "Hounslow", "#b2add6" )+ , ( "Ealing", "#e2f8ca" )+ , ( "Havering", "#a1bde6" )+ , ( "Hillingdon", "#e8aa95" )+ , ( "Harrow", "#8bd0eb" )+ , ( "Brent", "#dfb89b" )+ , ( "Barnet", "#a2e7ed" )+ , ( "Lambeth", "#e3aba7" )+ , ( "Southwark", "#86cbd1" )+ , ( "Lewisham", "#ecb1c2" )+ , ( "Greenwich", "#acd8ba" )+ , ( "Bexley", "#e4bad9" )+ , ( "Enfield", "#9bd6ca" )+ , ( "Waltham Forest", "#cec9f3" )+ , ( "Redbridge", "#c9d2a8" )+ , ( "Sutton", "#d1c1d9" )+ , ( "Richmond upon Thames", "#ddcba2" )+ , ( "Merton", "#a2acbd" )+ , ( "Wandsworth", "#deefd6" )+ , ( "Hammersmith and Fulham", "#b5d7a7" )+ , ( "Kensington and Chelsea", "#f6d4c9" )+ , ( "Westminster", "#add4e0" )+ , ( "Camden", "#d9b9ad" )+ , ( "Tower Hamlets", "#c6e1db" )+ , ( "Islington", "#e0c7ce" )+ , ( "Hackney", "#a6b79f" )+ , ( "Haringey", "#cbd5e7" )+ , ( "Newham", "#c2d2ba" )+ , ( "Barking and Dagenham", "#ebe2cf" )+ , ( "City of London", "#c7bfad" )+ ]+++tubeLineColors :: [ScaleProperty]+tubeLineColors =+ categoricalDomainMap+ [ ( "Bakerloo", "rgb(137,78,36)" )+ , ( "Central", "rgb(220,36,30)" )+ , ( "Circle", "rgb(255,206,0)" )+ , ( "District", "rgb(1,114,41)" )+ , ( "DLR", "rgb(0,175,173)" )+ , ( "Hammersmith & City", "rgb(215,153,175)" )+ , ( "Jubilee", "rgb(106,114,120)" )+ , ( "Metropolitan", "rgb(114,17,84)" )+ , ( "Northern", "rgb(0,0,0)" )+ , ( "Piccadilly", "rgb(0,24,168)" )+ , ( "Victoria", "rgb(0,160,226)" )+ , ( "Waterloo & City", "rgb(106,187,170)" )+ ]+++sphere1 :: VegaLite+sphere1 =+ let+ dataVals =+ dataFromUrl "https://gicentre.github.io/data/geoTutorials/world-110m.json"+ [ TopojsonFeature "countries1" ]++ proj =+ projection [ PrType Orthographic ]+ in+ toVegaLite [ width 300, height 300, dataVals, proj, mark Geoshape [ MFill "rgb(149,181,146)" ] ]+++sphere2 :: VegaLite+sphere2 =+ let+ countryData =+ dataFromUrl "https://gicentre.github.io/data/geoTutorials/world-110m.json"+ [ TopojsonFeature "countries1" ]++ proj =+ projection [ PrType Orthographic ]++ sphereSpec =+ asSpec [ sphere, mark Geoshape [ MFill "aliceblue" ] ]++ countrySpec =+ asSpec [ countryData, mark Geoshape [ MFill "rgb(149,181,146)" ] ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ sphereSpec, countrySpec ] ]+++graticule1 :: VegaLite+graticule1 =+ let+ proj =+ projection [ PrType Orthographic, PrRotate (-42) (-30) 0 ]++ sphereSpec =+ asSpec [ sphere, mark Geoshape [ MFill "aliceblue" ] ]++ gratSpec =+ asSpec [ graticule [], mark Geoshape [ MFilled False, MStrokeWidth 0.3 ] ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ sphereSpec, gratSpec ] ]+++graticule2 :: VegaLite+graticule2 =+ let+ proj =+ projection [ PrType Orthographic, PrRotate (-42) (-30) 0 ]++ sphereSpec =+ asSpec [ sphere, mark Geoshape [ MFill "aliceblue" ] ]++ gratSpec =+ asSpec+ [ graticule [ GrExtent ( 0, 0 ) ( 90, 90 )+ , GrStep ( 2, 2 )+ , GrPrecision 2 ]+ , mark Geoshape [ MFilled False, MStrokeWidth 0.3 ]+ ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ sphereSpec, gratSpec ] ]+++graticule3 :: VegaLite+graticule3 =+ let+ proj =+ projection [ PrType Orthographic, PrRotate (-42) (-30) 0 ]++ sphereSpec =+ asSpec [ sphere, mark Geoshape [ MFill "aliceblue" ] ]++ gratSpec =+ asSpec+ [ graticule+ [ GrExtentMajor ( 0, 0 ) ( 90, 90 )+ , GrExtentMinor ( 0, 0 ) ( 90, 75.01 )+ , GrStepMinor ( 2, 2 )+ ]+ , mark Geoshape [ MFilled False, MStrokeWidth 0.3 ]+ ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ sphereSpec, gratSpec ] ]+++graticule4 :: VegaLite+graticule4 =+ let+ proj =+ projection [ PrType Orthographic, PrRotate (-42) (-30) 0 ]++ sphereSpec =+ asSpec [ sphere, mark Geoshape [ MFill "aliceblue" ] ]++ gratSpec =+ asSpec+ [ graticule [ GrStepMinor ( 15, 30 ) ]+ , mark Geoshape [ MFilled False, MStrokeWidth 0.3 ]+ ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ sphereSpec, gratSpec ] ]++scale1 :: VegaLite+scale1 =+ let+ dataVals =+ dataFromUrl "https://gicentre.github.io/data/geoTutorials/world-110m.json"+ [ TopojsonFeature "countries1" ]++ proj =+ projection [ PrType Orthographic, PrScale 470 ]++ countrySpec =+ asSpec [ dataVals, mark Geoshape [ MFill "rgb(149,181,146)" ] ]++ gratSpec =+ asSpec+ [ graticule [ GrStepMinor ( 5, 5 ) ]+ , mark Geoshape [ MFilled False, MStrokeWidth 0.3 ]+ ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ countrySpec, gratSpec ] ]+++translate1 :: VegaLite+translate1 =+ let+ dataVals =+ dataFromUrl "https://gicentre.github.io/data/geoTutorials/world-110m.json"+ [ TopojsonFeature "countries1" ]++ proj =+ projection [ PrType Orthographic, PrTranslate 0 100 ]++ countrySpec =+ asSpec [ dataVals, mark Geoshape [ MFill "rgb(149,181,146)" ] ]++ gratSpec =+ asSpec+ [ graticule [ GrStepMinor ( 5, 5 ) ]+ , mark Geoshape [ MFilled False, MStrokeWidth 0.3 ]+ ]+ in+ toVegaLite [ width 300, height 300, proj, layer [ countrySpec, gratSpec ] ]+++mapComp1 :: VegaLite+mapComp1 =+ let+ globe =+ asSpec+ [ width 300+ , height 300+ , dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , projection [ PrType Orthographic ]+ , mark Geoshape [ MFilled False ]+ ]+ in+ toVegaLite [ hConcat [ globe, globe, globe ] ]+++mapComp2 :: VegaLite+mapComp2 =+ let+ globe =+ let+ graticuleSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , mark Geoshape [ MFilled False, MStroke "#411", MStrokeWidth 0.1 ]+ ]++ countrySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/world-110m.json" [ TopojsonFeature "land" ]+ , mark Geoshape [ MFill "black", MFillOpacity 0.7 ]+ ]+ in+ asSpec [ width 300, height 300, projection [ PrType Orthographic ], layer [ graticuleSpec, countrySpec ] ]+ in+ toVegaLite+ [ configure $ configuration (View [ ViewStroke Nothing ]) $ []+ , hConcat [ globe, globe, globe ]+ ]+++mapComp3 :: VegaLite+mapComp3 =+ let+ rotatedSpec rot =+ let+ graticuleSpec =+ asSpec+ [ width 300+ , height 300+ , projection [ PrType Orthographic, PrRotate rot 0 0 ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , mark Geoshape [ MFilled False, MStroke "#411", MStrokeWidth 0.1 ]+ ]++ countrySpec =+ asSpec+ [ width 300+ , height 300+ , projection [ PrType Orthographic, PrRotate rot 0 0 ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/world-110m.json" [ TopojsonFeature "countries" ]+ , mark Geoshape [ MStroke "white", MFill "black", MStrokeWidth 0.5 ]+ ]+ in+ asSpec [ layer [ graticuleSpec, countrySpec ] ]+ in+ toVegaLite+ [ configure $ configuration (View [ ViewStroke Nothing ]) $ [], hConcat [ rotatedSpec (-65), rotatedSpec 115, rotatedSpec (-65) ] ]+++mapComp4 :: VegaLite+mapComp4 =+ let+ rotatedSpec rot =+ let+ seaSpec =+ asSpec+ [ width 300+ , height 300+ , projection [ PrType Orthographic, PrRotate 0 0 0 ]+ , dataFromUrl "data/globe.json" [ TopojsonFeature "globe" ]+ , mark Geoshape [ MFill "#c1e7f5", MStrokeOpacity 0 ]+ ]++ graticuleSpec =+ asSpec+ [ width 300+ , height 300+ , projection [ PrType Orthographic, PrRotate rot 0 0 ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , mark Geoshape [ MFilled False, MStroke "#411", MStrokeWidth 0.1 ]+ ]++ countrySpec =+ asSpec+ [ width 300+ , height 300+ , projection [ PrType Orthographic, PrRotate rot 0 0 ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/world-110m.json" [ TopojsonFeature "countries" ]+ , mark Geoshape [ MStroke "white", MFill "#242", MStrokeWidth 0.1 ]+ ]+ in+ asSpec [ layer [ seaSpec, graticuleSpec, countrySpec ] ]+ in+ toVegaLite+ [ configure $ configuration (View [ ViewStroke Nothing ]) $ [], hConcat [ rotatedSpec 0, rotatedSpec (-40) ] ]+++dotMap1 :: VegaLite+dotMap1 =+ let+ enc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . size [ MNumber 1 ]+ . color [ MName "digit", MmType Nominal ]+ in+ toVegaLite+ [ description "US zip codes: One dot per zipcode colored by first digit"+ , width 500+ , height 300+ , projection [ PrType AlbersUsa ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/zipcodes.csv" []+ , transform $ calculateAs "substring(datum.zip_code, 0, 1)" "digit" $ []+ , mark Circle []+ , enc []+ ]+++scribbleMap1 :: VegaLite+scribbleMap1 =+ let+ stateCondition =+ T.pack $+ concatMap (\s -> "&& datum.state !='" <> s <> "'") [ "AS", "FM", "PW", "MH", "GU", "MP", "VI", "PR" ]++ config =+ configure+ . configuration (TitleStyle [ TFont "Roboto", TFontWeight W300, TFontSize 28 ])+ . configuration (View [ ViewStroke Nothing ])++ trans =+ transform+ . filter (FExpr ("datum.latitude != '' && datum.county != 'Honolulu' " <> stateCondition))+ . calculateAs "datum.state == 'HI' ? 'hi' : (datum.state == 'AK' ? 'ak' : 'continent')" "conterminous"++ enc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . order [ OName "zip_code", OmType Quantitative ]+ . color [ MString "#666" ]+ . detail [ DName "conterminous", DmType Nominal ]+ in+ toVegaLite+ [ title "US connected zip codes" []+ , config []+ , width 1000+ , height 600+ , projection [ PrType AlbersUsa ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/zipcodes.csv" []+ , trans []+ , mark Line [ MStrokeWidth 0.2, MInterpolate Monotone ]+ , enc []+ ]++scribbleMap2 :: VegaLite+scribbleMap2 =+ let+ stateCondition =+ T.pack $+ concatMap (\s -> "&& datum.state !='" <> s <> "'") [ "AS", "FM", "PW", "MH", "GU", "MP", "VI", "PR" ]++ config =+ configure+ . configuration (TitleStyle [ TFont "Roboto", TFontWeight W300, TFontSize 28 ])+ . configuration (View [ ViewStroke Nothing ])++ trans =+ transform+ . filter (FExpr ("datum.latitude != '' && datum.county != 'Honolulu' " <> stateCondition))+ . calculateAs "substring(datum.zip_code, 0, 3)" "digit3"+ . calculateAs "length(datum.zip_code+' ')" "ziplen"++ enc =+ encoding+ . position Longitude [ PName "longitude", PmType Quantitative ]+ . position Latitude [ PName "latitude", PmType Quantitative ]+ . order [ OName "zip_code", OmType Quantitative ]+ . color [ MName "digit3", MmType Nominal, MLegend [] ]+ . detail [ DName "ziplen", DmType Nominal ]+ in+ toVegaLite+ [ title "US connected zip codes, coloured by first three digits" []+ , config []+ , width 1000+ , height 600+ , projection [ PrType AlbersUsa ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/zipcodes.csv" []+ , trans []+ , mark Line [ MStrokeWidth 0.2, MInterpolate Monotone ]+ , enc []+ ]++map1d :: VegaLite+map1d =+ let+ geoData =+ dataFromUrl "https://gicentre.github.io/data/geoTutorials/londonBoroughs.json"+ [ TopojsonFeature "boroughs" ]++ centroidData =+ dataFromUrl "https://gicentre.github.io/data/geoTutorials/londonCentroids.csv"++ backgroundSpec =+ asSpec [ geoData, mark Geoshape [ MFill "lightgrey", MStroke "white" ] ]++ cEnc =+ encoding+ . position Longitude [ PName "cx", PmType Quantitative ]+ . position Latitude [ PName "cy", PmType Quantitative ]++ hEnc =+ encoding+ . position Longitude [ PName "cx", PmType Quantitative ]+ . position Latitude [ PNumber 51.28 ]++ vEnc =+ encoding+ . position Longitude [ PNumber (-0.52) ]+ . position Latitude [ PName "cy", PmType Quantitative ]++ cSpec =+ asSpec [ centroidData [], mark Circle [], cEnc [] ]++ hSpec =+ asSpec [ centroidData [], mark Circle [], hEnc [] ]++ vSpec =+ asSpec [ centroidData [], mark Circle [], vEnc [] ]+ in+ toVegaLite+ [ width 500, height 400+ , layer [ backgroundSpec, cSpec, hSpec, vSpec ] ]
@@ -0,0 +1,86 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite HyperlinkTests.elm as of version 1.12.0+--+module HyperlinkTests (testSpecs) where++import Graphics.Vega.VegaLite hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("hyperlink1", hyperlink1)+ , ("hyperlink2", hyperlink2)+ , ("hyperlink3", hyperlink3)+ ]+ +hyperlink1 :: VegaLite+hyperlink1 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "label" (Strings [ "Vega", "Vega-Lite" ])+ . dataColumn "url" (Strings [ "https://vega.github.io/vega", "https://vega.github.io/vega-lite" ])++ encCircle =+ encoding+ . position X [ PName "label", PmType Nominal, PAxis [] ]+ . size [ MNumber 8000 ]+ . color [ MName "label", MmType Nominal, MLegend [] ]+ . hyperlink [ HName "url", HmType Nominal ]++ encLabel =+ encoding+ . position X [ PName "label", PmType Nominal, PAxis [] ]+ . text [ TName "label", TmType Nominal ]+ . color [ MString "white" ]+ . size [ MNumber 16 ]++ symbolSpec =+ asSpec [ mark Circle [ MCursor CPointer ], encCircle [] ]++ labelSpec =+ asSpec [ mark Text [], encLabel [] ]+ in+ toVegaLite+ [ dataVals [], layer [ symbolSpec, labelSpec ] ]++hyperlink2 :: VegaLite+hyperlink2 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative ]+ . hyperlink [ HString "http://www.imdb.com" ]+ in+ toVegaLite [ dataVals, mark Point [ MCursor CPointer ], enc [] ]++hyperlink3 :: VegaLite+hyperlink3 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative ]+ . color+ [ MDataCondition+ [ (Expr "datum.IMDB_Rating*10 > datum.Rotten_Tomatoes_Rating"+ , [ MString "steelblue" ])+ ]+ [ MString "red" ]+ ]+ . hyperlink+ [ HDataCondition+ [ (Expr "datum.IMDB_Rating*10 > datum.Rotten_Tomatoes_Rating"+ , [ HString "http://www.imdb.com" ])+ ]+ [ HString "https://www.rottentomatoes.com" ]+ ]+ in+ toVegaLite [ dataVals, mark Point [ MCursor CPointer ], enc [] ]
@@ -0,0 +1,172 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite GeoTests.elm as of version 1.12.0+--+module InteractionTests (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter)+++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("interaction1", interaction1)+ , ("interaction2", interaction2)+ , ("interaction3", interaction3)+ , ("interaction4", interaction4)+ , ("interaction5", interaction5)+ , ("interaction6", interaction6)+ , ("interaction7", interaction7)+ , ("interaction8", interaction8)+ ]+++crimeData :: Data+crimeData = dataFromUrl "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv" []+++cScale :: [ScaleProperty]+cScale =+ categoricalDomainMap+ [ ( "Anti-social behaviour", "rgb(59,118,175)" )+ , ( "Burglary", "rgb(81,157,62)" )+ , ( "Criminal damage and arson", "rgb(141,106,184)" )+ , ( "Drugs", "rgb(239,133,55)" )+ , ( "Robbery", "rgb(132,88,78)" )+ , ( "Vehicle crime", "rgb(213,126,190)" )+ ]+++month, crimes :: BuildLabelledSpecs+month = position X [ PName "month", PmType Temporal, PNoTitle ]+crimes = position Y [ PName "reportedCrimes", PmType Quantitative, PTitle "Reported crimes" ]++enc, encHighlight :: [LabelledSpec] -> PropertySpec+enc =+ encoding+ . month+ . crimes+ . color [ MName "crimeType", MmType Nominal, MScale cScale ]+++encHighlight =+ encoding+ . month+ . crimes+ . color+ [ MSelectionCondition (SelectionName "mySelection")+ [ MName "crimeType", MmType Nominal, MScale cScale ]+ [ MString "black" ]+ ]+ . opacity+ [ MSelectionCondition (SelectionName "mySelection")+ [ MNumber 1 ]+ [ MNumber 0.1 ]+ ]++interaction1 :: VegaLite+interaction1 =+ let+ sel =+ selection . select "mySelection" Single []+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Line [] ]+++interaction2 :: VegaLite+interaction2 =+ let+ sel =+ selection . select "mySelection" Multi []+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Line [] ]+++interaction3 :: VegaLite+interaction3 =+ let+ sel =+ selection+ . select "mySelection" Single [ Nearest True, Fields [ "crimeType" ] ]+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Circle [] ]+++interaction4 :: VegaLite+interaction4 =+ let+ sel =+ selection+ . select "mySelection" Interval [ Empty, Encodings [ ChX ] ]+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Circle [] ]+++interaction5 :: VegaLite+interaction5 =+ let+ sel =+ selection+ . select "mySelection" Interval [ BindScales, Encodings [ ChX ] ]+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Circle [] ]+++interaction6 :: VegaLite+interaction6 =+ let+ sel =+ selection+ . select "mySelection" Interval [ BindScales ]+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Circle [] ]+++interaction7 :: VegaLite+interaction7 =+ let+ sel =+ selection+ . select "mySelection"+ Single+ [ Fields [ "crimeType" ]+ , Nearest True+ , Bind+ [ IRadio "crimeType"+ [ InName " "+ , InOptions+ [ "Anti-social behaviour"+ , "Criminal damage and arson"+ , "Drugs"+ , "Robbery"+ , "Vehicle crime"+ ]+ ]+ ]+ ]+ in+ toVegaLite [ width 540, crimeData, sel [], encHighlight [], mark Circle [] ]+++interaction8 :: VegaLite+interaction8 =+ let+ sel =+ selection+ . select "maxSlider"+ Single+ [ SInit [ ( "maxReported", Number 14000 ) ]+ , Bind [ IRange "maxReported" [ InName "Max", InMin 400, InMax 14000 ] ]+ ]+ . select "minSlider"+ Single+ [ SInit [ ( "minReported", Number 0 ) ]+ , Bind [ IRange "minReported" [ InName "Min", InMax 12800 ] ]+ ]++ trans =+ transform+ . filter (FExpr "datum.reportedCrimes >= minSlider_minReported && maxSlider_maxReported >= datum.reportedCrimes")+ in+ toVegaLite [ width 540, crimeData, trans [], sel [], enc [], mark Circle [] ]
@@ -0,0 +1,118 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite LegendTests.elm as of version 1.12.0+--+module LegendTests (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("legend1", legend1)+ , ("legend2", legend2)+ , ("legend3", legend3)+ , ("legend4", legend4)+ , ("legend5", legend5)+ , ("legend6", legend6)+ , ("legend7", legend7)+ , ("legend8", legend8)+ , ("legend9", legend9)+ , ("legend10", legend10)+ , ("legend11", legend11)+ ]++legendCore :: [LegendProperty] -> VegaLite+legendCore legProps =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal, MLegend legProps ]+ . size [ MName "Horsepower", MmType Quantitative, MLegend legProps ]+ . opacity [ MName "Weight_in_lbs", MmType Quantitative, MLegend legProps ]+ in+ toVegaLite [ width 300, height 300, dataVals [], enc [], mark Circle [] ]++legendCoreCfg :: [LegendConfig] -> VegaLite+legendCoreCfg cfg =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal ]+ . size [ MName "Horsepower", MmType Quantitative ]+ . opacity [ MName "Weight_in_lbs", MmType Quantitative ]+ in+ toVegaLite+ [ (configure . configuration (Legend cfg)) []+ , width 300+ , height 300+ , dataVals []+ , enc []+ , mark Circle []+ ]++legend1 :: VegaLite+legend1 = legendCoreCfg []++legend2 :: VegaLite+legend2 = legendCore [ LOrient LOTop ]++legend3 :: VegaLite+legend3 = legendCore [ LOrient LOTopRight ]++legend4 :: VegaLite+legend4 = legendCore [ LOrient LORight ]++legend5 :: VegaLite+legend5 = legendCore [ LOrient LOBottomRight ]++legend6 :: VegaLite+legend6 = legendCore [ LOrient LOBottom ]++legend7 :: VegaLite+legend7 = legendCore [ LOrient LOBottomLeft ]++legend8 :: VegaLite+legend8 = legendCore [ LOrient LOLeft ]++legend9 :: VegaLite+legend9 = legendCore [ LOrient LOTopLeft ]++legend10 :: VegaLite+legend10 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Origin", MmType Nominal,+ MLegend [ LOrient LONone, LeX 232, LeY 5 ] ]+ in+ toVegaLite [ width 300, height 300, dataVals [], enc [], mark Circle [] ]++legend11 :: VegaLite+legend11 =+ legendCoreCfg+ [ LeSymbolStrokeWidth 3+ , LeSymbolStrokeColor "black"+ , LeRowPadding 15+ , LeTitlePadding 20+ , LeStrokeColor "lightgrey"+ , LeStrokeWidth 5+ , LePadding 30+ , LeStrokeDash [ 4, 2, 6, 1 ]+ ]
@@ -0,0 +1,192 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite NullTests.elm as of version 1.12.0+--++module NullTests (testSpecs) where++import Data.Function ((&))+import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("axis1", axis1)+ , ("scale0", scale0)+ , ("scale1", scale1)+ , ("scale2", scale2)+ , ("scale3", scale3)+ , ("scale4", scale4)+ , ("scale5", scale5)+ , ("filter1", filter1)+ , ("filter2", filter2)+ ]+++axis1 :: VegaLite+axis1 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "x" (Numbers [ 0, 1000, 1000, 0, 0, 1000 ])+ . dataColumn "y" (Numbers [ 1000, 1000, 0, 0, 1000, 0 ])+ . dataColumn "order" (Numbers [1..6])++ enc =+ encoding+ . position X [ PName "x", PmType Quantitative, PAxis [] ]+ . position Y [ PName "y", PmType Quantitative, PAxis [] ]+ . order [ OName "order", OmType Ordinal ]+ in+ toVegaLite [ dataVals [], enc [], mark Line [] ]+++scaleEncode :: (VLProperty, VLSpec) -> VegaLite+scaleEncode enc =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "x" (Numbers [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ])+ . dataColumn "y" (Numbers [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ])+ . dataColumn "val" (Numbers [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ])+ . dataColumn "cat" (Strings [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" ])+ in+ toVegaLite [ width 400, height 400, dataVals [], enc, mark Point [] ]+++scale0 :: VegaLite+scale0 =+ (encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative ]+ . color [ MName "val", MmType Ordinal ]+ . size [ MName "val", MmType Quantitative ]+ . shape [ MName "cat", MmType Nominal ]+ )+ []+ & scaleEncode+++scale1 :: VegaLite+scale1 =+ (encoding+ . position X [ PName "x", PmType Quantitative, PScale [] ]+ . position Y [ PName "y", PmType Quantitative ]+ . color [ MName "val", MmType Ordinal ]+ . size [ MName "val", MmType Quantitative ]+ . shape [ MName "cat", MmType Nominal ]+ )+ []+ & scaleEncode+++scale2 :: VegaLite+scale2 =+ (encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative, PScale [] ]+ . color [ MName "val", MmType Ordinal ]+ . size [ MName "val", MmType Quantitative ]+ . shape [ MName "cat", MmType Nominal ]+ )+ []+ & scaleEncode+++scale3 :: VegaLite+scale3 =+ (encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative ]+ . color [ MName "val", MmType Ordinal, MScale [] ]+ . size [ MName "val", MmType Quantitative ]+ . shape [ MName "cat", MmType Nominal ]+ )+ []+ & scaleEncode+++scale4 :: VegaLite+scale4 =+ (encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative ]+ . color [ MName "val", MmType Ordinal ]+ . size [ MName "val", MmType Quantitative, MScale [] ]+ . shape [ MName "cat", MmType Nominal ]+ )+ []+ & scaleEncode+++scale5 :: VegaLite+scale5 =+ (encoding+ . position X [ PName "x", PmType Quantitative ]+ . position Y [ PName "y", PmType Quantitative ]+ . color [ MName "val", MmType Ordinal ]+ . size [ MName "val", MmType Quantitative ]+ . shape [ MName "cat", MmType Nominal, MScale [] ]+ )+ []+ & scaleEncode+++filter1 :: VegaLite+filter1 =+ let+ config =+ configure+ . configuration (RemoveInvalid False)++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative ]+ . color+ [ MDataCondition+ [ (Expr "datum.IMDB_Rating === null || datum.Rotten_Tomatoes_Rating === null"+ , [ MString "#ddd" ] )+ ]+ [ MString "rgb(76,120,168)" ]+ ]+ in+ toVegaLite+ [ config []+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Point[]+ , enc []+ ]++filter2 :: VegaLite+filter2 =+ let+ config =+ configure+ . configuration (RemoveInvalid False)++ trans =+ transform+ . filter (FValid "IMDB_Rating")+ . filter (FValid "Rotten_Tomatoes_Rating")++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative ]+ . position Y [ PName "Rotten_Tomatoes_Rating", PmType Quantitative ]+ . color+ [ MDataCondition+ [ (Expr "datum.IMDB_Rating === null || datum.Rotten_Tomatoes_Rating === null"+ , [ MString "#ddd" ])+ ]+ [ MString "rgb(76,120,168)" ]+ ]+ in+ toVegaLite+ [ config []+ , trans []+ , dataFromUrl "https://vega.github.io/vega-lite/data/movies.json" []+ , mark Point[]+ , enc []+ ]
@@ -0,0 +1,125 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite PositionTests.elm as of version 1.12.0+--++module PositionTests (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("position1", position1)+ , ("position2", position2)+ , ("position3", position3)+ , ("position4", position4)+ , ("position5", position5)+ , ("position6", position6)+ , ("position7", position7)+ , ("position8", position8)+ , ("position9", position9)+ , ("position10", position10)+ , ("position11", position11)+ , ("position12", position12)+ ]+++pOrdinal, pQuant :: PositionChannel+pOrdinal = PmType Ordinal+pQuant = PmType Quantitative++pName :: T.Text -> PositionChannel+pName = PName++bar :: [MarkProperty] -> PropertySpec+bar = mark Bar+++emptyData, someData :: [DataColumn] -> Data+emptyData =+ dataFromColumns []+ . dataColumn "empty" (Numbers [0])++someData =+ dataFromColumns []+ . dataColumn "cat" (Numbers [1, 2, 3, 4, 5])+ . dataColumn "val" (Numbers [10, 20, 30, 20, 10])+ . dataColumn "empty" (Numbers [0])+++position1 :: VegaLite+position1 =+ toVegaLite [ emptyData []+ , mark Circle [ MX 150, MY 150, MSize 200 ] ]++position2 :: VegaLite+position2 =+ toVegaLite [ emptyData []+ , mark Bar [ MX 150, MY 150 ] ]+++position3 :: VegaLite+position3 =+ toVegaLite [ emptyData []+ , mark Bar [ MX 150, MY 150, MX2 200 ] ]+++position4 :: VegaLite+position4 =+ toVegaLite [ emptyData []+ , mark Bar [ MX 150, MY 150, MY2 200 ] ]+++position5 :: VegaLite+position5 =+ toVegaLite [ emptyData []+ , mark Bar [ MX 150, MY 150, MX2 200, MY2 200 ] ]+++position6 :: VegaLite+position6 =+ let+ enc =+ encoding+ . position X [ pName "cat", pOrdinal ]+ . position Y [ pName "val", pQuant ]+ in+ toVegaLite [ width 300, someData [], enc [], bar [ MWidth 20 ] ]+++position7 :: VegaLite+position7 =+ let+ enc =+ encoding+ . position X [ pName "val", pQuant ]+ . position Y [ pName "cat", pOrdinal ]+ in+ toVegaLite [ height 300, someData [], enc [], bar [ MHeight 20 ] ]+++barAlign :: Double -> VegaLite+barAlign x =+ let+ enc =+ encoding+ . position X+ [ pName "cat"+ , pOrdinal+ , PScale [ SAlign x, SPaddingInner 0.5 ]+ ]+ . position Y [ pName "val", pQuant ]+ in+ toVegaLite [ width 400, someData [], enc [], bar [] ]+++position8, position9, position10, position11, position12 :: VegaLite+position8 = barAlign (-10) -- test clamping+position9 = barAlign 0.3+position10 = barAlign 0.5+position11 = barAlign 0.7+position12 = barAlign 10 -- test clamping
@@ -0,0 +1,161 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ProjctionTests.elm as of version 1.12.0+--+module ProjectionTests (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter)+++testSpecs :: [(String, VegaLite)]+testSpecs = standardProjs+ ++ [ configExample+ , reflectExample False False+ , reflectExample True False+ , reflectExample False True+ , reflectExample True True+ ]+ ++ d3Projections+++{- Some relevant data sources:++ https://github.com/deldersveld/topojson+ https://github.com/topojson/world-atlas++ graticule.json produced with mapshaper.org:+ open console and type -graticule then export as topojson.+-}+++worldMapTemplate :: String -> [ProjectionProperty] -> (String, VegaLite)+worldMapTemplate tText projProps =+ ( tText+ , toVegaLite+ [ width 500+ , height 300+ , title (T.pack tText) []+ , background "#c1e7f5"+ , projection projProps++ --, dataFromUrl "https://vega.github.io/vega-lite/data/world-110m.json" [ TopojsonFeature "countries" ]+ , dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , mark Geoshape [ MFillOpacity 0.01, MStroke "#411", MStrokeWidth 0.5 ]+ ]+ )++standardProjs :: [(String, VegaLite)]+standardProjs =+ [ worldMapTemplate "Albers" [ PrType Albers ]+ , worldMapTemplate "AzimuthalEqualArea" [ PrType AzimuthalEqualArea ]+ , worldMapTemplate "AzimuthalEquidistant" [ PrType AzimuthalEquidistant ]+ , worldMapTemplate "ConicConformal" [ PrType ConicConformal, PrClipAngle (Just 65) ]+ , worldMapTemplate "ConicEqualArea" [ PrType ConicEqualArea ]+ , worldMapTemplate "ConicEquidistant" [ PrType ConicEquidistant ]+ , worldMapTemplate "Equirectangular" [ PrType Equirectangular ]+ , worldMapTemplate "Gnomonic" [ PrType Gnomonic ]+ , worldMapTemplate "Identity" [ PrType Identity ]+ , worldMapTemplate "Mercator" [ PrType Mercator ]+ , worldMapTemplate "Orthographic" [ PrType Orthographic ]+ , worldMapTemplate "Stereographic" [ PrType Stereographic ]+ , worldMapTemplate "TransverseMercator" [ PrType TransverseMercator ]+ ]+++d3Projections :: [(String, VegaLite)]+d3Projections =+ -- Note these require registering via JavaScript in the hosting page.+ let+ customSpec pText =+ worldMapTemplate pText [ PrType (Custom (T.pack pText))+ , PrClipAngle (Just 179.999)+ , PrRotate 20 (-90) 0+ , PrPrecision 0.1 ]+ in+ map customSpec [ "airy", "aitoff", "armadillo", "august", "baker", "berghaus", "bertin1953", "boggs", "bonne", "bottomley", "collignon", "craig", "craster", "cylindricalequalarea", "cylindricalstereographic", "eckert1", "eckert2", "eckert3", "eckert4", "eckert5", "eckert6", "eisenlohr", "fahey", "foucaut", "gingery", "winkel3" ]+++configExample :: (String, VegaLite)+configExample =+ let+ cfg =+ configure+ . configuration (Background "rgb(251,247,238)")+ . configuration (TitleStyle [ TFont "Roboto", TFontWeight W600, TFontSize 18 ])+ . configuration (View [ ViewWidth 500, ViewHeight 300, ViewStroke Nothing ])+ . configuration (Autosize [ AFit ])+ . configuration (Projection [ PrType Orthographic, PrRotate 0 0 0 ])++ globeSpec =+ asSpec+ [ dataFromUrl "data/globe.json" [ TopojsonFeature "globe" ]+ , mark Geoshape [ MColor "#c1e7f5" ]+ ]++ graticuleSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , mark Geoshape [ MFillOpacity 0.01, MStroke "#411", MStrokeWidth 0.1 ]+ ]++ countrySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/world-110m.json" [ TopojsonFeature "countries" ]+ , mark Geoshape [ MColor "#708E71" ]+ ]+ in+ ( "configExample"+ , toVegaLite [ title "Hello, World!" [], cfg [], layer [ globeSpec, graticuleSpec, countrySpec ] ]+ )+++reflectExample :: Bool -> Bool -> (String, VegaLite)+reflectExample rx ry =+ let+ tname =+ if not rx && not ry then+ "identityExample"++ else+ "reflect"+ ++ (if rx then+ "X"++ else+ ""+ )+ ++ (if ry then+ "Y"++ else+ ""+ )+ ++ "Example"++ globeSpec =+ asSpec+ [ dataFromUrl "data/globe.json" [ TopojsonFeature "globe" ]+ , mark Geoshape [ MColor "#c1e7f5" ]+ , projection [ PrType Identity, PrReflectX rx, PrReflectY ry ]+ ]++ graticuleSpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/graticule.json" [ TopojsonFeature "graticule" ]+ , mark Geoshape [ MFillOpacity 0.01, MStroke "#411", MStrokeWidth 0.1 ]+ , projection [ PrType Identity, PrReflectX rx, PrReflectY ry ]+ ]++ countrySpec =+ asSpec+ [ dataFromUrl "https://vega.github.io/vega-lite/data/world-110m.json" [ TopojsonFeature "countries" ]+ , mark Geoshape [ MColor "#708E71" ]+ , projection [ PrType Identity, PrReflectX rx, PrReflectY ry ]+ ]+ in+ ( tname, toVegaLite [ width 500, height 250, layer [ globeSpec, graticuleSpec, countrySpec ] ] )
@@ -0,0 +1,228 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ScaleTests.elm as of version 1.12.0+--+module ScaleTests (testSpecs) where++import Graphics.Vega.VegaLite hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("scale1", scale1)+ , ("scale2", scale2)+ , ("scale3", scale3)+ , ("scale4", scale4)+ , ("scale5", scale5)+ , ("scale6", scale6)+ , ("scale7", scale7)+ , ("scale8", scale8)+ , ("scale9", scale9)+ ]++scale1 :: VegaLite+scale1 =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MString "rgb(203,24,29)" ]+ . size [ MName "Acceleration", MmType Quantitative, MBin [] ]+ . opacity [ MName "Acceleration", MmType Quantitative, MBin [] ]+ in+ toVegaLite [ cars, enc [],+ mark Point [ MFilled True, MStroke "white", MStrokeWidth 0.4 ] ]++scale2 :: VegaLite+scale2 =+ let+ conf =+ configure+ . configuration (Range [ RRamp "reds" ])++ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . color [ MName "Acceleration", MmType Quantitative, MBin [] ]+ in+ toVegaLite [ conf [], cars, enc [], mark Point [] ]+++scale3 :: VegaLite+scale3 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position Y+ [ PName "b"+ , PmType Nominal+ , PSort []+ , PAxis [ AxTicks False, AxDomain False, AxNoTitle ]+ ]+ . size+ [ MName "b"+ , MmType Quantitative+ , MScale [ SType ScQuantile ]+ ]+ . color+ [ MName "b"+ , MmType Quantitative+ , MScale [ SType ScQuantile ]+ , MLegend [ LTitle "Quantile" ]+ ]+ in+ toVegaLite [ dataVals [], enc [], mark Circle [] ]+++scale4 :: VegaLite+scale4 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position Y+ [ PName "b"+ , PmType Nominal+ , PSort []+ , PAxis [ AxTicks False, AxDomain False, AxNoTitle ]+ ]+ . size+ [ MName "b"+ , MmType Quantitative+ , MScale [ SType ScQuantize ]+ ]+ . color+ [ MName "b"+ , MmType Quantitative+ , MScale [ SType ScQuantize, SZero True ]+ , MLegend [ LTitle "Quantize" ]+ ]+ in+ toVegaLite [ dataVals [], enc [], mark Circle [] ]++scale5 :: VegaLite+scale5 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position Y+ [ PName "b"+ , PmType Nominal+ , PSort []+ , PAxis [ AxTicks False, AxDomain False, AxNoTitle ]+ ]+ . size+ [ MName "b"+ , MmType Quantitative+ , MScale+ [ SType ScThreshold+ , SDomain (DNumbers [ 30, 70 ])+ , SRange (RNumbers [ 80, 200, 320 ])+ ]+ ]+ . color+ [ MName "b"+ , MmType Quantitative+ , MScale+ [ SType ScThreshold+ , SDomain (DNumbers [ 30, 70 ])+ , SScheme "viridis" []+ ]+ , MLegend [ LTitle "Threshold" ]+ ]+ in+ toVegaLite [ dataVals [], enc [], mark Circle [] ]+++scale6 :: VegaLite+scale6 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "r" (Numbers [ 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 ])++ enc =+ encoding+ . size+ [ MName "r"+ , MmType Quantitative+ , MScale [ SRange (RNumbers [ 0, 80000 ]) ]+ , MLegend []+ ]+ in+ toVegaLite [ dataVals [], mark Point [], enc [] ]+++scale7 :: VegaLite+scale7 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "r" (Numbers [ 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 ])++ enc =+ encoding+ . size+ [ MName "r"+ , MmType Quantitative+ , MScale [ SRange (RNumbers [ 0, 80000 ]), SType ScPow, SExponent 2 ]+ , MLegend []+ ]+ in+ toVegaLite [ dataVals [], mark Point [], enc [] ]+++scale8 :: VegaLite+scale8 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "r" (Numbers [ 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 ])++ enc =+ encoding+ . size+ [ MName "r"+ , MmType Quantitative+ , MScale [ SRange (RNumbers [ 0, 80000 ]), SType ScPow, SExponent 1.2 ]+ , MLegend []+ ]+ in+ toVegaLite [ dataVals [], mark Point [], enc [] ]+++scale9 :: VegaLite+scale9 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "r" (Numbers [ 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 ])++ enc =+ encoding+ . size+ [ MName "r"+ , MmType Quantitative+ , MScale [ SRange (RNumbers [ 0, 80000 ]), SType ScLog, SBase (exp 1) ]+ , MLegend []+ ]+ in+ toVegaLite [ dataVals [], mark Point [], enc [] ]
@@ -0,0 +1,318 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ShapeTests.elm as of version 1.12.0+--++module ShapeTests (testSpecs) where++import qualified Data.Map as M+import qualified Data.Text as T++import Data.Maybe (fromMaybe)+import Graphics.Vega.VegaLite++import Prelude hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("defNominal", scatter1)+ , ("defOrdinal", scatter2)+ , ("size1", scatter3)+ , ("size2", scatter4)+ , ("size3", scatter5)+ , ("multi1", scatter6)+ , ("multi2", scatter7)+ , ("multi3", scatter8)+ , ("multi4", scatter9)+ , ("multi5", scatter10)+ , ("multi6", scatter11)+ , ("custom1", scatter12)+ , ("custom2", scatter13)+ , ("custom3", scatter14)+ , ("custom4", scatter15)+ , ("isotype1", personGrid)+ , ("point1", point1)+ , ("point2", point2)+ , ("point3", point3)+ , ("point4", point4)+ , ("point5", point5)+ , ("point6", point6)+ , ("point7", point7)+ ]+++chart :: T.Text -> ([a] -> [LabelledSpec]) -> VegaLite+chart des enc =+ toVegaLite+ [ description des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , (transform+ . calculateAs "year(datum.Year)" "YearOfManufacture"+ . filter (FExpr "datum.YearOfManufacture == 1970")+ )+ []+ , mark Point [ MFilled True ]+ , (encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . opacity [ MNumber 0.6 ]+ . enc+ )+ []+ ]+++pointChart :: T.Text -> Bool -> Symbol -> VegaLite+pointChart des filled sym =+ toVegaLite+ [ description des+ , dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []+ , (transform+ . calculateAs "year(datum.Year)" "YearOfManufacture"+ . filter (FExpr "datum.YearOfManufacture == 1970")+ )+ []+ , mark Point [ MFilled filled, MShape sym ]+ , (encoding+ . position X [ PName "Horsepower", PmType Quantitative ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]+ . opacity [ MNumber 0.6 ]+ )+ []+ ]+++unitSquare, largeSquare, square, tri, cross :: T.Text+unitSquare = "M -0.5 -0.5 h 1 v 1 h -1z"+largeSquare = "M -5 -5 h 10 v 10 h -10z"+square = "M -1.5 -1.5 h 3 v 3 h -3z"+tri = "M -1.5 -1.5 h 3 l -1.5 3z"+cross = "M -1.5 -1.5 m1 0 h 1 v 1 h 1 v 1 h -1 v 1 h -1 v -1 h -1 v -1 h 1z"+++scatter1 :: VegaLite+scatter1 =+ chart "Default nominal shapes."+ (shape [ MName "Origin", MmType Nominal ])+++scatter2 :: VegaLite+scatter2 =+ chart "Default ordinal shapes."+ (shape [ MName "Cylinders", MmType Ordinal ])+++scatter3 :: VegaLite+scatter3 =+ chart "Enlarged shapes (but legend shapes should remain same size)"+ (shape [ MName "Origin", MmType Nominal ]+ . size [ MNumber 200 ]+ )+++scatter4 :: VegaLite+scatter4 =+ chart "Reduced shapes (but legend shapes should remain same size)"+ (shape [ MName "Origin", MmType Nominal ]+ . size [ MNumber 20 ]+ )+++scatter5 :: VegaLite+scatter5 =+ chart "Fixed shape, sized by number of cylinder category"+ (size [ MName "Cylinders", MmType Ordinal ])+++scatter6 :: VegaLite+scatter6 =+ chart "Sized by number of cylinders, shape by origin"+ (shape [ MName "Origin", MmType Nominal ]+ . size [ MName "Cylinders", MmType Ordinal ]+ )+++scatter7 :: VegaLite+scatter7 =+ chart "Sized and shaped by number of cylinders (should only have a single set of legend items)"+ (shape [ MName "Cylinders", MmType Ordinal ]+ . size [ MName "Cylinders", MmType Ordinal ]+ )+++scatter8 :: VegaLite+scatter8 =+ chart "Sized, shaped and coloured by number of cylinders (should only have a single set of legend items)"+ (shape [ MName "Cylinders", MmType Ordinal ]+ . size [ MName "Cylinders", MmType Ordinal ]+ . color [ MName "Cylinders", MmType Ordinal ]+ )+++scatter9 :: VegaLite+scatter9 =+ chart "Custom-shaped and coloured by origin (should only have a single set of legend items)"+ (shape [ MName "Origin", MmType Nominal ]+ . color [ MName "Origin", MmType Nominal ]+ )+++scatter10 :: VegaLite+scatter10 =+ chart "Custom-shaped and coloured by origin (should only have a single set of legend items)"+ (shape+ [ MName "Origin"+ , MmType Nominal+ , MScale (categoricalDomainMap+ [ ( "Europe", square )+ , ( "Japan", cross )+ , ( "USA", tri )+ ])+ ]+ . color [ MName "Origin", MmType Nominal ]+ )+++scatter11 :: VegaLite+scatter11 =+ chart "Sized, shaped and coloured by number of cylinders (should have two sets of legend items)"+ (shape [ MName "Cylinders", MmType Ordinal ]+ . size [ MName "Cylinders", MmType Ordinal ]+ . color [ MName "Origin", MmType Nominal ]+ )+++scatter12 :: VegaLite+scatter12 =+ chart "Custom nominal shape with unit area."+ (shape [ MPath unitSquare ])+++scatter13 :: VegaLite+scatter13 =+ chart "Custom nominal shape with unit area sized by Cylinders."+ (shape [ MPath unitSquare ]+ . size [ MName "Cylinders", MmType Ordinal ]+ )+++scatter14 :: VegaLite+scatter14 =+ chart "Custom nominal shape with area of 10x10 pixel units."+ (shape [ MPath largeSquare ]+ . color [ MName "Origin", MmType Nominal ]+ )+++scatter15 :: VegaLite+scatter15 =+ chart "Custom shape sets encoding origin."+ (shape+ [ MName "Origin"+ , MmType Nominal+ , MScale (categoricalDomainMap+ [ ( "Europe", square )+ , ( "Japan", cross )+ , ( "USA", tri )+ ])+ ]+ )+++isotypes :: M.Map T.Text T.Text+isotypes =+ let+ cow =+ "M4 -2c0 0 0.9 -0.7 1.1 -0.8c0.1 -0.1 -0.1 0.5 -0.3 0.7c-0.2 0.2 1.1 1.1 1.1 1.2c0 0.2 -0.2 0.8 -0.4 0.7c-0.1 0 -0.8 -0.3 -1.3 -0.2c-0.5 0.1 -1.3 1.6 -1.5 2c-0.3 0.4 -0.6 0.4 -0.6 0.4c0 0.1 0.3 1.7 0.4 1.8c0.1 0.1 -0.4 0.1 -0.5 0c0 0 -0.6 -1.9 -0.6 -1.9c-0.1 0 -0.3 -0.1 -0.3 -0.1c0 0.1 -0.5 1.4 -0.4 1.6c0.1 0.2 0.1 0.3 0.1 0.3c0 0 -0.4 0 -0.4 0c0 0 -0.2 -0.1 -0.1 -0.3c0 -0.2 0.3 -1.7 0.3 -1.7c0 0 -2.8 -0.9 -2.9 -0.8c-0.2 0.1 -0.4 0.6 -0.4 1c0 0.4 0.5 1.9 0.5 1.9l-0.5 0l-0.6 -2l0 -0.6c0 0 -1 0.8 -1 1c0 0.2 -0.2 1.3 -0.2 1.3c0 0 0.3 0.3 0.2 0.3c0 0 -0.5 0 -0.5 0c0 0 -0.2 -0.2 -0.1 -0.4c0 -0.1 0.2 -1.6 0.2 -1.6c0 0 0.5 -0.4 0.5 -0.5c0 -0.1 0 -2.7 -0.2 -2.7c-0.1 0 -0.4 2 -0.4 2c0 0 0 0.2 -0.2 0.5c-0.1 0.4 -0.2 1.1 -0.2 1.1c0 0 -0.2 -0.1 -0.2 -0.2c0 -0.1 -0.1 -0.7 0 -0.7c0.1 -0.1 0.3 -0.8 0.4 -1.4c0 -0.6 0.2 -1.3 0.4 -1.5c0.1 -0.2 0.6 -0.4 0.6 -0.4z"++ pig =+ "M1.2 -2c0 0 0.7 0 1.2 0.5c0.5 0.5 0.4 0.6 0.5 0.6c0.1 0 0.7 0 0.8 0.1c0.1 0 0.2 0.2 0.2 0.2c0 0 -0.6 0.2 -0.6 0.3c0 0.1 0.4 0.9 0.6 0.9c0.1 0 0.6 0 0.6 0.1c0 0.1 0 0.7 -0.1 0.7c-0.1 0 -1.2 0.4 -1.5 0.5c-0.3 0.1 -1.1 0.5 -1.1 0.7c-0.1 0.2 0.4 1.2 0.4 1.2l-0.4 0c0 0 -0.4 -0.8 -0.4 -0.9c0 -0.1 -0.1 -0.3 -0.1 -0.3l-0.2 0l-0.5 1.3l-0.4 0c0 0 -0.1 -0.4 0 -0.6c0.1 -0.1 0.3 -0.6 0.3 -0.7c0 0 -0.8 0 -1.5 -0.1c-0.7 -0.1 -1.2 -0.3 -1.2 -0.2c0 0.1 -0.4 0.6 -0.5 0.6c0 0 0.3 0.9 0.3 0.9l-0.4 0c0 0 -0.4 -0.5 -0.4 -0.6c0 -0.1 -0.2 -0.6 -0.2 -0.5c0 0 -0.4 0.4 -0.6 0.4c-0.2 0.1 -0.4 0.1 -0.4 0.1c0 0 -0.1 0.6 -0.1 0.6l-0.5 0l0 -1c0 0 0.5 -0.4 0.5 -0.5c0 -0.1 -0.7 -1.2 -0.6 -1.4c0.1 -0.1 0.1 -1.1 0.1 -1.1c0 0 -0.2 0.1 -0.2 0.1c0 0 0 0.9 0 1c0 0.1 -0.2 0.3 -0.3 0.3c-0.1 0 0 -0.5 0 -0.9c0 -0.4 0 -0.4 0.2 -0.6c0.2 -0.2 0.6 -0.3 0.8 -0.8c0.3 -0.5 1 -0.6 1 -0.6z"++ sheep =+ "M-4.1 -0.5c0.2 0 0.2 0.2 0.5 0.2c0.3 0 0.3 -0.2 0.5 -0.2c0.2 0 0.2 0.2 0.4 0.2c0.2 0 0.2 -0.2 0.5 -0.2c0.2 0 0.2 0.2 0.4 0.2c0.2 0 0.2 -0.2 0.4 -0.2c0.1 0 0.2 0.2 0.4 0.1c0.2 0 0.2 -0.2 0.4 -0.3c0.1 0 0.1 -0.1 0.4 0c0.3 0 0.3 -0.4 0.6 -0.4c0.3 0 0.6 -0.3 0.7 -0.2c0.1 0.1 1.4 1 1.3 1.4c-0.1 0.4 -0.3 0.3 -0.4 0.3c-0.1 0 -0.5 -0.4 -0.7 -0.2c-0.3 0.2 -0.1 0.4 -0.2 0.6c-0.1 0.1 -0.2 0.2 -0.3 0.4c0 0.2 0.1 0.3 0 0.5c-0.1 0.2 -0.3 0.2 -0.3 0.5c0 0.3 -0.2 0.3 -0.3 0.6c-0.1 0.2 0 0.3 -0.1 0.5c-0.1 0.2 -0.1 0.2 -0.2 0.3c-0.1 0.1 0.3 1.1 0.3 1.1l-0.3 0c0 0 -0.3 -0.9 -0.3 -1c0 -0.1 -0.1 -0.2 -0.3 -0.2c-0.2 0 -0.3 0.1 -0.4 0.4c0 0.3 -0.2 0.8 -0.2 0.8l-0.3 0l0.3 -1c0 0 0.1 -0.6 -0.2 -0.5c-0.3 0.1 -0.2 -0.1 -0.4 -0.1c-0.2 -0.1 -0.3 0.1 -0.4 0c-0.2 -0.1 -0.3 0.1 -0.5 0c-0.2 -0.1 -0.1 0 -0.3 0.3c-0.2 0.3 -0.4 0.3 -0.4 0.3l0.2 1.1l-0.3 0l-0.2 -1.1c0 0 -0.4 -0.6 -0.5 -0.4c-0.1 0.3 -0.1 0.4 -0.3 0.4c-0.1 -0.1 -0.2 1.1 -0.2 1.1l-0.3 0l0.2 -1.1c0 0 -0.3 -0.1 -0.3 -0.5c0 -0.3 0.1 -0.5 0.1 -0.7c0.1 -0.2 -0.1 -1 -0.2 -1.1c-0.1 -0.2 -0.2 -0.8 -0.2 -0.8c0 0 -0.1 -0.5 0.4 -0.8z"++ person =+ "M1.7 -1.7h-0.8c0.3 -0.2 0.6 -0.5 0.6 -0.9c0 -0.6 -0.4 -1 -1 -1c-0.6 0 -1 0.4 -1 1c0 0.4 0.2 0.7 0.6 0.9h-0.8c-0.4 0 -0.7 0.3 -0.7 0.6v1.9c0 0.3 0.3 0.6 0.6 0.6h0.2c0 0 0 0.1 0 0.1v1.9c0 0.3 0.2 0.6 0.3 0.6h1.3c0.2 0 0.3 -0.3 0.3 -0.6v-1.8c0 0 0 -0.1 0 -0.1h0.2c0.3 0 0.6 -0.3 0.6 -0.6v-2c0.2 -0.3 -0.1 -0.6 -0.4 -0.6z"+ in+ M.fromList [ ( "cow", cow ), ( "pig", pig ), ( "sheep", sheep ), ( "person", person ) ]++++{- Grid of selectable person icons.+ Inspired by Alan Smith's D3 example http://bl.ocks.org/alansmithy/d832fc03f6e6a91e99f4+ and based around Amit Kapoor's unit chart example https://bl.ocks.org/amitkaps/d6648bd8ddb1c1e3706d7530126d1e2b+-}+++personGrid :: VegaLite+personGrid =+ let+ config =+ configure+ . configuration (View [ ViewStroke Nothing ])++ dataVals =+ dataFromColumns []+ . dataColumn "id" (Numbers [1 .. 100])++ trans =+ transform+ . calculateAs "ceil (datum.id/10)" "col"+ . calculateAs "datum.id - datum.col*10" "row"++ sel =+ selection+ . select "highlight" Interval []++ mpath = M.lookup "person" isotypes+ enc =+ encoding+ . position X [ PName "col", PmType Ordinal, PAxis [] ]+ . position Y [ PName "row", PmType Ordinal, PAxis [] ]+ . shape [ MPath (fromMaybe "circle" mpath) ]+ . color+ [ MSelectionCondition (SelectionName "highlight")+ [ MString "rgb(194,81,64)" ]+ [ MString "rgb(167,165,156)" ]+ ]+ . size [ MNumber 90 ]+ in+ toVegaLite+ [ config []+ , width 400+ , height 400+ , dataVals []+ , trans []+ , mark Point [ MFilled True ]+ , enc []+ , sel []+ ]+++point1 :: VegaLite+point1 = pointChart "square-unfilled" False SymSquare+++point2 :: VegaLite+point2 = pointChart "cross-filled" True SymCross+++point3 :: VegaLite+point3 = pointChart "diamond-unfilled" False SymDiamond+++-- not going to try all the triangles+point4 :: VegaLite+point4 = pointChart "triangle-unfilled" False SymTriangle+++point5 :: VegaLite+point5 = pointChart "stroke-unfilled" False SymStroke+++point6 :: VegaLite+point6 = pointChart "arrow-filled" True SymArrow+++point7 :: VegaLite+point7 = pointChart "wedge-unfilled" False SymWedge
@@ -0,0 +1,103 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite SortTests.elm as of version 1.12.0+--+module SortTests (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("ascending", sortAsc)+ , ("descending", sortDesc)+ , ("weighted", sortWeight)+ , ("custom", sortCustom)+ , ("stack1", stack1)+ ]+++sortQuant :: T.Text -> [SortProperty] -> VegaLite+sortQuant yField sps =+ let+ datavals =+ dataFromColumns []+ . dataColumn "Horsepower" (Numbers [ 1, 5, 2, 3, 4 ])+ . dataColumn "Weight_in_lbs" (Numbers [ 19, 21, 58, 12, 13 ])++ enc =+ encoding+ . position X [ PName "Horsepower", PmType Quantitative, PSort sps ]+ . position Y [ PName yField, PmType Quantitative ]+ . order [ OName yField, OmType Ordinal ]+ in+ toVegaLite [ height 300, datavals [], enc [], mark Line [ MStrokeWidth 0.5 ] ]+++sortAsc, sortDesc :: VegaLite+sortAsc = sortQuant "Horsepower" [ Ascending ]+sortDesc = sortQuant "Horsepower" [ Descending ]++sortWeight :: VegaLite+sortWeight =+ sortQuant "Weight_in_lbs" [ ByFieldOp "Weight_in_lbs" Mean ]++sortCustom :: VegaLite+sortCustom =+ let+ datavals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "Z", "Y", "X" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53 ])++ enc =+ encoding+ . position X+ [ PName "a"+ , PmType Ordinal+ , PSort [ CustomSort (Strings [ "B", "A", "C" ]) ]+ ]+ . position Y [ PName "b", PmType Quantitative ]+ in+ toVegaLite [ datavals [], enc [], mark Bar [] ]++stack1 :: VegaLite+stack1 =+ let+ cars =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ trans =+ transform+ . aggregate [ opAs Count "" "count_*" ] [ "Origin", "Cylinders" ]+ . stack "count_*"+ []+ "stack_count_Origin1"+ "stack_count_Origin2"+ [ StOffset StNormalize, StSort [ WAscending "Origin" ] ]+ . window+ [ ( [ WAggregateOp Min, WField "stack_count_Origin1" ], "x" )+ , ( [ WAggregateOp Max, WField "stack_count_Origin2" ], "x2" )+ ]+ [ WFrame Nothing Nothing, WGroupBy [ "Origin" ] ]+ . stack "count_*"+ [ "Origin" ]+ "y"+ "y2"+ [ StOffset StNormalize, StSort [ WAscending "Cylinders" ] ]++ enc =+ encoding+ . position X [ PName "x", PmType Quantitative, PAxis [] ]+ . position X2 [ PName "x2" ]+ . position Y [ PName "y", PmType Quantitative, PAxis [] ]+ . position Y2 [ PName "y2" ]+ . color [ MName "Origin", MmType Nominal ]+ . opacity [ MName "Cylinders", MmType Quantitative, MLegend [] ]+ . tooltips+ [ [ TName "Origin", TmType Nominal ]+ , [ TName "Cylinders", TmType Quantitative ]+ ]+ in+ toVegaLite [ cars, trans [], enc [], mark Rect [] ]
@@ -0,0 +1,159 @@+{-# LANGUAGE OverloadedStrings #-}++{-++Tests for hvega, using tasty-golden.++The idea is that we check the JSON serialization of a specification+against a previously-generated value, stored as a separate file. This+allows external checks of the spec (e.g. by validating against the+Vega-Lite schema), and tests in visualizers. That is, the main aim+is to perform a series of regression tests, rather than unit or+property tests. Each module - based on the Elm VegaLite tests -+provides a labelled-list of VegaLite specifications, as++ testSpecs :: [(String, VegaLite)]++and these labels are used as the file name of the "golden" file (with+a ".vl" suffix) in a sub-directory for the module.++To make the output easier to compare against, the Aeson pretty-printer+is used. This relies on the pretty-printer being deterministic (i.e.+the key/value pairs of dictionaries get displayed in the same order).++-}++import qualified Data.ByteString.Lazy.Char8 as BL8++import Data.Aeson.Encode.Pretty (encodePretty)++import System.FilePath ((</>), (<.>))++import Test.Tasty (defaultMain, TestTree, testGroup)+import Test.Tasty.Golden (goldenVsString)++import Prelude hiding (filter, repeat)++import Graphics.Vega.VegaLite++-- Test specifications+--+import qualified AxisTests as AxT+import qualified ColorTests as ColT+import qualified CompositeTests as CompT+import qualified ConditionalTests as CondT+import qualified ConfigTests as ConfT+import qualified DataTests as DT+import qualified FillStrokeTests as FST+import qualified GeoTests as GT+import qualified HyperlinkTests as HT+import qualified InteractionTests as IT+import qualified LegendTests as LT+import qualified NullTests as NT+import qualified PositionTests as PT+import qualified ProjectionTests as PjT+import qualified ScaleTests as ScT+import qualified ShapeTests as ShT+import qualified SortTests as SoT+import qualified TextFormatTests as TfT+import qualified TimeTests as TmT+import qualified TooltipTests as TT+import qualified TrailTests as TrT+import qualified ViewCompositionTests as VT+import qualified WindowTransformTests as WT++-- extend from the "tests" to gallery plots+import qualified Gallery.Advanced as GADV+import qualified Gallery.Area as GA+import qualified Gallery.Bar as GB+import qualified Gallery.Dist as GD+import qualified Gallery.Error as GE+import qualified Gallery.Facet as GF+import qualified Gallery.Geo as GG+import qualified Gallery.Interaction as GI+import qualified Gallery.Label as GLBL+import qualified Gallery.Layer as GLYR+import qualified Gallery.Line as GLN+import qualified Gallery.Multi as GM+import qualified Gallery.Repeat as GR+import qualified Gallery.Scatter as GS+import qualified Gallery.Table as GTBL++-- The "golden" output is "tests/specs/<label>/<name>.vl"+-- where label can now itself contain sub-directories, so should+-- rework this.+--+toTest :: VegaLite -> IO BL8.ByteString+toTest = pure . encodePretty . fromVL++toFP :: String -> String -> FilePath+toFP label tname = "tests" </> "specs" </> label </> (tname <.> ".vl")++-- types don't nicely match up with toFP here, but FilePath and String+-- are aliases so it doesn't cause a problem yet.+--+gallery :: String -> String+gallery = ("gallery" </>)++toTests :: String -> String -> [(String, VegaLite)] -> TestTree+toTests lbl dname tests = testGroup lbl+ [ goldenVsString tname (toFP dname tname) (toTest tspec)+ | (tname, tspec) <- tests+ ]++-- these are placed in the "gallery" sub-directory+toGTests :: String -> String -> [(String, VegaLite)] -> TestTree+toGTests lbl dname = toTests lbl (gallery dname)+++baseTests :: TestTree+baseTests = testGroup "base"+ [ toTests "Axis" "axis" AxT.testSpecs+ , toTests "Color" "color" ColT.testSpecs+ , toTests "Composite" "composite" CompT.testSpecs+ , toTests "Conditional" "conditional" CondT.testSpecs+ , toTests "Config" "config" ConfT.testSpecs+ , toTests "Data" "data" DT.testSpecs+ , toTests "FillStroke" "fillstroke" FST.testSpecs+ , toTests "Geo" "geo" GT.testSpecs+ , toTests "Hyperlink" "hyperlink" HT.testSpecs+ , toTests "Interaction" "interaction" IT.testSpecs+ , toTests "Legend" "legend" LT.testSpecs+ , toTests "Null" "null" NT.testSpecs+ , toTests "Position" "position" PT.testSpecs+ , toTests "Projection" "projection" PjT.testSpecs+ , toTests "Scale" "scale" ScT.testSpecs+ , toTests "Shape" "shape" ShT.testSpecs+ , toTests "Sort" "sort" SoT.testSpecs+ , toTests "TextFormat" "textformat" TfT.testSpecs+ , toTests "Time" "time" TmT.testSpecs+ , toTests "Tooltip" "tooltip" TT.testSpecs+ , toTests "Trail" "trail" TrT.testSpecs+ , toTests "ViewComposition" "viewcomposition" VT.testSpecs+ , toTests "WindowTransform" "windowtransform" WT.testSpecs+ ]++galleryTests :: TestTree+galleryTests = testGroup "Gallery"+ [ toGTests "Advanced" "advanced" GADV.testSpecs+ , toGTests "Area" "area" GA.testSpecs+ , toGTests "Bar" "bar" GB.testSpecs+ , toGTests "Dist" "dist" GD.testSpecs+ , toGTests "Error" "error" GE.testSpecs+ , toGTests "Facet" "facet" GF.testSpecs+ , toGTests "Geo" "geo" GG.testSpecs+ , toGTests "Interaction" "interaction" GI.testSpecs+ , toGTests "Label" "label" GLBL.testSpecs+ , toGTests "Layer" "layer" GLYR.testSpecs+ , toGTests "Line" "line" GLN.testSpecs+ , toGTests "Multi" "multi" GM.testSpecs+ , toGTests "Repeat" "repeat" GR.testSpecs+ , toGTests "Scatter" "scatter" GS.testSpecs+ , toGTests "Table" "table" GTBL.testSpecs+ ]++allTests :: TestTree+allTests = testGroup "Vega-Lite" [baseTests, galleryTests]++main :: IO ()+main = defaultMain allTests
@@ -0,0 +1,83 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite TextFormatTests.elm as of version 1.12.0+--++module TextFormatTests (testSpecs) where++import qualified Data.Text as T++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("textFormat1", textFormat1)+ , ("textFormat2", textFormat2)+ ]++textFormat1 :: VegaLite+textFormat1 =+ let+ xs = map (T.pack . show) [1981 .. 2001 :: Int]+ ys = map (\n -> 2011 + 1991 - n) [1991 .. 2011]+ + dataVals =+ dataFromColumns []+ . dataColumn "a" (Strings xs)+ . dataColumn "b" (Numbers ys)++ encSym =+ encoding+ . position X [ PName "a", PmType Temporal ]+ . position Y [ PName "b", PmType Quantitative ]++ specSym =+ asSpec [ mark Circle [], encSym [] ]++ encLabel =+ encoding+ . position X [ PName "a", PmType Temporal+ , PAxis [ AxFormatAsTemporal+ , AxFormat "%y" ] ]+ . position Y [ PName "b", PmType Quantitative+ , PScale [ SZero False ]+ , PAxis [ AxFormatAsNum+ , AxFormat ".2f" ] ]+ . text [ TName "a", TmType Temporal+ , TFormatAsTemporal+ , TFormat "%b `%y" ]+ . color [ MName "a", MmType Temporal+ , MLegend [ LFormatAsTemporal+ , LFormat "%b %Y" ] ]++ specLabel =+ asSpec [ mark Text [ MdY 4, MdX 22 ], encLabel [] ]+ in+ toVegaLite [ width 600, height 400, dataVals []+ , layer [ specSym, specLabel ] ]++textFormat2 :: VegaLite+textFormat2 =+ let+ dataVals =+ dataFromUrl "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"++ trans =+ transform+ . filter (FExpr "datum.month >= '2016'")++ enc =+ encoding+ . position X [ PName "crimeType", PmType Nominal+ , PAxis [ AxTitle "" ] ]+ . position Y [ PName "reportedCrimes", PmType Quantitative+ , PAggregate Sum ]+ . color [ MName "crimeType", MmType Nominal, MLegend [] ]+ . column [ FName "month", FmType Temporal+ , FHeader [ HFormatAsTemporal+ , HFormat "%b %y" ] ]+ in+ toVegaLite [ width 100, dataVals [], trans []+ , mark Bar [], enc [] ]
@@ -0,0 +1,168 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite TimeTests.elm as of version 1.12.0+--++module TimeTests (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("timeYear", timeYear)+ , ("timeQuarter", timeQuarter)+ , ("timeQuarterMonth", timeQuarterMonth)+ , ("timeMonth", timeMonth)+ , ("timeMonthDate", timeMonthDate)+ , ("timeDate", timeDate)+ , ("timeYearMonthDateHours", timeYearMonthDateHours)+ , ("timeYearMonthDateHoursMinutes", timeYearMonthDateHoursMinutes)+ , ("timeYearMonthDateHoursMinutesSeconds", timeYearMonthDateHoursMinutesSeconds)+ , ("timeDay", timeDay)+ , ("timeHours", timeHours)+ , ("timeHoursMinutes", timeHoursMinutes)+ , ("timeHoursMinutesSeconds", timeHoursMinutesSeconds)+ , ("timeMinutes", timeMinutes)+ , ("timeMinutesSeconds", timeMinutesSeconds)+ , ("localTime", localTime)+ , ("utcTime", utcTime)+ ]+++timeByUnit :: TimeUnit -> VegaLite+timeByUnit tu =+ let+ dataVals =+ dataFromUrl "https://gicentre.github.io/data/tests/timeTest.tsv" []++ enc =+ encoding+ . position X [ PName "date", PmType Temporal, PTimeUnit tu ]+ . position Y [ PName "temperature", PmType Quantitative+ , PAggregate Mean, PScale [ SZero False ] ]+ in+ toVegaLite [ width 800, dataVals, enc []+ , mark Line [ MStrokeWidth 0.2 ] ]+++timeYear :: VegaLite+timeYear = timeByUnit Year+++timeQuarter :: VegaLite+timeQuarter = timeByUnit Quarter+++timeQuarterMonth :: VegaLite+timeQuarterMonth = timeByUnit QuarterMonth+++timeMonth :: VegaLite+timeMonth = timeByUnit Month+++timeMonthDate :: VegaLite+timeMonthDate = timeByUnit MonthDate+++timeDate :: VegaLite+timeDate = timeByUnit Date+++timeYearMonthDateHours :: VegaLite+timeYearMonthDateHours = timeByUnit YearMonthDateHours+++timeYearMonthDateHoursMinutes :: VegaLite+timeYearMonthDateHoursMinutes = timeByUnit YearMonthDateHoursMinutes+++timeYearMonthDateHoursMinutesSeconds :: VegaLite+timeYearMonthDateHoursMinutesSeconds =+ timeByUnit YearMonthDateHoursMinutesSeconds+++timeDay :: VegaLite+timeDay = timeByUnit Day+++timeHours :: VegaLite+timeHours = timeByUnit Hours+++timeHoursMinutes :: VegaLite+timeHoursMinutes = timeByUnit HoursMinutes+++timeHoursMinutesSeconds :: VegaLite+timeHoursMinutesSeconds = timeByUnit HoursMinutesSeconds+++timeMinutes :: VegaLite+timeMinutes = timeByUnit Minutes+++timeMinutesSeconds :: VegaLite+timeMinutesSeconds = timeByUnit MinutesSeconds++-- TODO: Add milliseconds example+-- | SecondsMilliseconds+-- | Milliseconds+++data Date+ = Local+ | UTC+++parseTime :: Date -> VegaLite+parseTime dType =+ let+ format =+ case dType of+ Local ->+ FoDate "%d %b %Y %H:%M"++ UTC ->+ FoUtc "%d %b %Y %H:%M"++ tu =+ case dType of+ Local ->+ PTimeUnit YearMonthDateHours++ UTC ->+ PTimeUnit (Utc YearMonthDateHours)++ timeScale =+ case dType of+ Local ->+ PScale [ SType ScTime ]++ UTC ->+ PScale [ SType ScUtc ]++ dataVals =+ dataFromColumns [ Parse [ ( "date", format ) ] ]+ . dataColumn "date" (Strings [ "28 Oct 2017 22:00", "28 Oct 2017 23:00", "29 Oct 2017 00:00", "29 Oct 2017 01:00", "29 Oct 2017 02:00", "29 Oct 2017 03:00", "29 Oct 2017 04:00" ])+ . dataColumn "value" (Numbers [ 1, 2, 3, 4, 5, 6, 7 ])++ enc =+ encoding+ . position X [ PName "date", PmType Temporal+ , tu, timeScale+ , PAxis [ AxFormat "%d %b %H:%M" ] ]+ . position Y [ PName "value", PmType Quantitative ]+ . size [ MNumber 500 ]+ in+ toVegaLite [ width 800, dataVals [], enc [], mark Circle [] ]+++localTime :: VegaLite+localTime = parseTime Local+++utcTime :: VegaLite+utcTime = parseTime UTC
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite TooltipTests.elm as of version 1.12.0+--+module TooltipTests (testSpecs) where++import Graphics.Vega.VegaLite hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("tooltip1", tooltip1)+ , ("tooltip2", tooltip2)+ ]+ +tooltip1 :: VegaLite+tooltip1 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ . tooltip [ TName "b", TmType Quantitative ]+ in+ toVegaLite [ dataVals [], mark Bar [], enc [] ]++tooltip2 :: VegaLite+tooltip2 =+ let+ dataVals =+ dataFromColumns []+ . dataColumn "a" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I" ])+ . dataColumn "b" (Numbers [ 28, 55, 43, 91, 81, 53, 19, 87, 52 ])++ enc =+ encoding+ . position X [ PName "a", PmType Ordinal ]+ . position Y [ PName "b", PmType Quantitative ]+ . tooltips+ [ [ TName "a", TmType Ordinal ]+ , [ TName "b", TmType Quantitative ]+ ]+ in+ toVegaLite [ dataVals [], mark Bar [], enc [] ]
@@ -0,0 +1,52 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite TrailTests.elm as of version 1.12.0+--+module TrailTests (testSpecs) where++import Graphics.Vega.VegaLite hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("trail1", trail1)+ , ("trail2", trail2)+ ]+++trail1 :: VegaLite+trail1 =+ let+ enc =+ encoding+ . position X [ PName "date", PmType Temporal+ , PAxis [ AxFormat "%Y" ] ]+ . position Y [ PName "price", PmType Quantitative ]+ . size [ MName "price", MmType Quantitative ]+ . color [ MName "symbol", MmType Nominal ]+ in+ toVegaLite+ [ width 400+ , height 400+ , dataFromUrl "https://vega.github.io/vega-lite/data/stocks.csv" []+ , mark Trail []+ , enc []+ ]+++trail2 :: VegaLite+trail2 =+ let+ dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/driving.json"++ enc =+ encoding+ . position X [ PName "miles", PmType Quantitative+ , PScale [ SZero False ] ]+ . position Y [ PName "gas", PmType Quantitative+ , PScale [ SZero False ] ]+ . size [ MName "year", MmType Temporal, MLegend [] ]+ in+ toVegaLite [ dataVals []+ , mark Trail [ MOrder False ]+ , enc [] ]
@@ -0,0 +1,250 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite ViewCompositionTests.elm as of version 1.12.0+--+module ViewCompositionTests (testSpecs) where++import qualified Prelude as P++import Graphics.Vega.VegaLite++import Prelude hiding (filter, repeat)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("columns1", columns1)+ , ("columns2", columns2)+ , ("columns3", columns3)+ , ("columns4", columns4)+ , ("grid1", grid1)+ , ("grid2", grid2)+ , ("grid3", grid3)+ , ("grid4", grid4)+ , ("grid5", grid5)+ ]+++genderChart :: [HeaderProperty] -> [HeaderProperty] -> VegaLite+genderChart hdProps cProps =+ let+ conf =+ configure . configuration (HeaderStyle cProps)++ pop =+ dataFromUrl "https://vega.github.io/vega-lite/data/population.json" []++ trans =+ transform+ . filter (FExpr "datum.year == 2000")+ . calculateAs "datum.sex == 2 ? 'Female' : 'Male'" "gender"++ enc =+ encoding+ . column+ [ FName "gender"+ , FmType Nominal+ , FHeader hdProps+ ]+ . position X+ [ PName "age"+ , PmType Ordinal+ , PScale [ SRangeStep (Just 17) ]+ ]+ . position Y+ [ PName "people"+ , PmType Quantitative+ , PAggregate Sum+ , PAxis [ AxTitle "Population" ]+ ]+ . color+ [ MName "gender"+ , MmType Nominal+ , MScale [ SRange (RStrings [ "#EA98D2", "#659CCA" ]) ]+ ]+ in+ toVegaLite [ conf [], pop, trans [], enc [], mark Bar [] ]+++columns1, columns2, columns3, columns4 :: VegaLite+columns1 = genderChart [] []+columns2 = genderChart [ HTitleFontSize 20, HLabelFontSize 15 ] []+columns3 = genderChart [] [ HTitleFontSize 20, HLabelFontSize 15 ]+columns4 =+ genderChart+ [ HTitleFontSize 20+ , HLabelFontSize 15+ , HTitlePadding (-27)+ , HLabelPadding 40+ ]+ []++-- is this in the prelude+repeatN :: Int -> a -> [a]+repeatN n = take n . P.repeat++dataVals :: [DataColumn] -> Data+dataVals =+ let+ rows =+ Numbers $ concatMap (repeatN (3 * 5)) [ 1, 2, 3, 4 ]++ cols =+ Numbers $ concat $ repeatN 4 $ concatMap (repeatN 3) [ 1, 2, 3, 4, 5 ]++ cats =+ Numbers $ concat $ repeatN (4 * 5) [ 1, 2, 3 ]++ vals =+ Numbers $ [ 30, 15, 12, 25, 30, 25, 10, 28, 11, 18, 24, 16, 10, 10, 10 ]+ ++ [ 8, 8, 29, 11, 24, 12, 26, 32, 9, 8, 18, 28, 8, 20, 24 ]+ ++ [ 21, 15, 20, 4, 13, 12, 27, 21, 14, 5, 1, 2, 11, 2, 5 ]+ ++ [ 14, 20, 24, 20, 2, 9, 15, 14, 13, 22, 30, 30, 10, 8, 12 ]++ in+ dataFromColumns []+ . dataColumn "row" rows+ . dataColumn "col" cols+ . dataColumn "cat" cats+ . dataColumn "val" vals+++grid1 :: VegaLite+grid1 =+ let+ encByCatVal =+ encoding+ . position X [ PName "cat", PmType Ordinal, PAxis [] ]+ . position Y [ PName "val", PmType Quantitative, PAxis [] ]+ . color [ MName "cat", MmType Nominal, MLegend [] ]++ specByCatVal =+ asSpec [ width 120, height 120, mark Bar [], encByCatVal [] ]++ cfg = configure+ . configuration (HeaderStyle [ HLabelFontSize 0.1 ])+ . configuration (View [ ViewStroke Nothing, ViewHeight 120 ])+ . configuration (FacetStyle [ FSpacing 80, FColumns 5 ])++ in+ toVegaLite+ [ cfg []+ , dataVals []+ , spacingRC 20 80+ , specification specByCatVal+ , facet+ [ RowBy [ FName "row", FmType Ordinal, FNoTitle ]+ , ColumnBy [ FName "col", FmType Ordinal, FHeader [ HNoTitle ] ]+ ]+ ]+++grid2 :: VegaLite+grid2 =+ let+ encByCatVal =+ encoding+ . position X [ PName "cat", PmType Ordinal, PAxis [] ]+ . position Y [ PName "val", PmType Quantitative, PAxis [] ]+ . color [ MName "cat", MmType Nominal, MLegend [] ]++ specByCatVal =+ asSpec [ width 120, height 120, mark Bar [], encByCatVal [] ]++ cfg = configure+ . configuration (HeaderStyle [ HLabelFontSize 0.1 ])+ . configuration (View [ ViewStroke Nothing, ViewHeight 120 ])+ . configuration (FacetStyle [ FSpacing 80, FColumns 5 ])++ trans =+ transform+ . calculateAs "datum.row * 1000 + datum.col" "index"+ in+ toVegaLite+ [ cfg []+ , dataVals []+ , trans []+ , columns 5+ , specification specByCatVal+ , facetFlow [ FName "index", FmType Ordinal, FHeader [ HNoTitle ] ]+ ]+++-- This has been changed from the Elm version so that it validates+-- against the v3.4.0 specification.+--+grid3 :: VegaLite+grid3 =+ let+ encByCatVal =+ encoding+ . position X [ PName "cat", PmType Ordinal, PAxis [] ]+ . position Y [ PName "val", PmType Quantitative, PAxis [] ]+ . color [ MName "cat", MmType Nominal, MLegend [] ]++ specByCatVal =+ asSpec [ width 120, height 120, mark Bar [], encByCatVal [] ]++ cfg = configure+ . configuration (HeaderStyle [ HLabelFontSize 0.1 ])+ . configuration (View [ ViewStroke Nothing, ViewHeight 120 ])+ . configuration (FacetStyle [ FSpacing 80 ])++ trans =+ transform+ . calculateAs "datum.row * 1000 + datum.col" "index"+ in+ toVegaLite+ [ cfg []+ , dataVals []+ , trans []+ , columns 5+ , specification specByCatVal+ , facetFlow [ FName "index", FmType Ordinal, FHeader [ HNoTitle ] ]+ ]+++grid4 :: VegaLite+grid4 =+ let+ carData =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ enc =+ encoding+ . position X [ PRepeat Flow, PmType Quantitative, PBin [] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ . color [ MName "Origin", MmType Nominal ]++ spec =+ asSpec [ carData [], mark Bar [], enc [] ]+ in+ toVegaLite+ [ columns 3+ , repeatFlow [ "Horsepower", "Miles_per_Gallon", "Acceleration", "Displacement", "Weight_in_lbs" ]+ , specification spec+ ]+++grid5 :: VegaLite+grid5 =+ let+ carData =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json"++ enc =+ encoding+ . position X [ PRepeat Row, PmType Quantitative, PBin [] ]+ . position Y [ PmType Quantitative, PAggregate Count ]+ . color [ MName "Origin", MmType Nominal ]++ spec =+ asSpec [ carData [], mark Bar [], enc [] ]+ in+ toVegaLite+ [ repeat+ [ RowFields [ "Horsepower", "Miles_per_Gallon", "Acceleration", "Displacement", "Weight_in_lbs" ]+ ]+ , specification spec+ ]++
@@ -0,0 +1,281 @@+{-# LANGUAGE OverloadedStrings #-}++--+-- Based on the Elm VegaLite WindowTransformTests.elm as of version 1.12.0+--+module WindowTransformTests (testSpecs) where++import Graphics.Vega.VegaLite++import Prelude hiding (filter)++testSpecs :: [(String, VegaLite)]+testSpecs = [ ("window1", window1)+ , ("window2", window2)+ , ("window3", window3)+ , ("window4", window4)+ , ("window5", window5)+ , ("window6", window6)+ , ("window7", window7)+ , ("joinAggregate1", joinAggregate1)+ , ("joinAggregate2", joinAggregate2)+ , ("joinAggregate3", joinAggregate3)+ ]++window1 :: VegaLite+window1 =+ let dataVals =+ dataFromColumns []+ . dataColumn "Activity" (Strings [ "Sleeping", "Eating", "TV", "Work", "Exercise" ])+ . dataColumn "Time" (Numbers [ 8, 2, 4, 8, 2 ])++ trans =+ transform+ . window [ ( [ WAggregateOp Sum, WField "Time" ], "TotalTime" ) ]+ [ WFrame Nothing Nothing ]+ . calculateAs "datum.Time/datum.TotalTime * 100" "PercentOfTotal"++ enc =+ encoding+ . position X [ PName "PercentOfTotal", PmType Quantitative, PAxis [ AxTitle "% of total time" ] ]+ . position Y [ PName "Activity", PmType Nominal, PScale [ SRangeStep (Just 12) ] ]+ in+ toVegaLite [ dataVals [], trans [], mark Bar [], enc [] ]+++window2 :: VegaLite+window2 =+ let dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ trans =+ transform+ . filter (FExpr "datum.IMDB_Rating != null")+ . window [ ( [ WAggregateOp Mean, WField "IMDB_Rating" ], "AverageRating" ) ]+ [ WFrame Nothing Nothing ]+ . filter (FExpr "(datum.IMDB_Rating - datum.AverageRating) > 2.5")++ barEnc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [ AxTitle "IMDB Rating" ] ]+ . position Y [ PName "Title", PmType Ordinal ]++ barSpec =+ asSpec [ mark Bar [], barEnc [] ]++ ruleEnc =+ encoding+ . position X [ PName "AverageRating", PAggregate Mean, PmType Quantitative ]++ ruleSpec =+ asSpec [ mark Rule [ MColor "red" ], ruleEnc [] ]+ in+ toVegaLite [ dataVals [], trans [], layer [ barSpec, ruleSpec ] ]+++window3 :: VegaLite+window3 =+ let dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"+ [ Parse [ ( "Release_Date", FoDate "%d-%b-%y" ) ] ]++ trans =+ transform+ . filter (FExpr "datum.IMDB_Rating != null")+ . timeUnitAs Year "Release_Date" "year"+ . window [ ( [ WAggregateOp Mean, WField "IMDB_Rating" ], "AverageYearRating" ) ]+ [ WGroupBy [ "year" ], WFrame Nothing Nothing ]+ . filter (FExpr "(datum.IMDB_Rating - datum.AverageYearRating) > 2.5")++ barEnc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [ AxTitle "IMDB Rating" ] ]+ . position Y [ PName "Title", PmType Ordinal ]++ barSpec =+ asSpec [ mark Bar [ MClip True ], barEnc [] ]++ tickEnc =+ encoding+ . position X [ PName "AverageYearRating", PmType Quantitative ]+ . position Y [ PName "Title", PmType Ordinal ]+ . color [ MString "red" ]++ tickSpec = asSpec [ mark Tick [], tickEnc [] ]+ + in toVegaLite [ dataVals, trans [], layer [ barSpec, tickSpec ] ]+++window4 :: VegaLite+window4 =+ let dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"+ [ Parse [ ( "Release_Date", FoDate "%d-%b-%y" ) ] ]++ trans =+ transform+ . filter (FExpr "datum.IMDB_Rating != null")+ . filter (FRange "Release_Date" (DateRange [] [ DTYear 2019 ]))+ . window [ ( [ WAggregateOp Mean, WField "IMDB_Rating" ], "AverageRating" ) ]+ [ WFrame Nothing Nothing ]+ . calculateAs "datum.IMDB_Rating - datum.AverageRating" "RatingDelta"++ enc =+ encoding+ . position X [ PName "Release_Date", PmType Temporal ]+ . position Y [ PName "RatingDelta", PmType Quantitative, PAxis [ AxTitle "Residual" ] ]+ + in toVegaLite [ dataVals, trans [], enc [], mark Point [ MStrokeWidth 0.3, MOpacity 0.3 ] ]+++window5 :: VegaLite+window5 =+ let dataVals =+ dataFromColumns []+ . dataColumn "team" (Strings [ "Man Utd", "Chelsea", "Man City", "Spurs", "Man Utd", "Chelsea", "Man City", "Spurs", "Man Utd", "Chelsea", "Man City", "Spurs" ])+ . dataColumn "matchday" (Numbers [ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ])+ . dataColumn "point" (Numbers [ 3, 1, 1, 0, 6, 1, 0, 3, 9, 1, 0, 6 ])++ trans =+ transform+ . window+ [ ( [ WOp Rank ], "rank" ) ]+ [ WSort [ WDescending "point" ], WGroupBy [ "matchday" ] ]++ enc =+ encoding+ . position X [ PName "matchday", PmType Ordinal ]+ . position Y [ PName "rank", PmType Ordinal ]+ . color [ MName "team", MmType Nominal, MScale teamColours ]++ teamColours =+ categoricalDomainMap+ [ ( "Man Utd", "#cc2613" )+ , ( "Chelsea", "#125dc7" )+ , ( "Man City", "#8bcdfc" )+ , ( "Spurs", "#d1d1d1" )+ ]+ + in toVegaLite [ width 400, height 400, dataVals [], trans [], enc [], mark Line [ MOrient Vertical ] ]+++window6 :: VegaLite+window6 =+ let dataVals =+ dataFromColumns []+ . dataColumn "student" (Strings [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V" ])+ . dataColumn "score" (Numbers [ 100, 56, 88, 65, 45, 23, 66, 67, 13, 12, 50, 78, 66, 30, 97, 75, 24, 42, 76, 78, 21, 46 ])++ trans =+ transform+ . window [ ( [ WOp Rank ], "rank" ) ] [ WSort [ WDescending "score" ] ]+ . filter (FExpr "datum.rank <= 5")++ enc =+ encoding+ . position X [ PName "score", PmType Quantitative ]+ . position Y+ [ PName "student"+ , PmType Nominal+ , PSort [ ByFieldOp "score" Mean, Descending ]+ ]+ + in toVegaLite [ dataVals [], trans [], enc [], mark Bar [] ]++window7 :: VegaLite+window7 =+ let dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/cars.json" []++ trans =+ transform+ . filter (FExpr "datum.Miles_per_Gallon !== null")+ . timeUnitAs Year "Year" "year"+ . window [ ( [ WAggregateOp Mean, WField "Miles_per_Gallon" ], "Average_MPG" ) ]+ [ WSort [ WAscending "year" ], WIgnorePeers False, WFrame Nothing (Just 0) ]++ circleEnc =+ encoding+ . position X [ PName "Year", PmType Temporal, PTimeUnit Year ]+ . position Y [ PName "Miles_per_Gallon", PmType Quantitative ]++ circleSpec =+ asSpec [ mark Circle [], circleEnc [] ]++ lineEnc =+ encoding+ . position X [ PName "Year", PmType Temporal, PTimeUnit Year ]+ . position Y [ PName "Average_MPG", PmType Quantitative, PAxis [ AxTitle "Miles per gallon" ] ]++ lineSpec =+ asSpec [ mark Line [ MColor "red" ], lineEnc [] ]+ + in toVegaLite [ width 500, height 400, dataVals, trans [], layer [ circleSpec, lineSpec ] ]+++joinAggregate1 :: VegaLite+joinAggregate1 =+ let dataVals =+ dataFromColumns []+ . dataColumn "Activity" (Strings [ "Sleeping", "Eating", "TV", "Work", "Exercise" ])+ . dataColumn "Time" (Numbers [ 8, 2, 4, 8, 2 ])++ trans =+ transform+ . joinAggregate [ opAs Sum "Time" "TotalTime" ] []+ . calculateAs "datum.Time/datum.TotalTime * 100" "PercentOfTotal"++ enc =+ encoding+ . position X [ PName "PercentOfTotal", PmType Quantitative, PAxis [ AxTitle "% of total Time" ] ]+ . position Y [ PName "Activity", PmType Nominal, PScale [ SRangeStep (Just 12) ] ]+ + in toVegaLite [ dataVals [], trans [], enc [], mark Bar [] ]++joinAggregate2 :: VegaLite+joinAggregate2 =+ let dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ trans =+ transform+ . filter (FExpr "datum.IMDB_Rating != null")+ . joinAggregate [ opAs Mean "IMDB_Rating" "AverageRating" ] []+ . filter (FExpr "(datum.IMDB_Rating - datum.AverageRating) > 2.5")++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [ AxTitle "IMDB Rating" ] ]+ . position Y+ [ PName "Title"+ , PmType Nominal+ , PAxis [ AxTitle "" ]+ , PSort [ ByChannel ChX, Descending ]+ ]+ + in toVegaLite [ dataVals [], trans [], enc [], mark Bar [] ]++joinAggregate3 :: VegaLite+joinAggregate3 =+ let dataVals =+ dataFromUrl "https://vega.github.io/vega-lite/data/movies.json"++ trans =+ transform+ . filter (FExpr "datum.IMDB_Rating != null")+ . timeUnitAs Year "Release_Date" "year"+ . joinAggregate [ opAs Mean "IMDB_Rating" "AverageYearRating" ]+ [ WGroupBy [ "year" ] ]+ . filter (FExpr "(datum.IMDB_Rating - datum.AverageYearRating) > 2.5")++ enc =+ encoding+ . position X [ PName "IMDB_Rating", PmType Quantitative, PAxis [ AxTitle "IMDB Rating" ] ]+ . position Y+ [ PName "Title"+ , PmType Nominal+ , PAxis [ AxTitle "" ]+ , PSort [ ByChannel ChX, Descending ]+ ]+ + in toVegaLite [ dataVals [], trans [], enc [], mark Bar [] ]
@@ -0,0 +1,521 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "catX": "1",+ "y": 1+ },+ {+ "x": 2,+ "catX": "2",+ "y": 2+ },+ {+ "x": 3,+ "catX": "3",+ "y": 3+ },+ {+ "x": 4,+ "catX": "4",+ "y": 4+ },+ {+ "x": 5,+ "catX": "5",+ "y": 5+ },+ {+ "x": 6,+ "catX": "6",+ "y": 6+ },+ {+ "x": 7,+ "catX": "7",+ "y": 7+ },+ {+ "x": 8,+ "catX": "8",+ "y": 8+ },+ {+ "x": 9,+ "catX": "9",+ "y": 9+ },+ {+ "x": 10,+ "catX": "10",+ "y": 10+ },+ {+ "x": 11,+ "catX": "11",+ "y": 11+ },+ {+ "x": 12,+ "catX": "12",+ "y": 12+ },+ {+ "x": 13,+ "catX": "13",+ "y": 13+ },+ {+ "x": 14,+ "catX": "14",+ "y": 14+ },+ {+ "x": 15,+ "catX": "15",+ "y": 15+ },+ {+ "x": 16,+ "catX": "16",+ "y": 16+ },+ {+ "x": 17,+ "catX": "17",+ "y": 17+ },+ {+ "x": 18,+ "catX": "18",+ "y": 18+ },+ {+ "x": 19,+ "catX": "19",+ "y": 19+ },+ {+ "x": 20,+ "catX": "20",+ "y": 20+ },+ {+ "x": 21,+ "catX": "21",+ "y": 21+ },+ {+ "x": 22,+ "catX": "22",+ "y": 22+ },+ {+ "x": 23,+ "catX": "23",+ "y": 23+ },+ {+ "x": 24,+ "catX": "24",+ "y": 24+ },+ {+ "x": 25,+ "catX": "25",+ "y": 25+ },+ {+ "x": 26,+ "catX": "26",+ "y": 26+ },+ {+ "x": 27,+ "catX": "27",+ "y": 27+ },+ {+ "x": 28,+ "catX": "28",+ "y": 28+ },+ {+ "x": 29,+ "catX": "29",+ "y": 29+ },+ {+ "x": 30,+ "catX": "30",+ "y": 30+ },+ {+ "x": 31,+ "catX": "31",+ "y": 31+ },+ {+ "x": 32,+ "catX": "32",+ "y": 32+ },+ {+ "x": 33,+ "catX": "33",+ "y": 33+ },+ {+ "x": 34,+ "catX": "34",+ "y": 34+ },+ {+ "x": 35,+ "catX": "35",+ "y": 35+ },+ {+ "x": 36,+ "catX": "36",+ "y": 36+ },+ {+ "x": 37,+ "catX": "37",+ "y": 37+ },+ {+ "x": 38,+ "catX": "38",+ "y": 38+ },+ {+ "x": 39,+ "catX": "39",+ "y": 39+ },+ {+ "x": 40,+ "catX": "40",+ "y": 40+ },+ {+ "x": 41,+ "catX": "41",+ "y": 41+ },+ {+ "x": 42,+ "catX": "42",+ "y": 42+ },+ {+ "x": 43,+ "catX": "43",+ "y": 43+ },+ {+ "x": 44,+ "catX": "44",+ "y": 44+ },+ {+ "x": 45,+ "catX": "45",+ "y": 45+ },+ {+ "x": 46,+ "catX": "46",+ "y": 46+ },+ {+ "x": 47,+ "catX": "47",+ "y": 47+ },+ {+ "x": 48,+ "catX": "48",+ "y": 48+ },+ {+ "x": 49,+ "catX": "49",+ "y": 49+ },+ {+ "x": 50,+ "catX": "50",+ "y": 50+ },+ {+ "x": 51,+ "catX": "51",+ "y": 51+ },+ {+ "x": 52,+ "catX": "52",+ "y": 52+ },+ {+ "x": 53,+ "catX": "53",+ "y": 53+ },+ {+ "x": 54,+ "catX": "54",+ "y": 54+ },+ {+ "x": 55,+ "catX": "55",+ "y": 55+ },+ {+ "x": 56,+ "catX": "56",+ "y": 56+ },+ {+ "x": 57,+ "catX": "57",+ "y": 57+ },+ {+ "x": 58,+ "catX": "58",+ "y": 58+ },+ {+ "x": 59,+ "catX": "59",+ "y": 59+ },+ {+ "x": 60,+ "catX": "60",+ "y": 60+ },+ {+ "x": 61,+ "catX": "61",+ "y": 61+ },+ {+ "x": 62,+ "catX": "62",+ "y": 62+ },+ {+ "x": 63,+ "catX": "63",+ "y": 63+ },+ {+ "x": 64,+ "catX": "64",+ "y": 64+ },+ {+ "x": 65,+ "catX": "65",+ "y": 65+ },+ {+ "x": 66,+ "catX": "66",+ "y": 66+ },+ {+ "x": 67,+ "catX": "67",+ "y": 67+ },+ {+ "x": 68,+ "catX": "68",+ "y": 68+ },+ {+ "x": 69,+ "catX": "69",+ "y": 69+ },+ {+ "x": 70,+ "catX": "70",+ "y": 70+ },+ {+ "x": 71,+ "catX": "71",+ "y": 71+ },+ {+ "x": 72,+ "catX": "72",+ "y": 72+ },+ {+ "x": 73,+ "catX": "73",+ "y": 73+ },+ {+ "x": 74,+ "catX": "74",+ "y": 74+ },+ {+ "x": 75,+ "catX": "75",+ "y": 75+ },+ {+ "x": 76,+ "catX": "76",+ "y": 76+ },+ {+ "x": 77,+ "catX": "77",+ "y": 77+ },+ {+ "x": 78,+ "catX": "78",+ "y": 78+ },+ {+ "x": 79,+ "catX": "79",+ "y": 79+ },+ {+ "x": 80,+ "catX": "80",+ "y": 80+ },+ {+ "x": 81,+ "catX": "81",+ "y": 81+ },+ {+ "x": 82,+ "catX": "82",+ "y": 82+ },+ {+ "x": 83,+ "catX": "83",+ "y": 83+ },+ {+ "x": 84,+ "catX": "84",+ "y": 84+ },+ {+ "x": 85,+ "catX": "85",+ "y": 85+ },+ {+ "x": 86,+ "catX": "86",+ "y": 86+ },+ {+ "x": 87,+ "catX": "87",+ "y": 87+ },+ {+ "x": 88,+ "catX": "88",+ "y": 88+ },+ {+ "x": 89,+ "catX": "89",+ "y": 89+ },+ {+ "x": 90,+ "catX": "90",+ "y": 90+ },+ {+ "x": 91,+ "catX": "91",+ "y": 91+ },+ {+ "x": 92,+ "catX": "92",+ "y": 92+ },+ {+ "x": 93,+ "catX": "93",+ "y": 93+ },+ {+ "x": 94,+ "catX": "94",+ "y": 94+ },+ {+ "x": 95,+ "catX": "95",+ "y": 95+ },+ {+ "x": 96,+ "catX": "96",+ "y": 96+ },+ {+ "x": 97,+ "catX": "97",+ "y": 97+ },+ {+ "x": 98,+ "catX": "98",+ "y": 98+ },+ {+ "x": 99,+ "catX": "99",+ "y": 99+ },+ {+ "x": 100,+ "catX": "100",+ "y": 100+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,521 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "catX": "1",+ "y": 1+ },+ {+ "x": 2,+ "catX": "2",+ "y": 2+ },+ {+ "x": 3,+ "catX": "3",+ "y": 3+ },+ {+ "x": 4,+ "catX": "4",+ "y": 4+ },+ {+ "x": 5,+ "catX": "5",+ "y": 5+ },+ {+ "x": 6,+ "catX": "6",+ "y": 6+ },+ {+ "x": 7,+ "catX": "7",+ "y": 7+ },+ {+ "x": 8,+ "catX": "8",+ "y": 8+ },+ {+ "x": 9,+ "catX": "9",+ "y": 9+ },+ {+ "x": 10,+ "catX": "10",+ "y": 10+ },+ {+ "x": 11,+ "catX": "11",+ "y": 11+ },+ {+ "x": 12,+ "catX": "12",+ "y": 12+ },+ {+ "x": 13,+ "catX": "13",+ "y": 13+ },+ {+ "x": 14,+ "catX": "14",+ "y": 14+ },+ {+ "x": 15,+ "catX": "15",+ "y": 15+ },+ {+ "x": 16,+ "catX": "16",+ "y": 16+ },+ {+ "x": 17,+ "catX": "17",+ "y": 17+ },+ {+ "x": 18,+ "catX": "18",+ "y": 18+ },+ {+ "x": 19,+ "catX": "19",+ "y": 19+ },+ {+ "x": 20,+ "catX": "20",+ "y": 20+ },+ {+ "x": 21,+ "catX": "21",+ "y": 21+ },+ {+ "x": 22,+ "catX": "22",+ "y": 22+ },+ {+ "x": 23,+ "catX": "23",+ "y": 23+ },+ {+ "x": 24,+ "catX": "24",+ "y": 24+ },+ {+ "x": 25,+ "catX": "25",+ "y": 25+ },+ {+ "x": 26,+ "catX": "26",+ "y": 26+ },+ {+ "x": 27,+ "catX": "27",+ "y": 27+ },+ {+ "x": 28,+ "catX": "28",+ "y": 28+ },+ {+ "x": 29,+ "catX": "29",+ "y": 29+ },+ {+ "x": 30,+ "catX": "30",+ "y": 30+ },+ {+ "x": 31,+ "catX": "31",+ "y": 31+ },+ {+ "x": 32,+ "catX": "32",+ "y": 32+ },+ {+ "x": 33,+ "catX": "33",+ "y": 33+ },+ {+ "x": 34,+ "catX": "34",+ "y": 34+ },+ {+ "x": 35,+ "catX": "35",+ "y": 35+ },+ {+ "x": 36,+ "catX": "36",+ "y": 36+ },+ {+ "x": 37,+ "catX": "37",+ "y": 37+ },+ {+ "x": 38,+ "catX": "38",+ "y": 38+ },+ {+ "x": 39,+ "catX": "39",+ "y": 39+ },+ {+ "x": 40,+ "catX": "40",+ "y": 40+ },+ {+ "x": 41,+ "catX": "41",+ "y": 41+ },+ {+ "x": 42,+ "catX": "42",+ "y": 42+ },+ {+ "x": 43,+ "catX": "43",+ "y": 43+ },+ {+ "x": 44,+ "catX": "44",+ "y": 44+ },+ {+ "x": 45,+ "catX": "45",+ "y": 45+ },+ {+ "x": 46,+ "catX": "46",+ "y": 46+ },+ {+ "x": 47,+ "catX": "47",+ "y": 47+ },+ {+ "x": 48,+ "catX": "48",+ "y": 48+ },+ {+ "x": 49,+ "catX": "49",+ "y": 49+ },+ {+ "x": 50,+ "catX": "50",+ "y": 50+ },+ {+ "x": 51,+ "catX": "51",+ "y": 51+ },+ {+ "x": 52,+ "catX": "52",+ "y": 52+ },+ {+ "x": 53,+ "catX": "53",+ "y": 53+ },+ {+ "x": 54,+ "catX": "54",+ "y": 54+ },+ {+ "x": 55,+ "catX": "55",+ "y": 55+ },+ {+ "x": 56,+ "catX": "56",+ "y": 56+ },+ {+ "x": 57,+ "catX": "57",+ "y": 57+ },+ {+ "x": 58,+ "catX": "58",+ "y": 58+ },+ {+ "x": 59,+ "catX": "59",+ "y": 59+ },+ {+ "x": 60,+ "catX": "60",+ "y": 60+ },+ {+ "x": 61,+ "catX": "61",+ "y": 61+ },+ {+ "x": 62,+ "catX": "62",+ "y": 62+ },+ {+ "x": 63,+ "catX": "63",+ "y": 63+ },+ {+ "x": 64,+ "catX": "64",+ "y": 64+ },+ {+ "x": 65,+ "catX": "65",+ "y": 65+ },+ {+ "x": 66,+ "catX": "66",+ "y": 66+ },+ {+ "x": 67,+ "catX": "67",+ "y": 67+ },+ {+ "x": 68,+ "catX": "68",+ "y": 68+ },+ {+ "x": 69,+ "catX": "69",+ "y": 69+ },+ {+ "x": 70,+ "catX": "70",+ "y": 70+ },+ {+ "x": 71,+ "catX": "71",+ "y": 71+ },+ {+ "x": 72,+ "catX": "72",+ "y": 72+ },+ {+ "x": 73,+ "catX": "73",+ "y": 73+ },+ {+ "x": 74,+ "catX": "74",+ "y": 74+ },+ {+ "x": 75,+ "catX": "75",+ "y": 75+ },+ {+ "x": 76,+ "catX": "76",+ "y": 76+ },+ {+ "x": 77,+ "catX": "77",+ "y": 77+ },+ {+ "x": 78,+ "catX": "78",+ "y": 78+ },+ {+ "x": 79,+ "catX": "79",+ "y": 79+ },+ {+ "x": 80,+ "catX": "80",+ "y": 80+ },+ {+ "x": 81,+ "catX": "81",+ "y": 81+ },+ {+ "x": 82,+ "catX": "82",+ "y": 82+ },+ {+ "x": 83,+ "catX": "83",+ "y": 83+ },+ {+ "x": 84,+ "catX": "84",+ "y": 84+ },+ {+ "x": 85,+ "catX": "85",+ "y": 85+ },+ {+ "x": 86,+ "catX": "86",+ "y": 86+ },+ {+ "x": 87,+ "catX": "87",+ "y": 87+ },+ {+ "x": 88,+ "catX": "88",+ "y": 88+ },+ {+ "x": 89,+ "catX": "89",+ "y": 89+ },+ {+ "x": 90,+ "catX": "90",+ "y": 90+ },+ {+ "x": 91,+ "catX": "91",+ "y": 91+ },+ {+ "x": 92,+ "catX": "92",+ "y": 92+ },+ {+ "x": 93,+ "catX": "93",+ "y": 93+ },+ {+ "x": 94,+ "catX": "94",+ "y": 94+ },+ {+ "x": 95,+ "catX": "95",+ "y": 95+ },+ {+ "x": 96,+ "catX": "96",+ "y": 96+ },+ {+ "x": 97,+ "catX": "97",+ "y": 97+ },+ {+ "x": 98,+ "catX": "98",+ "y": 98+ },+ {+ "x": 99,+ "catX": "99",+ "y": 99+ },+ {+ "x": 100,+ "catX": "100",+ "y": 100+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "catX",+ "type": "ordinal"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,521 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "catX": "1",+ "y": 1+ },+ {+ "x": 2,+ "catX": "2",+ "y": 2+ },+ {+ "x": 3,+ "catX": "3",+ "y": 3+ },+ {+ "x": 4,+ "catX": "4",+ "y": 4+ },+ {+ "x": 5,+ "catX": "5",+ "y": 5+ },+ {+ "x": 6,+ "catX": "6",+ "y": 6+ },+ {+ "x": 7,+ "catX": "7",+ "y": 7+ },+ {+ "x": 8,+ "catX": "8",+ "y": 8+ },+ {+ "x": 9,+ "catX": "9",+ "y": 9+ },+ {+ "x": 10,+ "catX": "10",+ "y": 10+ },+ {+ "x": 11,+ "catX": "11",+ "y": 11+ },+ {+ "x": 12,+ "catX": "12",+ "y": 12+ },+ {+ "x": 13,+ "catX": "13",+ "y": 13+ },+ {+ "x": 14,+ "catX": "14",+ "y": 14+ },+ {+ "x": 15,+ "catX": "15",+ "y": 15+ },+ {+ "x": 16,+ "catX": "16",+ "y": 16+ },+ {+ "x": 17,+ "catX": "17",+ "y": 17+ },+ {+ "x": 18,+ "catX": "18",+ "y": 18+ },+ {+ "x": 19,+ "catX": "19",+ "y": 19+ },+ {+ "x": 20,+ "catX": "20",+ "y": 20+ },+ {+ "x": 21,+ "catX": "21",+ "y": 21+ },+ {+ "x": 22,+ "catX": "22",+ "y": 22+ },+ {+ "x": 23,+ "catX": "23",+ "y": 23+ },+ {+ "x": 24,+ "catX": "24",+ "y": 24+ },+ {+ "x": 25,+ "catX": "25",+ "y": 25+ },+ {+ "x": 26,+ "catX": "26",+ "y": 26+ },+ {+ "x": 27,+ "catX": "27",+ "y": 27+ },+ {+ "x": 28,+ "catX": "28",+ "y": 28+ },+ {+ "x": 29,+ "catX": "29",+ "y": 29+ },+ {+ "x": 30,+ "catX": "30",+ "y": 30+ },+ {+ "x": 31,+ "catX": "31",+ "y": 31+ },+ {+ "x": 32,+ "catX": "32",+ "y": 32+ },+ {+ "x": 33,+ "catX": "33",+ "y": 33+ },+ {+ "x": 34,+ "catX": "34",+ "y": 34+ },+ {+ "x": 35,+ "catX": "35",+ "y": 35+ },+ {+ "x": 36,+ "catX": "36",+ "y": 36+ },+ {+ "x": 37,+ "catX": "37",+ "y": 37+ },+ {+ "x": 38,+ "catX": "38",+ "y": 38+ },+ {+ "x": 39,+ "catX": "39",+ "y": 39+ },+ {+ "x": 40,+ "catX": "40",+ "y": 40+ },+ {+ "x": 41,+ "catX": "41",+ "y": 41+ },+ {+ "x": 42,+ "catX": "42",+ "y": 42+ },+ {+ "x": 43,+ "catX": "43",+ "y": 43+ },+ {+ "x": 44,+ "catX": "44",+ "y": 44+ },+ {+ "x": 45,+ "catX": "45",+ "y": 45+ },+ {+ "x": 46,+ "catX": "46",+ "y": 46+ },+ {+ "x": 47,+ "catX": "47",+ "y": 47+ },+ {+ "x": 48,+ "catX": "48",+ "y": 48+ },+ {+ "x": 49,+ "catX": "49",+ "y": 49+ },+ {+ "x": 50,+ "catX": "50",+ "y": 50+ },+ {+ "x": 51,+ "catX": "51",+ "y": 51+ },+ {+ "x": 52,+ "catX": "52",+ "y": 52+ },+ {+ "x": 53,+ "catX": "53",+ "y": 53+ },+ {+ "x": 54,+ "catX": "54",+ "y": 54+ },+ {+ "x": 55,+ "catX": "55",+ "y": 55+ },+ {+ "x": 56,+ "catX": "56",+ "y": 56+ },+ {+ "x": 57,+ "catX": "57",+ "y": 57+ },+ {+ "x": 58,+ "catX": "58",+ "y": 58+ },+ {+ "x": 59,+ "catX": "59",+ "y": 59+ },+ {+ "x": 60,+ "catX": "60",+ "y": 60+ },+ {+ "x": 61,+ "catX": "61",+ "y": 61+ },+ {+ "x": 62,+ "catX": "62",+ "y": 62+ },+ {+ "x": 63,+ "catX": "63",+ "y": 63+ },+ {+ "x": 64,+ "catX": "64",+ "y": 64+ },+ {+ "x": 65,+ "catX": "65",+ "y": 65+ },+ {+ "x": 66,+ "catX": "66",+ "y": 66+ },+ {+ "x": 67,+ "catX": "67",+ "y": 67+ },+ {+ "x": 68,+ "catX": "68",+ "y": 68+ },+ {+ "x": 69,+ "catX": "69",+ "y": 69+ },+ {+ "x": 70,+ "catX": "70",+ "y": 70+ },+ {+ "x": 71,+ "catX": "71",+ "y": 71+ },+ {+ "x": 72,+ "catX": "72",+ "y": 72+ },+ {+ "x": 73,+ "catX": "73",+ "y": 73+ },+ {+ "x": 74,+ "catX": "74",+ "y": 74+ },+ {+ "x": 75,+ "catX": "75",+ "y": 75+ },+ {+ "x": 76,+ "catX": "76",+ "y": 76+ },+ {+ "x": 77,+ "catX": "77",+ "y": 77+ },+ {+ "x": 78,+ "catX": "78",+ "y": 78+ },+ {+ "x": 79,+ "catX": "79",+ "y": 79+ },+ {+ "x": 80,+ "catX": "80",+ "y": 80+ },+ {+ "x": 81,+ "catX": "81",+ "y": 81+ },+ {+ "x": 82,+ "catX": "82",+ "y": 82+ },+ {+ "x": 83,+ "catX": "83",+ "y": 83+ },+ {+ "x": 84,+ "catX": "84",+ "y": 84+ },+ {+ "x": 85,+ "catX": "85",+ "y": 85+ },+ {+ "x": 86,+ "catX": "86",+ "y": 86+ },+ {+ "x": 87,+ "catX": "87",+ "y": 87+ },+ {+ "x": 88,+ "catX": "88",+ "y": 88+ },+ {+ "x": 89,+ "catX": "89",+ "y": 89+ },+ {+ "x": 90,+ "catX": "90",+ "y": 90+ },+ {+ "x": 91,+ "catX": "91",+ "y": 91+ },+ {+ "x": 92,+ "catX": "92",+ "y": 92+ },+ {+ "x": 93,+ "catX": "93",+ "y": 93+ },+ {+ "x": 94,+ "catX": "94",+ "y": 94+ },+ {+ "x": 95,+ "catX": "95",+ "y": 95+ },+ {+ "x": 96,+ "catX": "96",+ "y": 96+ },+ {+ "x": 97,+ "catX": "97",+ "y": 97+ },+ {+ "x": 98,+ "catX": "98",+ "y": 98+ },+ {+ "x": 99,+ "catX": "99",+ "y": 99+ },+ {+ "x": 100,+ "catX": "100",+ "y": 100+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,529 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "catX": "1",+ "y": 1+ },+ {+ "x": 2,+ "catX": "2",+ "y": 2+ },+ {+ "x": 3,+ "catX": "3",+ "y": 3+ },+ {+ "x": 4,+ "catX": "4",+ "y": 4+ },+ {+ "x": 5,+ "catX": "5",+ "y": 5+ },+ {+ "x": 6,+ "catX": "6",+ "y": 6+ },+ {+ "x": 7,+ "catX": "7",+ "y": 7+ },+ {+ "x": 8,+ "catX": "8",+ "y": 8+ },+ {+ "x": 9,+ "catX": "9",+ "y": 9+ },+ {+ "x": 10,+ "catX": "10",+ "y": 10+ },+ {+ "x": 11,+ "catX": "11",+ "y": 11+ },+ {+ "x": 12,+ "catX": "12",+ "y": 12+ },+ {+ "x": 13,+ "catX": "13",+ "y": 13+ },+ {+ "x": 14,+ "catX": "14",+ "y": 14+ },+ {+ "x": 15,+ "catX": "15",+ "y": 15+ },+ {+ "x": 16,+ "catX": "16",+ "y": 16+ },+ {+ "x": 17,+ "catX": "17",+ "y": 17+ },+ {+ "x": 18,+ "catX": "18",+ "y": 18+ },+ {+ "x": 19,+ "catX": "19",+ "y": 19+ },+ {+ "x": 20,+ "catX": "20",+ "y": 20+ },+ {+ "x": 21,+ "catX": "21",+ "y": 21+ },+ {+ "x": 22,+ "catX": "22",+ "y": 22+ },+ {+ "x": 23,+ "catX": "23",+ "y": 23+ },+ {+ "x": 24,+ "catX": "24",+ "y": 24+ },+ {+ "x": 25,+ "catX": "25",+ "y": 25+ },+ {+ "x": 26,+ "catX": "26",+ "y": 26+ },+ {+ "x": 27,+ "catX": "27",+ "y": 27+ },+ {+ "x": 28,+ "catX": "28",+ "y": 28+ },+ {+ "x": 29,+ "catX": "29",+ "y": 29+ },+ {+ "x": 30,+ "catX": "30",+ "y": 30+ },+ {+ "x": 31,+ "catX": "31",+ "y": 31+ },+ {+ "x": 32,+ "catX": "32",+ "y": 32+ },+ {+ "x": 33,+ "catX": "33",+ "y": 33+ },+ {+ "x": 34,+ "catX": "34",+ "y": 34+ },+ {+ "x": 35,+ "catX": "35",+ "y": 35+ },+ {+ "x": 36,+ "catX": "36",+ "y": 36+ },+ {+ "x": 37,+ "catX": "37",+ "y": 37+ },+ {+ "x": 38,+ "catX": "38",+ "y": 38+ },+ {+ "x": 39,+ "catX": "39",+ "y": 39+ },+ {+ "x": 40,+ "catX": "40",+ "y": 40+ },+ {+ "x": 41,+ "catX": "41",+ "y": 41+ },+ {+ "x": 42,+ "catX": "42",+ "y": 42+ },+ {+ "x": 43,+ "catX": "43",+ "y": 43+ },+ {+ "x": 44,+ "catX": "44",+ "y": 44+ },+ {+ "x": 45,+ "catX": "45",+ "y": 45+ },+ {+ "x": 46,+ "catX": "46",+ "y": 46+ },+ {+ "x": 47,+ "catX": "47",+ "y": 47+ },+ {+ "x": 48,+ "catX": "48",+ "y": 48+ },+ {+ "x": 49,+ "catX": "49",+ "y": 49+ },+ {+ "x": 50,+ "catX": "50",+ "y": 50+ },+ {+ "x": 51,+ "catX": "51",+ "y": 51+ },+ {+ "x": 52,+ "catX": "52",+ "y": 52+ },+ {+ "x": 53,+ "catX": "53",+ "y": 53+ },+ {+ "x": 54,+ "catX": "54",+ "y": 54+ },+ {+ "x": 55,+ "catX": "55",+ "y": 55+ },+ {+ "x": 56,+ "catX": "56",+ "y": 56+ },+ {+ "x": 57,+ "catX": "57",+ "y": 57+ },+ {+ "x": 58,+ "catX": "58",+ "y": 58+ },+ {+ "x": 59,+ "catX": "59",+ "y": 59+ },+ {+ "x": 60,+ "catX": "60",+ "y": 60+ },+ {+ "x": 61,+ "catX": "61",+ "y": 61+ },+ {+ "x": 62,+ "catX": "62",+ "y": 62+ },+ {+ "x": 63,+ "catX": "63",+ "y": 63+ },+ {+ "x": 64,+ "catX": "64",+ "y": 64+ },+ {+ "x": 65,+ "catX": "65",+ "y": 65+ },+ {+ "x": 66,+ "catX": "66",+ "y": 66+ },+ {+ "x": 67,+ "catX": "67",+ "y": 67+ },+ {+ "x": 68,+ "catX": "68",+ "y": 68+ },+ {+ "x": 69,+ "catX": "69",+ "y": 69+ },+ {+ "x": 70,+ "catX": "70",+ "y": 70+ },+ {+ "x": 71,+ "catX": "71",+ "y": 71+ },+ {+ "x": 72,+ "catX": "72",+ "y": 72+ },+ {+ "x": 73,+ "catX": "73",+ "y": 73+ },+ {+ "x": 74,+ "catX": "74",+ "y": 74+ },+ {+ "x": 75,+ "catX": "75",+ "y": 75+ },+ {+ "x": 76,+ "catX": "76",+ "y": 76+ },+ {+ "x": 77,+ "catX": "77",+ "y": 77+ },+ {+ "x": 78,+ "catX": "78",+ "y": 78+ },+ {+ "x": 79,+ "catX": "79",+ "y": 79+ },+ {+ "x": 80,+ "catX": "80",+ "y": 80+ },+ {+ "x": 81,+ "catX": "81",+ "y": 81+ },+ {+ "x": 82,+ "catX": "82",+ "y": 82+ },+ {+ "x": 83,+ "catX": "83",+ "y": 83+ },+ {+ "x": 84,+ "catX": "84",+ "y": 84+ },+ {+ "x": 85,+ "catX": "85",+ "y": 85+ },+ {+ "x": 86,+ "catX": "86",+ "y": 86+ },+ {+ "x": 87,+ "catX": "87",+ "y": 87+ },+ {+ "x": 88,+ "catX": "88",+ "y": 88+ },+ {+ "x": 89,+ "catX": "89",+ "y": 89+ },+ {+ "x": 90,+ "catX": "90",+ "y": 90+ },+ {+ "x": 91,+ "catX": "91",+ "y": 91+ },+ {+ "x": 92,+ "catX": "92",+ "y": 92+ },+ {+ "x": 93,+ "catX": "93",+ "y": 93+ },+ {+ "x": 94,+ "catX": "94",+ "y": 94+ },+ {+ "x": 95,+ "catX": "95",+ "y": 95+ },+ {+ "x": 96,+ "catX": "96",+ "y": 96+ },+ {+ "x": 97,+ "catX": "97",+ "y": 97+ },+ {+ "x": 98,+ "catX": "98",+ "y": 98+ },+ {+ "x": 99,+ "catX": "99",+ "y": 99+ },+ {+ "x": 100,+ "catX": "100",+ "y": 100+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "type": "quantitative",+ "axis": {+ "values": [+ 1,+ 25,+ 39,+ 90+ ]+ }+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,530 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "catX": "1",+ "y": 1+ },+ {+ "x": 2,+ "catX": "2",+ "y": 2+ },+ {+ "x": 3,+ "catX": "3",+ "y": 3+ },+ {+ "x": 4,+ "catX": "4",+ "y": 4+ },+ {+ "x": 5,+ "catX": "5",+ "y": 5+ },+ {+ "x": 6,+ "catX": "6",+ "y": 6+ },+ {+ "x": 7,+ "catX": "7",+ "y": 7+ },+ {+ "x": 8,+ "catX": "8",+ "y": 8+ },+ {+ "x": 9,+ "catX": "9",+ "y": 9+ },+ {+ "x": 10,+ "catX": "10",+ "y": 10+ },+ {+ "x": 11,+ "catX": "11",+ "y": 11+ },+ {+ "x": 12,+ "catX": "12",+ "y": 12+ },+ {+ "x": 13,+ "catX": "13",+ "y": 13+ },+ {+ "x": 14,+ "catX": "14",+ "y": 14+ },+ {+ "x": 15,+ "catX": "15",+ "y": 15+ },+ {+ "x": 16,+ "catX": "16",+ "y": 16+ },+ {+ "x": 17,+ "catX": "17",+ "y": 17+ },+ {+ "x": 18,+ "catX": "18",+ "y": 18+ },+ {+ "x": 19,+ "catX": "19",+ "y": 19+ },+ {+ "x": 20,+ "catX": "20",+ "y": 20+ },+ {+ "x": 21,+ "catX": "21",+ "y": 21+ },+ {+ "x": 22,+ "catX": "22",+ "y": 22+ },+ {+ "x": 23,+ "catX": "23",+ "y": 23+ },+ {+ "x": 24,+ "catX": "24",+ "y": 24+ },+ {+ "x": 25,+ "catX": "25",+ "y": 25+ },+ {+ "x": 26,+ "catX": "26",+ "y": 26+ },+ {+ "x": 27,+ "catX": "27",+ "y": 27+ },+ {+ "x": 28,+ "catX": "28",+ "y": 28+ },+ {+ "x": 29,+ "catX": "29",+ "y": 29+ },+ {+ "x": 30,+ "catX": "30",+ "y": 30+ },+ {+ "x": 31,+ "catX": "31",+ "y": 31+ },+ {+ "x": 32,+ "catX": "32",+ "y": 32+ },+ {+ "x": 33,+ "catX": "33",+ "y": 33+ },+ {+ "x": 34,+ "catX": "34",+ "y": 34+ },+ {+ "x": 35,+ "catX": "35",+ "y": 35+ },+ {+ "x": 36,+ "catX": "36",+ "y": 36+ },+ {+ "x": 37,+ "catX": "37",+ "y": 37+ },+ {+ "x": 38,+ "catX": "38",+ "y": 38+ },+ {+ "x": 39,+ "catX": "39",+ "y": 39+ },+ {+ "x": 40,+ "catX": "40",+ "y": 40+ },+ {+ "x": 41,+ "catX": "41",+ "y": 41+ },+ {+ "x": 42,+ "catX": "42",+ "y": 42+ },+ {+ "x": 43,+ "catX": "43",+ "y": 43+ },+ {+ "x": 44,+ "catX": "44",+ "y": 44+ },+ {+ "x": 45,+ "catX": "45",+ "y": 45+ },+ {+ "x": 46,+ "catX": "46",+ "y": 46+ },+ {+ "x": 47,+ "catX": "47",+ "y": 47+ },+ {+ "x": 48,+ "catX": "48",+ "y": 48+ },+ {+ "x": 49,+ "catX": "49",+ "y": 49+ },+ {+ "x": 50,+ "catX": "50",+ "y": 50+ },+ {+ "x": 51,+ "catX": "51",+ "y": 51+ },+ {+ "x": 52,+ "catX": "52",+ "y": 52+ },+ {+ "x": 53,+ "catX": "53",+ "y": 53+ },+ {+ "x": 54,+ "catX": "54",+ "y": 54+ },+ {+ "x": 55,+ "catX": "55",+ "y": 55+ },+ {+ "x": 56,+ "catX": "56",+ "y": 56+ },+ {+ "x": 57,+ "catX": "57",+ "y": 57+ },+ {+ "x": 58,+ "catX": "58",+ "y": 58+ },+ {+ "x": 59,+ "catX": "59",+ "y": 59+ },+ {+ "x": 60,+ "catX": "60",+ "y": 60+ },+ {+ "x": 61,+ "catX": "61",+ "y": 61+ },+ {+ "x": 62,+ "catX": "62",+ "y": 62+ },+ {+ "x": 63,+ "catX": "63",+ "y": 63+ },+ {+ "x": 64,+ "catX": "64",+ "y": 64+ },+ {+ "x": 65,+ "catX": "65",+ "y": 65+ },+ {+ "x": 66,+ "catX": "66",+ "y": 66+ },+ {+ "x": 67,+ "catX": "67",+ "y": 67+ },+ {+ "x": 68,+ "catX": "68",+ "y": 68+ },+ {+ "x": 69,+ "catX": "69",+ "y": 69+ },+ {+ "x": 70,+ "catX": "70",+ "y": 70+ },+ {+ "x": 71,+ "catX": "71",+ "y": 71+ },+ {+ "x": 72,+ "catX": "72",+ "y": 72+ },+ {+ "x": 73,+ "catX": "73",+ "y": 73+ },+ {+ "x": 74,+ "catX": "74",+ "y": 74+ },+ {+ "x": 75,+ "catX": "75",+ "y": 75+ },+ {+ "x": 76,+ "catX": "76",+ "y": 76+ },+ {+ "x": 77,+ "catX": "77",+ "y": 77+ },+ {+ "x": 78,+ "catX": "78",+ "y": 78+ },+ {+ "x": 79,+ "catX": "79",+ "y": 79+ },+ {+ "x": 80,+ "catX": "80",+ "y": 80+ },+ {+ "x": 81,+ "catX": "81",+ "y": 81+ },+ {+ "x": 82,+ "catX": "82",+ "y": 82+ },+ {+ "x": 83,+ "catX": "83",+ "y": 83+ },+ {+ "x": 84,+ "catX": "84",+ "y": 84+ },+ {+ "x": 85,+ "catX": "85",+ "y": 85+ },+ {+ "x": 86,+ "catX": "86",+ "y": 86+ },+ {+ "x": 87,+ "catX": "87",+ "y": 87+ },+ {+ "x": 88,+ "catX": "88",+ "y": 88+ },+ {+ "x": 89,+ "catX": "89",+ "y": 89+ },+ {+ "x": 90,+ "catX": "90",+ "y": 90+ },+ {+ "x": 91,+ "catX": "91",+ "y": 91+ },+ {+ "x": 92,+ "catX": "92",+ "y": 92+ },+ {+ "x": 93,+ "catX": "93",+ "y": 93+ },+ {+ "x": 94,+ "catX": "94",+ "y": 94+ },+ {+ "x": 95,+ "catX": "95",+ "y": 95+ },+ {+ "x": 96,+ "catX": "96",+ "y": 96+ },+ {+ "x": 97,+ "catX": "97",+ "y": 97+ },+ {+ "x": 98,+ "catX": "98",+ "y": 98+ },+ {+ "x": 99,+ "catX": "99",+ "y": 99+ },+ {+ "x": 100,+ "catX": "100",+ "y": 100+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "catX",+ "type": "ordinal",+ "axis": {+ "values": [+ "1",+ "25",+ "39",+ "dummy",+ "90"+ ]+ }+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,88 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "date": "2019-01-01 09:00:00",+ "y": 1+ },+ {+ "date": "2019-01-02 09:00:00",+ "y": 2+ },+ {+ "date": "2019-01-03 09:00:00",+ "y": 3+ },+ {+ "date": "2019-01-04 09:00:00",+ "y": 4+ },+ {+ "date": "2019-01-05 09:00:00",+ "y": 5+ },+ {+ "date": "2019-01-06 09:00:00",+ "y": 6+ },+ {+ "date": "2019-01-07 09:00:00",+ "y": 7+ },+ {+ "date": "2019-01-08 09:00:00",+ "y": 8+ },+ {+ "date": "2019-01-09 09:00:00",+ "y": 9+ },+ {+ "date": "2019-01-10 09:00:00",+ "y": 10+ },+ {+ "date": "2019-01-11 09:00:00",+ "y": 11+ },+ {+ "date": "2019-01-12 09:00:00",+ "y": 12+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "values": [+ {+ "date": 4,+ "year": 2019,+ "month": "Jan"+ },+ {+ "date": 8,+ "year": 2019,+ "month": "Jan"+ },+ {+ "date": 20,+ "year": 2019,+ "month": "Jan"+ }+ ]+ }+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,54 @@+{+ "config": {+ "axisY": {+ "gridColor": "blue"+ },+ "axisX": {+ "gridColor": "red"+ },+ "axis": {+ "gridWidth": 8+ }+ },+ "mark": {+ "size": 5000,+ "opacity": 1,+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 20,+ "y": 10+ },+ {+ "cat": "b",+ "x": 10,+ "y": 20+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal",+ "legend": null+ },+ "x": {+ "field": "x",+ "type": "quantitative",+ "axis": {+ "zindex": 2+ }+ },+ "y": {+ "field": "y",+ "type": "quantitative",+ "axis": {+ "zindex": 1+ }+ }+ }+}
@@ -0,0 +1,40 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "#f33",+ "#33f"+ ]+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Custom continuous colour scheme (red to blue ramp)."+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "scale": {+ "range": [+ "#e33",+ "#3a3",+ "#33d"+ ]+ },+ "type": "nominal"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Custom discrete colours (red, green, blue)."+}
@@ -0,0 +1,34 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Default continuous colour scales."+}
@@ -0,0 +1,34 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Default nominal colour scales."+}
@@ -0,0 +1,34 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Default ordinal colour scales."+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": -0.1,+ "type": "cubehelix-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix-long interpolation, gamma of -0.1"+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": 0,+ "type": "cubehelix-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix-long interpolation, gamma of 0"+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": 1,+ "type": "cubehelix-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix-long interpolation with default gamma value of 1"+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": 2,+ "type": "cubehelix-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix-long interpolation, gamma of 2"+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": 10,+ "type": "cubehelix-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix-long interpolation, gamma of 10"+}
@@ -0,0 +1,44 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "type": "hsl"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "HSL interpolation."+}
@@ -0,0 +1,44 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "type": "hsl-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "HSL-long interpolation."+}
@@ -0,0 +1,44 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "type": "lab"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Lab interpolation."+}
@@ -0,0 +1,44 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "type": "hcl"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "HCL interpolation."+}
@@ -0,0 +1,44 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "type": "hcl-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "HCL-long interpolation."+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": 1,+ "type": "cubehelix"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix interpolation."+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "interpolate": {+ "gamma": 1,+ "type": "cubehelix-long"+ },+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "cube-helix-long interpolation."+}
@@ -0,0 +1,37 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "scheme": "plasma"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Continuous colour scale based on named vega schame. Should use the entire plasma colour scheme."+}
@@ -0,0 +1,43 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "scheme": {+ "extent": [+ 0.5,+ 1+ ],+ "name": "plasma"+ }+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Continuous colour scale based on named vega schame. Should use the upper half of the plasma colour scheme."+}
@@ -0,0 +1,38 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "scheme": "plasma"+ },+ "sort": "descending",+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Continuous colour scale based on named vega schame. Should use the flipped plasma colour scheme (i.e. red to orange)."+}
@@ -0,0 +1,44 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "scheme": {+ "extent": [+ 0,+ 0.5+ ],+ "name": "plasma"+ }+ },+ "sort": "descending",+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Continuous colour scale based on named vega schame. Should use the first half of the flipped plasma colour scheme (i.e. red to orange)."+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "type": "linear"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Linear (default) colour scale."+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "type": "pow"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Power colour scale with default (1) exponent."+}
@@ -0,0 +1,42 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "exponent": 3,+ "range": [+ "yellow",+ "red"+ ],+ "type": "pow"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Cubic Power colour scale."+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "type": "sqrt"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Square root colour scale."+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Acceleration",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "type": "log"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Log colour scale."+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "accelerationZScore",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "type": "symlog"+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "SymLog colour scale with default slope constant (1)."+}
@@ -0,0 +1,42 @@+{+ "transform": [+ {+ "as": "accelerationZScore",+ "calculate": "(datum.Acceleration - 15.52)/2.80"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "accelerationZScore",+ "scale": {+ "range": [+ "yellow",+ "red"+ ],+ "type": "symlog",+ "constant": 1.0e-2+ },+ "type": "quantitative"+ },+ "size": {+ "value": 60+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "SymLog colour scale with slope constant of 0.01."+}
@@ -0,0 +1,23 @@+{+ "mark": {+ "extent": "min-max",+ "type": "boxplot"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "age",+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ }+ }+ }+}
@@ -0,0 +1,23 @@+{+ "mark": {+ "extent": 2,+ "type": "boxplot"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "age",+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ }+ }+ }+}
@@ -0,0 +1,42 @@+{+ "mark": {+ "median": {+ "strokeWidth": 0,+ "size": 18,+ "fill": "black"+ },+ "box": {+ "color": "firebrick"+ },+ "rule": {+ "strokeWidth": 0.4+ },+ "extent": 0.5,+ "outliers": {+ "strokeWidth": 0.3,+ "color": "black",+ "size": 10+ },+ "type": "boxplot",+ "ticks": {+ "size": 8+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "age",+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ }+ }+ }+}
@@ -0,0 +1,27 @@+{+ "mark": {+ "borders": {},+ "extent": "ci",+ "interpolate": "monotone",+ "type": "errorband"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "scale": {+ "zero": false+ },+ "title": "Miles per Gallon (95% CI)",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,27 @@+{+ "mark": {+ "borders": {},+ "extent": "stdev",+ "interpolate": "monotone",+ "type": "errorband"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "scale": {+ "zero": false+ },+ "title": "Miles per Gallon (1 stdev)",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,26 @@+{+ "mark": {+ "extent": "ci",+ "type": "errorbar",+ "ticks": {+ "stroke": "blue"+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "yield",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ },+ "y": {+ "field": "variety",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,26 @@+{+ "mark": {+ "extent": "stdev",+ "type": "errorbar",+ "ticks": {+ "stroke": "blue"+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "yield",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ },+ "y": {+ "field": "variety",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,49 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "type": "errorbar",+ "ticks": {}+ },+ "encoding": {+ "color": {+ "value": "#4682b4"+ },+ "x": {+ "field": "yield",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ },+ "y": {+ "field": "variety",+ "type": "ordinal"+ }+ }+ },+ {+ "mark": {+ "color": "black",+ "type": "point",+ "filled": true+ },+ "encoding": {+ "x": {+ "field": "yield",+ "aggregate": "mean",+ "type": "quantitative"+ },+ "y": {+ "field": "variety",+ "type": "ordinal"+ }+ }+ }+ ],+ "description": "Error bars with color encoding"+}
@@ -0,0 +1,25 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "myZoomPan": {+ "bind": "scales",+ "type": "interval"+ }+ },+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,26 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "myZoomPan": {+ "clear": "click[event.shiftKey]",+ "bind": "scales",+ "type": "interval"+ }+ },+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,32 @@+{+ "config": {+ "invalidValues": null+ },+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "value": "#0099ee",+ "condition": {+ "value": "#ddd",+ "test": {+ "or": [+ "datum.IMDB_Rating === null",+ "datum.Rotten_Tomatoes_Rating === null"+ ]+ }+ }+ },+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,53 @@+{+ "mark": {+ "size": 800,+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "value": 10+ },+ {+ "value": 20+ },+ {+ "value": 30+ },+ {+ "value": 40+ },+ {+ "value": 50+ },+ {+ "value": 60+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "value": "black",+ "condition": [+ {+ "value": "blue",+ "test": "datum.value < 40"+ },+ {+ "value": "red",+ "test": "datum.value < 50"+ },+ {+ "value": "yellow",+ "test": "datum.value < 60"+ }+ ]+ },+ "x": {+ "field": "value",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,42 @@+{+ "mark": {+ "cursor": "grab",+ "type": "rect"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "alex": {+ "type": "interval",+ "translate": "[mousedown[!event.shiftKey], mouseup] > mousemove",+ "on": "[mousedown[!event.shiftKey], mouseup] > mousemove"+ },+ "morgan": {+ "mark": {+ "stroke": "#e34a33",+ "fill": "#fdbb84",+ "fillOpacity": 0.5+ },+ "type": "interval",+ "translate": "[mousedown[event.shiftKey], mouseup] > mousemove",+ "on": "[mousedown[event.shiftKey], mouseup] > mousemove"+ }+ },+ "encoding": {+ "color": {+ "field": "*",+ "aggregate": "count",+ "type": "quantitative"+ },+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,51 @@+{+ "mark": {+ "cursor": "grab",+ "type": "rect"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "alex": {+ "type": "interval",+ "translate": "[mousedown[!event.shiftKey], mouseup] > mousemove",+ "on": "[mousedown[!event.shiftKey], mouseup] > mousemove"+ },+ "morgan": {+ "mark": {+ "stroke": "#e34a33",+ "fill": "#fdbb84",+ "fillOpacity": 0.5+ },+ "type": "interval",+ "translate": "[mousedown[event.shiftKey], mouseup] > mousemove",+ "on": "[mousedown[event.shiftKey], mouseup] > mousemove"+ }+ },+ "encoding": {+ "color": {+ "value": "gray",+ "condition": {+ "field": "*",+ "aggregate": "count",+ "selection": {+ "and": [+ "alex",+ "morgan"+ ]+ },+ "type": "quantitative"+ }+ },+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,63 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "vconcat": [+ {+ "mark": "point",+ "selection": {+ "brush": {+ "type": "interval"+ }+ },+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "and": [+ {+ "selection": "brush"+ },+ "datum.Weight_in_lbs > 3000"+ ]+ }+ }+ ],+ "mark": "point",+ "encoding": {+ "x": {+ "field": "Acceleration",+ "scale": {+ "domain": [+ 0,+ 25+ ]+ },+ "type": "quantitative"+ },+ "y": {+ "field": "Displacement",+ "scale": {+ "domain": [+ 0,+ 500+ ]+ },+ "type": "quantitative"+ }+ }+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,37 @@+{+ "mark": {+ "cursor": "grab",+ "type": "rect"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "clear": false,+ "type": "interval",+ "translate": "[mousedown[!event.shiftKey], mouseup] > mousemove",+ "on": "[mousedown[!event.shiftKey], mouseup] > mousemove"+ }+ },+ "encoding": {+ "color": {+ "value": "gray",+ "condition": {+ "field": "*",+ "aggregate": "count",+ "selection": "mySelection",+ "type": "quantitative"+ }+ },+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,38 @@+{+ "mark": {+ "cursor": "grab",+ "type": "rect"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "empty": "none",+ "clear": "mouseup",+ "type": "interval",+ "translate": "[mousedown[!event.shiftKey], mouseup] > mousemove",+ "on": "[mousedown[!event.shiftKey], mouseup] > mousemove"+ }+ },+ "encoding": {+ "color": {+ "value": "gray",+ "condition": {+ "field": "*",+ "aggregate": "count",+ "selection": "mySelection",+ "type": "quantitative"+ }+ },+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 200,+ "config": {+ "axis": {+ "labelFontStyle": "bold",+ "titleFont": "serif",+ "titleFontStyle": "italic",+ "labelFont": "serif",+ "titleAnchor": "end"+ }+ },+ "mark": {+ "size": 100,+ "type": "point"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "title": "Car Scatter",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,111 @@+{+ "hconcat": [+ {+ "height": 200,+ "mark": {+ "size": 100,+ "type": "point"+ },+ "width": 200,+ "title": "Car Scatter",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "bar",+ "width": 200,+ "title": "Car Histogram",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "area",+ "width": 200,+ "title": "Car Streamgraph",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative",+ "axis": null,+ "stack": "center"+ }+ }+ }+ ],+ "config": {+ "title": {+ "color": "#fff",+ "font": "Roboto"+ },+ "axis": {+ "domainColor": "yellow",+ "labelColor": "#fcf",+ "titleFont": "Roboto",+ "titleColor": "rgb(200,255,200)",+ "gridColor": "rgb(255,255,200)",+ "labelFont": "Roboto",+ "tickColor": "white",+ "gridOpacity": 0.2+ },+ "background": "black",+ "legend": {+ "gradientStrokeColor": "yellow",+ "fillColor": "#333",+ "labelColor": "white",+ "titleFont": "Roboto",+ "symbolFillColor": "red",+ "titleColor": "rgb(200,200,200)",+ "labelFont": "Roboto",+ "strokeColor": "#444"+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "scale": {+ "color": "independent",+ "shape": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,85 @@+{+ "hconcat": [+ {+ "height": 200,+ "mark": {+ "size": 100,+ "type": "point"+ },+ "width": 200,+ "title": "Car Scatter",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "bar",+ "width": 200,+ "title": "Car Histogram",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "area",+ "width": 200,+ "title": "Car Streamgraph",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative",+ "axis": null,+ "stack": "center"+ }+ }+ }+ ],+ "config": {},+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "scale": {+ "color": "independent",+ "shape": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,89 @@+{+ "hconcat": [+ {+ "height": 200,+ "mark": {+ "size": 100,+ "type": "point"+ },+ "width": 200,+ "title": "Car Scatter",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "bar",+ "width": 200,+ "title": "Car Histogram",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "area",+ "width": 200,+ "title": "Car Streamgraph",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative",+ "axis": null,+ "stack": "center"+ }+ }+ }+ ],+ "config": {+ "mark": {+ "filled": false+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "scale": {+ "color": "independent",+ "shape": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,102 @@+{+ "hconcat": [+ {+ "height": 200,+ "mark": {+ "size": 100,+ "type": "point"+ },+ "width": 200,+ "title": "Car Scatter",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "bar",+ "width": 200,+ "title": "Car Histogram",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "area",+ "width": 200,+ "title": "Car Streamgraph",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative",+ "axis": null,+ "stack": "center"+ }+ }+ }+ ],+ "config": {+ "area": {+ "filled": false+ },+ "mark": {+ "opacity": 1,+ "fill": "black",+ "filled": true+ },+ "point": {+ "stroke": "white",+ "strokeOpacity": 0.2,+ "filled": true+ },+ "bar": {+ "filled": true+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "scale": {+ "color": "independent",+ "shape": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,42 @@+{+ "height": 200,+ "config": {+ "autosize": {+ "type": "fit"+ },+ "padding": {+ "bottom": 0,+ "left": 90,+ "right": 30,+ "top": 60+ }+ },+ "mark": {+ "size": 100,+ "type": "point"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "title": "Car Scatter",+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,120 @@+{+ "hconcat": [+ {+ "height": 200,+ "mark": {+ "size": 100,+ "type": "point"+ },+ "width": 200,+ "title": {+ "color": "brown",+ "text": "Car Scatter",+ "fontSize": 12+ },+ "encoding": {+ "color": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "bar",+ "width": 200,+ "view": {+ "cornerRadius": 18,+ "strokeWidth": 4,+ "strokeCap": "round",+ "strokeJoin": "bevel",+ "stroke": "red",+ "fill": "white",+ "strokeDash": [+ 10,+ 10+ ]+ },+ "title": "Car Histogram",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 200,+ "mark": "area",+ "width": 200,+ "view": {+ "style": [+ "myStyle",+ "mySecondStyle"+ ]+ },+ "title": "Car Streamgraph",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative",+ "axis": null,+ "stack": "center"+ }+ }+ }+ ],+ "config": {+ "style": {+ "mySecondStyle": {+ "stroke": "blue",+ "fill": "black"+ },+ "myStyle": {+ "fill": "red",+ "strokeOpacity": 1,+ "fillOpacity": 0.1+ }+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "scale": {+ "color": "independent",+ "shape": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "background": "yellow"+}
@@ -0,0 +1,49 @@+{+ "data": {+ "values": [+ {+ "a": "A",+ "b": 28+ },+ {+ "a": "B",+ "b": 55+ },+ {+ "a": "C",+ "b": 43+ },+ {+ "a": "D",+ "b": 91+ },+ {+ "a": "E",+ "b": 81+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "a",+ "type": "ordinal"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "text": "Test",+ "type": "text"+ },+ "data": null+ }+ ]+}
@@ -0,0 +1,65 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "bin_start": 8,+ "count": 7,+ "bin_end": 10+ },+ {+ "bin_start": 10,+ "count": 29,+ "bin_end": 12+ },+ {+ "bin_start": 12,+ "count": 71,+ "bin_end": 14+ },+ {+ "bin_start": 14,+ "count": 127,+ "bin_end": 16+ },+ {+ "bin_start": 16,+ "count": 94,+ "bin_end": 18+ },+ {+ "bin_start": 18,+ "count": 54,+ "bin_end": 20+ },+ {+ "bin_start": 20,+ "count": 17,+ "bin_end": 22+ },+ {+ "bin_start": 22,+ "count": 5,+ "bin_end": 24+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x2": {+ "field": "bin_end"+ },+ "x": {+ "field": "bin_start",+ "bin": "binned",+ "type": "quantitative",+ "axis": {+ "tickMinStep": 2+ }+ },+ "y": {+ "field": "count",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,110 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "x": 10.6+ },+ {+ "x": 12.1+ },+ {+ "x": 9.4+ },+ {+ "x": 11.5+ },+ {+ "x": 12.6+ },+ {+ "x": 10.7+ },+ {+ "x": 11.6+ },+ {+ "x": 7.7+ },+ {+ "x": 12+ },+ {+ "x": 10.6+ },+ {+ "x": 16.5+ },+ {+ "x": 8.7+ },+ {+ "x": 7.6+ },+ {+ "x": 10.2+ },+ {+ "x": 10+ },+ {+ "x": 9.8+ },+ {+ "x": 11+ },+ {+ "x": 9+ },+ {+ "x": 10.4+ },+ {+ "x": 11.6+ },+ {+ "x": 11.2+ },+ {+ "x": 11.1+ },+ {+ "x": 11.7+ },+ {+ "x": 12.1+ },+ {+ "x": 9.9+ },+ {+ "x": 8.9+ },+ {+ "x": 10.9+ },+ {+ "x": 14.6+ },+ {+ "x": 11.4+ },+ {+ "x": 12.1+ }+ ]+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "bin": true,+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,235 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "x": 10.6+ },+ {+ "x": 12.1+ },+ {+ "x": 9.4+ },+ {+ "x": 11.5+ },+ {+ "x": 12.6+ },+ {+ "x": 10.7+ },+ {+ "x": 11.6+ },+ {+ "x": 7.7+ },+ {+ "x": 12+ },+ {+ "x": 10.6+ },+ {+ "x": 16.5+ },+ {+ "x": 8.7+ },+ {+ "x": 7.6+ },+ {+ "x": 10.2+ },+ {+ "x": 10+ },+ {+ "x": 9.8+ },+ {+ "x": 11+ },+ {+ "x": 9+ },+ {+ "x": 10.4+ },+ {+ "x": 11.6+ },+ {+ "x": 11.2+ },+ {+ "x": 11.1+ },+ {+ "x": 11.7+ },+ {+ "x": 12.1+ },+ {+ "x": 9.9+ },+ {+ "x": 8.9+ },+ {+ "x": 10.9+ },+ {+ "x": 14.6+ },+ {+ "x": 11.4+ },+ {+ "x": 12.1+ },+ {+ "x": 12.2+ },+ {+ "x": 11.3+ },+ {+ "x": 13.1+ },+ {+ "x": 14.3+ },+ {+ "x": 9.8+ },+ {+ "x": 12.7+ },+ {+ "x": 9.2+ },+ {+ "x": 8.7+ },+ {+ "x": 11.3+ },+ {+ "x": 6.5+ },+ {+ "x": 11.1+ },+ {+ "x": 8.9+ },+ {+ "x": 11.8+ },+ {+ "x": 10.5+ },+ {+ "x": 12.8+ },+ {+ "x": 11.1+ },+ {+ "x": 11.2+ },+ {+ "x": 7+ },+ {+ "x": 12.4+ },+ {+ "x": 11.3+ },+ {+ "x": 8.3+ },+ {+ "x": 12.4+ },+ {+ "x": 12.1+ },+ {+ "x": 9.4+ },+ {+ "x": 8.6+ },+ {+ "x": 11.1+ },+ {+ "x": 8.9+ },+ {+ "x": 8.4+ },+ {+ "x": 10.5+ },+ {+ "x": 9.9+ },+ {+ "x": 6.5+ },+ {+ "x": 8.2+ },+ {+ "x": 12.7+ },+ {+ "x": 7.7+ },+ {+ "x": 11.1+ },+ {+ "x": 8.1+ },+ {+ "x": 8.1+ },+ {+ "x": 10.7+ },+ {+ "x": 9.8+ },+ {+ "x": 11.2+ },+ {+ "x": 11.2+ }+ ]+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "bin": {+ "anchor": 0.5+ },+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,30 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,61 @@+{+ "mark": "bar",+ "data": {+ "name": "myData3"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ },+ "datasets": {+ "myData1": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ],+ "myData2": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ],+ "myData3": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ]+ }+}
@@ -0,0 +1,30 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,30 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,17 @@+{+ "mark": "bar",+ "data": {+ "url": "data/dataTest.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,17 @@+{+ "mark": "bar",+ "data": {+ "url": "data/dataTest.tsv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,21 @@+{+ "mark": "bar",+ "data": {+ "url": "data/dataTest.csv",+ "format": {+ "type": "dsv",+ "delimiter": ","+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,17 @@+{+ "mark": "bar",+ "data": {+ "url": "data/dataTest.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,61 @@+{+ "mark": "bar",+ "data": {+ "name": "myData1"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ },+ "datasets": {+ "myData1": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ],+ "myData2": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ],+ "myData3": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ]+ }+}
@@ -0,0 +1,61 @@+{+ "mark": "bar",+ "data": {+ "name": "myData2"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ },+ "datasets": {+ "myData1": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ],+ "myData2": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ],+ "myData3": [+ {+ "cat": "a",+ "val": 10+ },+ {+ "cat": "b",+ "val": 18+ },+ {+ "cat": "c",+ "val": 12+ }+ ]+ }+}
@@ -0,0 +1,59 @@+{+ "transform": [+ {+ "filter": "datum.a == 'A' || datum.a == 'C' || datum.a == 'E'"+ }+ ],+ "mark": "bar",+ "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+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "a",+ "type": "ordinal"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,78 @@+{+ "transform": [+ {+ "filter": {+ "or": [+ {+ "or": [+ {+ "equal": "A",+ "field": "a"+ },+ {+ "equal": "C",+ "field": "a"+ }+ ]+ },+ {+ "equal": "E",+ "field": "a"+ }+ ]+ }+ }+ ],+ "mark": "bar",+ "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+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "a",+ "type": "ordinal"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,57 @@+{+ "transform": [+ {+ "as": [+ "quant",+ "cat"+ ],+ "flatten": [+ "foo",+ "bar"+ ]+ }+ ],+ "mark": "circle",+ "data": {+ "values": [+ {+ "foo": [+ 1,+ 2+ ],+ "key": "alpha",+ "bar": [+ "A",+ "B"+ ]+ },+ {+ "foo": [+ 3,+ 4,+ 5+ ],+ "key": "beta",+ "bar": [+ "C",+ "D"+ ]+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "key",+ "type": "nominal"+ },+ "x": {+ "field": "quant",+ "type": "quantitative"+ },+ "y": {+ "field": "cat",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,48 @@+{+ "transform": [+ {+ "as": [+ "k",+ "v"+ ],+ "fold": [+ "gold",+ "silver"+ ]+ }+ ],+ "mark": "bar",+ "data": {+ "values": [+ {+ "silver": 20,+ "country": "USA",+ "gold": 10+ },+ {+ "silver": 26,+ "country": "Canada",+ "gold": 7+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "country",+ "type": "nominal"+ },+ "x": {+ "field": "country",+ "type": "nominal"+ },+ "column": {+ "field": "k",+ "type": "nominal"+ },+ "y": {+ "field": "v",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,24 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonBoroughs.json",+ "format": {+ "feature": "boroughs",+ "type": "topojson"+ }+ },+ "width": 700,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "id",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,100 @@+{+ "height": 400,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": "geoshape",+ "data": {+ "values": {+ "features": [+ {+ "geometry": {+ "coordinates": [+ [+ [+ -3,+ 52+ ],+ [+ 4,+ 52+ ],+ [+ 4,+ 45+ ],+ [+ -3,+ 45+ ],+ [+ -3,+ 52+ ]+ ]+ ],+ "type": "Polygon"+ },+ "type": "Feature",+ "properties": {+ "Region": "Southsville"+ }+ },+ {+ "geometry": {+ "coordinates": [+ [+ [+ -3,+ 59+ ],+ [+ 4,+ 59+ ],+ [+ 4,+ 52+ ],+ [+ -3,+ 52+ ],+ [+ -3,+ 59+ ]+ ]+ ],+ "type": "Polygon"+ },+ "type": "Feature",+ "properties": {+ "Region": "Northerton"+ }+ }+ ],+ "type": "FeatureCollection"+ },+ "format": {+ "property": "features",+ "type": "json"+ }+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic"+ },+ "encoding": {+ "color": {+ "field": "properties.Region",+ "type": "nominal",+ "legend": {+ "title": null+ }+ }+ }+}
@@ -0,0 +1,70 @@+{+ "transform": [+ {+ "groupby": [+ "c"+ ],+ "value": 0,+ "key": "a",+ "impute": "b"+ }+ ],+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,74 @@+{+ "transform": [+ {+ "groupby": [+ "c"+ ],+ "key": "a",+ "method": "mean",+ "frame": [+ -2,+ 2+ ],+ "impute": "b"+ }+ ],+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,75 @@+{+ "transform": [+ {+ "groupby": [+ "c"+ ],+ "keyvals": {+ "start": 1,+ "step": 1,+ "stop": 4+ },+ "value": 100,+ "key": "a",+ "impute": "b"+ }+ ],+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,63 @@+{+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "impute": {+ "value": 0+ },+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,63 @@+{+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "impute": {+ "method": "mean"+ },+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,67 @@+{+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "impute": {+ "method": "mean",+ "frame": [+ -2,+ 2+ ]+ },+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,66 @@+{+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "impute": {+ "keyvals": [+ 4+ ],+ "value": 100+ },+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,68 @@+{+ "mark": "line",+ "data": {+ "values": [+ {+ "a": 0,+ "b": 28,+ "c": 0+ },+ {+ "a": 0,+ "b": 91,+ "c": 1+ },+ {+ "a": 1,+ "b": 43,+ "c": 0+ },+ {+ "a": 1,+ "b": 55,+ "c": 1+ },+ {+ "a": 2,+ "b": 81,+ "c": 0+ },+ {+ "a": 2,+ "b": 53,+ "c": 1+ },+ {+ "a": 3,+ "b": 19,+ "c": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "c",+ "type": "nominal"+ },+ "x": {+ "field": "a",+ "scale": {+ "nice": 1+ },+ "type": "quantitative"+ },+ "y": {+ "field": "b",+ "impute": {+ "keyvals": {+ "start": 4,+ "step": 1,+ "stop": 6+ },+ "value": 100+ },+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,55 @@+{+ "mark": "bar",+ "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+ }+ ],+ "name": "source"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "a",+ "type": "ordinal"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,18 @@+{+ "mark": "bar",+ "data": {+ "url": "data/dataTest.tsv",+ "name": "myName"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,18 @@+{+ "mark": "bar",+ "data": {+ "values": [],+ "name": "source"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "nominal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,49 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "y": 10+ },+ {+ "x": 2,+ "y": 30+ },+ {+ "x": 3,+ "y": null+ },+ {+ "x": 4,+ "y": 15+ },+ {+ "x": 5,+ "y": null+ },+ {+ "x": 6,+ "y": 40+ },+ {+ "x": 7,+ "y": 20+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,39 @@+{+ "hconcat": [+ {+ "mark": "point",+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "sample": 200+ }+ ],+ "mark": "point",+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,27 @@+{+ "transform": [+ {+ "as": "v",+ "calculate": "sin(datum.data)"+ }+ ],+ "mark": "line",+ "data": {+ "sequence": {+ "start": 0,+ "step": 0.1,+ "stop": 12.7+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "data",+ "type": "quantitative"+ },+ "y": {+ "field": "v",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,28 @@+{+ "transform": [+ {+ "as": "v",+ "calculate": "sin(datum.u)"+ }+ ],+ "mark": "line",+ "data": {+ "sequence": {+ "as": "u",+ "start": 0,+ "step": 0.1,+ "stop": 12.7+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "u",+ "type": "quantitative"+ },+ "y": {+ "field": "v",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,56 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "stroke": {},+ "fill": {},+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,61 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "stroke": {+ "field": "y",+ "type": "ordinal"+ },+ "fill": {+ "value": "red"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,61 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "stroke": {+ "value": "red"+ },+ "fill": {+ "field": "y",+ "type": "ordinal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,54 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,55 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "fill": {},+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,58 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "fill": {+ "field": "y",+ "type": "ordinal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,57 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "fill": {+ "value": "red"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,63 @@+{+ "height": 300,+ "mark": "geoshape",+ "data": {+ "values": {+ "features": [+ {+ "geometry": {+ "coordinates": [+ [+ [+ -2,+ 58+ ],+ [+ 3,+ 58+ ],+ [+ 3,+ 53+ ],+ [+ -2,+ 53+ ],+ [+ -2,+ 58+ ]+ ]+ ],+ "type": "Polygon"+ },+ "type": "Feature"+ },+ {+ "geometry": {+ "coordinates": [+ [+ 4,+ 52+ ],+ [+ 4,+ 59+ ],+ [+ -3,+ 59+ ]+ ],+ "type": "LineString"+ },+ "type": "Feature"+ }+ ],+ "type": "FeatureCollection"+ }+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,69 @@+{+ "height": 300,+ "mark": "geoshape",+ "data": {+ "values": {+ "features": [+ {+ "geometry": {+ "coordinates": [+ [+ [+ -2,+ 58+ ],+ [+ 3,+ 58+ ],+ [+ 3,+ 53+ ],+ [+ -2,+ 53+ ],+ [+ -2,+ 58+ ]+ ]+ ],+ "type": "Polygon"+ },+ "type": "Feature"+ },+ {+ "geometry": {+ "coordinates": [+ [+ 4,+ 52+ ],+ [+ 4,+ 59+ ],+ [+ -3,+ 59+ ]+ ],+ "type": "LineString"+ },+ "type": "Feature"+ }+ ],+ "type": "FeatureCollection"+ }+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "features.geometry.type",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,55 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "stroke": {},+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,58 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "stroke": {+ "field": "y",+ "type": "ordinal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,57 @@+{+ "height": 200,+ "mark": {+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 36,+ "val": 4,+ "y": 4+ }+ ]+ },+ "width": 200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "cat",+ "type": "nominal"+ },+ "size": {+ "value": 2000+ },+ "stroke": {+ "value": "red"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,64 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "sum",+ "as": "TotalTime",+ "field": "Time"+ }+ ],+ "frame": [+ null,+ null+ ]+ },+ {+ "as": "PercentOfTotal",+ "calculate": "datum.Time/datum.TotalTime * 100"+ }+ ],+ "mark": "bar",+ "data": {+ "values": [+ {+ "Time": 8,+ "Activity": "Sleeping"+ },+ {+ "Time": 2,+ "Activity": "Eating"+ },+ {+ "Time": 4,+ "Activity": "TV"+ },+ {+ "Time": 8,+ "Activity": "Work"+ },+ {+ "Time": 2,+ "Activity": "Exercise"+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "PercentOfTotal",+ "type": "quantitative",+ "axis": {+ "title": "% of total time"+ }+ },+ "y": {+ "field": "Activity",+ "scale": {+ "rangeStep": 12+ },+ "type": "nominal"+ }+ },+ "description": "Calculation of percentage of total"+}
@@ -0,0 +1,59 @@+{+ "transform": [+ {+ "filter": "isValid(datum.IMDB_Rating)"+ },+ {+ "window": [+ {+ "op": "mean",+ "as": "AverageRating",+ "field": "IMDB_Rating"+ }+ ],+ "frame": [+ null,+ null+ ]+ },+ {+ "filter": "(datum.IMDB_Rating - datum.AverageRating) > 2.5"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative",+ "axis": {+ "title": "IMDB Rating"+ }+ },+ "y": {+ "field": "Title",+ "type": "ordinal"+ }+ }+ },+ {+ "mark": {+ "color": "red",+ "type": "rule"+ },+ "encoding": {+ "x": {+ "field": "AverageRating",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "Calculation of difference from average"+}
@@ -0,0 +1,78 @@+{+ "transform": [+ {+ "filter": "isValid(datum.IMDB_Rating)"+ },+ {+ "as": "year",+ "field": "Release_Date",+ "timeUnit": "year"+ },+ {+ "window": [+ {+ "op": "mean",+ "as": "AverageYearRating",+ "field": "IMDB_Rating"+ }+ ],+ "groupby": [+ "year"+ ],+ "frame": [+ null,+ null+ ]+ },+ {+ "filter": "(datum.IMDB_Rating - datum.AverageYearRating) > 2.5"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json",+ "format": {+ "parse": {+ "Release_Date": "date:'%d-%b-%y'"+ }+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "type": "bar",+ "clip": true+ },+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative",+ "axis": {+ "title": "IMDB Rating"+ }+ },+ "y": {+ "field": "Title",+ "type": "ordinal"+ }+ }+ },+ {+ "mark": "tick",+ "encoding": {+ "color": {+ "value": "red"+ },+ "x": {+ "field": "AverageYearRating",+ "type": "quantitative"+ },+ "y": {+ "field": "Title",+ "type": "ordinal"+ }+ }+ }+ ],+ "description": "Calculation of difference from annual average"+}
@@ -0,0 +1,58 @@+{+ "transform": [+ {+ "filter": "isValid(datum.IMDB_Rating)"+ },+ {+ "filter": {+ "field": "Release_Date",+ "range": [+ null,+ {+ "year": 2019+ }+ ]+ }+ },+ {+ "window": [+ {+ "op": "mean",+ "as": "AverageRating",+ "field": "IMDB_Rating"+ }+ ],+ "frame": [+ null,+ null+ ]+ },+ {+ "as": "RatingDelta",+ "calculate": "datum.IMDB_Rating - datum.AverageRating"+ }+ ],+ "mark": {+ "strokeWidth": 0.3,+ "opacity": 0.3,+ "type": "point"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Release_Date",+ "type": "temporal"+ },+ "y": {+ "field": "RatingDelta",+ "type": "quantitative",+ "axis": {+ "title": "Residual"+ }+ }+ },+ "description": "A scatterplot showing each movie in the database and the difference from the average movie rating."+}
@@ -0,0 +1,140 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "rank",+ "as": "rank"+ }+ ],+ "groupby": [+ "matchday"+ ],+ "sort": [+ {+ "field": "point",+ "order": "descending"+ },+ {+ "field": "diff",+ "order": "descending"+ }+ ]+ }+ ],+ "mark": {+ "orient": "vertical",+ "type": "line"+ },+ "data": {+ "values": [+ {+ "diff": -1,+ "point": 0,+ "matchday": 1,+ "team": "Germany"+ },+ {+ "diff": 1,+ "point": 3,+ "matchday": 1,+ "team": "Mexico"+ },+ {+ "diff": -1,+ "point": 0,+ "matchday": 1,+ "team": "South Korea"+ },+ {+ "diff": 1,+ "point": 3,+ "matchday": 1,+ "team": "Sweden"+ },+ {+ "diff": 0,+ "point": 3,+ "matchday": 2,+ "team": "Germany"+ },+ {+ "diff": 2,+ "point": 6,+ "matchday": 2,+ "team": "Mexico"+ },+ {+ "diff": -2,+ "point": 0,+ "matchday": 2,+ "team": "South Korea"+ },+ {+ "diff": 0,+ "point": 3,+ "matchday": 2,+ "team": "Sweden"+ },+ {+ "diff": -2,+ "point": 3,+ "matchday": 3,+ "team": "Germany"+ },+ {+ "diff": -1,+ "point": 6,+ "matchday": 3,+ "team": "Mexico"+ },+ {+ "diff": 0,+ "point": 3,+ "matchday": 3,+ "team": "South Korea"+ },+ {+ "diff": 3,+ "point": 6,+ "matchday": 3,+ "team": "Sweden"+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "title": {+ "fontStyle": "italic",+ "text": "World Cup 2018: Group F Rankings",+ "frame": "bounds"+ },+ "encoding": {+ "color": {+ "field": "team",+ "scale": {+ "domain": [+ "Germany",+ "Mexico",+ "South Korea",+ "Sweden"+ ],+ "range": [+ "black",+ "#127153",+ "#c91a3c",+ "#0c71ab"+ ]+ },+ "type": "nominal"+ },+ "x": {+ "field": "matchday",+ "type": "ordinal"+ },+ "y": {+ "field": "rank",+ "type": "ordinal"+ }+ },+ "description": "Line chart showing ranks over time for thw World Cup 2018 Group F teams"+}
@@ -0,0 +1,233 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "sum",+ "as": "sum",+ "field": "amount"+ }+ ]+ },+ {+ "window": [+ {+ "op": "lead",+ "as": "lead",+ "field": "label"+ }+ ]+ },+ {+ "as": "lead",+ "calculate": "datum.lead === null ? datum.label : datum.lead"+ },+ {+ "as": "previous_sum",+ "calculate": "datum.label === 'End' ? 0 : datum.sum - datum.amount"+ },+ {+ "as": "amount",+ "calculate": "datum.label === 'End' ? datum.sum : datum.amount"+ },+ {+ "as": "text_amount",+ "calculate": "(datum.label !== 'Begin' && datum.label !== 'End' && datum.amount > 0 ? '+' : '') + datum.amount"+ },+ {+ "as": "center",+ "calculate": "(datum.sum + datum.previous_sum) / 2"+ },+ {+ "as": "sum_dec",+ "calculate": "datum.sum < datum.previous_sum ? datum.sum : ''"+ },+ {+ "as": "sum_inc",+ "calculate": "datum.sum > datum.previous_sum ? datum.sum : ''"+ }+ ],+ "height": 450,+ "data": {+ "values": [+ {+ "amount": 4000,+ "label": "Begin"+ },+ {+ "amount": 1707,+ "label": "Jan"+ },+ {+ "amount": -1425,+ "label": "Feb"+ },+ {+ "amount": -1030,+ "label": "Mar"+ },+ {+ "amount": 1812,+ "label": "Apr"+ },+ {+ "amount": -1067,+ "label": "May"+ },+ {+ "amount": -1481,+ "label": "Jun"+ },+ {+ "amount": 1228,+ "label": "Jul"+ },+ {+ "amount": 1176,+ "label": "Aug"+ },+ {+ "amount": 1146,+ "label": "Sep"+ },+ {+ "amount": 1205,+ "label": "Oct"+ },+ {+ "amount": -1388,+ "label": "Nov"+ },+ {+ "amount": 1492,+ "label": "Dec"+ },+ {+ "amount": 0,+ "label": "End"+ }+ ]+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "size": 45,+ "type": "bar"+ },+ "encoding": {+ "color": {+ "value": "#93c4aa",+ "condition": [+ {+ "value": "#f7e0b6",+ "test": "datum.label === 'Begin' || datum.label === 'End'"+ },+ {+ "value": "#f78a64",+ "test": "datum.sum < datum.previous_sum"+ }+ ]+ },+ "y2": {+ "field": "sum"+ },+ "y": {+ "field": "previous_sum",+ "title": "Amount",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "x2Offset": 22.5,+ "strokeWidth": 2,+ "color": "#404040",+ "opacity": 1,+ "xOffset": -22.5,+ "type": "rule"+ },+ "encoding": {+ "x2": {+ "field": "lead"+ },+ "y": {+ "field": "sum",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "dy": -8,+ "color": "#404040",+ "type": "text",+ "fontWeight": "bold"+ },+ "encoding": {+ "text": {+ "field": "sum_inc",+ "type": "nominal"+ },+ "y": {+ "field": "sum_inc",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "dy": 8,+ "color": "#404040",+ "type": "text",+ "baseline": "top",+ "fontWeight": "bold"+ },+ "encoding": {+ "text": {+ "field": "sum_dec",+ "type": "nominal"+ },+ "y": {+ "field": "sum_dec",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "type": "text",+ "baseline": "middle",+ "fontWeight": "bold"+ },+ "encoding": {+ "color": {+ "value": "white",+ "condition": {+ "value": "#725a30",+ "test": "datum.label === 'Begin' || datum.label === 'End'"+ }+ },+ "text": {+ "field": "text_amount",+ "type": "nominal"+ },+ "y": {+ "field": "center",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "label",+ "sort": null,+ "title": "Months",+ "type": "ordinal"+ }+ },+ "description": "Waterfall chart of monthly profit and loss"+}
@@ -0,0 +1,34 @@+{+ "transform": [+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/lookup_people.csv"+ },+ "key": "name",+ "fields": [+ "age",+ "height"+ ]+ },+ "lookup": "person"+ }+ ],+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/lookup_groups.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "group",+ "type": "ordinal"+ },+ "y": {+ "field": "age",+ "aggregate": "mean",+ "type": "quantitative"+ }+ },+ "description": "Using the lookup transform to combine data"+}
@@ -0,0 +1,198 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "count",+ "as": "index"+ }+ ]+ },+ {+ "fold": [+ "petalLength",+ "petalWidth",+ "sepalLength",+ "sepalWidth"+ ]+ },+ {+ "groupby": [+ "key"+ ],+ "joinaggregate": [+ {+ "op": "min",+ "as": "min",+ "field": "value"+ },+ {+ "op": "max",+ "as": "max",+ "field": "value"+ }+ ]+ },+ {+ "as": "normVal",+ "calculate": "(datum.value - datum.min) / (datum.max-datum.min)"+ },+ {+ "as": "mid",+ "calculate": "(datum.min + datum.max) / 2"+ }+ ],+ "height": 300,+ "config": {+ "style": {+ "tick": {+ "orient": "horizontal",+ "tooltip": null+ },+ "label": {+ "dx": -5,+ "tooltip": null,+ "align": "right",+ "baseline": "middle"+ }+ },+ "view": {+ "stroke": null+ },+ "axisX": {+ "labelAngle": 0,+ "domain": false,+ "tickColor": "#ccc"+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/iris.json"+ },+ "width": 600,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "opacity": 0.3,+ "type": "line"+ },+ "encoding": {+ "color": {+ "field": "species",+ "type": "nominal"+ },+ "tooltip": [+ {+ "field": "petalLength",+ "type": "quantitative"+ },+ {+ "field": "petalWidth",+ "type": "quantitative"+ },+ {+ "field": "sepalLength",+ "type": "quantitative"+ },+ {+ "field": "sepalWidth",+ "type": "quantitative"+ }+ ],+ "x": {+ "field": "key",+ "type": "nominal"+ },+ "detail": {+ "field": "index",+ "type": "nominal"+ },+ "y": {+ "field": "normVal",+ "type": "quantitative",+ "axis": null+ }+ }+ },+ {+ "mark": {+ "color": "#ccc",+ "type": "rule"+ },+ "encoding": {+ "x": {+ "field": "key",+ "type": "nominal",+ "axis": {+ "title": null+ }+ },+ "detail": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "style": "label",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "max",+ "aggregate": "max",+ "type": "quantitative"+ },+ "x": {+ "field": "key",+ "type": "nominal"+ },+ "y": {+ "value": 0+ }+ }+ },+ {+ "mark": {+ "style": "label",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "mid",+ "aggregate": "min",+ "type": "quantitative"+ },+ "x": {+ "field": "key",+ "type": "nominal"+ },+ "y": {+ "value": 150+ }+ }+ },+ {+ "mark": {+ "style": "label",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "min",+ "aggregate": "min",+ "type": "quantitative"+ },+ "x": {+ "field": "key",+ "type": "nominal"+ },+ "y": {+ "value": "height"+ }+ }+ }+ ],+ "description": "Parallel coordinates plot with manual generation of parallel axes"+}
@@ -0,0 +1,21 @@+{+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Production_Budget",+ "aggregate": {+ "argmax": "US_Gross"+ },+ "type": "quantitative"+ },+ "y": {+ "field": "Major_Genre",+ "type": "nominal"+ }+ },+ "description": "Production budget of the film with highest US Gross in each major genre."+}
@@ -0,0 +1,28 @@+{+ "height": 200,+ "mark": "area",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "timeUnit": "yearmonth",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "count",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": {+ "title": "Count"+ }+ }+ },+ "description": "Unemployment over time (area chart)"+}
@@ -0,0 +1,30 @@+{+ "transform": [+ {+ "filter": "datum.symbol === 'GOOG'"+ }+ ],+ "mark": {+ "line": true,+ "point": true,+ "type": "area"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Area chart with overlaid lines and point markers"+}
@@ -0,0 +1,30 @@+{+ "mark": "area",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "series",+ "scale": {+ "scheme": "category20b"+ },+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "timeUnit": "yearmonth",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "count",+ "aggregate": "sum",+ "type": "quantitative"+ }+ },+ "description": "Unemployment across industries as a stacked area chart."+}
@@ -0,0 +1,35 @@+{+ "height": 200,+ "mark": "area",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "series",+ "scale": {+ "scheme": "category20b"+ },+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "timeUnit": "yearmonth",+ "type": "temporal",+ "axis": {+ "domain": false,+ "format": "%Y"+ }+ },+ "y": {+ "field": "count",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": null,+ "stack": "normalize"+ }+ },+ "description": "Unemployment across industries as a normalised area chart."+}
@@ -0,0 +1,35 @@+{+ "height": 200,+ "mark": "area",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "series",+ "scale": {+ "scheme": "category20b"+ },+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "timeUnit": "yearmonth",+ "type": "temporal",+ "axis": {+ "domain": false,+ "format": "%Y"+ }+ },+ "y": {+ "field": "count",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": null,+ "stack": "center"+ }+ },+ "description": "Unemployment across industries as a streamgraph (centred, stacked area chart)."+}
@@ -0,0 +1,159 @@+{+ "height": 50,+ "config": {+ "area": {+ "orient": "vertical",+ "interpolate": "monotone"+ }+ },+ "data": {+ "values": [+ {+ "x": 1,+ "y": 28+ },+ {+ "x": 2,+ "y": 55+ },+ {+ "x": 3,+ "y": 43+ },+ {+ "x": 4,+ "y": 91+ },+ {+ "x": 5,+ "y": 81+ },+ {+ "x": 6,+ "y": 53+ },+ {+ "x": 7,+ "y": 19+ },+ {+ "x": 8,+ "y": 87+ },+ {+ "x": 9,+ "y": 52+ },+ {+ "x": 10,+ "y": 48+ },+ {+ "x": 11,+ "y": 24+ },+ {+ "x": 12,+ "y": 49+ },+ {+ "x": 13,+ "y": 87+ },+ {+ "x": 14,+ "y": 66+ },+ {+ "x": 15,+ "y": 17+ },+ {+ "x": 16,+ "y": 27+ },+ {+ "x": 17,+ "y": 68+ },+ {+ "x": 18,+ "y": 16+ },+ {+ "x": 19,+ "y": 49+ },+ {+ "x": 20,+ "y": 15+ }+ ]+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "type": "area",+ "clip": true+ },+ "encoding": {+ "opacity": {+ "value": 0.6+ },+ "y": {+ "field": "y",+ "scale": {+ "domain": [+ 0,+ 50+ ]+ },+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "as": "ny",+ "calculate": "datum.y - 50"+ }+ ],+ "mark": {+ "type": "area",+ "clip": true+ },+ "encoding": {+ "opacity": {+ "value": 0.3+ },+ "y": {+ "field": "ny",+ "scale": {+ "domain": [+ 0,+ 50+ ]+ },+ "type": "quantitative",+ "axis": {+ "title": "y"+ }+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "x",+ "scale": {+ "zero": false,+ "nice": false+ },+ "type": "quantitative"+ }+ },+ "description": "Horizon chart with 2 layers. (See https://idl.cs.washington.edu/papers/horizon/ for more details on horizon charts.)"+}
@@ -0,0 +1,247 @@+{+ "transform": [+ {+ "groupby": [+ "Origin",+ "Cylinders"+ ],+ "aggregate": [+ {+ "op": "count",+ "as": "count_*"+ }+ ]+ },+ {+ "groupby": [],+ "as": [+ "stack_count_Origin1",+ "stack_count_Origin2"+ ],+ "offset": "normalize",+ "sort": [+ {+ "field": "Origin",+ "order": "ascending"+ }+ ],+ "stack": "count_*"+ },+ {+ "window": [+ {+ "op": "min",+ "as": "x",+ "field": "stack_count_Origin1"+ },+ {+ "op": "max",+ "as": "x2",+ "field": "stack_count_Origin2"+ },+ {+ "op": "dense_rank",+ "as": "rank_Cylinders"+ },+ {+ "op": "distinct",+ "as": "distinct_Cylinders",+ "field": "Cylinders"+ }+ ],+ "groupby": [+ "Origin"+ ],+ "sort": [+ {+ "field": "Cylinders",+ "order": "ascending"+ }+ ],+ "frame": [+ null,+ null+ ]+ },+ {+ "window": [+ {+ "op": "dense_rank",+ "as": "rank_Origin"+ }+ ],+ "sort": [+ {+ "field": "Origin",+ "order": "ascending"+ }+ ],+ "frame": [+ null,+ null+ ]+ },+ {+ "groupby": [+ "Origin"+ ],+ "as": [+ "y",+ "y2"+ ],+ "offset": "normalize",+ "sort": [+ {+ "field": "Cylinders",+ "order": "ascending"+ }+ ],+ "stack": "count_*"+ },+ {+ "as": "ny",+ "calculate": "datum.y + (datum.rank_Cylinders - 1) * datum.distinct_Cylinders * 0.01 / 3"+ },+ {+ "as": "ny2",+ "calculate": "datum.y2 + (datum.rank_Cylinders - 1) * datum.distinct_Cylinders * 0.01 / 3"+ },+ {+ "as": "nx",+ "calculate": "datum.x + (datum.rank_Origin - 1) * 0.01"+ },+ {+ "as": "nx2",+ "calculate": "datum.x2 + (datum.rank_Origin - 1) * 0.01"+ },+ {+ "as": "xc",+ "calculate": "(datum.nx+datum.nx2)/2"+ },+ {+ "as": "yc",+ "calculate": "(datum.ny+datum.ny2)/2"+ }+ ],+ "config": {+ "concat": {+ "spacing": 10+ },+ "view": {+ "stroke": null+ },+ "axis": {+ "domain": false,+ "labels": false,+ "grid": false,+ "ticks": false+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "scale": {+ "x": "shared"+ }+ },+ "vconcat": [+ {+ "mark": {+ "align": "center",+ "type": "text",+ "baseline": "middle"+ },+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": null+ },+ "text": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "xc",+ "aggregate": "min",+ "title": "Origin",+ "type": "quantitative",+ "axis": {+ "orient": "top"+ }+ }+ }+ },+ {+ "layer": [+ {+ "mark": "rect",+ "encoding": {+ "x2": {+ "field": "nx2"+ },+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": null+ },+ "opacity": {+ "field": "Cylinders",+ "type": "quantitative",+ "legend": null+ },+ "tooltip": [+ {+ "field": "Origin",+ "type": "nominal"+ },+ {+ "field": "Cylinders",+ "type": "quantitative"+ }+ ],+ "x": {+ "field": "nx",+ "type": "quantitative",+ "axis": null+ },+ "y2": {+ "field": "ny2"+ },+ "y": {+ "field": "ny",+ "type": "quantitative",+ "axis": null+ }+ }+ },+ {+ "mark": {+ "type": "text",+ "baseline": "middle"+ },+ "encoding": {+ "text": {+ "field": "Cylinders",+ "type": "nominal"+ },+ "x": {+ "field": "xc",+ "type": "quantitative",+ "axis": null+ },+ "y": {+ "field": "yc",+ "type": "quantitative",+ "axis": {+ "title": "Cylinders"+ }+ }+ }+ }+ ]+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,55 @@+{+ "mark": "bar",+ "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+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "a",+ "type": "ordinal"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ },+ "description": "A simple bar chart with embedded data."+}
@@ -0,0 +1,48 @@+{+ "transform": [+ {+ "filter": "datum.year == 2000"+ },+ {+ "as": "gender",+ "calculate": "datum.sex == 2 ? 'Female' : 'Male'"+ }+ ],+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "gender",+ "scale": {+ "range": [+ "#e377c2",+ "#1f77b4"+ ]+ },+ "type": "nominal"+ },+ "opacity": {+ "value": 0.7+ },+ "x": {+ "field": "age",+ "scale": {+ "rangeStep": 17+ },+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ },+ "stack": null+ }+ },+ "description": "Layered bar chart showing the US population distribution of age groups and gender in 2000."+}
@@ -0,0 +1,376 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "percentage_end": -18.4,+ "value": 24,+ "percentage_start": -19.1,+ "type": "Strongly disagree",+ "percentage": 0.7,+ "question": "Q1"+ },+ {+ "percentage_end": -9.2,+ "value": 294,+ "percentage_start": -18.4,+ "type": "Disagree",+ "percentage": 9.1,+ "question": "Q1"+ },+ {+ "percentage_end": 9.2,+ "value": 594,+ "percentage_start": -9.2,+ "type": "Neither agree nor disagree",+ "percentage": 18.5,+ "question": "Q1"+ },+ {+ "percentage_end": 69.2,+ "value": 1927,+ "percentage_start": 9.2,+ "type": "Agree",+ "percentage": 59.9,+ "question": "Q1"+ },+ {+ "percentage_end": 80.9,+ "value": 376,+ "percentage_start": 69.2,+ "type": "Strongly agree",+ "percentage": 11.7,+ "question": "Q1"+ },+ {+ "percentage_end": -18.2,+ "value": 2,+ "percentage_start": -36.4,+ "type": "Strongly disagree",+ "percentage": 18.2,+ "question": "Q2"+ },+ {+ "percentage_end": 0,+ "value": 2,+ "percentage_start": -18.2,+ "type": "Disagree",+ "percentage": 18.2,+ "question": "Q2"+ },+ {+ "percentage_end": 0,+ "value": 0,+ "percentage_start": 0,+ "type": "Neither agree nor disagree",+ "percentage": 0,+ "question": "Q2"+ },+ {+ "percentage_end": 63.6,+ "value": 7,+ "percentage_start": 0,+ "type": "Agree",+ "percentage": 63.6,+ "question": "Q2"+ },+ {+ "percentage_end": 63.6,+ "value": 11,+ "percentage_start": 63.6,+ "type": "Strongly agree",+ "percentage": 0,+ "question": "Q2"+ },+ {+ "percentage_end": -10,+ "value": 2,+ "percentage_start": -30,+ "type": "Strongly disagree",+ "percentage": 20,+ "question": "Q3"+ },+ {+ "percentage_end": -10,+ "value": 0,+ "percentage_start": -10,+ "type": "Disagree",+ "percentage": 0,+ "question": "Q3"+ },+ {+ "percentage_end": 10,+ "value": 2,+ "percentage_start": -10,+ "type": "Neither agree nor disagree",+ "percentage": 20,+ "question": "Q3"+ },+ {+ "percentage_end": 50,+ "value": 4,+ "percentage_start": 10,+ "type": "Agree",+ "percentage": 40,+ "question": "Q3"+ },+ {+ "percentage_end": 70,+ "value": 2,+ "percentage_start": 50,+ "type": "Strongly agree",+ "percentage": 20,+ "question": "Q3"+ },+ {+ "percentage_end": -15.6,+ "value": 0,+ "percentage_start": -15.6,+ "type": "Strongly disagree",+ "percentage": 0,+ "question": "Q4"+ },+ {+ "percentage_end": -3.1,+ "value": 2,+ "percentage_start": -15.6,+ "type": "Disagree",+ "percentage": 12.5,+ "question": "Q4"+ },+ {+ "percentage_end": 3.1,+ "value": 1,+ "percentage_start": -3.1,+ "type": "Neither agree nor disagree",+ "percentage": 6.3,+ "question": "Q4"+ },+ {+ "percentage_end": 46.9,+ "value": 7,+ "percentage_start": 3.1,+ "type": "Agree",+ "percentage": 43.8,+ "question": "Q4"+ },+ {+ "percentage_end": 84.4,+ "value": 6,+ "percentage_start": 46.9,+ "type": "Strongly agree",+ "percentage": 37.5,+ "question": "Q4"+ },+ {+ "percentage_end": -10.4,+ "value": 0,+ "percentage_start": -10.4,+ "type": "Strongly disagree",+ "percentage": 0,+ "question": "Q5"+ },+ {+ "percentage_end": -6.3,+ "value": 1,+ "percentage_start": -10.4,+ "type": "Disagree",+ "percentage": 4.2,+ "question": "Q5"+ },+ {+ "percentage_end": 6.3,+ "value": 3,+ "percentage_start": -6.3,+ "type": "Neither agree nor disagree",+ "percentage": 12.5,+ "question": "Q5"+ },+ {+ "percentage_end": 72.9,+ "value": 16,+ "percentage_start": 6.3,+ "type": "Agree",+ "percentage": 66.7,+ "question": "Q5"+ },+ {+ "percentage_end": 89.6,+ "value": 4,+ "percentage_start": 72.9,+ "type": "Strongly agree",+ "percentage": 16.7,+ "question": "Q5"+ },+ {+ "percentage_end": -12.5,+ "value": 1,+ "percentage_start": -18.8,+ "type": "Strongly disagree",+ "percentage": 6.3,+ "question": "Q6"+ },+ {+ "percentage_end": -6.3,+ "value": 1,+ "percentage_start": -12.5,+ "type": "Disagree",+ "percentage": 6.3,+ "question": "Q6"+ },+ {+ "percentage_end": 6.3,+ "value": 2,+ "percentage_start": -6.3,+ "type": "Neither agree nor disagree",+ "percentage": 12.5,+ "question": "Q6"+ },+ {+ "percentage_end": 62.5,+ "value": 9,+ "percentage_start": 6.3,+ "type": "Agree",+ "percentage": 56.3,+ "question": "Q6"+ },+ {+ "percentage_end": 81.3,+ "value": 3,+ "percentage_start": 62.5,+ "type": "Strongly agree",+ "percentage": 18.8,+ "question": "Q6"+ },+ {+ "percentage_end": -10,+ "value": 0,+ "percentage_start": -10,+ "type": "Strongly disagree",+ "percentage": 0,+ "question": "Q7"+ },+ {+ "percentage_end": -10,+ "value": 0,+ "percentage_start": -10,+ "type": "Disagree",+ "percentage": 0,+ "question": "Q7"+ },+ {+ "percentage_end": 10,+ "value": 1,+ "percentage_start": -10,+ "type": "Neither agree nor disagree",+ "percentage": 20,+ "question": "Q7"+ },+ {+ "percentage_end": 90,+ "value": 4,+ "percentage_start": 10,+ "type": "Agree",+ "percentage": 80,+ "question": "Q7"+ },+ {+ "percentage_end": 90,+ "value": 0,+ "percentage_start": 90,+ "type": "Strongly agree",+ "percentage": 0,+ "question": "Q7"+ },+ {+ "percentage_end": 0,+ "value": 0,+ "percentage_start": 0,+ "type": "Strongly disagree",+ "percentage": 0,+ "question": "Q8"+ },+ {+ "percentage_end": 0,+ "value": 0,+ "percentage_start": 0,+ "type": "Disagree",+ "percentage": 0,+ "question": "Q8"+ },+ {+ "percentage_end": 0,+ "value": 0,+ "percentage_start": 0,+ "type": "Neither agree nor disagree",+ "percentage": 0,+ "question": "Q8"+ },+ {+ "percentage_end": 0,+ "value": 0,+ "percentage_start": 0,+ "type": "Agree",+ "percentage": 0,+ "question": "Q8"+ },+ {+ "percentage_end": 100,+ "value": 2,+ "percentage_start": 0,+ "type": "Strongly agree",+ "percentage": 100,+ "question": "Q8"+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x2": {+ "field": "percentage_end"+ },+ "color": {+ "field": "type",+ "scale": {+ "domain": [+ "Strongly disagree",+ "Disagree",+ "Neither agree nor disagree",+ "Agree",+ "Strongly agree"+ ],+ "range": [+ "#c30d24",+ "#f3a583",+ "#cccccc",+ "#94c6da",+ "#1770ab"+ ],+ "type": "ordinal"+ },+ "type": "nominal",+ "legend": {+ "title": "Response"+ }+ },+ "x": {+ "field": "percentage_start",+ "type": "quantitative",+ "axis": {+ "title": "Percentage"+ }+ },+ "y": {+ "field": "question",+ "type": "nominal",+ "axis": {+ "minExtent": 60,+ "offset": 5,+ "domain": false,+ "title": "Question",+ "ticks": false+ }+ }+ },+ "description": "A diverging stacked bar chart for sentiments towards a set of eight questions, displayed as percentages with neutral responses straddling the 0% mark."+}
@@ -0,0 +1,56 @@+{+ "config": {+ "style": {+ "label": {+ "dx": 3,+ "align": "left",+ "baseline": "middle"+ }+ }+ },+ "data": {+ "values": [+ {+ "a": "A",+ "b": 28+ },+ {+ "a": "B",+ "b": 55+ },+ {+ "a": "C",+ "b": 43+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar"+ },+ {+ "mark": {+ "style": "label",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "b",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "b",+ "type": "quantitative"+ },+ "y": {+ "field": "a",+ "type": "ordinal"+ }+ },+ "description": "A simple bar chart with embedded data labels."+}
@@ -0,0 +1,267 @@+{+ "height": 200,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": {+ "type": "point",+ "filled": true+ },+ "data": {+ "values": [+ {+ "country": "United States",+ "animal": "cattle",+ "col": 1+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 2+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 3+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 4+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 5+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 6+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 7+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 8+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 9+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 1+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 2+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 3+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 4+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 5+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 6+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 1+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 2+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 3+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 4+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 5+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 6+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 7+ },+ {+ "country": "Great Britain",+ "animal": "cattle",+ "col": 1+ },+ {+ "country": "Great Britain",+ "animal": "cattle",+ "col": 2+ },+ {+ "country": "Great Britain",+ "animal": "cattle",+ "col": 3+ },+ {+ "country": "Great Britain",+ "animal": "pigs",+ "col": 1+ },+ {+ "country": "Great Britain",+ "animal": "pigs",+ "col": 2+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 1+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 2+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 3+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 4+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 5+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 6+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 7+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 8+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 9+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 10+ }+ ]+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "animal",+ "scale": {+ "domain": [+ "person",+ "cattle",+ "pigs",+ "sheep"+ ],+ "range": [+ "rgb(162,160,152)",+ "rgb(194,81,64)",+ "rgb(93,93,93)",+ "rgb(91,131,149)"+ ]+ },+ "type": "nominal",+ "legend": null+ },+ "size": {+ "value": 200+ },+ "opacity": {+ "value": 1+ },+ "shape": {+ "field": "animal",+ "scale": {+ "domain": [+ "person",+ "cattle",+ "pigs",+ "sheep"+ ],+ "range": [+ "circle",+ "M4 -2c0 0 0.9 -0.7 1.1 -0.8c0.1 -0.1 -0.1 0.5 -0.3 0.7c-0.2 0.2 1.1 1.1 1.1 1.2c0 0.2 -0.2 0.8 -0.4 0.7c-0.1 0 -0.8 -0.3 -1.3 -0.2c-0.5 0.1 -1.3 1.6 -1.5 2c-0.3 0.4 -0.6 0.4 -0.6 0.4c0 0.1 0.3 1.7 0.4 1.8c0.1 0.1 -0.4 0.1 -0.5 0c0 0 -0.6 -1.9 -0.6 -1.9c-0.1 0 -0.3 -0.1 -0.3 -0.1c0 0.1 -0.5 1.4 -0.4 1.6c0.1 0.2 0.1 0.3 0.1 0.3c0 0 -0.4 0 -0.4 0c0 0 -0.2 -0.1 -0.1 -0.3c0 -0.2 0.3 -1.7 0.3 -1.7c0 0 -2.8 -0.9 -2.9 -0.8c-0.2 0.1 -0.4 0.6 -0.4 1c0 0.4 0.5 1.9 0.5 1.9l-0.5 0l-0.6 -2l0 -0.6c0 0 -1 0.8 -1 1c0 0.2 -0.2 1.3 -0.2 1.3c0 0 0.3 0.3 0.2 0.3c0 0 -0.5 0 -0.5 0c0 0 -0.2 -0.2 -0.1 -0.4c0 -0.1 0.2 -1.6 0.2 -1.6c0 0 0.5 -0.4 0.5 -0.5c0 -0.1 0 -2.7 -0.2 -2.7c-0.1 0 -0.4 2 -0.4 2c0 0 0 0.2 -0.2 0.5c-0.1 0.4 -0.2 1.1 -0.2 1.1c0 0 -0.2 -0.1 -0.2 -0.2c0 -0.1 -0.1 -0.7 0 -0.7c0.1 -0.1 0.3 -0.8 0.4 -1.4c0 -0.6 0.2 -1.3 0.4 -1.5c0.1 -0.2 0.6 -0.4 0.6 -0.4z",+ "M1.2 -2c0 0 0.7 0 1.2 0.5c0.5 0.5 0.4 0.6 0.5 0.6c0.1 0 0.7 0 0.8 0.1c0.1 0 0.2 0.2 0.2 0.2c0 0 -0.6 0.2 -0.6 0.3c0 0.1 0.4 0.9 0.6 0.9c0.1 0 0.6 0 0.6 0.1c0 0.1 0 0.7 -0.1 0.7c-0.1 0 -1.2 0.4 -1.5 0.5c-0.3 0.1 -1.1 0.5 -1.1 0.7c-0.1 0.2 0.4 1.2 0.4 1.2l-0.4 0c0 0 -0.4 -0.8 -0.4 -0.9c0 -0.1 -0.1 -0.3 -0.1 -0.3l-0.2 0l-0.5 1.3l-0.4 0c0 0 -0.1 -0.4 0 -0.6c0.1 -0.1 0.3 -0.6 0.3 -0.7c0 0 -0.8 0 -1.5 -0.1c-0.7 -0.1 -1.2 -0.3 -1.2 -0.2c0 0.1 -0.4 0.6 -0.5 0.6c0 0 0.3 0.9 0.3 0.9l-0.4 0c0 0 -0.4 -0.5 -0.4 -0.6c0 -0.1 -0.2 -0.6 -0.2 -0.5c0 0 -0.4 0.4 -0.6 0.4c-0.2 0.1 -0.4 0.1 -0.4 0.1c0 0 -0.1 0.6 -0.1 0.6l-0.5 0l0 -1c0 0 0.5 -0.4 0.5 -0.5c0 -0.1 -0.7 -1.2 -0.6 -1.4c0.1 -0.1 0.1 -1.1 0.1 -1.1c0 0 -0.2 0.1 -0.2 0.1c0 0 0 0.9 0 1c0 0.1 -0.2 0.3 -0.3 0.3c-0.1 0 0 -0.5 0 -0.9c0 -0.4 0 -0.4 0.2 -0.6c0.2 -0.2 0.6 -0.3 0.8 -0.8c0.3 -0.5 1 -0.6 1 -0.6z",+ "M-4.1 -0.5c0.2 0 0.2 0.2 0.5 0.2c0.3 0 0.3 -0.2 0.5 -0.2c0.2 0 0.2 0.2 0.4 0.2c0.2 0 0.2 -0.2 0.5 -0.2c0.2 0 0.2 0.2 0.4 0.2c0.2 0 0.2 -0.2 0.4 -0.2c0.1 0 0.2 0.2 0.4 0.1c0.2 0 0.2 -0.2 0.4 -0.3c0.1 0 0.1 -0.1 0.4 0c0.3 0 0.3 -0.4 0.6 -0.4c0.3 0 0.6 -0.3 0.7 -0.2c0.1 0.1 1.4 1 1.3 1.4c-0.1 0.4 -0.3 0.3 -0.4 0.3c-0.1 0 -0.5 -0.4 -0.7 -0.2c-0.3 0.2 -0.1 0.4 -0.2 0.6c-0.1 0.1 -0.2 0.2 -0.3 0.4c0 0.2 0.1 0.3 0 0.5c-0.1 0.2 -0.3 0.2 -0.3 0.5c0 0.3 -0.2 0.3 -0.3 0.6c-0.1 0.2 0 0.3 -0.1 0.5c-0.1 0.2 -0.1 0.2 -0.2 0.3c-0.1 0.1 0.3 1.1 0.3 1.1l-0.3 0c0 0 -0.3 -0.9 -0.3 -1c0 -0.1 -0.1 -0.2 -0.3 -0.2c-0.2 0 -0.3 0.1 -0.4 0.4c0 0.3 -0.2 0.8 -0.2 0.8l-0.3 0l0.3 -1c0 0 0.1 -0.6 -0.2 -0.5c-0.3 0.1 -0.2 -0.1 -0.4 -0.1c-0.2 -0.1 -0.3 0.1 -0.4 0c-0.2 -0.1 -0.3 0.1 -0.5 0c-0.2 -0.1 -0.1 0 -0.3 0.3c-0.2 0.3 -0.4 0.3 -0.4 0.3l0.2 1.1l-0.3 0l-0.2 -1.1c0 0 -0.4 -0.6 -0.5 -0.4c-0.1 0.3 -0.1 0.4 -0.3 0.4c-0.1 -0.1 -0.2 1.1 -0.2 1.1l-0.3 0l0.2 -1.1c0 0 -0.3 -0.1 -0.3 -0.5c0 -0.3 0.1 -0.5 0.1 -0.7c0.1 -0.2 -0.1 -1 -0.2 -1.1c-0.1 -0.2 -0.2 -0.8 -0.2 -0.8c0 0 -0.1 -0.5 0.4 -0.8z"+ ]+ },+ "type": "nominal",+ "legend": null+ },+ "row": {+ "field": "country",+ "header": {+ "title": null+ },+ "type": "nominal"+ },+ "x": {+ "field": "col",+ "type": "ordinal",+ "axis": null+ },+ "y": {+ "field": "animal",+ "type": "ordinal",+ "axis": null+ }+ },+ "description": "Isotype bar chart inspired by this Only An Ocean Between, 1943. Population Live Stock, p.13."+}
@@ -0,0 +1,249 @@+{+ "transform": [+ {+ "as": "emoji",+ "calculate": "{'cattle': '🐄', 'pigs': '🐖', 'sheep': '🐏'}[datum.animal]"+ },+ {+ "window": [+ {+ "op": "rank",+ "as": "rank"+ }+ ],+ "groupby": [+ "country",+ "animal"+ ]+ }+ ],+ "height": 200,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": {+ "type": "text",+ "baseline": "middle"+ },+ "data": {+ "values": [+ {+ "country": "United States",+ "animal": "cattle",+ "col": 1+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 2+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 3+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 4+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 5+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 6+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 7+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 8+ },+ {+ "country": "United States",+ "animal": "cattle",+ "col": 9+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 1+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 2+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 3+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 4+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 5+ },+ {+ "country": "United States",+ "animal": "pigs",+ "col": 6+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 1+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 2+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 3+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 4+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 5+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 6+ },+ {+ "country": "United States",+ "animal": "sheep",+ "col": 7+ },+ {+ "country": "Great Britain",+ "animal": "cattle",+ "col": 1+ },+ {+ "country": "Great Britain",+ "animal": "cattle",+ "col": 2+ },+ {+ "country": "Great Britain",+ "animal": "cattle",+ "col": 3+ },+ {+ "country": "Great Britain",+ "animal": "pigs",+ "col": 1+ },+ {+ "country": "Great Britain",+ "animal": "pigs",+ "col": 2+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 1+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 2+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 3+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 4+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 5+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 6+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 7+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 8+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 9+ },+ {+ "country": "Great Britain",+ "animal": "sheep",+ "col": 10+ }+ ]+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "size": {+ "value": 65+ },+ "text": {+ "field": "emoji",+ "type": "nominal"+ },+ "row": {+ "field": "country",+ "header": {+ "title": null+ },+ "type": "nominal"+ },+ "x": {+ "field": "rank",+ "type": "ordinal",+ "axis": null+ },+ "y": {+ "field": "animal",+ "sort": null,+ "type": "nominal",+ "axis": null+ }+ },+ "description": "Isotype bar chart using emojis for symbols"+}
@@ -0,0 +1,22 @@+{+ "mark": {+ "binSpacing": 0,+ "type": "bar"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "bin": true,+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ },+ "description": "Simple histogram of IMDB ratings."+}
@@ -0,0 +1,31 @@+{+ "transform": [+ {+ "filter": "datum.year == 2000"+ }+ ],+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "people",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": {+ "title": "population"+ }+ },+ "y": {+ "field": "age",+ "scale": {+ "rangeStep": 17+ },+ "sort": "descending",+ "type": "ordinal"+ }+ },+ "description": "A bar chart showing the US population distribution of age groups in 2000."+}
@@ -0,0 +1,60 @@+{+ "transform": [+ {+ "filter": "datum.year == 2000"+ },+ {+ "as": "gender",+ "calculate": "datum.sex == 2 ? 'Female' : 'Male'"+ }+ ],+ "config": {+ "view": {+ "stroke": null+ },+ "axis": {+ "domainWidth": 1+ }+ },+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "gender",+ "scale": {+ "range": [+ "#EA98D2",+ "#659CCA"+ ]+ },+ "type": "nominal"+ },+ "x": {+ "field": "gender",+ "scale": {+ "rangeStep": 12+ },+ "type": "nominal",+ "axis": {+ "title": null+ }+ },+ "column": {+ "field": "age",+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": {+ "grid": false,+ "title": "population"+ }+ }+ },+ "description": "Grouped bar chart showing population structure by age and gender."+}
@@ -0,0 +1,45 @@+{+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "weather",+ "scale": {+ "domain": [+ "sun",+ "fog",+ "drizzle",+ "rain",+ "snow"+ ],+ "range": [+ "#e7ba52",+ "#c7c7c7",+ "#aec7ea",+ "#1f77b4",+ "#9467bd"+ ]+ },+ "type": "nominal",+ "legend": {+ "title": "Weather type"+ }+ },+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal",+ "axis": {+ "title": "Month of the year"+ }+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ },+ "description": "Seattle weather stacked bar chart"+}
@@ -0,0 +1,23 @@+{+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "site",+ "type": "nominal"+ },+ "x": {+ "field": "yield",+ "aggregate": "sum",+ "type": "quantitative"+ },+ "y": {+ "field": "variety",+ "type": "nominal"+ }+ },+ "description": "Barley crop yields as a horizontal stacked bar chart"+}
@@ -0,0 +1,45 @@+{+ "transform": [+ {+ "filter": "datum.year == 2000"+ },+ {+ "as": "gender",+ "calculate": "datum.sex == 2 ? 'Female' : 'Male'"+ }+ ],+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "gender",+ "scale": {+ "range": [+ "#EA98D2",+ "#659CCA"+ ]+ },+ "type": "nominal"+ },+ "x": {+ "field": "age",+ "scale": {+ "rangeStep": 17+ },+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ },+ "stack": "normalize"+ }+ },+ "description": "Population structure as a normalised stacked bar chart."+}
@@ -0,0 +1,37 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "start": 1,+ "end": 3,+ "task": "A"+ },+ {+ "start": 3,+ "end": 8,+ "task": "B"+ },+ {+ "start": 8,+ "end": 10,+ "task": "C"+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x2": {+ "field": "end"+ },+ "x": {+ "field": "start",+ "type": "quantitative"+ },+ "y": {+ "field": "task",+ "type": "ordinal"+ }+ },+ "description": "A simple bar chart with ranged data (aka Gantt Chart)."+}
@@ -0,0 +1,36 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "color": "red",+ "b": 28+ },+ {+ "color": "green",+ "b": 55+ },+ {+ "color": "blue",+ "b": 43+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "color",+ "scale": null,+ "type": "nominal"+ },+ "x": {+ "field": "color",+ "type": "nominal"+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ },+ "description": "A bar chart that directly encodes color names in the data."+}
@@ -0,0 +1,22 @@+{+ "mark": {+ "binSpacing": 0,+ "type": "bar"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "bin": true,+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ },+ "description": "Simple histogram of IMDB ratings."+}
@@ -0,0 +1,39 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "count",+ "as": "cumulativeCount",+ "field": "count"+ }+ ],+ "sort": [+ {+ "field": "IMDB_Rating",+ "order": "ascending"+ }+ ],+ "frame": [+ null,+ 0+ ]+ }+ ],+ "mark": "area",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "cumulativeCount",+ "type": "quantitative"+ }+ },+ "description": "Cumulative frequency distribution"+}
@@ -0,0 +1,87 @@+{+ "transform": [+ {+ "as": "bin_IMDB_Rating",+ "field": "IMDB_Rating",+ "bin": true+ },+ {+ "groupby": [+ "bin_IMDB_Rating",+ "bin_IMDB_Rating_end"+ ],+ "aggregate": [+ {+ "op": "count",+ "as": "count"+ }+ ]+ },+ {+ "filter": "datum.bin_IMDB_Rating !== null"+ },+ {+ "window": [+ {+ "op": "sum",+ "as": "cumulativeCount",+ "field": "count"+ }+ ],+ "sort": [+ {+ "field": "bin_IMDB_Rating",+ "order": "ascending"+ }+ ],+ "frame": [+ null,+ 0+ ]+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "y": {+ "field": "cumulativeCount",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "yellow",+ "opacity": 0.5,+ "type": "bar"+ },+ "encoding": {+ "y": {+ "field": "count",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x2": {+ "field": "bin_IMDB_Rating_end"+ },+ "x": {+ "field": "bin_IMDB_Rating",+ "scale": {+ "zero": false+ },+ "type": "quantitative",+ "axis": {+ "title": "IMDB rating"+ }+ }+ },+ "description": "A layered histogram and cumulative histogram."+}
@@ -0,0 +1,118 @@+{+ "transform": [+ {+ "groupby": [+ "age"+ ],+ "aggregate": [+ {+ "op": "min",+ "as": "lowerWhisker",+ "field": "people"+ },+ {+ "op": "q1",+ "as": "lowerBox",+ "field": "people"+ },+ {+ "op": "median",+ "as": "midBox",+ "field": "people"+ },+ {+ "op": "q3",+ "as": "upperBox",+ "field": "people"+ },+ {+ "op": "max",+ "as": "upperWhisker",+ "field": "people"+ }+ ]+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "style": "boxWhisker",+ "type": "rule"+ },+ "encoding": {+ "y2": {+ "field": "lowerBox"+ },+ "y": {+ "field": "lowerWhisker",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ }+ }+ }+ },+ {+ "mark": {+ "style": "boxWhisker",+ "type": "rule"+ },+ "encoding": {+ "y2": {+ "field": "upperWhisker"+ },+ "y": {+ "field": "upperBox",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "style": "box",+ "type": "bar"+ },+ "encoding": {+ "size": {+ "value": 5+ },+ "y2": {+ "field": "upperBox"+ },+ "y": {+ "field": "lowerBox",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "style": "boxMid",+ "type": "tick"+ },+ "encoding": {+ "color": {+ "value": "white"+ },+ "size": {+ "value": 5+ },+ "y": {+ "field": "midBox",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "age",+ "type": "ordinal"+ }+ },+ "description": "A vertical 2D box plot showing median, min, and max in the US population distribution of age groups in 2000."+}
@@ -0,0 +1,120 @@+{+ "transform": [+ {+ "groupby": [+ "age"+ ],+ "aggregate": [+ {+ "op": "q1",+ "as": "lowerBox",+ "field": "people"+ },+ {+ "op": "q3",+ "as": "upperBox",+ "field": "people"+ },+ {+ "op": "median",+ "as": "midBox",+ "field": "people"+ }+ ]+ },+ {+ "as": "IQR",+ "calculate": "datum.upperBox - datum.lowerBox"+ },+ {+ "as": "upperWhisker",+ "calculate": "datum.upperBox + datum.IQR * 1.5"+ },+ {+ "as": "lowerWhisker",+ "calculate": "max(0,datum.lowerBox - datum.IQR *1.5)"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "style": "boxWhisker",+ "type": "rule"+ },+ "encoding": {+ "y2": {+ "field": "lowerBox"+ },+ "y": {+ "field": "lowerWhisker",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ }+ }+ }+ },+ {+ "mark": {+ "style": "boxWhisker",+ "type": "rule"+ },+ "encoding": {+ "y2": {+ "field": "upperWhisker"+ },+ "y": {+ "field": "upperBox",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "style": "box",+ "type": "bar"+ },+ "encoding": {+ "size": {+ "value": 5+ },+ "y2": {+ "field": "upperBox"+ },+ "y": {+ "field": "lowerBox",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "style": "boxMid",+ "type": "tick"+ },+ "encoding": {+ "color": {+ "value": "white"+ },+ "size": {+ "value": 5+ },+ "y": {+ "field": "midBox",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "age",+ "type": "ordinal"+ }+ },+ "description": "A Tukey box plot showing median and interquartile range in the US population distribution of age groups in 2000. This isn't strictly a Tukey box plot as the IQR extends beyond the min/max values for some age cohorts."+}
@@ -0,0 +1,51 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "type": "point",+ "filled": true+ },+ "encoding": {+ "color": {+ "value": "black"+ },+ "x": {+ "field": "yield",+ "scale": {+ "zero": false+ },+ "aggregate": "mean",+ "type": "quantitative",+ "axis": {+ "title": "Barley Yield"+ }+ }+ }+ },+ {+ "mark": "rule",+ "encoding": {+ "x2": {+ "field": "yield",+ "aggregate": "ci1"+ },+ "x": {+ "field": "yield",+ "aggregate": "ci0",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "y": {+ "field": "variety",+ "type": "ordinal"+ }+ },+ "description": "Error bars showing confidence intervals"+}
@@ -0,0 +1,75 @@+{+ "transform": [+ {+ "groupby": [+ "variety"+ ],+ "aggregate": [+ {+ "op": "mean",+ "as": "mean",+ "field": "yield"+ },+ {+ "op": "stdev",+ "as": "stdev",+ "field": "yield"+ }+ ]+ },+ {+ "as": "lower",+ "calculate": "datum.mean-datum.stdev"+ },+ {+ "as": "upper",+ "calculate": "datum.mean+datum.stdev"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "type": "point",+ "filled": true+ },+ "encoding": {+ "color": {+ "value": "black"+ },+ "x": {+ "field": "mean",+ "scale": {+ "zero": false+ },+ "type": "quantitative",+ "axis": {+ "title": "Barley Yield"+ }+ }+ }+ },+ {+ "mark": "rule",+ "encoding": {+ "x2": {+ "field": "lower"+ },+ "x": {+ "field": "upper",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "y": {+ "field": "variety",+ "type": "ordinal"+ }+ },+ "description": "Error bars showing standard deviations"+}
@@ -0,0 +1,46 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "area",+ "encoding": {+ "opacity": {+ "value": 0.3+ },+ "y2": {+ "field": "Miles_per_Gallon",+ "aggregate": "ci1"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "aggregate": "ci0",+ "type": "quantitative",+ "axis": {+ "title": "Miles/Gallon"+ }+ }+ }+ },+ {+ "mark": "line",+ "encoding": {+ "y": {+ "field": "Miles_per_Gallon",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "Year",+ "timeUnit": "year",+ "type": "temporal"+ }+ },+ "description": "Line chart with confidence interval band."+}
@@ -0,0 +1,75 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "point",+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "groupby": [],+ "aggregate": [+ {+ "op": "mean",+ "as": "mean_MPG",+ "field": "Miles_per_Gallon"+ },+ {+ "op": "stdev",+ "as": "dev_MPG",+ "field": "Miles_per_Gallon"+ }+ ]+ },+ {+ "as": "upper",+ "calculate": "datum.mean_MPG+datum.dev_MPG"+ },+ {+ "as": "lower",+ "calculate": "datum.mean_MPG-datum.dev_MPG"+ }+ ],+ "layer": [+ {+ "mark": "rule",+ "encoding": {+ "y": {+ "field": "mean_MPG",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "rect",+ "encoding": {+ "opacity": {+ "value": 0.2+ },+ "y2": {+ "field": "upper"+ },+ "y": {+ "field": "lower",+ "type": "quantitative"+ }+ }+ }+ ]+ }+ ],+ "description": "A scatterplot showing horsepower and miles per gallon for various cars with a global mean and standard deviation overlay."+}
@@ -0,0 +1,48 @@+{+ "transform": [+ {+ "filter": "datum.year == 2000"+ },+ {+ "as": "gender",+ "calculate": "datum.sex == 2 ? 'Female' : 'Male'"+ }+ ],+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "gender",+ "scale": {+ "range": [+ "#EA98D2",+ "#659CCA"+ ]+ },+ "type": "nominal"+ },+ "row": {+ "field": "gender",+ "type": "nominal"+ },+ "x": {+ "field": "age",+ "scale": {+ "rangeStep": 17+ },+ "type": "ordinal"+ },+ "y": {+ "field": "people",+ "aggregate": "sum",+ "type": "quantitative",+ "axis": {+ "title": "Population"+ }+ }+ },+ "description": "A trellis bar chart showing the US population distribution of age groups and gender in 2000"+}
@@ -0,0 +1,27 @@+{+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "site",+ "type": "nominal"+ },+ "x": {+ "field": "yield",+ "aggregate": "sum",+ "type": "quantitative"+ },+ "column": {+ "field": "year",+ "type": "ordinal"+ },+ "y": {+ "field": "variety",+ "type": "nominal"+ }+ },+ "description": "Barley crop yields in 1931 and 1932 shown as stacked bar charts"+}
@@ -0,0 +1,22 @@+{+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Worldwide_Gross",+ "type": "quantitative"+ },+ "column": {+ "field": "MPAA_Rating",+ "type": "ordinal"+ },+ "y": {+ "field": "US_DVD_Sales",+ "type": "quantitative"+ }+ },+ "description": "Scatterplots of movie takings vs profits for different MPAA ratings"+}
@@ -0,0 +1,25 @@+{+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "row": {+ "field": "Origin",+ "type": "ordinal"+ },+ "x": {+ "field": "Horsepower",+ "bin": {+ "maxbins": 15+ },+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ },+ "description": "Disitributions of car engine power for different countries of origin"+}
@@ -0,0 +1,31 @@+{+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/anscombe.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "X",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ },+ "column": {+ "field": "Series",+ "type": "ordinal"+ },+ "y": {+ "field": "Y",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ }+ },+ "description": "Anscombe's Quartet"+}
@@ -0,0 +1,47 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "spec": {+ "mark": "point",+ "encoding": {+ "color": {+ "field": "year",+ "type": "nominal"+ },+ "x": {+ "field": "yield",+ "scale": {+ "zero": false+ },+ "aggregate": "median",+ "type": "quantitative"+ },+ "y": {+ "field": "variety",+ "scale": {+ "rangeStep": 12+ },+ "sort": {+ "encoding": "x",+ "order": "descending"+ },+ "type": "ordinal"+ }+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "columns": 2,+ "facet": {+ "field": "site",+ "header": {+ "title": null+ },+ "sort": {+ "op": "median",+ "field": "yield"+ },+ "type": "ordinal"+ },+ "description": "The Trellis display by Becker et al. helped establish small multiples as a 'powerful mechanism for understanding interactions in studies of how a response depends on explanatory variables'"+}
@@ -0,0 +1,52 @@+{+ "height": 50,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": "area",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "width": 300,+ "resolve": {+ "scale": {+ "y": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "symbol",+ "type": "nominal",+ "legend": null+ },+ "row": {+ "field": "symbol",+ "header": {+ "labelAngle": 0,+ "title": "Stock price"+ },+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y",+ "grid": false,+ "title": null+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative",+ "axis": {+ "grid": false,+ "title": null+ }+ }+ },+ "description": "Stock prices of five large companies as a small multiples of area charts"+}
@@ -0,0 +1,42 @@+{+ "transform": [+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/unemployment.tsv"+ },+ "key": "id",+ "fields": [+ "rate"+ ]+ },+ "lookup": "id"+ }+ ],+ "height": 300,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "counties",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "field": "rate",+ "sort": "descending",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "as": "digit",+ "calculate": "substring(datum.zip_code, 0, 1)"+ }+ ],+ "height": 300,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/zipcodes.csv"+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "field": "digit",+ "type": "nominal"+ },+ "size": {+ "value": 1+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ }+ },+ "description": "US zip codes: One dot per zipcode colored by first digit"+}
@@ -0,0 +1,53 @@+{+ "height": 300,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "layer": [+ {+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "value": "#eee"+ }+ }+ },+ {+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "encoding": {+ "color": {+ "value": "steelblue"+ },+ "size": {+ "value": 5+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "One dot per airport in the US overlayed on geoshape"+}
@@ -0,0 +1,125 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "layer": [+ {+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "value": "#eee"+ }+ }+ },+ {+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "encoding": {+ "color": {+ "value": "gray"+ },+ "size": {+ "value": 5+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "equal": "SEA",+ "field": "origin"+ }+ },+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "key": "iata",+ "fields": [+ "latitude",+ "longitude"+ ]+ },+ "lookup": "origin"+ },+ {+ "as": "origin_latitude",+ "calculate": "datum.latitude"+ },+ {+ "as": "origin_longitude",+ "calculate": "datum.longitude"+ },+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "key": "iata",+ "fields": [+ "latitude",+ "longitude"+ ]+ },+ "lookup": "destination"+ },+ {+ "as": "dest_latitude",+ "calculate": "datum.latitude"+ },+ {+ "as": "dest_longitude",+ "calculate": "datum.longitude"+ }+ ],+ "mark": "rule",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/flights-airport.csv"+ },+ "encoding": {+ "latitude": {+ "field": "origin_latitude",+ "type": "quantitative"+ },+ "latitude2": {+ "field": "dest_latitude"+ },+ "longitude": {+ "field": "origin_longitude",+ "type": "quantitative"+ },+ "longitude2": {+ "field": "dest_longitude"+ }+ }+ }+ ],+ "description": "Rules (line segments) connecting SEA to every airport reachable via direct flight"+}
@@ -0,0 +1,61 @@+{+ "config": {+ "view": {+ "stroke": null+ }+ },+ "resolve": {+ "scale": {+ "color": "independent"+ }+ },+ "repeat": {+ "row": [+ "population",+ "engineers",+ "hurricanes"+ ]+ },+ "spec": {+ "transform": [+ {+ "as": "geo",+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ },+ "key": "id"+ },+ "lookup": "id"+ }+ ],+ "height": 300,+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/population_engineers_hurricanes.csv"+ },+ "width": 500,+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "field": {+ "repeat": "row"+ },+ "sort": "descending",+ "type": "quantitative"+ },+ "shape": {+ "field": "geo",+ "type": "geojson"+ }+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Population per state, engineers per state, and hurricanes per state"+}
@@ -0,0 +1,51 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "layer": [+ {+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "value": "#ccc"+ }+ }+ },+ {+ "mark": "text",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-state-capitals.json"+ },+ "encoding": {+ "text": {+ "field": "city",+ "type": "nominal"+ },+ "latitude": {+ "field": "lat",+ "type": "quantitative"+ },+ "longitude": {+ "field": "lon",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "US state capitals overlayed on map of the US"+}
@@ -0,0 +1,125 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "layer": [+ {+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "value": "#eee"+ }+ }+ },+ {+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "encoding": {+ "color": {+ "value": "gray"+ },+ "size": {+ "value": 5+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "key": "iata",+ "fields": [+ "latitude",+ "longitude"+ ]+ },+ "lookup": "airport"+ }+ ],+ "mark": "line",+ "data": {+ "values": [+ {+ "airport": "SEA",+ "order": 1+ },+ {+ "airport": "SFO",+ "order": 2+ },+ {+ "airport": "LAX",+ "order": 3+ },+ {+ "airport": "LAS",+ "order": 4+ },+ {+ "airport": "DFW",+ "order": 5+ },+ {+ "airport": "DEN",+ "order": 6+ },+ {+ "airport": "ORD",+ "order": 7+ },+ {+ "airport": "JFK",+ "order": 8+ },+ {+ "airport": "ATL",+ "order": 9+ }+ ]+ },+ "encoding": {+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ },+ "order": {+ "field": "order",+ "type": "ordinal"+ }+ }+ }+ ],+ "description": "Line drawn between airports in the U.S. simulating a flight itinerary"+}
@@ -0,0 +1,49 @@+{+ "transform": [+ {+ "as": "geo",+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ },+ "key": "id"+ },+ "lookup": "id"+ }+ ],+ "height": 300,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/income.json"+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "field": "pct",+ "sort": "descending",+ "type": "quantitative"+ },+ "shape": {+ "field": "geo",+ "type": "geojson"+ },+ "row": {+ "field": "group",+ "type": "nominal"+ }+ },+ "description": "Income in the U.S. by state, faceted over income brackets"+}
@@ -0,0 +1,119 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 700,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "strokeWidth": 2,+ "stroke": "rgb(251,247,238)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonBoroughs.json",+ "format": {+ "feature": "boroughs",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "value": "#ddc"+ }+ }+ },+ {+ "transform": [+ {+ "as": "bLabel",+ "calculate": "indexof (datum.name,' ') > 0 ? substring(datum.name,0,indexof(datum.name, ' ')) : datum.name"+ }+ ],+ "mark": "text",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonCentroids.json"+ },+ "encoding": {+ "size": {+ "value": 8+ },+ "text": {+ "field": "bLabel",+ "type": "nominal"+ },+ "latitude": {+ "field": "cy",+ "type": "quantitative"+ },+ "opacity": {+ "value": 0.6+ },+ "longitude": {+ "field": "cx",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "strokeWidth": 2,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonTubeLines.json",+ "format": {+ "feature": "line",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "field": "id",+ "scale": {+ "domain": [+ "Bakerloo",+ "Central",+ "Circle",+ "District",+ "DLR",+ "Hammersmith & City",+ "Jubilee",+ "Metropolitan",+ "Northern",+ "Piccadilly",+ "Victoria",+ "Waterloo & City"+ ],+ "range": [+ "rgb(137,78,36)",+ "rgb(220,36,30)",+ "rgb(255,206,0)",+ "rgb(1,114,41)",+ "rgb(0,175,173)",+ "rgb(215,153,175)",+ "rgb(106,114,120)",+ "rgb(114,17,84)",+ "rgb(0,0,0)",+ "rgb(0,24,168)",+ "rgb(0,160,226)",+ "rgb(106,187,170)"+ ]+ },+ "type": "nominal",+ "legend": {+ "offset": 0,+ "orient": "bottom-right",+ "title": null+ }+ }+ }+ }+ ],+ "description": "Geographic position of London underground lines"+}
@@ -0,0 +1,102 @@+{+ "config": {+ "scale": {+ "bandPaddingInner": 0.2+ }+ },+ "mark": {+ "cursor": "pointer",+ "stroke": "black",+ "fill": "#4C78A8",+ "type": "bar"+ },+ "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+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "highlight": {+ "empty": "none",+ "type": "single",+ "on": "mouseover"+ },+ "select": {+ "type": "multi"+ }+ },+ "encoding": {+ "strokeWidth": {+ "value": 0,+ "condition": [+ {+ "value": 2,+ "test": {+ "and": [+ {+ "selection": "select"+ },+ "length(data(\"select_store\"))"+ ]+ }+ },+ {+ "value": 1,+ "selection": "highlight"+ }+ ]+ },+ "x": {+ "field": "a",+ "type": "ordinal"+ },+ "fillOpacity": {+ "value": 0.3,+ "condition": {+ "value": 1,+ "selection": "select"+ }+ },+ "y": {+ "field": "b",+ "type": "quantitative"+ }+ },+ "description": "A bar chart with highlighting on hover and selecting on click. Inspired by Tableau's interaction style."+}
@@ -0,0 +1,80 @@+{+ "config": {+ "axisY": {+ "minExtent": 30+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "color": "orange",+ "type": "line"+ },+ "encoding": {+ "y": {+ "field": "temp_max",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "red",+ "type": "line"+ },+ "encoding": {+ "y": {+ "field": "temp_min",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "rule",+ "selection": {+ "hover": {+ "empty": "none",+ "type": "single",+ "on": "mouseover"+ }+ },+ "encoding": {+ "color": {+ "condition": {+ "value": "transparent",+ "selection": {+ "not": "hover"+ }+ }+ }+ }+ }+ ],+ "encoding": {+ "tooltip": [+ {+ "field": "date",+ "timeUnit": "yearmonthdate",+ "type": "temporal"+ },+ {+ "field": "temp_max",+ "type": "quantitative"+ },+ {+ "field": "temp_min",+ "type": "quantitative"+ }+ ],+ "x": {+ "field": "date",+ "timeUnit": "yearmonthdate",+ "type": "temporal"+ }+ },+ "description": "Multi Series Line Chart with Tooltip"+}
@@ -0,0 +1,32 @@+{+ "mark": "point",+ "data": {+ "url": "data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "brush": {+ "init": null,+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Cylinders",+ "selection": "brush",+ "type": "ordinal"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Drag out a rectangular brush to hughlight points."+}
@@ -0,0 +1,37 @@+{+ "mark": "point",+ "data": {+ "url": "data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "brush": {+ "init": {+ "x": [+ 55,+ 160+ ]+ },+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Cylinders",+ "selection": "brush",+ "type": "ordinal"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Drag out a rectangular brush to hughlight points."+}
@@ -0,0 +1,37 @@+{+ "mark": "point",+ "data": {+ "url": "data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "brush": {+ "init": {+ "y": [+ 13,+ 37+ ]+ },+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Cylinders",+ "selection": "brush",+ "type": "ordinal"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Drag out a rectangular brush to hughlight points."+}
@@ -0,0 +1,41 @@+{+ "mark": "point",+ "data": {+ "url": "data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "brush": {+ "init": {+ "x": [+ 55,+ 160+ ],+ "y": [+ 13,+ 37+ ]+ },+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Cylinders",+ "selection": "brush",+ "type": "ordinal"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Drag out a rectangular brush to hughlight points."+}
@@ -0,0 +1,36 @@+{+ "transform": [+ {+ "as": "url",+ "calculate": "'https://www.google.com/search?q=' + datum.Name"+ }+ ],+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "href": {+ "field": "url",+ "type": "nominal"+ },+ "tooltip": {+ "field": "Name",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Scatterplot with external links and tooltips"+}
@@ -0,0 +1,31 @@+{+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "myBrush": {+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Cylinders",+ "selection": "myBrush",+ "type": "ordinal"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Drag out a rectangular brush to highlight points"+}
@@ -0,0 +1,45 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/unemployment-across-industries.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "area",+ "selection": {+ "myBrush": {+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "myBrush"+ }+ }+ ],+ "mark": {+ "color": "goldenrod",+ "type": "area"+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "date",+ "timeUnit": "yearmonth",+ "type": "temporal"+ },+ "y": {+ "field": "count",+ "aggregate": "sum",+ "type": "quantitative"+ }+ },+ "description": "Area chart with rectangular brush"+}
@@ -0,0 +1,32 @@+{+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "myPaintbrush": {+ "nearest": true,+ "type": "multi",+ "on": "mouseover"+ }+ },+ "encoding": {+ "size": {+ "value": 50,+ "condition": {+ "value": 300,+ "selection": "myPaintbrush"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Mouse over individual points or select multiple points with the shift key"+}
@@ -0,0 +1,40 @@+{+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "myGrid": {+ "bind": "scales",+ "type": "interval"+ }+ },+ "encoding": {+ "size": {+ "field": "Cylinders",+ "type": "quantitative"+ },+ "x": {+ "field": "Horsepower",+ "scale": {+ "domain": [+ 75,+ 150+ ]+ },+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "scale": {+ "domain": [+ 20,+ 40+ ]+ },+ "type": "quantitative"+ }+ },+ "description": "Drag to pan. Zoom in or out with mousewheel/zoom gesture."+}
@@ -0,0 +1,86 @@+{+ "transform": [+ {+ "as": "Year",+ "calculate": "year(datum.Year)"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "circle",+ "selection": {+ "CylYr": {+ "init": {+ "Cylinders": 4,+ "Year": 1977+ },+ "bind": {+ "Cylinders": {+ "max": 8,+ "input": "range",+ "name": "Cylinders ",+ "step": 1,+ "min": 3+ },+ "Year": {+ "max": 1981,+ "input": "range",+ "name": "Year ",+ "step": 1,+ "min": 1969+ }+ },+ "type": "single",+ "fields": [+ "Cylinders",+ "Year"+ ]+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Origin",+ "selection": "CylYr",+ "type": "nominal"+ }+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "CylYr"+ }+ }+ ],+ "mark": "circle",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "size": {+ "value": 100+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "Drag the sliders to highlight points"+}
@@ -0,0 +1,59 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "selection": {+ "myBrush": {+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ },+ "encoding": {+ "opacity": {+ "value": 0.7,+ "condition": {+ "value": 1,+ "selection": "myBrush"+ }+ },+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "myBrush"+ }+ }+ ],+ "mark": "rule",+ "encoding": {+ "color": {+ "value": "firebrick"+ },+ "size": {+ "value": 3+ }+ },+ "description": "Drag over bars to update selection average"+ }+ ],+ "encoding": {+ "y": {+ "field": "precipitation",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,109 @@+{+ "height": 400,+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv",+ "format": {+ "parse": {+ "date": "date"+ }+ }+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "layer": [+ {+ "mark": "line"+ },+ {+ "mark": "point",+ "selection": {+ "myTooltip": {+ "nearest": true,+ "empty": "none",+ "encodings": [+ "x"+ ],+ "type": "single",+ "on": "mouseover"+ }+ },+ "encoding": {+ "opacity": {+ "value": 0,+ "condition": {+ "value": 1,+ "selection": "myTooltip"+ }+ }+ }+ }+ ],+ "encoding": {+ "color": {+ "field": "symbol",+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "type": "temporal"+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "myTooltip"+ }+ }+ ],+ "layer": [+ {+ "mark": {+ "color": "gray",+ "type": "rule"+ },+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal"+ }+ }+ },+ {+ "mark": {+ "dx": 5,+ "dy": -5,+ "align": "left",+ "type": "text"+ },+ "encoding": {+ "color": {+ "field": "symbol",+ "type": "nominal"+ },+ "text": {+ "field": "price",+ "type": "quantitative"+ },+ "x": {+ "field": "date",+ "type": "temporal"+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ }+ }+ ]+ }+ ],+ "description": "Displays tooltips for all stock prices of the hovered time"+}
@@ -0,0 +1,56 @@+{+ "config": {+ "style": {+ "label": {+ "dx": 3,+ "align": "left",+ "baseline": "middle"+ }+ }+ },+ "data": {+ "values": [+ {+ "a": "A",+ "b": 28+ },+ {+ "a": "B",+ "b": 55+ },+ {+ "a": "C",+ "b": 43+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar"+ },+ {+ "mark": {+ "style": "label",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "b",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "b",+ "type": "quantitative"+ },+ "y": {+ "field": "a",+ "type": "ordinal"+ }+ },+ "description": "A simple bar chart with embedded data labels"+}
@@ -0,0 +1,51 @@+{+ "config": {+ "text": {+ "baseline": "middle"+ },+ "scale": {+ "bandPaddingInner": 0,+ "bandPaddingOuter": 0+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "rect",+ "encoding": {+ "color": {+ "field": "*",+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "text",+ "encoding": {+ "color": {+ "value": "white"+ },+ "text": {+ "field": "*",+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "ordinal"+ }+ },+ "description": "Layering text over 'heatmap'"+}
@@ -0,0 +1,157 @@+{+ "transform": [+ {+ "as": "year",+ "calculate": "year(datum.Date)"+ },+ {+ "as": "month",+ "calculate": "month(datum.Date)"+ },+ {+ "as": "decade",+ "calculate": "floor(datum.year / 10)"+ },+ {+ "as": "scaled_date",+ "calculate": "(datum.year % 10) + (datum.month / 12)"+ }+ ],+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/co2-concentration.csv",+ "format": {+ "parse": {+ "Date": "utc:'%Y-%m-%d'"+ }+ }+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "orient": "vertical",+ "type": "line"+ },+ "encoding": {+ "color": {+ "field": "decade",+ "type": "nominal",+ "legend": null+ }+ }+ },+ {+ "transform": [+ {+ "groupby": [+ "decade"+ ],+ "aggregate": [+ {+ "op": "argmin",+ "as": "aggregated",+ "field": "scaled_date"+ }+ ]+ },+ {+ "as": "scaled_date",+ "calculate": "datum.aggregated.scaled_date"+ },+ {+ "as": "CO2",+ "calculate": "datum.aggregated.CO2"+ }+ ],+ "mark": {+ "dx": 3,+ "dy": 1,+ "align": "left",+ "type": "text",+ "baseline": "top"+ },+ "encoding": {+ "text": {+ "field": "aggregated.year",+ "type": "nominal"+ }+ }+ },+ {+ "transform": [+ {+ "groupby": [+ "decade"+ ],+ "aggregate": [+ {+ "op": "argmax",+ "as": "aggregated",+ "field": "scaled_date"+ }+ ]+ },+ {+ "as": "scaled_date",+ "calculate": "datum.aggregated.scaled_date"+ },+ {+ "as": "CO2",+ "calculate": "datum.aggregated.CO2"+ }+ ],+ "mark": {+ "dx": 3,+ "dy": 1,+ "align": "left",+ "type": "text",+ "baseline": "bottom"+ },+ "encoding": {+ "text": {+ "field": "aggregated.year",+ "type": "nominal"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "scaled_date",+ "type": "quantitative",+ "axis": {+ "values": [+ 1,+ 2,+ 3,+ 4,+ 5,+ 6,+ 7,+ 8,+ 9+ ],+ "tickCount": 10,+ "title": "Year into decade"+ }+ },+ "y": {+ "field": "CO2",+ "scale": {+ "zero": false+ },+ "type": "quantitative",+ "axis": {+ "title": "CO2 concentration in ppm"+ }+ }+ },+ "description": "Carbon dioxide in the atmosphere."+}
@@ -0,0 +1,166 @@+{+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "data": {+ "values": [+ {+ "Value": 54.8,+ "Day": 1+ },+ {+ "Value": 112.1,+ "Day": 2+ },+ {+ "Value": 63.6,+ "Day": 3+ },+ {+ "Value": 37.6,+ "Day": 4+ },+ {+ "Value": 79.7,+ "Day": 5+ },+ {+ "Value": 137.9,+ "Day": 6+ },+ {+ "Value": 120.1,+ "Day": 7+ },+ {+ "Value": 103.3,+ "Day": 8+ },+ {+ "Value": 394.8,+ "Day": 9+ },+ {+ "Value": 199.5,+ "Day": 10+ },+ {+ "Value": 72.3,+ "Day": 11+ },+ {+ "Value": 51.1,+ "Day": 12+ },+ {+ "Value": 112,+ "Day": 13+ },+ {+ "Value": 174.5,+ "Day": 14+ },+ {+ "Value": 130.5,+ "Day": 15+ }+ ]+ },+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "Day",+ "type": "ordinal",+ "axis": {+ "labelAngle": 0+ }+ },+ "y": {+ "field": "Value",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "filter": "datum.Value >= 300"+ },+ {+ "as": "baseline",+ "calculate": "300"+ }+ ],+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#e45755"+ },+ "x": {+ "field": "Day",+ "type": "ordinal",+ "axis": {+ "labelAngle": 0+ }+ },+ "y2": {+ "field": "Value"+ },+ "y": {+ "field": "baseline",+ "type": "quantitative"+ }+ }+ }+ ]+ },+ {+ "data": {+ "values": [+ {+ "ThresholdValue": 300,+ "Threshold": "hazardous"+ }+ ]+ },+ "layer": [+ {+ "mark": "rule",+ "encoding": {+ "y": {+ "field": "ThresholdValue",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "dx": -2,+ "dy": -4,+ "align": "right",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "Threshold",+ "type": "ordinal"+ },+ "x": {+ "value": "width"+ },+ "y": {+ "field": "ThresholdValue",+ "type": "quantitative",+ "axis": {+ "title": "PM2.5 Value"+ }+ }+ }+ }+ ]+ }+ ],+ "description": "Bar chart that highlights values beyond a threshold. The PM2.5 value of Beijing observed 15 days, highlighting the days when PM2.5 level is hazardous to human health. Data source https://chartaccent.github.io/chartaccent.html"+}
@@ -0,0 +1,40 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal"+ },+ "y": {+ "field": "precipitation",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "rule",+ "encoding": {+ "color": {+ "value": "red"+ },+ "size": {+ "value": 3+ },+ "y": {+ "field": "precipitation",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "Monthly precipitation with mean value overlay"+}
@@ -0,0 +1,40 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "bin": true,+ "type": "quantitative",+ "axis": null+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "rule",+ "encoding": {+ "color": {+ "value": "red"+ },+ "size": {+ "value": 5+ },+ "x": {+ "field": "IMDB_Rating",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "Histogram with global mean overlay"+}
@@ -0,0 +1,247 @@+{+ "data": {+ "values": [+ {+ "year": "1875",+ "population": 1309+ },+ {+ "year": "1890",+ "population": 1558+ },+ {+ "year": "1910",+ "population": 4512+ },+ {+ "year": "1925",+ "population": 8180+ },+ {+ "year": "1933",+ "population": 15915+ },+ {+ "year": "1939",+ "population": 24824+ },+ {+ "year": "1946",+ "population": 28275+ },+ {+ "year": "1950",+ "population": 29189+ },+ {+ "year": "1964",+ "population": 29881+ },+ {+ "year": "1971",+ "population": 26007+ },+ {+ "year": "1981",+ "population": 24029+ },+ {+ "year": "1985",+ "population": 23340+ },+ {+ "year": "1989",+ "population": 22307+ },+ {+ "year": "1990",+ "population": 22087+ },+ {+ "year": "1991",+ "population": 22139+ },+ {+ "year": "1992",+ "population": 22105+ },+ {+ "year": "1993",+ "population": 22242+ },+ {+ "year": "1994",+ "population": 22801+ },+ {+ "year": "1995",+ "population": 24273+ },+ {+ "year": "1996",+ "population": 25640+ },+ {+ "year": "1997",+ "population": 27393+ },+ {+ "year": "1998",+ "population": 29505+ },+ {+ "year": "1999",+ "population": 32124+ },+ {+ "year": "2000",+ "population": 33791+ },+ {+ "year": "2001",+ "population": 35297+ },+ {+ "year": "2002",+ "population": 36179+ },+ {+ "year": "2003",+ "population": 36829+ },+ {+ "year": "2004",+ "population": 37493+ },+ {+ "year": "2005",+ "population": 38376+ },+ {+ "year": "2006",+ "population": 39008+ },+ {+ "year": "2007",+ "population": 39366+ },+ {+ "year": "2008",+ "population": 39821+ },+ {+ "year": "2009",+ "population": 40179+ },+ {+ "year": "2010",+ "population": 40511+ },+ {+ "year": "2011",+ "population": 40465+ },+ {+ "year": "2012",+ "population": 40905+ },+ {+ "year": "2013",+ "population": 41258+ },+ {+ "year": "2014",+ "population": 41777+ }+ ],+ "format": {+ "parse": {+ "year": "date:'%Y'"+ }+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "rect",+ "data": {+ "values": [+ {+ "event": "Nazi Rule",+ "start": "1933",+ "end": "1945"+ },+ {+ "event": "GDR (East Germany)",+ "start": "1948",+ "end": "1989"+ }+ ],+ "format": {+ "parse": {+ "start": "date:'%Y'",+ "end": "date:'%Y'"+ }+ }+ },+ "encoding": {+ "x2": {+ "field": "end",+ "timeUnit": "year"+ },+ "color": {+ "field": "event",+ "type": "nominal"+ },+ "x": {+ "field": "start",+ "timeUnit": "year",+ "type": "temporal",+ "axis": null+ }+ }+ },+ {+ "mark": "line",+ "encoding": {+ "color": {+ "value": "#333"+ },+ "x": {+ "field": "year",+ "timeUnit": "year",+ "type": "temporal",+ "axis": {+ "title": null+ }+ },+ "y": {+ "field": "population",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "point",+ "encoding": {+ "color": {+ "value": "#333"+ },+ "x": {+ "field": "year",+ "timeUnit": "year",+ "type": "temporal",+ "axis": {+ "title": null+ }+ },+ "y": {+ "field": "population",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "The population of the German city of Falkensee over time with annotated time periods highlighted"+}
@@ -0,0 +1,289 @@+{+ "transform": [+ {+ "as": "isIncrease",+ "calculate": "datum.open > datum.close"+ }+ ],+ "data": {+ "values": [+ {+ "low": 28.45,+ "ret": -4.89396411092985,+ "close": 30.04,+ "date": "01-Jun-2009",+ "open": 28.7,+ "high": 30.05,+ "signal": "short"+ },+ {+ "low": 28.3,+ "ret": -0.322580645161295,+ "close": 29.63,+ "date": "02-Jun-2009",+ "open": 30.04,+ "high": 30.13,+ "signal": "short"+ },+ {+ "low": 29.62,+ "ret": 3.68663594470045,+ "close": 31.02,+ "date": "03-Jun-2009",+ "open": 29.62,+ "high": 31.79,+ "signal": "short"+ },+ {+ "low": 29.92,+ "ret": 4.51010886469673,+ "close": 30.18,+ "date": "04-Jun-2009",+ "open": 31.02,+ "high": 31.02,+ "signal": "short"+ },+ {+ "low": 28.85,+ "ret": 6.08424336973478,+ "close": 29.62,+ "date": "05-Jun-2009",+ "open": 29.39,+ "high": 30.81,+ "signal": "short"+ },+ {+ "low": 26.41,+ "ret": 1.2539184952978,+ "close": 29.77,+ "date": "08-Jun-2009",+ "open": 30.84,+ "high": 31.82,+ "signal": "short"+ },+ {+ "low": 27.79,+ "ret": -5.02431118314424,+ "close": 28.27,+ "date": "09-Jun-2009",+ "open": 29.77,+ "high": 29.77,+ "signal": "short"+ },+ {+ "low": 26.9,+ "ret": -5.46623794212217,+ "close": 28.46,+ "date": "10-Jun-2009",+ "open": 26.9,+ "high": 29.74,+ "signal": "short"+ },+ {+ "low": 26.81,+ "ret": -8.3743842364532,+ "close": 28.11,+ "date": "11-Jun-2009",+ "open": 27.36,+ "high": 28.11,+ "signal": "short"+ },+ {+ "low": 27.73,+ "ret": -5.52763819095477,+ "close": 28.15,+ "date": "12-Jun-2009",+ "open": 28.08,+ "high": 28.5,+ "signal": "short"+ },+ {+ "low": 29.64,+ "ret": 3.4920634920635,+ "close": 30.81,+ "date": "15-Jun-2009",+ "open": 29.7,+ "high": 31.09,+ "signal": "long"+ },+ {+ "low": 30.07,+ "ret": 0.155038759689914,+ "close": 32.68,+ "date": "16-Jun-2009",+ "open": 30.81,+ "high": 32.75,+ "signal": "short"+ },+ {+ "low": 30.64,+ "ret": 5.82822085889571,+ "close": 31.54,+ "date": "17-Jun-2009",+ "open": 31.19,+ "high": 32.77,+ "signal": "short"+ },+ {+ "low": 29.6,+ "ret": 8.17610062893082,+ "close": 30.03,+ "date": "18-Jun-2009",+ "open": 31.54,+ "high": 31.54,+ "signal": "short"+ },+ {+ "low": 27.56,+ "ret": 8.59872611464968,+ "close": 27.99,+ "date": "19-Jun-2009",+ "open": 29.16,+ "high": 29.32,+ "signal": "short"+ },+ {+ "low": 30.3,+ "ret": 15.4907975460123,+ "close": 31.17,+ "date": "22-Jun-2009",+ "open": 30.4,+ "high": 32.05,+ "signal": "short"+ },+ {+ "low": 27.83,+ "ret": 11.7370892018779,+ "close": 30.58,+ "date": "23-Jun-2009",+ "open": 31.3,+ "high": 31.54,+ "signal": "short"+ },+ {+ "low": 28.79,+ "ret": -10.4234527687296,+ "close": 29.05,+ "date": "24-Jun-2009",+ "open": 30.58,+ "high": 30.58,+ "signal": "long"+ },+ {+ "low": 26.3,+ "ret": 0,+ "close": 26.36,+ "date": "25-Jun-2009",+ "open": 29.45,+ "high": 29.56,+ "signal": "long"+ },+ {+ "low": 25.76,+ "ret": 0,+ "close": 25.93,+ "date": "26-Jun-2009",+ "open": 27.09,+ "high": 27.22,+ "signal": "long"+ },+ {+ "low": 25.29,+ "ret": 5.26315789473684,+ "close": 25.35,+ "date": "29-Jun-2009",+ "open": 25.93,+ "high": 27.18,+ "signal": "long"+ },+ {+ "low": 25.02,+ "ret": 6.73758865248228,+ "close": 26.35,+ "date": "30-Jun-2009",+ "open": 25.36,+ "high": 27.38,+ "signal": "long"+ }+ ]+ },+ "width": 320,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "rule",+ "encoding": {+ "color": {+ "field": "isIncrease",+ "scale": {+ "range": [+ "#ae1325",+ "#06982d"+ ]+ },+ "type": "nominal",+ "legend": null+ },+ "x": {+ "field": "date",+ "scale": {+ "domain": [+ {+ "date": 31,+ "year": 2009,+ "month": "May"+ },+ {+ "date": 1,+ "year": 2009,+ "month": "Jul"+ }+ ]+ },+ "timeUnit": "yearmonthdate",+ "type": "temporal",+ "axis": {+ "format": "%m/%d",+ "title": "Date in 2009"+ }+ },+ "y2": {+ "field": "high"+ },+ "y": {+ "field": "low",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "field": "isIncrease",+ "type": "nominal",+ "legend": null+ },+ "size": {+ "value": 5+ },+ "x": {+ "field": "date",+ "timeUnit": "yearmonthdate",+ "type": "temporal"+ },+ "y2": {+ "field": "close"+ },+ "y": {+ "field": "open",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "A candlestick chart inspired by Protovis (http://mbostock.github.io/protovis/ex/candlestick.html)"+}
@@ -0,0 +1,99 @@+{+ "transform": [+ {+ "filter": {+ "field": "country",+ "oneOf": [+ "China",+ "India",+ "United States",+ "Indonesia",+ "Brazil"+ ]+ }+ },+ {+ "filter": {+ "field": "year",+ "oneOf": [+ 1955,+ 2000+ ]+ }+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/countries.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "line",+ "encoding": {+ "color": {+ "value": "#db646f"+ },+ "x": {+ "field": "life_expect",+ "type": "quantitative"+ },+ "detail": {+ "field": "country",+ "type": "nominal"+ }+ }+ },+ {+ "mark": {+ "type": "point",+ "filled": true+ },+ "encoding": {+ "color": {+ "field": "year",+ "scale": {+ "domain": [+ 1955,+ 2000+ ],+ "range": [+ "#e6959c",+ "#911a24"+ ]+ },+ "type": "ordinal",+ "legend": {+ "title": "Year"+ }+ },+ "size": {+ "value": 100+ },+ "opacity": {+ "value": 1+ },+ "x": {+ "field": "life_expect",+ "type": "quantitative",+ "axis": {+ "title": "Life Expectancy (years)"+ }+ }+ }+ }+ ],+ "encoding": {+ "y": {+ "field": "country",+ "type": "nominal",+ "axis": {+ "minExtent": 70,+ "offset": 5,+ "domain": false,+ "title": "Country",+ "ticks": false+ }+ }+ },+ "description": "A ranged dot plot that uses 'layer' to convey changing life expectancy for the five most populous countries (between 1955 and 2000)."+}
@@ -0,0 +1,187 @@+{+ "config": {+ "tick": {+ "thickness": 2+ }+ },+ "data": {+ "values": [+ {+ "measures": [+ 220,+ 270+ ],+ "markers": [+ 250+ ],+ "ranges": [+ 150,+ 225,+ 300+ ],+ "title": "Revenue"+ },+ {+ "measures": [+ 21,+ 23+ ],+ "markers": [+ 26+ ],+ "ranges": [+ 20,+ 25,+ 30+ ],+ "title": "Profit"+ },+ {+ "measures": [+ 100,+ 320+ ],+ "markers": [+ 550+ ],+ "ranges": [+ 350,+ 500,+ 600+ ],+ "title": "Order size"+ },+ {+ "measures": [+ 1000,+ 1650+ ],+ "markers": [+ 2100+ ],+ "ranges": [+ 1400,+ 2000,+ 2500+ ],+ "title": "New customers"+ },+ {+ "measures": [+ 3.2,+ 4.7+ ],+ "markers": [+ 4.4+ ],+ "ranges": [+ 3.5,+ 4.25,+ 5+ ],+ "title": "Satisfaction"+ }+ ]+ },+ "resolve": {+ "scale": {+ "x": "independent"+ }+ },+ "spec": {+ "layer": [+ {+ "mark": {+ "color": "#eee",+ "type": "bar"+ },+ "encoding": {+ "x": {+ "field": "ranges[2]",+ "scale": {+ "nice": false+ },+ "type": "quantitative",+ "axis": {+ "title": null+ }+ }+ }+ },+ {+ "mark": {+ "color": "#ddd",+ "type": "bar"+ },+ "encoding": {+ "x": {+ "field": "ranges[1]",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "#ccc",+ "type": "bar"+ },+ "encoding": {+ "x": {+ "field": "ranges[0]",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "lightsteelblue",+ "size": 10,+ "type": "bar"+ },+ "encoding": {+ "x": {+ "field": "measures[1]",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "steelblue",+ "size": 10,+ "type": "bar"+ },+ "encoding": {+ "x": {+ "field": "measures[0]",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "black",+ "type": "tick"+ },+ "encoding": {+ "x": {+ "field": "markers[0]",+ "type": "quantitative"+ }+ }+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "facet": {+ "row": {+ "field": "title",+ "header": {+ "labelAngle": 30,+ "title": null+ },+ "type": "ordinal"+ }+ },+ "description": "Bullet chart"+}
@@ -0,0 +1,53 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "resolve": {+ "scale": {+ "y": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "y": {+ "field": "precipitation",+ "aggregate": "mean",+ "type": "quantitative",+ "axis": {+ "grid": false+ }+ }+ }+ },+ {+ "mark": "line",+ "encoding": {+ "color": {+ "value": "firebrick"+ },+ "y": {+ "field": "temp_max",+ "scale": {+ "zero": false+ },+ "aggregate": "mean",+ "type": "quantitative",+ "axis": {+ "grid": false+ }+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal"+ }+ },+ "description": "Layered bar/line chart with dual axes"+}
@@ -0,0 +1,159 @@+{+ "height": 50,+ "config": {+ "area": {+ "orient": "vertical",+ "interpolate": "monotone"+ }+ },+ "data": {+ "values": [+ {+ "x": 1,+ "y": 28+ },+ {+ "x": 2,+ "y": 55+ },+ {+ "x": 3,+ "y": 43+ },+ {+ "x": 4,+ "y": 91+ },+ {+ "x": 5,+ "y": 81+ },+ {+ "x": 6,+ "y": 53+ },+ {+ "x": 7,+ "y": 19+ },+ {+ "x": 8,+ "y": 87+ },+ {+ "x": 9,+ "y": 52+ },+ {+ "x": 10,+ "y": 48+ },+ {+ "x": 11,+ "y": 24+ },+ {+ "x": 12,+ "y": 49+ },+ {+ "x": 13,+ "y": 87+ },+ {+ "x": 14,+ "y": 66+ },+ {+ "x": 15,+ "y": 17+ },+ {+ "x": 16,+ "y": 27+ },+ {+ "x": 17,+ "y": 68+ },+ {+ "x": 18,+ "y": 16+ },+ {+ "x": 19,+ "y": 49+ },+ {+ "x": 20,+ "y": 15+ }+ ]+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "type": "area",+ "clip": true+ },+ "encoding": {+ "opacity": {+ "value": 0.6+ },+ "y": {+ "field": "y",+ "scale": {+ "domain": [+ 0,+ 50+ ]+ },+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "as": "ny",+ "calculate": "datum.y - 50"+ }+ ],+ "mark": {+ "type": "area",+ "clip": true+ },+ "encoding": {+ "opacity": {+ "value": 0.3+ },+ "y": {+ "field": "ny",+ "scale": {+ "domain": [+ 0,+ 50+ ]+ },+ "type": "quantitative",+ "axis": {+ "title": "y"+ }+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "x",+ "scale": {+ "zero": false,+ "nice": false+ },+ "type": "quantitative"+ }+ },+ "description": "Horizon chart with 2 layers. (See https://idl.cs.washington.edu/papers/horizon/ for more details on horizon charts.)"+}
@@ -0,0 +1,181 @@+{+ "height": 200,+ "data": {+ "url": "https://vega.github.io/vega-lite/data/weather.json"+ },+ "width": 250,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "title": "Weekly Weather Observations and Predictions",+ "layer": [+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#ccc"+ },+ "size": {+ "value": 20+ },+ "x": {+ "field": "id",+ "type": "ordinal",+ "axis": {+ "title": "Day"+ }+ },+ "y2": {+ "field": "record.high"+ },+ "y": {+ "field": "record.low",+ "scale": {+ "domain": [+ 10,+ 70+ ]+ },+ "type": "quantitative",+ "axis": {+ "title": "Temperature (F)"+ }+ }+ }+ },+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#999"+ },+ "size": {+ "value": 20+ },+ "x": {+ "field": "id",+ "type": "ordinal"+ },+ "y2": {+ "field": "normal.high"+ },+ "y": {+ "field": "normal.low",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#000"+ },+ "size": {+ "value": 12+ },+ "x": {+ "field": "id",+ "type": "ordinal"+ },+ "y2": {+ "field": "actual.high"+ },+ "y": {+ "field": "actual.low",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#000"+ },+ "size": {+ "value": 12+ },+ "x": {+ "field": "id",+ "type": "ordinal"+ },+ "y2": {+ "field": "forecast.low.high"+ },+ "y": {+ "field": "forecast.low.low",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#000"+ },+ "size": {+ "value": 3+ },+ "x": {+ "field": "id",+ "type": "ordinal"+ },+ "y2": {+ "field": "forecast.high.low"+ },+ "y": {+ "field": "forecast.low.high",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "#000"+ },+ "size": {+ "value": 12+ },+ "x": {+ "field": "id",+ "type": "ordinal"+ },+ "y2": {+ "field": "forecast.high.high"+ },+ "y": {+ "field": "forecast.high.low",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "dy": -105,+ "align": "center",+ "type": "text"+ },+ "encoding": {+ "text": {+ "field": "day",+ "type": "nominal"+ },+ "x": {+ "field": "id",+ "type": "ordinal",+ "axis": {+ "domain": false,+ "orient": "top",+ "titlePadding": 25,+ "labels": false,+ "title": "Day",+ "ticks": false+ }+ }+ }+ }+ ],+ "description": "A layered bar chart with floating bars representing weekly weather data"+}
@@ -0,0 +1,66 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "mean",+ "as": "rolling_mean",+ "field": "temp_max"+ }+ ],+ "frame": [+ -15,+ 15+ ]+ }+ ],+ "height": 300,+ "data": {+ "url": "data/seattle-weather.csv"+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "opacity": 0.3,+ "type": "point"+ },+ "encoding": {+ "x": {+ "field": "date",+ "title": "Date",+ "type": "temporal",+ "axis": {+ "zindex": 1,+ "gridColor": "orange",+ "gridOpacity": 0.8+ }+ },+ "y": {+ "field": "temp_max",+ "title": "Max Temperature",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "color": "red",+ "size": 3,+ "type": "line"+ },+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal"+ },+ "y": {+ "field": "rolling_mean",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "Plot showing a 30 day rolling average with raw values in the background."+}
@@ -0,0 +1,26 @@+{+ "transform": [+ {+ "filter": "datum.symbol === 'GOOG'"+ }+ ],+ "mark": "line",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Google's stock price over time."+}
@@ -0,0 +1,157 @@+{+ "transform": [+ {+ "as": "year",+ "calculate": "year(datum.Date)"+ },+ {+ "as": "month",+ "calculate": "month(datum.Date)"+ },+ {+ "as": "decade",+ "calculate": "floor(datum.year / 10)"+ },+ {+ "as": "scaled_date",+ "calculate": "(datum.year % 10) + (datum.month / 12)"+ }+ ],+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/co2-concentration.csv",+ "format": {+ "parse": {+ "Date": "utc:'%Y-%m-%d'"+ }+ }+ },+ "width": 800,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "orient": "vertical",+ "type": "line"+ },+ "encoding": {+ "color": {+ "field": "decade",+ "type": "nominal",+ "legend": null+ }+ }+ },+ {+ "transform": [+ {+ "groupby": [+ "decade"+ ],+ "aggregate": [+ {+ "op": "argmin",+ "as": "aggregated",+ "field": "scaled_date"+ }+ ]+ },+ {+ "as": "scaled_date",+ "calculate": "datum.aggregated.scaled_date"+ },+ {+ "as": "CO2",+ "calculate": "datum.aggregated.CO2"+ }+ ],+ "mark": {+ "dx": 3,+ "dy": 1,+ "align": "left",+ "type": "text",+ "baseline": "top"+ },+ "encoding": {+ "text": {+ "field": "aggregated.year",+ "type": "nominal"+ }+ }+ },+ {+ "transform": [+ {+ "groupby": [+ "decade"+ ],+ "aggregate": [+ {+ "op": "argmax",+ "as": "aggregated",+ "field": "scaled_date"+ }+ ]+ },+ {+ "as": "scaled_date",+ "calculate": "datum.aggregated.scaled_date"+ },+ {+ "as": "CO2",+ "calculate": "datum.aggregated.CO2"+ }+ ],+ "mark": {+ "dx": 3,+ "dy": 1,+ "align": "left",+ "type": "text",+ "baseline": "bottom"+ },+ "encoding": {+ "text": {+ "field": "aggregated.year",+ "type": "nominal"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "scaled_date",+ "type": "quantitative",+ "axis": {+ "values": [+ 1,+ 2,+ 3,+ 4,+ 5,+ 6,+ 7,+ 8,+ 9+ ],+ "tickCount": 10,+ "title": "Year into decade"+ }+ },+ "y": {+ "field": "CO2",+ "scale": {+ "zero": false+ },+ "type": "quantitative",+ "axis": {+ "title": "CO2 concentration in ppm"+ }+ }+ },+ "description": "Carbon dioxide in the atmosphere."+}
@@ -0,0 +1,135 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "rank",+ "as": "rank"+ }+ ],+ "groupby": [+ "matchday"+ ],+ "sort": [+ {+ "field": "point",+ "order": "descending"+ },+ {+ "field": "diff",+ "order": "descending"+ }+ ]+ }+ ],+ "mark": {+ "orient": "vertical",+ "type": "line"+ },+ "data": {+ "values": [+ {+ "diff": -1,+ "point": 0,+ "matchday": 1,+ "team": "Germany"+ },+ {+ "diff": 1,+ "point": 3,+ "matchday": 1,+ "team": "Mexico"+ },+ {+ "diff": -1,+ "point": 0,+ "matchday": 1,+ "team": "South Korea"+ },+ {+ "diff": 1,+ "point": 3,+ "matchday": 1,+ "team": "Sweden"+ },+ {+ "diff": 0,+ "point": 3,+ "matchday": 2,+ "team": "Germany"+ },+ {+ "diff": 2,+ "point": 6,+ "matchday": 2,+ "team": "Mexico"+ },+ {+ "diff": -2,+ "point": 0,+ "matchday": 2,+ "team": "South Korea"+ },+ {+ "diff": 0,+ "point": 3,+ "matchday": 2,+ "team": "Sweden"+ },+ {+ "diff": -2,+ "point": 3,+ "matchday": 3,+ "team": "Germany"+ },+ {+ "diff": -1,+ "point": 6,+ "matchday": 3,+ "team": "Mexico"+ },+ {+ "diff": 0,+ "point": 3,+ "matchday": 3,+ "team": "South Korea"+ },+ {+ "diff": 3,+ "point": 6,+ "matchday": 3,+ "team": "Sweden"+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "team",+ "scale": {+ "domain": [+ "Germany",+ "Mexico",+ "South Korea",+ "Sweden"+ ],+ "range": [+ "black",+ "#127153",+ "#c91a3c",+ "#0c71ab"+ ]+ },+ "type": "nominal"+ },+ "x": {+ "field": "matchday",+ "type": "ordinal"+ },+ "y": {+ "field": "rank",+ "type": "ordinal"+ }+ },+ "description": "Line chart showing ranks over time for thw World Cup 2018 Group F teams"+}
@@ -0,0 +1,59 @@+{+ "transform": [+ {+ "as": "v",+ "calculate": "sin(datum.u)"+ },+ {+ "as": "w",+ "calculate": "cos(datum.u)"+ }+ ],+ "height": 150,+ "data": {+ "sequence": {+ "as": "u",+ "start": 0,+ "step": 0.1,+ "stop": 12.7+ }+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "line",+ "encoding": {+ "x": {+ "field": "u",+ "title": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "v",+ "title": "sin(x)",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "stroke": "firebrick",+ "type": "line"+ },+ "encoding": {+ "x": {+ "field": "u",+ "title": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "w",+ "title": "cos(x)",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "Plots a function using a generated sequence"+}
@@ -0,0 +1,32 @@+{+ "transform": [+ {+ "filter": "datum.symbol === 'GOOG'"+ }+ ],+ "mark": {+ "color": "green",+ "point": {+ "color": "purple"+ },+ "type": "line"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Google's stock price over time with point markers."+}
@@ -0,0 +1,25 @@+{+ "mark": "line",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "symbol",+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Stock prices of 5 tech companies over time."+}
@@ -0,0 +1,27 @@+{+ "mark": "line",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/barley.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "site",+ "type": "nominal"+ },+ "x": {+ "field": "year",+ "scale": {+ "rangeStep": 50,+ "padding": 0.5+ },+ "type": "ordinal"+ },+ "y": {+ "field": "yield",+ "aggregate": "median",+ "type": "quantitative"+ }+ },+ "description": "Slope graph showing the change in yield for different barley sites. It shows the error in the year labels for the Morris site."+}
@@ -0,0 +1,29 @@+{+ "transform": [+ {+ "filter": "datum.symbol === 'GOOG'"+ }+ ],+ "mark": {+ "interpolate": "step-after",+ "type": "line"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Google's stock price over time (quantized as a step-chart)."+}
@@ -0,0 +1,29 @@+{+ "transform": [+ {+ "filter": "datum.symbol === 'GOOG'"+ }+ ],+ "mark": {+ "interpolate": "monotone",+ "type": "line"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Google's stock price over time (smoothed with monotonic interpolation)."+}
@@ -0,0 +1,31 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/driving.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "miles",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ },+ "order": {+ "field": "year",+ "type": "temporal"+ },+ "y": {+ "field": "gas",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ }+ },+ "description": "A connected scatterplot can be created by customizing line order and adding point marker in the line mark definition."+}
@@ -0,0 +1,29 @@+{+ "mark": "trail",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/stocks.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "symbol",+ "type": "nominal"+ },+ "size": {+ "field": "price",+ "type": "quantitative"+ },+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ },+ "description": "Stock prices of five tech companies over time double encoding price with vertical position and line thickness."+}
@@ -0,0 +1,50 @@+{+ "mark": {+ "point": true,+ "type": "line"+ },+ "data": {+ "values": [+ {+ "x": 1,+ "y": 10+ },+ {+ "x": 2,+ "y": 30+ },+ {+ "x": 3,+ "y": null+ },+ {+ "x": 4,+ "y": 15+ },+ {+ "x": 5,+ "y": null+ },+ {+ "x": 6,+ "y": 40+ },+ {+ "x": 7,+ "y": 20+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ },+ "description": "Line chart with markers and invalid values."+}
@@ -0,0 +1,61 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/sp500.csv"+ },+ "vconcat": [+ {+ "mark": "area",+ "width": 500,+ "encoding": {+ "x": {+ "field": "date",+ "scale": {+ "domain": {+ "selection": "myBrush"+ }+ },+ "type": "temporal",+ "axis": {+ "title": null+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative"+ }+ }+ },+ {+ "height": 60,+ "mark": "area",+ "width": 480,+ "selection": {+ "myBrush": {+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ },+ "encoding": {+ "x": {+ "field": "date",+ "type": "temporal",+ "axis": {+ "format": "%Y"+ }+ },+ "y": {+ "field": "price",+ "type": "quantitative",+ "axis": {+ "tickCount": 3,+ "grid": false+ }+ }+ }+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Overview and detail."+}
@@ -0,0 +1,70 @@+{+ "repeat": {+ "column": [+ "distance",+ "delay",+ "time"+ ]+ },+ "spec": {+ "transform": [+ {+ "as": "time",+ "calculate": "hours(datum.date)"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/flights-2k.json",+ "format": {+ "parse": {+ "date": "date"+ }+ }+ },+ "layer": [+ {+ "mark": "bar",+ "selection": {+ "myBrush": {+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "myBrush"+ }+ }+ ],+ "mark": "bar",+ "encoding": {+ "color": {+ "value": "goldenrod"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": {+ "repeat": "column"+ },+ "bin": {+ "maxbins": 20+ },+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ },+ "description": "Cross-filter."+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,60 @@+{+ "repeat": {+ "row": [+ "Horsepower",+ "Acceleration",+ "Miles_per_Gallon"+ ],+ "column": [+ "Miles_per_Gallon",+ "Acceleration",+ "Horsepower"+ ]+ },+ "spec": {+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "selection": {+ "myBrush": {+ "resolve": "union",+ "zoom": "wheel![event.shiftKey]",+ "type": "interval",+ "translate": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!",+ "on": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"+ },+ "grid": {+ "bind": "scales",+ "resolve": "global",+ "zoom": "wheel![event.shiftKey]",+ "type": "interval",+ "translate": "[mousedown[!event.shiftKey], window:mouseup] > window:mousemove!"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Origin",+ "selection": "myBrush",+ "type": "nominal"+ }+ },+ "x": {+ "field": {+ "repeat": "column"+ },+ "type": "quantitative"+ },+ "y": {+ "field": {+ "repeat": "row"+ },+ "type": "quantitative"+ }+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Scatterplot matrix"+}
@@ -0,0 +1,110 @@+{+ "config": {+ "range": {+ "heatmap": {+ "scheme": "greenblue"+ }+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "resolve": {+ "legend": {+ "color": "independent",+ "size": "independent"+ }+ },+ "vconcat": [+ {+ "layer": [+ {+ "mark": "rect",+ "width": 300,+ "encoding": {+ "color": {+ "aggregate": "count",+ "type": "quantitative",+ "legend": {+ "title": null+ }+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "myPts"+ }+ }+ ],+ "mark": "point",+ "encoding": {+ "color": {+ "value": "#666"+ },+ "size": {+ "aggregate": "count",+ "type": "quantitative",+ "legend": {+ "title": "In Selected Category"+ }+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "bin": {+ "maxbins": 10+ },+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "bin": {+ "maxbins": 10+ },+ "type": "quantitative"+ }+ }+ },+ {+ "height": 120,+ "mark": "bar",+ "width": 420,+ "selection": {+ "myPts": {+ "encodings": [+ "x"+ ],+ "type": "single"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "value": "steelblue",+ "selection": "myPts"+ }+ },+ "x": {+ "field": "Major_Genre",+ "type": "nominal",+ "axis": {+ "labelAngle": -40+ }+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "A dashboard with cross-highlighting"+}
@@ -0,0 +1,142 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "vconcat": [+ {+ "transform": [+ {+ "filter": {+ "selection": "myClick"+ }+ }+ ],+ "height": 300,+ "mark": "point",+ "width": 600,+ "selection": {+ "myBrush": {+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "#cfdebe",+ "condition": {+ "field": "weather",+ "scale": {+ "domain": [+ "sun",+ "fog",+ "drizzle",+ "rain",+ "snow"+ ],+ "range": [+ "#e7ba52",+ "#c7c7c7",+ "#aec7ea",+ "#1f77b4",+ "#9467bd"+ ]+ },+ "selection": "myBrush",+ "title": "Weather",+ "type": "nominal"+ }+ },+ "size": {+ "field": "precipitation",+ "scale": {+ "domain": [+ -1,+ 50+ ]+ },+ "type": "quantitative"+ },+ "x": {+ "field": "date",+ "timeUnit": "monthdate",+ "type": "temporal",+ "axis": {+ "format": "%b",+ "title": "Date"+ }+ },+ "y": {+ "field": "temp_max",+ "scale": {+ "domain": [+ -5,+ 40+ ]+ },+ "type": "quantitative",+ "axis": {+ "title": "Maximum Daily Temperature (C)"+ }+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "myBrush"+ }+ }+ ],+ "mark": "bar",+ "width": 600,+ "selection": {+ "myClick": {+ "encodings": [+ "color"+ ],+ "type": "multi"+ }+ },+ "encoding": {+ "color": {+ "value": "#acbf98",+ "condition": {+ "field": "weather",+ "scale": {+ "domain": [+ "sun",+ "fog",+ "drizzle",+ "rain",+ "snow"+ ],+ "range": [+ "#e7ba52",+ "#c7c7c7",+ "#aec7ea",+ "#1f77b4",+ "#9467bd"+ ]+ },+ "selection": "myClick",+ "type": "nominal"+ }+ },+ "x": {+ "aggregate": "count",+ "type": "quantitative"+ },+ "y": {+ "field": "weather",+ "type": "nominal"+ }+ }+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "title": "Seattle Weather, 2012-2015",+ "description": "A dashboard with cross-highlighting"+}
@@ -0,0 +1,163 @@+{+ "transform": [+ {+ "window": [+ {+ "op": "row_number",+ "as": "rowNumber"+ }+ ]+ }+ ],+ "hconcat": [+ {+ "mark": "point",+ "selection": {+ "brush": {+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Cylinders",+ "selection": "brush",+ "type": "ordinal"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "brush"+ }+ },+ {+ "window": [+ {+ "op": "rank",+ "as": "rank"+ }+ ]+ },+ {+ "filter": {+ "field": "rank",+ "lt": 20+ }+ }+ ],+ "mark": "text",+ "title": "Engine power",+ "encoding": {+ "text": {+ "field": "Horsepower",+ "type": "nominal"+ },+ "y": {+ "field": "rowNumber",+ "type": "ordinal",+ "axis": null+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "brush"+ }+ },+ {+ "window": [+ {+ "op": "rank",+ "as": "rank"+ }+ ]+ },+ {+ "filter": {+ "field": "rank",+ "lt": 20+ }+ }+ ],+ "mark": "text",+ "title": "Efficiency (mpg)",+ "encoding": {+ "text": {+ "field": "Miles_per_Gallon",+ "type": "nominal"+ },+ "y": {+ "field": "rowNumber",+ "type": "ordinal",+ "axis": null+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "brush"+ }+ },+ {+ "window": [+ {+ "op": "rank",+ "as": "rank"+ }+ ]+ },+ {+ "filter": {+ "field": "rank",+ "lt": 20+ }+ }+ ],+ "mark": "text",+ "title": "Country of origin",+ "encoding": {+ "text": {+ "field": "Origin",+ "type": "nominal"+ },+ "y": {+ "field": "rowNumber",+ "type": "ordinal",+ "axis": null+ }+ }+ }+ ],+ "config": {+ "view": {+ "stroke": null+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "resolve": {+ "legend": {+ "color": "independent"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Drag a rectangular brush to show (first 20) selected points in a table."+}
@@ -0,0 +1,178 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 900,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "layer": [+ {+ "mark": {+ "stroke": "#fff",+ "fill": "#ddd",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "states",+ "type": "topojson"+ }+ }+ },+ {+ "transform": [+ {+ "filter": {+ "selection": "mySelection"+ }+ },+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "key": "iata",+ "fields": [+ "latitude",+ "longitude"+ ]+ },+ "lookup": "origin"+ },+ {+ "as": "oLat",+ "calculate": "datum.latitude"+ },+ {+ "as": "oLon",+ "calculate": "datum.longitude"+ },+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "key": "iata",+ "fields": [+ "latitude",+ "longitude"+ ]+ },+ "lookup": "destination"+ },+ {+ "as": "dLat",+ "calculate": "datum.latitude"+ },+ {+ "as": "dLon",+ "calculate": "datum.longitude"+ }+ ],+ "mark": {+ "color": "black",+ "opacity": 0.35,+ "type": "rule"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/flights-airport.csv"+ },+ "encoding": {+ "latitude": {+ "field": "oLat",+ "type": "quantitative"+ },+ "latitude2": {+ "field": "dLat"+ },+ "longitude": {+ "field": "oLon",+ "type": "quantitative"+ },+ "longitude2": {+ "field": "dLon"+ }+ }+ },+ {+ "transform": [+ {+ "groupby": [+ "origin"+ ],+ "aggregate": [+ {+ "op": "count",+ "as": "routes"+ }+ ]+ },+ {+ "from": {+ "data": {+ "url": "https://vega.github.io/vega-lite/data/airports.csv"+ },+ "key": "iata",+ "fields": [+ "state",+ "latitude",+ "longitude"+ ]+ },+ "lookup": "origin"+ },+ {+ "filter": "datum.state !== 'PR' && datum.state !== 'VI'"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/flights-airport.csv"+ },+ "selection": {+ "mySelection": {+ "nearest": true,+ "empty": "none",+ "type": "single",+ "on": "mouseover",+ "fields": [+ "origin"+ ]+ }+ },+ "encoding": {+ "size": {+ "field": "routes",+ "scale": {+ "range": [+ 0,+ 1000+ ]+ },+ "type": "quantitative",+ "legend": null+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ },+ "order": {+ "field": "routes",+ "sort": "descending",+ "type": "quantitative"+ }+ }+ }+ ],+ "description": "One dot per airport in the US overlayed on geoshape"+}
@@ -0,0 +1,68 @@+{+ "data": {+ "url": "https://vega.github.io/vega-lite/data/weather.csv"+ },+ "repeat": {+ "column": [+ "temp_max",+ "precipitation",+ "wind"+ ]+ },+ "spec": {+ "layer": [+ {+ "mark": "line",+ "encoding": {+ "color": {+ "field": "location",+ "type": "nominal"+ },+ "opacity": {+ "value": 0.2+ },+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal"+ },+ "detail": {+ "field": "date",+ "timeUnit": "year",+ "type": "temporal"+ },+ "y": {+ "field": {+ "repeat": "column"+ },+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "line",+ "encoding": {+ "color": {+ "field": "location",+ "type": "nominal"+ },+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal"+ },+ "y": {+ "field": {+ "repeat": "column"+ },+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Monthly weather information for individual years and overall average for Seatle and New York"+}
@@ -0,0 +1,48 @@+{+ "transform": [+ {+ "filter": "datum.location === 'Seattle'"+ }+ ],+ "data": {+ "url": "https://vega.github.io/vega-lite/data/weather.csv"+ },+ "vconcat": [+ {+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal"+ },+ "y": {+ "field": "precipitation",+ "aggregate": "mean",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "point",+ "encoding": {+ "size": {+ "aggregate": "count",+ "type": "quantitative"+ },+ "x": {+ "field": "temp_min",+ "bin": true,+ "type": "quantitative"+ },+ "y": {+ "field": "temp_max",+ "bin": true,+ "type": "quantitative"+ }+ }+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Two vertically concatenated charts that show a histogram of precipitation in Seattle and the relationship between min and max temperature"+}
@@ -0,0 +1,34 @@+{+ "repeat": {+ "column": [+ "Horsepower",+ "Miles_per_Gallon",+ "Acceleration"+ ]+ },+ "spec": {+ "mark": "bar",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": {+ "repeat": "column"+ },+ "bin": true,+ "type": "quantitative"+ },+ "y": {+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Horizontally repeated charts that show the histograms of different parameters of cars in different countries"+}
@@ -0,0 +1,60 @@+{+ "repeat": {+ "row": [+ "Horsepower",+ "Acceleration",+ "Miles_per_Gallon"+ ],+ "column": [+ "Miles_per_Gallon",+ "Acceleration",+ "Horsepower"+ ]+ },+ "spec": {+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "selection": {+ "myBrush": {+ "resolve": "union",+ "zoom": "wheel![event.shiftKey]",+ "type": "interval",+ "translate": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!",+ "on": "[mousedown[event.shiftKey], window:mouseup] > window:mousemove!"+ },+ "grid": {+ "bind": "scales",+ "resolve": "global",+ "zoom": "wheel![event.shiftKey]",+ "type": "interval",+ "translate": "[mousedown[!event.shiftKey], window:mouseup] > window:mousemove!"+ }+ },+ "encoding": {+ "color": {+ "value": "grey",+ "condition": {+ "field": "Origin",+ "selection": "myBrush",+ "type": "nominal"+ }+ },+ "x": {+ "field": {+ "repeat": "column"+ },+ "type": "quantitative"+ },+ "y": {+ "field": {+ "repeat": "row"+ },+ "type": "quantitative"+ }+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Scatterplot matrix"+}
@@ -0,0 +1,96 @@+{+ "config": {+ "range": {+ "heatmap": {+ "scheme": "greenblue"+ }+ },+ "view": {+ "stroke": null+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "vconcat": [+ {+ "height": 60,+ "mark": "bar",+ "encoding": {+ "x": {+ "field": "IMDB_Rating",+ "bin": true,+ "type": "quantitative",+ "axis": null+ },+ "y": {+ "scale": {+ "domain": [+ 0,+ 1000+ ]+ },+ "aggregate": "count",+ "type": "quantitative",+ "axis": {+ "title": null+ }+ }+ }+ },+ {+ "hconcat": [+ {+ "mark": "rect",+ "encoding": {+ "color": {+ "aggregate": "count",+ "type": "quantitative"+ },+ "x": {+ "field": "IMDB_Rating",+ "bin": true,+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "bin": true,+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "bar",+ "width": 60,+ "encoding": {+ "x": {+ "scale": {+ "domain": [+ 0,+ 1000+ ]+ },+ "aggregate": "count",+ "type": "quantitative",+ "axis": {+ "title": null+ }+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "bin": true,+ "type": "quantitative",+ "axis": null+ }+ }+ }+ ],+ "spacing": 15,+ "bounds": "flush"+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "description": "Marginal histograms show the counts along the x and y dimension",+ "spacing": 15,+ "bounds": "flush"+}
@@ -0,0 +1,23 @@+{+ "mark": {+ "tooltip": {+ "content": "data"+ },+ "type": "point"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "A scatterplot showing horsepower and miles per gallon for various cars (via point marks)."+}
@@ -0,0 +1,54 @@+{+ "transform": [+ {+ "filter": "datum.Entity !== 'All natural disasters'"+ }+ ],+ "height": 400,+ "mark": {+ "strokeWidth": 1,+ "opacity": 0.8,+ "stroke": "black",+ "type": "circle"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/disasters.csv"+ },+ "width": 600,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Entity",+ "type": "nominal",+ "legend": null+ },+ "size": {+ "field": "Deaths",+ "scale": {+ "range": [+ 0,+ 5000+ ]+ },+ "type": "quantitative",+ "legend": {+ "title": "Annual Global Deaths"+ }+ },+ "x": {+ "field": "Year",+ "type": "ordinal",+ "axis": {+ "labelAngle": 0+ }+ },+ "y": {+ "field": "Entity",+ "type": "nominal",+ "axis": {+ "title": null+ }+ }+ },+ "description": "Visualization of global deaths from natural disasters. Copy of chart from https://ourworldindata.org/natural-catastrophes"+}
@@ -0,0 +1,32 @@+{+ "transform": [+ {+ "as": "OriginInitial",+ "calculate": "datum.Origin[0]"+ }+ ],+ "mark": "text",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "text": {+ "field": "OriginInitial",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "A scatterplot showing horsepower and miles per gallon with country of origin double encoded by colour and text symbol."+}
@@ -0,0 +1,14 @@+{+ "mark": "tick",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-weather.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "precipitation",+ "type": "quantitative"+ }+ },+ "description": "Shows the distribution of a single variable (precipitation) using tick marks."+}
@@ -0,0 +1,18 @@+{+ "mark": "tick",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Cylinders",+ "type": "ordinal"+ }+ },+ "description": "Shows the relationship between horsepower and the number of cylinders using tick marks."+}
@@ -0,0 +1,26 @@+{+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "shape": {+ "field": "Origin",+ "type": "nominal"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "A scatterplot showing horsepower and miles per gallon with country of origin double encoded by colour and shape."+}
@@ -0,0 +1,28 @@+{+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "size": {+ "aggregate": "count",+ "type": "quantitative"+ },+ "x": {+ "field": "IMDB_Rating",+ "bin": {+ "maxbins": 10+ },+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "bin": {+ "maxbins": 10+ },+ "type": "quantitative"+ }+ },+ "description": "A binned scatterplot comparing IMDB and Rotten Tomatoes rating with marks sized by number of reviews."+}
@@ -0,0 +1,22 @@+{+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "size": {+ "field": "Acceleration",+ "type": "quantitative"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "A bubbleplot showing horsepower on x, miles per gallons on y, and acceleration on size."+}
@@ -0,0 +1,28 @@+{+ "config": {+ "invalidValues": null+ },+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "value": "rgb(76,120,168)",+ "condition": {+ "value": "#ddd",+ "test": "datum.IMDB_Rating === null || datum.Rotten_Tomatoes_Rating === null"+ }+ },+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "type": "quantitative"+ }+ },+ "description": "Scatterplot with Null values in grey"+}
@@ -0,0 +1,18 @@+{+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ },+ "description": "A scatterplot showing horsepower and miles per gallon for various cars (via circle marks)."+}
@@ -0,0 +1,39 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/gapminder-health-income.csv"+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "view": {+ "bind": "scales",+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "#000"+ },+ "size": {+ "field": "population",+ "type": "quantitative"+ },+ "x": {+ "field": "income",+ "scale": {+ "type": "log"+ },+ "type": "quantitative"+ },+ "y": {+ "field": "health",+ "scale": {+ "zero": false+ },+ "type": "quantitative"+ }+ },+ "description": "A bubble plot showing the correlation between health and income for 187 countries in the world (modified from an example in Lisa Charlotte Rost's blog post 'One Chart, Twelve Charting Libraries' --http://lisacharlotterost.github.io/2016/05/17/one-chart-code/)."+}
@@ -0,0 +1,23 @@+{+ "mark": "rect",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Horsepower",+ "aggregate": "mean",+ "type": "quantitative"+ },+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "nominal"+ }+ },+ "description": "'Table heatmap' showing engine size/power for three countries."+}
@@ -0,0 +1,47 @@+{+ "config": {+ "scale": {+ "rangeStep": 13+ },+ "view": {+ "strokeWidth": 0+ },+ "axis": {+ "domain": false+ }+ },+ "mark": "rect",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/seattle-temps.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "temp",+ "aggregate": "max",+ "type": "quantitative",+ "legend": {+ "title": null+ }+ },+ "x": {+ "field": "date",+ "timeUnit": "date",+ "type": "ordinal",+ "axis": {+ "labelAngle": 0,+ "format": "%e",+ "title": "Day"+ }+ },+ "y": {+ "field": "date",+ "timeUnit": "month",+ "type": "ordinal",+ "axis": {+ "title": "Month"+ }+ }+ },+ "description": "Annual weather 'heatmap'"+}
@@ -0,0 +1,56 @@+{+ "transform": [+ {+ "filter": {+ "and": [+ {+ "field": "IMDB_Rating",+ "valid": true+ },+ {+ "field": "Rotten_Tomatoes_Rating",+ "valid": true+ }+ ]+ }+ }+ ],+ "height": 200,+ "config": {+ "range": {+ "heatmap": {+ "scheme": "greenblue"+ }+ },+ "view": {+ "stroke": null+ }+ },+ "mark": "rect",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "aggregate": "count",+ "type": "quantitative"+ },+ "x": {+ "field": "IMDB_Rating",+ "bin": {+ "maxbins": 60+ },+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "bin": {+ "maxbins": 40+ },+ "type": "quantitative"+ }+ },+ "description": "'Binned heatmap' comparing movie ratings."+}
@@ -0,0 +1,25 @@+{+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/github.csv"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "size": {+ "field": "count",+ "aggregate": "sum",+ "type": "quantitative"+ },+ "x": {+ "field": "time",+ "timeUnit": "hours",+ "type": "ordinal"+ },+ "y": {+ "field": "time",+ "timeUnit": "day",+ "type": "ordinal"+ }+ },+ "description": "Table bubble plot in the style of a Github punched card."+}
@@ -0,0 +1,51 @@+{+ "config": {+ "text": {+ "baseline": "middle"+ },+ "scale": {+ "bandPaddingInner": 0,+ "bandPaddingOuter": 0+ }+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": "rect",+ "encoding": {+ "color": {+ "field": "*",+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "text",+ "encoding": {+ "color": {+ "value": "white"+ },+ "text": {+ "field": "*",+ "aggregate": "count",+ "type": "quantitative"+ }+ }+ }+ ],+ "encoding": {+ "x": {+ "field": "Cylinders",+ "type": "ordinal"+ },+ "y": {+ "field": "Origin",+ "type": "ordinal"+ }+ },+ "description": "Layering text over 'heatmap'."+}
@@ -0,0 +1,27 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": {+ "strokeOpacity": 0,+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonBoroughs.json",+ "format": {+ "feature": "boroughs",+ "type": "topojson"+ }+ },+ "width": 900,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "id",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,134 @@+{+ "height": 700,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 1200,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "strokeWidth": 2,+ "stroke": "rgb(251,247,238)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonBoroughs.json",+ "format": {+ "feature": "boroughs",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "field": "id",+ "scale": {+ "domain": [+ "Kingston upon Thames",+ "Croydon",+ "Bromley",+ "Hounslow",+ "Ealing",+ "Havering",+ "Hillingdon",+ "Harrow",+ "Brent",+ "Barnet",+ "Lambeth",+ "Southwark",+ "Lewisham",+ "Greenwich",+ "Bexley",+ "Enfield",+ "Waltham Forest",+ "Redbridge",+ "Sutton",+ "Richmond upon Thames",+ "Merton",+ "Wandsworth",+ "Hammersmith and Fulham",+ "Kensington and Chelsea",+ "Westminster",+ "Camden",+ "Tower Hamlets",+ "Islington",+ "Hackney",+ "Haringey",+ "Newham",+ "Barking and Dagenham",+ "City of London"+ ],+ "range": [+ "#9db7b1",+ "#d4b4e5",+ "#afb9cb",+ "#b2add6",+ "#e2f8ca",+ "#a1bde6",+ "#e8aa95",+ "#8bd0eb",+ "#dfb89b",+ "#a2e7ed",+ "#e3aba7",+ "#86cbd1",+ "#ecb1c2",+ "#acd8ba",+ "#e4bad9",+ "#9bd6ca",+ "#cec9f3",+ "#c9d2a8",+ "#d1c1d9",+ "#ddcba2",+ "#a2acbd",+ "#deefd6",+ "#b5d7a7",+ "#f6d4c9",+ "#add4e0",+ "#d9b9ad",+ "#c6e1db",+ "#e0c7ce",+ "#a6b79f",+ "#cbd5e7",+ "#c2d2ba",+ "#ebe2cf",+ "#c7bfad"+ ]+ },+ "type": "nominal",+ "legend": null+ },+ "opacity": {+ "value": 1+ }+ }+ },+ {+ "transform": [+ {+ "as": "bLabel",+ "calculate": "indexof (datum.name,' ') > 0 ? substring(datum.name,0,indexof(datum.name, ' ')) : datum.name"+ }+ ],+ "mark": "text",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonCentroids.json"+ },+ "encoding": {+ "text": {+ "field": "bLabel",+ "type": "nominal"+ },+ "latitude": {+ "field": "cy",+ "type": "quantitative"+ },+ "longitude": {+ "field": "cx",+ "type": "quantitative"+ }+ }+ }+ ]+}
@@ -0,0 +1,20 @@+{+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "counties",+ "type": "topojson"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "value": "black"+ }+ },+ "description": "Default map size"+}
@@ -0,0 +1,26 @@+{+ "config": {+ "view": {+ "height": 300,+ "width": 500+ }+ },+ "mark": "geoshape",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/us-10m.json",+ "format": {+ "feature": "counties",+ "type": "topojson"+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "value": "black"+ }+ },+ "description": "Default map size with view width and height specified in config."+}
@@ -0,0 +1,36 @@+{+ "transform": [+ {+ "as": "digit",+ "calculate": "substring(datum.zip_code, 0, 1)"+ }+ ],+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/zipcodes.csv"+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "encoding": {+ "color": {+ "field": "digit",+ "type": "nominal"+ },+ "size": {+ "value": 1+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ }+ },+ "description": "US zip codes: One dot per zipcode colored by first digit"+}
@@ -0,0 +1,34 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic",+ "rotate": [+ -42,+ -30,+ 0+ ]+ },+ "layer": [+ {+ "mark": {+ "fill": "aliceblue",+ "type": "geoshape"+ },+ "data": {+ "sphere": true+ }+ },+ {+ "mark": {+ "strokeWidth": 0.3,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "graticule": true+ }+ }+ ]+}
@@ -0,0 +1,50 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic",+ "rotate": [+ -42,+ -30,+ 0+ ]+ },+ "layer": [+ {+ "mark": {+ "fill": "aliceblue",+ "type": "geoshape"+ },+ "data": {+ "sphere": true+ }+ },+ {+ "mark": {+ "strokeWidth": 0.3,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "graticule": {+ "precision": 2,+ "extent": [+ [+ 0,+ 0+ ],+ [+ 90,+ 90+ ]+ ],+ "step": [+ 2,+ 2+ ]+ }+ }+ }+ ]+}
@@ -0,0 +1,59 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic",+ "rotate": [+ -42,+ -30,+ 0+ ]+ },+ "layer": [+ {+ "mark": {+ "fill": "aliceblue",+ "type": "geoshape"+ },+ "data": {+ "sphere": true+ }+ },+ {+ "mark": {+ "strokeWidth": 0.3,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "graticule": {+ "stepMinor": [+ 2,+ 2+ ],+ "extentMajor": [+ [+ 0,+ 0+ ],+ [+ 90,+ 90+ ]+ ],+ "extentMinor": [+ [+ 0,+ 0+ ],+ [+ 90,+ 75.01+ ]+ ]+ }+ }+ }+ ]+}
@@ -0,0 +1,39 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic",+ "rotate": [+ -42,+ -30,+ 0+ ]+ },+ "layer": [+ {+ "mark": {+ "fill": "aliceblue",+ "type": "geoshape"+ },+ "data": {+ "sphere": true+ }+ },+ {+ "mark": {+ "strokeWidth": 0.3,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "graticule": {+ "stepMinor": [+ 15,+ 30+ ]+ }+ }+ }+ ]+}
@@ -0,0 +1,22 @@+{+ "height": 500,+ "mark": {+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonTubeLines.json",+ "format": {+ "feature": "line",+ "type": "topojson"+ }+ },+ "width": 700,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "id",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,62 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "mark": {+ "strokeWidth": 2,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonTubeLines.json",+ "format": {+ "feature": "line",+ "type": "topojson"+ }+ },+ "width": 700,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "id",+ "scale": {+ "domain": [+ "Bakerloo",+ "Central",+ "Circle",+ "District",+ "DLR",+ "Hammersmith & City",+ "Jubilee",+ "Metropolitan",+ "Northern",+ "Piccadilly",+ "Victoria",+ "Waterloo & City"+ ],+ "range": [+ "rgb(137,78,36)",+ "rgb(220,36,30)",+ "rgb(255,206,0)",+ "rgb(1,114,41)",+ "rgb(0,175,173)",+ "rgb(215,153,175)",+ "rgb(106,114,120)",+ "rgb(114,17,84)",+ "rgb(0,0,0)",+ "rgb(0,24,168)",+ "rgb(0,160,226)",+ "rgb(106,187,170)"+ ]+ },+ "type": "nominal",+ "legend": {+ "orient": "bottom-right",+ "title": null+ }+ }+ }+}
@@ -0,0 +1,118 @@+{+ "height": 500,+ "config": {+ "view": {+ "stroke": null+ }+ },+ "width": 700,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "strokeWidth": 2,+ "stroke": "rgb(251,247,238)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonBoroughs.json",+ "format": {+ "feature": "boroughs",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "value": "#ddc"+ }+ }+ },+ {+ "transform": [+ {+ "as": "bLabel",+ "calculate": "indexof (datum.name,' ') > 0 ? substring(datum.name,0,indexof(datum.name, ' ')) : datum.name"+ }+ ],+ "mark": "text",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonCentroids.json"+ },+ "encoding": {+ "size": {+ "value": 8+ },+ "text": {+ "field": "bLabel",+ "type": "nominal"+ },+ "latitude": {+ "field": "cy",+ "type": "quantitative"+ },+ "opacity": {+ "value": 0.6+ },+ "longitude": {+ "field": "cx",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": {+ "strokeWidth": 2,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/londonTubeLines.json",+ "format": {+ "feature": "line",+ "type": "topojson"+ }+ },+ "encoding": {+ "color": {+ "field": "id",+ "scale": {+ "domain": [+ "Bakerloo",+ "Central",+ "Circle",+ "District",+ "DLR",+ "Hammersmith & City",+ "Jubilee",+ "Metropolitan",+ "Northern",+ "Piccadilly",+ "Victoria",+ "Waterloo & City"+ ],+ "range": [+ "rgb(137,78,36)",+ "rgb(220,36,30)",+ "rgb(255,206,0)",+ "rgb(1,114,41)",+ "rgb(0,175,173)",+ "rgb(215,153,175)",+ "rgb(106,114,120)",+ "rgb(114,17,84)",+ "rgb(0,0,0)",+ "rgb(0,24,168)",+ "rgb(0,160,226)",+ "rgb(106,187,170)"+ ]+ },+ "type": "nominal",+ "legend": {+ "offset": 0,+ "orient": "bottom-right",+ "title": null+ }+ }+ }+ }+ ]+}
@@ -0,0 +1,67 @@+{+ "height": 400,+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "stroke": "white",+ "fill": "lightgrey",+ "type": "geoshape"+ },+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/londonBoroughs.json",+ "format": {+ "feature": "boroughs",+ "type": "topojson"+ }+ }+ },+ {+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/londonCentroids.csv"+ },+ "encoding": {+ "latitude": {+ "field": "cy",+ "type": "quantitative"+ },+ "longitude": {+ "field": "cx",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/londonCentroids.csv"+ },+ "encoding": {+ "latitude": {+ "value": 51.28+ },+ "longitude": {+ "field": "cx",+ "type": "quantitative"+ }+ }+ },+ {+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/londonCentroids.csv"+ },+ "encoding": {+ "latitude": {+ "field": "cy",+ "type": "quantitative"+ },+ "longitude": {+ "value": -0.52+ }+ }+ }+ ]+}
@@ -0,0 +1,59 @@+{+ "hconcat": [+ {+ "height": 300,+ "mark": {+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic"+ }+ },+ {+ "height": 300,+ "mark": {+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic"+ }+ },+ {+ "height": 300,+ "mark": {+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic"+ }+ }+ ],+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,124 @@+{+ "hconcat": [+ {+ "height": 300,+ "width": 300,+ "projection": {+ "type": "orthographic"+ },+ "layer": [+ {+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ }+ },+ {+ "mark": {+ "fill": "black",+ "type": "geoshape",+ "fillOpacity": 0.7+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "land",+ "type": "topojson"+ }+ }+ }+ ]+ },+ {+ "height": 300,+ "width": 300,+ "projection": {+ "type": "orthographic"+ },+ "layer": [+ {+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ }+ },+ {+ "mark": {+ "fill": "black",+ "type": "geoshape",+ "fillOpacity": 0.7+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "land",+ "type": "topojson"+ }+ }+ }+ ]+ },+ {+ "height": 300,+ "width": 300,+ "projection": {+ "type": "orthographic"+ },+ "layer": [+ {+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ }+ },+ {+ "mark": {+ "fill": "black",+ "type": "geoshape",+ "fillOpacity": 0.7+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "land",+ "type": "topojson"+ }+ }+ }+ ]+ }+ ],+ "config": {+ "view": {+ "stroke": null+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,172 @@+{+ "hconcat": [+ {+ "layer": [+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ -65,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "white",+ "fill": "black",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "countries",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ -65,+ 0,+ 0+ ]+ }+ }+ ]+ },+ {+ "layer": [+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ 115,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "white",+ "fill": "black",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "countries",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ 115,+ 0,+ 0+ ]+ }+ }+ ]+ },+ {+ "layer": [+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ -65,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "white",+ "fill": "black",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "countries",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ -65,+ 0,+ 0+ ]+ }+ }+ ]+ }+ ],+ "config": {+ "view": {+ "stroke": null+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,166 @@+{+ "hconcat": [+ {+ "layer": [+ {+ "height": 300,+ "mark": {+ "fill": "#c1e7f5",+ "strokeOpacity": 0,+ "type": "geoshape"+ },+ "data": {+ "url": "data/globe.json",+ "format": {+ "feature": "globe",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ 0,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ 0,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "white",+ "fill": "#242",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "countries",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ 0,+ 0,+ 0+ ]+ }+ }+ ]+ },+ {+ "layer": [+ {+ "height": 300,+ "mark": {+ "fill": "#c1e7f5",+ "strokeOpacity": 0,+ "type": "geoshape"+ },+ "data": {+ "url": "data/globe.json",+ "format": {+ "feature": "globe",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ 0,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "#411",+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ -40,+ 0,+ 0+ ]+ }+ },+ {+ "height": 300,+ "mark": {+ "strokeWidth": 0.1,+ "stroke": "white",+ "fill": "#242",+ "type": "geoshape"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/world-110m.json",+ "format": {+ "feature": "countries",+ "type": "topojson"+ }+ },+ "width": 300,+ "projection": {+ "type": "orthographic",+ "rotate": [+ -40,+ 0,+ 0+ ]+ }+ }+ ]+ }+ ],+ "config": {+ "view": {+ "stroke": null+ }+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,39 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "scale": 470,+ "type": "orthographic"+ },+ "layer": [+ {+ "mark": {+ "fill": "rgb(149,181,146)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/world-110m.json",+ "format": {+ "feature": "countries1",+ "type": "topojson"+ }+ }+ },+ {+ "mark": {+ "strokeWidth": 0.3,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "graticule": {+ "stepMinor": [+ 5,+ 5+ ]+ }+ }+ }+ ]+}
@@ -0,0 +1,57 @@+{+ "transform": [+ {+ "filter": "datum.latitude != '' && datum.county != 'Honolulu' && datum.state !='AS'&& datum.state !='FM'&& datum.state !='PW'&& datum.state !='MH'&& datum.state !='GU'&& datum.state !='MP'&& datum.state !='VI'&& datum.state !='PR'"+ },+ {+ "as": "conterminous",+ "calculate": "datum.state == 'HI' ? 'hi' : (datum.state == 'AK' ? 'ak' : 'continent')"+ }+ ],+ "height": 600,+ "config": {+ "view": {+ "stroke": null+ },+ "title": {+ "fontSize": 28,+ "font": "Roboto",+ "fontWeight": 300+ }+ },+ "mark": {+ "strokeWidth": 0.2,+ "interpolate": "monotone",+ "type": "line"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/zipcodes.csv"+ },+ "width": 1000,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "title": "US connected zip codes",+ "encoding": {+ "color": {+ "value": "#666"+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ },+ "order": {+ "field": "zip_code",+ "type": "quantitative"+ },+ "detail": {+ "field": "conterminous",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,63 @@+{+ "transform": [+ {+ "filter": "datum.latitude != '' && datum.county != 'Honolulu' && datum.state !='AS'&& datum.state !='FM'&& datum.state !='PW'&& datum.state !='MH'&& datum.state !='GU'&& datum.state !='MP'&& datum.state !='VI'&& datum.state !='PR'"+ },+ {+ "as": "digit3",+ "calculate": "substring(datum.zip_code, 0, 3)"+ },+ {+ "as": "ziplen",+ "calculate": "length(datum.zip_code+' ')"+ }+ ],+ "height": 600,+ "config": {+ "view": {+ "stroke": null+ },+ "title": {+ "fontSize": 28,+ "font": "Roboto",+ "fontWeight": 300+ }+ },+ "mark": {+ "strokeWidth": 0.2,+ "interpolate": "monotone",+ "type": "line"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/zipcodes.csv"+ },+ "width": 1000,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albersUsa"+ },+ "title": "US connected zip codes, coloured by first three digits",+ "encoding": {+ "color": {+ "field": "digit3",+ "type": "nominal",+ "legend": null+ },+ "latitude": {+ "field": "latitude",+ "type": "quantitative"+ },+ "longitude": {+ "field": "longitude",+ "type": "quantitative"+ },+ "order": {+ "field": "zip_code",+ "type": "quantitative"+ },+ "detail": {+ "field": "ziplen",+ "type": "nominal"+ }+ }+}
@@ -0,0 +1,19 @@+{+ "height": 300,+ "mark": {+ "fill": "rgb(149,181,146)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/world-110m.json",+ "format": {+ "feature": "countries1",+ "type": "topojson"+ }+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic"+ }+}
@@ -0,0 +1,32 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic"+ },+ "layer": [+ {+ "mark": {+ "fill": "aliceblue",+ "type": "geoshape"+ },+ "data": {+ "sphere": true+ }+ },+ {+ "mark": {+ "fill": "rgb(149,181,146)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/world-110m.json",+ "format": {+ "feature": "countries1",+ "type": "topojson"+ }+ }+ }+ ]+}
@@ -0,0 +1,42 @@+{+ "height": 300,+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic",+ "translate": [+ 0,+ 100+ ]+ },+ "layer": [+ {+ "mark": {+ "fill": "rgb(149,181,146)",+ "type": "geoshape"+ },+ "data": {+ "url": "https://gicentre.github.io/data/geoTutorials/world-110m.json",+ "format": {+ "feature": "countries1",+ "type": "topojson"+ }+ }+ },+ {+ "mark": {+ "strokeWidth": 0.3,+ "type": "geoshape",+ "filled": false+ },+ "data": {+ "graticule": {+ "stepMinor": [+ 5,+ 5+ ]+ }+ }+ }+ ]+}
@@ -0,0 +1,62 @@+{+ "data": {+ "values": [+ {+ "url": "https://vega.github.io/vega",+ "label": "Vega"+ },+ {+ "url": "https://vega.github.io/vega-lite",+ "label": "Vega-Lite"+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "layer": [+ {+ "mark": {+ "cursor": "pointer",+ "type": "circle"+ },+ "encoding": {+ "color": {+ "field": "label",+ "type": "nominal",+ "legend": null+ },+ "size": {+ "value": 8000+ },+ "href": {+ "field": "url",+ "type": "nominal"+ },+ "x": {+ "field": "label",+ "type": "nominal",+ "axis": null+ }+ }+ },+ {+ "mark": "text",+ "encoding": {+ "color": {+ "value": "white"+ },+ "size": {+ "value": 16+ },+ "text": {+ "field": "label",+ "type": "nominal"+ },+ "x": {+ "field": "label",+ "type": "nominal",+ "axis": null+ }+ }+ }+ ]+}
@@ -0,0 +1,23 @@+{+ "mark": {+ "cursor": "pointer",+ "type": "point"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "href": {+ "value": "http://www.imdb.com"+ },+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,34 @@+{+ "mark": {+ "cursor": "pointer",+ "type": "point"+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "value": "red",+ "condition": {+ "value": "steelblue",+ "test": "datum.IMDB_Rating*10 > datum.Rotten_Tomatoes_Rating"+ }+ },+ "href": {+ "value": "https://www.rottentomatoes.com",+ "condition": {+ "value": "http://www.imdb.com",+ "test": "datum.IMDB_Rating*10 > datum.Rotten_Tomatoes_Rating"+ }+ },+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,58 @@+{+ "mark": "line",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "type": "single"+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,58 @@+{+ "mark": "line",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "type": "multi"+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,62 @@+{+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "nearest": true,+ "type": "single",+ "fields": [+ "crimeType"+ ]+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,62 @@+{+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "empty": "none",+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,62 @@+{+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "bind": "scales",+ "encodings": [+ "x"+ ],+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,59 @@+{+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "bind": "scales",+ "type": "interval"+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,75 @@+{+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "mySelection": {+ "nearest": true,+ "bind": {+ "crimeType": {+ "input": "radio",+ "name": " ",+ "options": [+ "Anti-social behaviour",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ]+ }+ },+ "type": "single",+ "fields": [+ "crimeType"+ ]+ }+ },+ "encoding": {+ "color": {+ "value": "black",+ "condition": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "selection": "mySelection",+ "type": "nominal"+ }+ },+ "opacity": {+ "value": 0.1,+ "condition": {+ "value": 1,+ "selection": "mySelection"+ }+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,76 @@+{+ "transform": [+ {+ "filter": "datum.reportedCrimes >= minSlider_minReported && maxSlider_maxReported >= datum.reportedCrimes"+ }+ ],+ "mark": "circle",+ "data": {+ "url": "https://gicentre.github.io/data/westMidlands/westMidsCrimesAggregated.tsv"+ },+ "width": 540,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "selection": {+ "maxSlider": {+ "init": {+ "maxReported": 14000+ },+ "bind": {+ "maxReported": {+ "max": 14000,+ "input": "range",+ "name": "Max",+ "min": 400+ }+ },+ "type": "single"+ },+ "minSlider": {+ "init": {+ "minReported": 0+ },+ "bind": {+ "minReported": {+ "max": 12800,+ "input": "range",+ "name": "Min"+ }+ },+ "type": "single"+ }+ },+ "encoding": {+ "color": {+ "field": "crimeType",+ "scale": {+ "domain": [+ "Anti-social behaviour",+ "Burglary",+ "Criminal damage and arson",+ "Drugs",+ "Robbery",+ "Vehicle crime"+ ],+ "range": [+ "rgb(59,118,175)",+ "rgb(81,157,62)",+ "rgb(141,106,184)",+ "rgb(239,133,55)",+ "rgb(132,88,78)",+ "rgb(213,126,190)"+ ]+ },+ "type": "nominal"+ },+ "x": {+ "field": "month",+ "title": null,+ "type": "temporal"+ },+ "y": {+ "field": "reportedCrimes",+ "title": "Reported crimes",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,34 @@+{+ "height": 300,+ "config": {+ "legend": {}+ },+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,28 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "none",+ "legendY": 5,+ "legendX": 232+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,48 @@+{+ "height": 300,+ "config": {+ "legend": {+ "symbolStrokeColor": "black",+ "strokeWidth": 5,+ "rowPadding": 15,+ "titlePadding": 20,+ "symbolStrokeWidth": 3,+ "strokeDash": [+ 4,+ 2,+ 6,+ 1+ ],+ "padding": 30,+ "strokeColor": "lightgrey"+ }+ },+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal"+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative"+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "top"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "top"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "top"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "top-right"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "top-right"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "top-right"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "right"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "right"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "right"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "bottom-right"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "bottom-right"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "bottom-right"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "bottom"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "bottom"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "bottom"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "bottom-left"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "bottom-left"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "bottom-left"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "left"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "left"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "left"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,40 @@+{+ "height": 300,+ "mark": "circle",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/cars.json"+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "Origin",+ "type": "nominal",+ "legend": {+ "orient": "top-left"+ }+ },+ "size": {+ "field": "Horsepower",+ "type": "quantitative",+ "legend": {+ "orient": "top-left"+ }+ },+ "opacity": {+ "field": "Weight_in_lbs",+ "type": "quantitative",+ "legend": {+ "orient": "top-left"+ }+ },+ "x": {+ "field": "Horsepower",+ "type": "quantitative"+ },+ "y": {+ "field": "Miles_per_Gallon",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,54 @@+{+ "mark": "line",+ "data": {+ "values": [+ {+ "x": 0,+ "order": 1,+ "y": 1000+ },+ {+ "x": 1000,+ "order": 2,+ "y": 1000+ },+ {+ "x": 1000,+ "order": 3,+ "y": 0+ },+ {+ "x": 0,+ "order": 4,+ "y": 0+ },+ {+ "x": 0,+ "order": 5,+ "y": 1000+ },+ {+ "x": 1000,+ "order": 6,+ "y": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "x",+ "type": "quantitative",+ "axis": null+ },+ "order": {+ "field": "order",+ "type": "ordinal"+ },+ "y": {+ "field": "y",+ "type": "quantitative",+ "axis": null+ }+ }+}
@@ -0,0 +1,27 @@+{+ "config": {+ "invalidValues": null+ },+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "value": "rgb(76,120,168)",+ "condition": {+ "value": "#ddd",+ "test": "datum.IMDB_Rating === null || datum.Rotten_Tomatoes_Rating === null"+ }+ },+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,41 @@+{+ "transform": [+ {+ "filter": {+ "field": "IMDB_Rating",+ "valid": true+ }+ },+ {+ "filter": {+ "field": "Rotten_Tomatoes_Rating",+ "valid": true+ }+ }+ ],+ "config": {+ "invalidValues": null+ },+ "mark": "point",+ "data": {+ "url": "https://vega.github.io/vega-lite/data/movies.json"+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "value": "rgb(76,120,168)",+ "condition": {+ "value": "#ddd",+ "test": "datum.IMDB_Rating === null || datum.Rotten_Tomatoes_Rating === null"+ }+ },+ "x": {+ "field": "IMDB_Rating",+ "type": "quantitative"+ },+ "y": {+ "field": "Rotten_Tomatoes_Rating",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,92 @@+{+ "height": 400,+ "mark": "point",+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 40,+ "val": 4,+ "y": 4+ },+ {+ "cat": "e",+ "x": 50,+ "val": 5,+ "y": 5+ },+ {+ "cat": "f",+ "x": 60,+ "val": 6,+ "y": 6+ },+ {+ "cat": "g",+ "x": 70,+ "val": 7,+ "y": 7+ },+ {+ "cat": "h",+ "x": 80,+ "val": 8,+ "y": 8+ },+ {+ "cat": "i",+ "x": 90,+ "val": 9,+ "y": 9+ },+ {+ "cat": "j",+ "x": 100,+ "val": 10,+ "y": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "val",+ "type": "ordinal"+ },+ "size": {+ "field": "val",+ "type": "quantitative"+ },+ "shape": {+ "field": "cat",+ "type": "nominal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,93 @@+{+ "height": 400,+ "mark": "point",+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 40,+ "val": 4,+ "y": 4+ },+ {+ "cat": "e",+ "x": 50,+ "val": 5,+ "y": 5+ },+ {+ "cat": "f",+ "x": 60,+ "val": 6,+ "y": 6+ },+ {+ "cat": "g",+ "x": 70,+ "val": 7,+ "y": 7+ },+ {+ "cat": "h",+ "x": 80,+ "val": 8,+ "y": 8+ },+ {+ "cat": "i",+ "x": 90,+ "val": 9,+ "y": 9+ },+ {+ "cat": "j",+ "x": 100,+ "val": 10,+ "y": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "val",+ "type": "ordinal"+ },+ "size": {+ "field": "val",+ "type": "quantitative"+ },+ "shape": {+ "field": "cat",+ "type": "nominal"+ },+ "x": {+ "field": "x",+ "scale": null,+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,93 @@+{+ "height": 400,+ "mark": "point",+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 40,+ "val": 4,+ "y": 4+ },+ {+ "cat": "e",+ "x": 50,+ "val": 5,+ "y": 5+ },+ {+ "cat": "f",+ "x": 60,+ "val": 6,+ "y": 6+ },+ {+ "cat": "g",+ "x": 70,+ "val": 7,+ "y": 7+ },+ {+ "cat": "h",+ "x": 80,+ "val": 8,+ "y": 8+ },+ {+ "cat": "i",+ "x": 90,+ "val": 9,+ "y": 9+ },+ {+ "cat": "j",+ "x": 100,+ "val": 10,+ "y": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "val",+ "type": "ordinal"+ },+ "size": {+ "field": "val",+ "type": "quantitative"+ },+ "shape": {+ "field": "cat",+ "type": "nominal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "scale": null,+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,93 @@+{+ "height": 400,+ "mark": "point",+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 40,+ "val": 4,+ "y": 4+ },+ {+ "cat": "e",+ "x": 50,+ "val": 5,+ "y": 5+ },+ {+ "cat": "f",+ "x": 60,+ "val": 6,+ "y": 6+ },+ {+ "cat": "g",+ "x": 70,+ "val": 7,+ "y": 7+ },+ {+ "cat": "h",+ "x": 80,+ "val": 8,+ "y": 8+ },+ {+ "cat": "i",+ "x": 90,+ "val": 9,+ "y": 9+ },+ {+ "cat": "j",+ "x": 100,+ "val": 10,+ "y": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "val",+ "scale": null,+ "type": "ordinal"+ },+ "size": {+ "field": "val",+ "type": "quantitative"+ },+ "shape": {+ "field": "cat",+ "type": "nominal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,93 @@+{+ "height": 400,+ "mark": "point",+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 40,+ "val": 4,+ "y": 4+ },+ {+ "cat": "e",+ "x": 50,+ "val": 5,+ "y": 5+ },+ {+ "cat": "f",+ "x": 60,+ "val": 6,+ "y": 6+ },+ {+ "cat": "g",+ "x": 70,+ "val": 7,+ "y": 7+ },+ {+ "cat": "h",+ "x": 80,+ "val": 8,+ "y": 8+ },+ {+ "cat": "i",+ "x": 90,+ "val": 9,+ "y": 9+ },+ {+ "cat": "j",+ "x": 100,+ "val": 10,+ "y": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "val",+ "type": "ordinal"+ },+ "size": {+ "field": "val",+ "scale": null,+ "type": "quantitative"+ },+ "shape": {+ "field": "cat",+ "type": "nominal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,93 @@+{+ "height": 400,+ "mark": "point",+ "data": {+ "values": [+ {+ "cat": "a",+ "x": 10,+ "val": 1,+ "y": 1+ },+ {+ "cat": "b",+ "x": 20,+ "val": 2,+ "y": 2+ },+ {+ "cat": "c",+ "x": 30,+ "val": 3,+ "y": 3+ },+ {+ "cat": "d",+ "x": 40,+ "val": 4,+ "y": 4+ },+ {+ "cat": "e",+ "x": 50,+ "val": 5,+ "y": 5+ },+ {+ "cat": "f",+ "x": 60,+ "val": 6,+ "y": 6+ },+ {+ "cat": "g",+ "x": 70,+ "val": 7,+ "y": 7+ },+ {+ "cat": "h",+ "x": 80,+ "val": 8,+ "y": 8+ },+ {+ "cat": "i",+ "x": 90,+ "val": 9,+ "y": 9+ },+ {+ "cat": "j",+ "x": 100,+ "val": 10,+ "y": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "color": {+ "field": "val",+ "type": "ordinal"+ },+ "size": {+ "field": "val",+ "type": "quantitative"+ },+ "shape": {+ "field": "cat",+ "scale": null,+ "type": "nominal"+ },+ "x": {+ "field": "x",+ "type": "quantitative"+ },+ "y": {+ "field": "y",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,16 @@+{+ "mark": {+ "size": 200,+ "x": 150,+ "type": "circle",+ "y": 150+ },+ "data": {+ "values": [+ {+ "empty": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,44 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "scale": {+ "paddingInner": 0.5,+ "align": 0.5+ },+ "type": "ordinal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,44 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "scale": {+ "paddingInner": 0.5,+ "align": 0.7+ },+ "type": "ordinal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,44 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "scale": {+ "paddingInner": 0.5,+ "align": 1+ },+ "type": "ordinal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,15 @@+{+ "mark": {+ "x": 150,+ "type": "bar",+ "y": 150+ },+ "data": {+ "values": [+ {+ "empty": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,16 @@+{+ "mark": {+ "x2": 200,+ "x": 150,+ "type": "bar",+ "y": 150+ },+ "data": {+ "values": [+ {+ "empty": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,16 @@+{+ "mark": {+ "x": 150,+ "type": "bar",+ "y2": 200,+ "y": 150+ },+ "data": {+ "values": [+ {+ "empty": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,17 @@+{+ "mark": {+ "x2": 200,+ "x": 150,+ "type": "bar",+ "y2": 200,+ "y": 150+ },+ "data": {+ "values": [+ {+ "empty": 0+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json"+}
@@ -0,0 +1,43 @@+{+ "mark": {+ "width": 20,+ "type": "bar"+ },+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "width": 300,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "type": "ordinal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,43 @@+{+ "height": 300,+ "mark": {+ "height": 20,+ "type": "bar"+ },+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "val",+ "type": "quantitative"+ },+ "y": {+ "field": "cat",+ "type": "ordinal"+ }+ }+}
@@ -0,0 +1,44 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "scale": {+ "paddingInner": 0.5,+ "align": 0+ },+ "type": "ordinal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,44 @@+{+ "mark": "bar",+ "data": {+ "values": [+ {+ "empty": 0,+ "cat": 1,+ "val": 10+ },+ {+ "cat": 2,+ "val": 20+ },+ {+ "cat": 3,+ "val": 30+ },+ {+ "cat": 4,+ "val": 20+ },+ {+ "cat": 5,+ "val": 10+ }+ ]+ },+ "width": 400,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "encoding": {+ "x": {+ "field": "cat",+ "scale": {+ "paddingInner": 0.5,+ "align": 0.3+ },+ "type": "ordinal"+ },+ "y": {+ "field": "val",+ "type": "quantitative"+ }+ }+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "albers"+ },+ "title": "Albers",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "azimuthalEqualArea"+ },+ "title": "AzimuthalEqualArea",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "azimuthalEquidistant"+ },+ "title": "AzimuthalEquidistant",+ "background": "#c1e7f5"+}
@@ -0,0 +1,24 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "clipAngle": 65,+ "type": "conicConformal"+ },+ "title": "ConicConformal",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "conicEqualarea"+ },+ "title": "ConicEqualArea",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "conicEquidistant"+ },+ "title": "ConicEquidistant",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "equirectangular"+ },+ "title": "Equirectangular",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "gnomonic"+ },+ "title": "Gnomonic",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "identity"+ },+ "title": "Identity",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "mercator"+ },+ "title": "Mercator",+ "background": "#c1e7f5"+}
@@ -0,0 +1,23 @@+{+ "height": 300,+ "mark": {+ "strokeWidth": 0.5,+ "stroke": "#411",+ "type": "geoshape",+ "fillOpacity": 1.0e-2+ },+ "data": {+ "url": "https://vega.github.io/vega-lite/data/graticule.json",+ "format": {+ "feature": "graticule",+ "type": "topojson"+ }+ },+ "width": 500,+ "$schema": "https://vega.github.io/schema/vega-lite/v3.json",+ "projection": {+ "type": "orthographic"+ },+ "title": "Orthographic",+ "background": "#c1e7f5"+}
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff
file too large to diff