Skip to main content
Version: 1.0.0

Introduction to Tick Layer

What is a tick layer?

A tick is largely similar to a point mark except for the fact that it has a start point and an end point and thus is always a straight line.

Example

const { muze, getDataFromSearchQuery } = viz;

const data = getDataFromSearchQuery();

const RowField = "Cylinders";
const ColumnField = "Horsepower";
const DetailField = "Name";

muze
  .canvas()
  .rows([RowField])
  .columns([ColumnField])
  .detail([DetailField])
  .layers([
    {
      mark: "tick",
    },
  ])
  .data(data)
  .mount("#chart");

Creating a dotplot using tick layer

Example

const { muze, getDataFromSearchQuery } = viz;

const data = getDataFromSearchQuery();

const RowField = "Acceleration";
const ColumnField = "Year";
const ColorField = "Origin";
const DetailField = "Name";

muze
  .canvas()
  .rows([RowField])
  .columns([ColumnField])
  .color(ColorField)
  .detail([DetailField])
  .layers([
    {
      mark: "tick",
    },
  ])
  .data(data)
  .mount("#chart");

Creating a reference line

Below is an example of creating a reference line on a bar chart.

We will add a bar layer for visualizing Year vs Horsepower, a tick layer for showing the average value and a text layer displaying the actual average value.

Example

const { muze, getDataFromSearchQuery } = viz;

const data = getDataFromSearchQuery();

const YearField = "Year";
const HorsepowerField = "Horsepower";
const AverageLineSourceName = "averageLine";
const CompositeBarName = "compositeBar";

let dm = data;

dm = dm.groupBy([YearField]);
dm = dm.sort([[HorsepowerField, "DESC"]]);

let layerFactory = muze.layerFactory;

// Compose layers to draw the bars as well as the reference line and text
layerFactory.composeLayers(CompositeBarName, [
  {
    name: "simplebar",
    mark: "bar",
    encoding: {
      x: `${CompositeBarName}.encoding.x`,
      y: `${CompositeBarName}.encoding.y`,
      color: `${CompositeBarName}.encoding.color`,
    },
  },
  {
    name: "averageLine",
    mark: "tick",
    source: AverageLineSourceName,
    className: "averageLine",
    encoding: {
      y: `${CompositeBarName}.encoding.y`,
      x: null,
    },
    calculateDomain: false,
  },
  {
    name: "averageText",
    mark: "text",
    source: AverageLineSourceName,
    className: "averageText",
    encoding: {
      y: `${CompositeBarName}.encoding.y`,
      text: `${CompositeBarName}.encoding.text`,
      background: {
        enabled: true,
      },
    },
    encodingTransform: (points, layer, dependencies) => {
      // Transforms the test after the physical dimension is resolved so that it comes in the middle of the background
      let width = layer.measurement().width;
      let smartLabel = dependencies.smartLabel;
      for (let i = 0; i < points.length; i++) {
        let size = smartLabel.getOriSize(points[i].text);
        points[i].update.x = width - 5;
        points[i].textanchor = "end";
        points[i].update.y -= size.height / 2;
        points[i].color = "#000";
      }
      return points;
    },
    calculateDomain: false,
  },
]);

muze
  .canvas()
  .rows([HorsepowerField])
  .columns([YearField])
  .transform({
    // Create different sources (data) from the root source (data). Layers can access these sources and draw any visualization
    [AverageLineSourceName]: (dt) => dt.groupBy([""]), // Removes all the dim and aggregate the measures
  })
  .layers([
    {
      mark: "bar",
    },
    {
      mark: "text",
      encoding: {
        x: {
          field: null,
          value: (d, i) => {
            return i.context.measurement().width - 80;
          },
        },
        y: {
          field: HorsepowerField,
          value: (d) => {
            return d.y - 10;
          },
        },
        text: {
          field: HorsepowerField,
          formatter: (value) => {
            return `Average Horsepower: ${Math.round(value)}`;
          },
        },
        color: {
          value: () => "black",
        },
      },
      source: AverageLineSourceName,
    },
    {
      mark: "tick",
      className: "averageLine",
      encoding: {
        x: {
          field: null,
        },
        y: HorsepowerField,
        color: {
          value: () => "black",
        },
      },
      source: AverageLineSourceName,
    },
  ])
  .title("Sorted bar with trendline", { position: "top", align: "left" })
  .subtitle(
    "Average horsepower per year with average horsepower of all time marked as reference",
    { position: "top", align: "left" },
  )
  .data(dm)
  .mount("#chart");