All Downloads are FREE. Search and download functionalities are using the official Maven repository.

smile.plot.vega.Facet.scala Maven / Gradle / Ivy

The newest version!
/*
 * 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._

/** A facet is a trellis plot (or small multiple) of a series of similar
  * plots that displays different subsets of the same data, facilitating
  * comparison across subsets.
  *
  * The facet channels (facet, row, and column) are encoding channels that
  * serves as macros for a facet specification. Vega-Lite automatically
  * translates this shortcut to use the facet operator.
  */
trait Facet extends View {
  /** A field definition for the (flexible) facet of trellis plots.
    * If either row or column is specified, this channel will be ignored.
    *
    * @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.
    * @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 casted
    *                 as ordinal.
    * @param align    The alignment to apply to row/column facet’s subplot.
    *                 The supported string values are "all", "each", and "none".
    *
    *                 - For "none", a flow layout will be used, in which
    *                   adjacent subviews are simply placed one after the other.
    *                 - For "each", subviews will be aligned into a clean
    *                   grid structure, but each row or column may be of
    *                   variable size.
    *                 - For "all", subviews will be aligned and each row
    *                   or column will be sized identically based on the
    *                   maximum observed size. String values for this
    *                   property will be applied to both grid rows and
    *                   columns.
    * @param center   Boolean flag indicating if facet’s subviews should
    *                 be centered relative to their respective rows or columns.
    * @param spacing  The spacing in pixels between facet’s sub-views.
    * @param columns  The number of columns to include in the view
    *                 composition layout.
    */
  def facet(field: String,
            `type`: String = "quantitative",
            bin: Either[Boolean, JsObject] = Left(false),
            timeUnit: String = "",
            align: String = "all",
            center: Boolean = false,
            spacing: Option[Int] = None,
            columns: Option[Int] = None): Facet = {
    if (!spec.contains("encoding")) spec.encoding = JsObject()
    spec.encoding.facet = Facet.field(field, `type`, bin, timeUnit, align, center, spacing)
    if (columns.isDefined) spec.facet.columns = columns.get
    this
  }

  /** A field definition for the vertical facet of trellis plots. */
  def row(field: String,
          `type`: String = "quantitative",
          bin: Either[Boolean, JsObject] = Left(false),
          timeUnit: String = "",
          align: String = "all",
          center: Boolean = false,
          spacing: Option[Int] = None): Facet = {
    if (!spec.contains("encoding")) spec.encoding = JsObject()
    spec.encoding.row = Facet.field(field, `type`, bin, timeUnit, align, center, spacing)
    this
  }

  /** A field definition for the horizontal facet of trellis plots. */
  def column(field: String,
             `type`: String = "quantitative",
             bin: Either[Boolean, JsObject] = Left(false),
             timeUnit: String = "",
             align: String = "all",
             center: Boolean = false,
             spacing: Option[Int] = None): Facet = {
    if (!spec.contains("encoding")) spec.encoding = JsObject()
    spec.encoding.column = Facet.field(field, `type`, bin, timeUnit, align, center, spacing)
    this
  }
}

object Facet {
  /** Returns a facet field Definition.
    *
    * @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.
    * @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 casted
    *                 as ordinal.
    * @param align    The alignment to apply to row/column facet’s subplot.
    *                 The supported string values are "all", "each", and "none".
    *
    *                 - For "none", a flow layout will be used, in which
    *                   adjacent subviews are simply placed one after the other.
    *                 - For "each", subviews will be aligned into a clean
    *                   grid structure, but each row or column may be of
    *                   variable size.
    *                 - For "all", subviews will be aligned and each row
    *                   or column will be sized identically based on the
    *                   maximum observed size. String values for this
    *                   property will be applied to both grid rows and
    *                   columns.
    * @param center   Boolean flag indicating if facet’s subviews should
    *                 be centered relative to their respective rows or columns.
    * @param spacing  The spacing in pixels between facet’s sub-views.
    */
  def field(field: String,
            `type`: String = "quantitative",
            bin: Either[Boolean, JsObject] = Left(false),
            timeUnit: String = "",
            align: String = "all",
            center: Boolean = false,
            spacing: Option[Int] = None): JsObject = {
    val json = View.field(field, `type`, bin, timeUnit)

    json.align = align
    json.center = center
    if (spacing.isDefined) json.spacing = spacing.get

    json
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy