Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2010-2021 Haifeng Li. All rights reserved.
*
* Smile is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Smile is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Smile. If not, see .
*/
package smile.plot.vega
import smile.json._
/** Single view specification, which describes a view that uses a single
* mark type to visualize the data.
*/
trait View extends VegaLite {
/** Sets the width of the data rectangle (plotting) dimensions. */
def width(width: Int): this.type = {
spec.width = width
this
}
/** Sets the height of the data rectangle (plotting) dimensions. */
def height(height: Int): this.type = {
spec.height = height
this
}
/** Sets the top-level width properties to "container" to indicate
* that the width of the plot should be the same as its surrounding
* container. The width and height can be set independently,
* for example, you can have a responsive width and a fixed height
* by setting width to "container" and height to a number.
*
* After setting width or height to "container", you need to ensure
* that the container's width or height is determined outside the plot.
* For example, the container can be a `
` element that has style
* width: 100%; height: 300px. When the container is not available
* or its size is not defined (e.g., in server-side rendering),
* the default width and height are config.view.continuousWidth
* and config.view.continuousHeight, respectively.
*/
def width(width: String): this.type = {
assert(width == "container", "Invalid width: " + width)
spec.width = "container"
this
}
/** Sets the top-level height properties to "container" to indicate
* that the height of the plot should be the same as its surrounding
* container. The width and height can be set independently,
* for example, you can have a responsive width and a fixed height
* by setting width to "container" and height to a number.
*
* After setting width or height to "container", you need to ensure
* that the container's width or height is determined outside the plot.
* For example, the container can be a `
` element that has style
* width: 100%; height: 300px. When the container is not available
* or its size is not defined (e.g., in server-side rendering),
* the default width and height are config.view.continuousWidth
* and config.view.continuousHeight, respectively.
*/
def height(height: String): this.type = {
assert(height == "container", "Invalid height: " + height)
spec.height = "container"
this
}
/** For a discrete x-field, sets the width per discrete step. */
def widthStep(step: Int): this.type = {
spec.width = JsObject("step" -> JsInt(step))
this
}
/** For a discrete y-field, sets the height per discrete step.. */
def heightStep(step: Int): this.type = {
spec.height = JsObject("step" -> JsInt(step))
this
}
/** Sets the mark definition object.
* Marks are the basic visual building block of a visualization.
* They provide basic shapes whose properties (such as position,
* size, and color) can be used to visually encode data, either
* from a data field, or a constant value.
*/
def mark(mark: JsObject): this.type = {
spec.mark = mark
this
}
/** Sets the mark property of a string (one of "bar", "circle",
* "square", "tick", "line", "area", "point", "rule", "geoshape",
* and "text"). */
def mark(mark: String): this.type = {
spec.mark = mark
this
}
/** Sets the channels x and y (quantitative),
* and optional color with default properties.
*/
def encode(x: String, y: String, color: Option[(String, String)] = None): this.type = {
this.x(x, "quantitative")
this.y(y, "quantitative")
color match {
case Some((field, t)) => this.color(field, t)
case None => ()
}
this
}
/** Sets the x channel as a datum field. */
def x(datum: JsValue): this.type = {
setPropertyDatum("x", datum)
this
}
/** Sets the y channel as a datum field. */
def y(datum: JsValue): this.type = {
setPropertyDatum("y", datum)
this
}
/** Sets the x field. */
def x(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = "",
scale: JsValue = JsUndefined,
axis: JsValue = JsUndefined,
sort: JsValue = JsUndefined,
band: Double = -1,
impute: JsValue = JsUndefined,
stack: JsValue = JsUndefined): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.x = View.positionField(field, `type`, bin, timeUnit,
aggregate, title, scale, axis, sort, band, impute, stack)
this
}
/** Sets the y field. */
def y(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = "",
scale: JsValue = JsUndefined,
axis: JsValue = JsUndefined,
sort: JsValue = JsUndefined,
band: Double = -1,
impute: JsValue = JsUndefined,
stack: JsValue = JsUndefined): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.y = View.positionField(field, `type`, bin, timeUnit,
aggregate, title, scale, axis, sort, band, impute, stack)
this
}
/** Sets the x2 field. */
def x2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.x2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the y2 field. */
def y2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.y2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the xError field. */
def xError(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.x = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the yError field. */
def yError(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.y = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the xError2 field. */
def xError2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.xError2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the yError2 field. */
def yError2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.yError2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the longitude field. */
def longitude(field: JsValue,
`type`: String = "quantitative",
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.longitude = View.field(field, `type`, bin, timeUnit, aggregate, title)
this
}
/** Sets the latitude field. */
def latitude(field: JsValue,
`type`: String = "quantitative",
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.latitude = View.field(field, `type`, bin, timeUnit, aggregate, title)
this
}
/** Sets the longitude2 field. */
def longitude2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.longitude2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the latitude2 field. */
def latitude2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.latitude2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the theta field. */
def theta(field: JsValue,
`type`: String = "quantitative",
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = "",
scale: JsValue = JsUndefined,
sort: String = "",
stack: JsValue = JsUndefined): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.theta = View.polarField(field, `type`, bin, timeUnit, aggregate, title, scale, sort, stack)
this
}
/** Sets the radius field. */
def radius(field: JsValue,
`type`: String = "quantitative",
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = "",
scale: JsValue = JsUndefined,
sort: String = "",
stack: JsValue = JsUndefined): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.radius = View.polarField(field, `type`, bin, timeUnit, aggregate, title, scale, sort, stack)
this
}
/** Sets the theta2 field. */
def theta2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.theta2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets the radius2 field. */
def radius2(field: JsValue,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding.radius2 = View.field(field, null, bin, timeUnit, aggregate, title)
this
}
/** Sets a mark property. */
def setProperty(prop: String,
field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding(prop) = View.markPropField(field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
this
}
/** Sets a mark property by value. */
def setPropertyValue(prop: String, value: JsValue): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding(prop) = JsObject("value" -> value)
this
}
/** Sets a mark property by datum. */
def setPropertyDatum(prop: String, datum: JsValue): this.type = {
if (!spec.contains("encoding")) spec.encoding = JsObject()
spec.encoding(prop) = JsObject("datum" -> datum)
this
}
/** Sets the color property. */
def color(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("color", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the color value. */
def color(value: JsValue): this.type = {
setPropertyValue("color", value)
}
/** Sets the angle property. */
def angle(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("angle", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the angle value. */
def angle(value: JsValue): this.type = {
setPropertyValue("angle", value)
}
/** Sets the fill property. */
def fill(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("fill", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the fill value. */
def fill(value: JsValue): this.type = {
setPropertyValue("fill", value)
}
/** Sets the stroke property. */
def stroke(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("stroke", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the stroke value. */
def stroke(value: JsValue): this.type = {
setPropertyValue("stroke", value)
}
/** Sets the shape property. */
def shape(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("shape", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the shape value. */
def shape(value: JsValue): this.type = {
setPropertyValue("shape", value)
}
/** Sets the size property. */
def size(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("size", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the size value. */
def size(value: JsValue): this.type = {
setPropertyValue("size", value)
}
/** Sets the text property. */
def text(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("text", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the text value. */
def text(value: JsValue): this.type = {
setPropertyValue("text", value)
}
/** Sets the opacity property. */
def opacity(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): this.type = {
setProperty("opacity", field, `type`, bin, timeUnit, aggregate, scale, legend, condition)
}
/** Sets the opacity value. */
def opacity(value: JsValue): this.type = {
setPropertyValue("opacity", value)
}
/** Sets the view background's fill and stroke.
* The background property of a top-level view specification defines the
* background of the whole visualization canvas. Meanwhile, the view
* property of a single-view or layer specification can define the
* background of the view.
*/
def view(background: JsObject): this.type = {
spec.view = background
this
}
/** Selections are the basic building block in Vega-Lite's grammar of
* interaction. They map user input (e.g., mouse moves and clicks,
* touch presses, etc.) into data queries, which can subsequently
* be used to drive conditional encoding rules, filter data points,
* or determine scale domains.
*
* The simplest definition of selection consists of a name and a type.
* The selection type determines the default events that trigger a
* selection and the resultant data query.
*
* Vega-Lite currently supports three selection types:
*
* - "single" to select a single discrete data value on click.
* - "multi" to select multiple discrete data value; the first value
* is selected on click and additional values toggled on shift-click.
* - "interval" to select a continuous range of data values on drag.
*
* @param selections (name, type) pairs
*/
def selection(selections: (String, String)*): this.type = {
spec.selection = JsObject(
selections.map { case (name, t) =>
name -> JsObject("type" -> JsString(t))
}: _*
)
this
}
/** Sets geographic projection, which will be applied to shape path for
* "geoshape" marks and to latitude and "longitude" channels for other
* marks.
*
* A cartographic projection maps longitude and latitude pairs to x, y
* coordinates. As with Vega, one can use projections in Vega-Lite to
* lay out both geographic points (such as locations on a map) represented
* by longitude and latitude coordinates, or to project geographic regions
* (such as countries and states) represented using the GeoJSON format.
* Projections are specified at the unit specification level, alongside
* encoding. Geographic coordinate data can then be mapped to longitude
* and latitude channels (and longitude2 and latitude2 for ranged marks).
*/
def projection(projection: JsObject): this.type = {
spec.projection = projection
this
}
}
object View {
/** Returns a field definition.
* To encode a particular field in the data set with an encoding channel,
* the channel's field definition must describe the field name and its
* data type.
*
* @param field A string defining the name of the field from which to
* pull a data value or an object defining iterated values
* from the repeat operator. field is not required if
* aggregate is count.
* @param `type` The encoded field's type of measurement ("quantitative",
* "temporal", "ordinal", or "nominal"). It can also be a
* "geojson" type for encoding ‘geoshape'.
*
* Data type describes the semantics of the data rather than
* the primitive data types (number, string, etc.). The same
* primitive data type can have different types of
* measurement. For example, numeric data can represent
* quantitative, ordinal, or nominal data.
*
* Data values for a temporal field can be either a
* date-time string (e.g., "2015-03-07 12:32:17",
* "17:01", "2015-03-16", "2015") or a timestamp
* number (e.g., 1552199579097).
*
* Secondary channels (e.g., x2, y2, xError, yError) do not
* have type as they have exactly the same type as their
* primary channels (e.g., x, y)
* @param bin A flag for binning a quantitative field.
* - If true, default binning parameters will be applied.
* - If "binned", this indicates that the data for the x
* (or y) channel are already binned.
* @param timeUnit Time unit (e.g., year, yearmonth, month, hours) for a
* temporal field, or a temporal field that gets cast
* as ordinal.
* @param aggregate Aggregation function for the field (e.g., "mean",
* "sum", "median", "min", "max", "count").
* @param title A title for the field. If null, the title will be
* removed. The default value is derived from the
* field's name and transformation function (aggregate,
* bin and timeUnit).
*/
def field(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = ""): JsObject = {
val json = JsObject()
// field is not required if aggregate is count.
if (field == null && aggregate != "count")
throw new IllegalArgumentException("field is null while aggregate is not count")
if (field != null) json.field = field
if (`type` != null) json("type") = `type`
if (bin != JsUndefined) json.bin = bin
if (timeUnit.nonEmpty) json.timeUnit = timeUnit
if (aggregate.nonEmpty) json.aggregate = aggregate
if (title == null) json.title = JsNull
else if (title.nonEmpty) json.title = title
json
}
/** Returns a position field definition.
* x and y position channels determine the position of the marks,
* or width/height of horizontal/vertical "area" and "bar".
* In addition, x2 and y2 can specify the span of ranged area, bar,
* rect, and rule.
*
* @param field A string defining the name of the field from which to
* pull a data value or an object defining iterated values
* from the repeat operator. field is not required if
* aggregate is count
* @param `type` The encoded field's type of measurement ("quantitative",
* "temporal", "ordinal", or "nominal"). It can also be a
* "geojson" type for encoding ‘geoshape'.
*
* Data type describes the semantics of the data rather than
* the primitive data types (number, string, etc.). The same
* primitive data type can have different types of
* measurement. For example, numeric data can represent
* quantitative, ordinal, or nominal data.
*
* Data values for a temporal field can be either a
* date-time string (e.g., "2015-03-07 12:32:17",
* "17:01", "2015-03-16", "2015") or a timestamp
* number (e.g., 1552199579097).
* @param bin A flag for binning a quantitative field.
* - If true, default binning parameters will be applied.
* - If "binned", this indicates that the data for the x
* (or y) channel are already binned.
* @param timeUnit Time unit (e.g., year, yearmonth, month, hours) for a
* temporal field, or a temporal field that gets cast
* as ordinal.
* @param aggregate Aggregation function for the field (e.g., "mean",
* "sum", "median", "min", "max", "count").
* @param title A title for the field. If null, the title will be
* removed. The default value is derived from the
* field's name and transformation function (aggregate,
* bin and timeUnit).
* @param scale An object defining properties of the channel's scale,
* which is the function that transforms values in the data
* domain (numbers, dates, strings, etc.) to visual values
* (pixels, colors, sizes) of the encoding channels.
*
* If null, the scale will be disabled and the data value
* will be directly encoded.
*
* If undefined, default scale properties are applied.
* @param axis An object defining properties of axis's gridlines, ticks
* and labels.
*
* If null, the axis for the encoding channel will be
* removed.
*
* If undefined, default axis properties are applied.
* @param sort Sort order for the encoded field.
*
* For continuous fields (quantitative or temporal), sort
* can be either "ascending" or "descending".
*
* For discrete fields, sort can be one of the following:
* - "ascending" or "descending" - for sorting by the values'
* natural order in JavaScript.
* - A string indicating an encoding channel name to sort
* by (e.g., "x" or "y") with an optional minus prefix for
* descending sort (e.g., "-x" to sort by x-field, descending).
* This channel string is short-form of a sort-by-encoding
* definition. For example, "sort": "-x" is equivalent to
* "sort": {"encoding": "x", "order": "descending"}.
* @param band For rect-based marks (rect, bar, and image), mark size
* relative to bandwidth of band scales or time units.
* If set to 1, the mark size is set to the bandwidth
* or the time unit interval. If set to 0.5, the mark
* size is half of the bandwidth or the time unit interval.
*
* For other marks, relative position on a band of a stacked,
* binned, time unit or band scale. If set to 0, the marks
* will be positioned at the beginning of the band. If set
* to 0.5, the marks will be positioned in the middle of
* the band.
* @param impute An object defining the properties of the Impute Operation
* to be applied. The field value of the other positional
* channel is taken as key of the Impute Operation. The
* field of the color channel if specified is used as
* groupby of the Impute Operation.
* @param stack Type of stacking offset if the field should be stacked.
* stack is only applicable for x, y, theta, and radius
* channels with continuous domains. For example, stack
* of y can be used to customize stacking for a vertical
* bar chart.
*
* stack can be one of the following values:
*
* - "zero" or true: stacking with baseline offset at zero
* value of the scale (for creating typical stacked bar
* and area chart).
* - "normalize": stacking with normalized domain (for
* creating normalized stacked bar and area charts.
* - "center": stacking with center baseline
* (for streamgraph).
* - null or false: No-stacking. This will produce layered
* bar and area chart.
*/
def positionField(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = "",
scale: JsValue = JsUndefined,
axis: JsValue = JsUndefined,
sort: JsValue = JsUndefined,
band: Double = -1,
impute: JsValue = JsUndefined,
stack: JsValue = JsUndefined): JsObject = {
val json = this.field(field, `type`, bin, timeUnit, aggregate, title)
if (scale != JsUndefined) json.scale = scale
if (axis != JsUndefined) json.axis = axis
if (sort != JsUndefined) json.sort = sort
if (band >= 0) json.band = band
if (impute != JsUndefined) json.impute = impute
if (stack != JsUndefined) json.stack = stack
json
}
/** Returns a polar field definition.
* theta and radius position channels determine the position or interval
* on polar coordindates for arc and text marks.
*
* @param field A string defining the name of the field from which to
* pull a data value or an object defining iterated values
* from the repeat operator. field is not required if
* aggregate is count
* @param `type` The encoded field's type of measurement ("quantitative",
* "temporal", "ordinal", or "nominal"). It can also be a
* "geojson" type for encoding ‘geoshape'.
*
* Data type describes the semantics of the data rather than
* the primitive data types (number, string, etc.). The same
* primitive data type can have different types of
* measurement. For example, numeric data can represent
* quantitative, ordinal, or nominal data.
*
* Data values for a temporal field can be either a
* date-time string (e.g., "2015-03-07 12:32:17",
* "17:01", "2015-03-16", "2015") or a timestamp
* number (e.g., 1552199579097).
* @param bin A flag for binning a quantitative field.
* - If true, default binning parameters will be applied.
* - If "binned", this indicates that the data for the x
* (or y) channel are already binned.
* @param timeUnit Time unit (e.g., year, yearmonth, month, hours) for a
* temporal field, or a temporal field that gets cast
* as ordinal.
* @param aggregate Aggregation function for the field (e.g., "mean",
* "sum", "median", "min", "max", "count").
* @param title A title for the field. If null, the title will be
* removed. The default value is derived from the
* field's name and transformation function (aggregate,
* bin and timeUnit).
* @param scale An object defining properties of the channel's scale,
* which is the function that transforms values in the data
* domain (numbers, dates, strings, etc.) to visual values
* (pixels, colors, sizes) of the encoding channels.
*
* If null, the scale will be disabled and the data value
* will be directly encoded.
*
* If undefined, default scale properties are applied.
* @param sort Sort order for the encoded field.
*
* For continuous fields (quantitative or temporal), sort
* can be either "ascending" or "descending".
*
* For discrete fields, sort can be one of the following:
* - "ascending" or "descending" – for sorting by the values'
* natural order in JavaScript.
* - A string indicating an encoding channel name to sort
* by (e.g., "x" or "y") with an optional minus prefix for
* descending sort (e.g., "-x" to sort by x-field, descending).
* This channel string is short-form of a sort-by-encoding
* definition. For example, "sort": "-x" is equivalent to
* "sort": {"encoding": "x", "order": "descending"}.
* @param stack Type of stacking offset if the field should be stacked.
* stack is only applicable for x, y, theta, and radius
* channels with continuous domains. For example, stack
* of y can be used to customize stacking for a vertical
* bar chart.
*
* stack can be one of the following values:
*
* - "zero" or true: stacking with baseline offset at zero
* value of the scale (for creating typical stacked bar
* and area chart).
* - "normalize": stacking with normalized domain (for
* creating normalized stacked bar and area charts.
* - "center": stacking with center baseline
* (for streamgraph).
* - null or false: No-stacking. This will produce layered
* bar and area chart.
*/
def polarField(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
title: String = "",
scale: JsValue = JsUndefined,
sort: String = "",
stack: JsValue = JsUndefined): JsObject = {
val json = this.field(field, `type`, bin, timeUnit, aggregate, title)
if (scale != JsUndefined) json.scale = scale
if (sort.nonEmpty) json.sort = sort
if (stack != JsUndefined) json.stack = stack
json
}
/** Returns a mark property field Definition.
* x and y position channels determine the position of the marks,
* or width/height of horizontal/vertical "area" and "bar".
* In addition, x2 and y2 can specify the span of ranged area, bar,
* rect, and rule.
*
* @param field A string defining the name of the field from which to
* pull a data value or an object defining iterated values
* from the repeat operator. field is not required if
* aggregate is count
* @param `type` The encoded field's type of measurement ("quantitative",
* "temporal", "ordinal", or "nominal"). It can also be a
* "geojson" type for encoding ‘geoshape'.
*
* Data type describes the semantics of the data rather than
* the primitive data types (number, string, etc.). The same
* primitive data type can have different types of
* measurement. For example, numeric data can represent
* quantitative, ordinal, or nominal data.
*
* Data values for a temporal field can be either a
* date-time string (e.g., "2015-03-07 12:32:17",
* "17:01", "2015-03-16", "2015") or a timestamp
* number (e.g., 1552199579097).
* @param bin A flag for binning a quantitative field.
* - If true, default binning parameters will be applied.
* - If "binned", this indicates that the data for the x
* (or y) channel are already binned.
* @param timeUnit Time unit (e.g., year, yearmonth, month, hours) for a
* temporal field, or a temporal field that gets cast
* as ordinal.
* @param aggregate Aggregation function for the field (e.g., "mean",
* "sum", "median", "min", "max", "count").
* @param scale An object defining properties of the channel's scale,
* which is the function that transforms values in the data
* domain (numbers, dates, strings, etc.) to visual values
* (pixels, colors, sizes) of the encoding channels.
*
* If null, the scale will be disabled and the data value
* will be directly encoded.
*
* If undefined, default scale properties are applied.
* @param legend An object defining properties of the legend. If null,
* the legend for the encoding channel will be removed.
* @param condition One or more value definition(s) with a selection or
* a test predicate.
*
* Note: A field definition's condition property can only
* contain conditional value definitions since Vega-Lite
* only allows at most one encoded field per encoding
* channel.
*/
def markPropField(field: JsValue,
`type`: String,
bin: JsValue = JsUndefined,
timeUnit: String = "",
aggregate: String = "",
scale: JsValue = JsUndefined,
legend: JsValue = JsUndefined,
condition: JsValue = JsUndefined): JsObject = {
val json = this.field(field, `type`, bin, timeUnit, aggregate)
if (scale != JsUndefined) json.scale = scale
if (legend != JsUndefined) json.legend = legend
if (condition != JsUndefined) json.condition = condition
json
}
}