hvega-0.11.0.0: src/Graphics/Vega/VegaLite/Scale.hs
{-# LANGUAGE OverloadedStrings #-}
{-|
Module : Graphics.Vega.VegaLite.Scale
Copyright : (c) Douglas Burke, 2018-2020
License : BSD3
Maintainer : dburke.gw@gmail.com
Stability : unstable
Portability : OverloadedStrings
Scale-related functionality.
-}
module Graphics.Vega.VegaLite.Scale
( ScaleDomain(..)
, DomainLimits(..)
, ScaleRange(..)
, ScaleNice(..)
, NTimeUnit(..)
-- not for external export
, scaleDomainProperty
, domainLimitsSpec
, scaleNiceSpec
) where
import qualified Data.Text as T
import Data.Aeson ((.=), object, toJSON)
import Graphics.Vega.VegaLite.Foundation
( Channel
, FieldName
, fromT
, channelLabel
)
import Graphics.Vega.VegaLite.Specification
( VLSpec
, LabelledSpec
, SelectionLabel
)
import Graphics.Vega.VegaLite.Time
( DateTime
, dateTimeSpec
)
{-|
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>.
In @0.11.0.0@ the functionality has been split into 'ScaleDomain' and
'DomainLimits'.
-}
data ScaleDomain
= DMax Double
-- ^ Sets the maximum value in the scale domain.
-- It is only intended for scales with a continuous domain.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| DMaxTime [DateTime]
-- ^ 'DMax' for dates.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| DMid Double
-- ^ Sets the mid-point of a continuous diverging domain.
--
-- It replaces 'Graphics.Vega.VegaLite.SDomainMid'.
--
-- @since 0.11.0.0
| DMin Double
-- ^ Sets the minimum value in the scale domain.
-- It is only intended for scales with a continuous domain.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| DMinTime [DateTime]
-- ^ 'DMin' for dates.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| DSelection SelectionLabel
-- ^ Scale domain based on a named interactive selection.
-- See also 'DSelectionField' and 'DSelectionChannel', which should
-- be used when a selection is
-- [projected](https://vega.github.io/vega-lite/docs/project.html)
-- over multiple fields or encodings.
--
-- In @0.7.0.0@ the argument type was changed to @SelectionLabel@
-- (which is a type synonym for @Text@).
| DSelectionField SelectionLabel FieldName
-- ^ Use the given selection /and/ associated field, when the selection
-- is projected over multiple fields or encodings.
--
-- @since 0.7.0.0
| DSelectionChannel SelectionLabel Channel
-- ^ Use the given selection /and/ associated encoding, when the selection
-- is projected over multiple fields or encodings.
--
-- @since 0.7.0.0
| DUnionWith DomainLimits
-- ^ Combine the domain of the data with the provided domain.
--
-- The following example will use a range of at least 0 to 100,
-- but this will be increased if the data (either initially or
-- via any updates to the Vege-Lite visualization) exceeds this:
--
-- @'Graphics.Vega.VegaLite.PScale' ['Graphics.Vega.VegaLite.SDomainOpt' (DUnionWith ('DNumbers' [0, 100]))]@
--
-- @since 0.6.0.0
| Unaggregated
-- ^ Indicate that a domain of aggregated data should be scaled to
-- the domain of the data prior to aggregation.
-- For now we do not include Unaggregated in DomainLimits as the
-- documentaiton suggests we should ubt the schema does not: see
-- https://github.com/vega/vega-lite/issues/7022
--
{-|
Represent the range of the domain, which is used by 'VL.SDomain'
and 'DUnionWith'.
Prior to @0.11.0.0@ this was part of 'ScaleDomain'.
@since 0.11.0.0
-}
data DomainLimits
= DNumbers [Double]
-- ^ Numeric values that define a scale domain.
--
-- It is expected that this contains two values (minimum and
-- maximum), but more can be given for
-- [piecewise quantitative scales](https://vega.github.io/vega-lite/docs/scale.html#piecewise).
| DStrings [T.Text]
-- ^ String values that define a scale domain
| DDateTimes [[DateTime]]
-- ^ Date-time values that define a scale domain.
scaleDomainProperty :: ScaleDomain -> LabelledSpec
scaleDomainProperty (DMax x) = "domainMax" .= x
scaleDomainProperty (DMaxTime dts) = "domainMax" .= dateTimeSpec dts
scaleDomainProperty (DMid x) = "domainMid" .= x
scaleDomainProperty (DMin x) = "domainMin" .= x
scaleDomainProperty (DMinTime dts) = "domainMin" .= dateTimeSpec dts
scaleDomainProperty (DSelection selName) = "domain" .= object ["selection" .= selName]
scaleDomainProperty (DSelectionField selName field) = "domain" .= object [ "selection" .= selName
, "field" .= field ]
scaleDomainProperty (DSelectionChannel selName ch) = "domain" .= object [ "selection" .= selName
, "encoding" .= channelLabel ch ]
scaleDomainProperty (DUnionWith sd) = "domain" .= object ["unionWith" .= domainLimitsSpec sd]
scaleDomainProperty Unaggregated = "domain" .= fromT "unaggregated"
domainLimitsSpec :: DomainLimits -> VLSpec
domainLimitsSpec (DNumbers nums) = toJSON (map toJSON nums)
domainLimitsSpec (DDateTimes dts) = toJSON (map dateTimeSpec dts)
domainLimitsSpec (DStrings cats) = toJSON (map toJSON cats)
{-|
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>.
Prior to version @0.10.0.0@ the time units were included in the constructors
for @ScaleNice@.
-}
data ScaleNice
= NTU NTimeUnit
-- ^ Time range.
| NInterval NTimeUnit 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.
{-|
The time intervals that can be rounded to \"nice\" numbers.
Prior to @0.10.0.0@ these were part of 'ScaleNice'.
-}
data NTimeUnit
= 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.
nTimeUnitSpec :: NTimeUnit -> VLSpec
nTimeUnitSpec NMillisecond = fromT "millisecond"
nTimeUnitSpec NSecond = fromT "second"
nTimeUnitSpec NMinute = fromT "minute"
nTimeUnitSpec NHour = fromT "hour"
nTimeUnitSpec NDay = fromT "day"
nTimeUnitSpec NWeek = fromT "week"
nTimeUnitSpec NMonth = fromT "month"
nTimeUnitSpec NYear = fromT "year"
scaleNiceSpec :: ScaleNice -> VLSpec
scaleNiceSpec (NTU tu) = nTimeUnitSpec tu
scaleNiceSpec (NInterval tu step) =
object ["interval" .= nTimeUnitSpec 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)
('Graphics.Vega.VegaLite.width' and 'Graphics.Vega.VegaLite.height') or via range steps and paddings properties (e.g. 'Graphics.Vega.VegaLite.SCRangeStep')
for band and point scales.
-}
data ScaleRange
= RField FieldName
-- ^ For [discrete](https://vega.github.io/vega-lite/docs/scale.html#discrete)
-- and [discretizing](https://vega.github.io/vega-lite/docs/scale.html#discretizing)
-- scales, the name if the field to use.
--
-- For example. if the field \"color\" contains CSS color names, we can say
-- @RField \"color\"@.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| RMax Double
-- ^ Sets the maximum value in the scale range.
-- It is only intended for scales with a continuous range.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| RMin Double
-- ^ Sets the minimum value in the scale range.
-- It is only intended for scales with a continuous range.
--
-- It is supported in Vega-Lite 4.14 and later.
--
-- @since 0.11.0.0
| RPair Double Double
-- ^ The minimum and maximum values.
--
-- @since 0.9.0.0
| RHeight Double
-- ^ Specify the width as a number and height as the string @"height"@.
--
-- @since 0.9.0.0
| RWidth Double
-- ^ Specify the height as a number and width as the string @"width"@.
--
-- @since 0.9.0.0
| 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).
--
-- Support for the two-element version may be removed (ie this left only
-- for piecewise scales).
| RNumberLists [[Double]]
-- ^ A scale range comprising of numeric lists, such as custom dash styles for
-- the 'Graphics.Vega.VegaLite.strokeDash' channel encoding.
--
-- @since 0.6.0.0
| 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\").
{-
TODO:
* TickCount accepts number or TimeInterval but this is a subset of ScaleNice
-}