Skip to content

Arrow

The "arrow" mark displays each data item as a directed line or ranged segment. It supports horizontal, vertical, and diagonal arrows, making it useful for genomic and protein annotations where span and direction both carry meaning, such as genes, transcripts, alignments, and directional protein domains, and for general directed relationships.

{
  "description": "Directional segments rendered with the arrow mark.",

  "data": {
    "values": [
      { "feature": "gene A", "start": 10, "end": 50, "strand": "+" },
      { "feature": "gene B", "start": 30, "end": 90, "strand": "-" }
    ]
  },

  "mark": { "type": "arrow", "size": 20 },

  "encoding": {
    "x": {
      "field": "start",
      "type": "index",
      "scale": { "domain": [0, 100] }
    },
    "x2": { "field": "end" },
    "y": {
      "field": "feature",
      "type": "nominal",
      "scale": { "type": "band", "padding": 0.25 }
    },
    "direction": {
      "field": "strand",
      "type": "nominal",
      "scale": { "domain": ["+", "-"], "range": ["forward", "reverse"] }
    }
  }
}

Channels

The arrow mark supports the primary and secondary position channels, the direction channel, and the color, stroke, fill, opacity, strokeOpacity, fillOpacity, and strokeWidth channels.

The position channels define the arrow endpoints. Axis-aligned arrows can use only x and x2, or only y and y2; diagonal arrows use both x/x2 and y/y2. By default, the arrowhead points from the primary endpoint (x, y) toward the secondary endpoint (x2, y2). The direction channel can override this and is often the most convenient way to map strand-like values such as + and - to "forward" and "reverse".

Shape is controlled with mark properties. The size mark property controls the stem thickness. Numeric size values are pixels. For axis-aligned arrows, size: { "band": 0.8 } uses a fraction of the perpendicular band width. If the perpendicular channel has no band-like scale, the fraction is resolved against the perpendicular view span. Band-relative size is not supported for diagonal arrows.

headWidth is a multiplier of the resolved size. Values above 1 make the arrowhead wider than the stem.

Properties

buildIndex
Type: boolean

Whether the x channel should build an index for efficient subset rendering. If omitted, GenomeSpy enables indexing automatically for positional x encodings.

clip
Type: boolean | "x" | "y" | "never"

Controls whether the mark is clipped to the UnitView's rectangle. The values "x" and "y" clip only in the corresponding screen-space direction. Inherited clipping from parent containers still applies unless "never" is used.

Default value: the direction of zoomable positional scales

color
Type: string | ExprRef

Color of the mark. Affects either fill or stroke, depending on the filled property.

cullByVisibleRange
Type: boolean | "x" | "y"

Hide point-like mark instances whose anchor falls outside the inherited visible range in the given screen-space direction.

cursor
Type: string | ExprRef

Mouse cursor shown while the pointer is over the mark. Mark cursor takes precedence over enclosing view cursors.

Default value: browser default

direction
Type: "forward" | "reverse" | ExprRef

Direction of the arrowhead. "forward" places the arrowhead at the secondary endpoint (x2, y2). "reverse" places it at the primary endpoint (x, y). For data-driven direction, use the direction encoding channel.

Default value: "forward"

fill
Type: string | ExprRef

The fill color.

fillOpacity
Type: number | ExprRef

The fill opacity. Value between 0 and 1.

filled
Type: boolean

Whether the color represents the fill color (true) or the stroke color (false).

headAngle
Type: number | ExprRef

Angle in degrees between the arrow axis and an outer edge of the arrowhead. Smaller values produce longer, narrower heads. Larger values produce shorter, blunter heads. Values are clamped to [1, 90].

Default value: 45

headNotchAngle
Type: number | ExprRef

Angle in degrees between the arrow axis and the arrowhead notch edge. 90 places the notch point at the tip, producing a triangular head when headAngle is less than 90. Applies to "triangle" heads. "open" heads use headAngle for the notch edge as well. Values are clamped to [1, 90].

Default value: 90

headPlacement
Type: "inside" | "outside" | ExprRef

Placement of the arrowhead relative to the encoded segment. "inside" keeps the whole arrowhead within the encoded segment. "outside" places the arrowhead beyond the encoded segment so that the head starts at the segment endpoint.

Default value: "inside"

headShape
Type: "triangle" | "open" | ExprRef

Shape of the arrowhead. "triangle" draws a filled head. "open" draws an open head whose thickness matches the resolved size, even when stem is false.

Default value: "triangle"

headSpacing
Type: number | null | ExprRef

Spacing between repeated arrowheads as a multiplier of resolved size. The effective spacing is at least the rendered arrowhead footprint, including stroke. If null, arrowheads are not repeated.

Default value: null

headWidth
Type: number | ExprRef

Width of the arrowhead as a multiplier of resolved size. Values above 1 make the arrowhead wider than the stem.

Default value: 3

minBufferSize
Type: number

Minimum size for WebGL buffers (number of data items). Allows for using bufferSubData() to update graphics.

This property is intended for internal use.

minSize
Type: number | ExprRef

Minimum resolved arrow stem thickness in pixels. Applies to numeric, band-relative, and encoded size values.

Default value: 1

minStemLength
Type: number | ExprRef

Minimum visible length of the arrow stem in pixels. When a non-repeated arrow is too short for the configured shape and minimum stem length, the affected notch or head angle is made blunter toward 90 degrees. For "inside" placement, this applies to "triangle" heads and is measured from the start of the stem to where the stem meets the head notch edge. For "outside" placement, this applies when startNotch is true and is measured from the start notch to the head start. Has no effect when stem is false.

Default value: 0

opacity
Type: number | ExprRef

Opacity of the mark. Affects fillOpacity or strokeOpacity, depending on the filled property.

size
Type: number | ArrowRelativeSize | ExprRef

Arrow stem thickness in pixels, or as a fraction of the perpendicular band or view span for axis-aligned arrows.

Numeric values are pixels. { "band": 0.8 } resolves to 80% of the perpendicular band width, or 80% of the perpendicular view span when no band scale is available. Use channel to explicitly select the reference channel. Band-relative size is not supported for diagonal arrows.

Default value: 8

startNotch
Type: boolean | ExprRef

Whether to draw a notch at the start of the arrow. The start notch uses the same slope as the arrowhead edge.

Default value: false

stem
Type: boolean | ExprRef

Whether to draw the arrow stem. When false, the resolved size still controls open-head thickness. minStemLength has no effect when the stem is hidden.

Default value: true

stroke
Type: string | ExprRef

The stroke color

strokeOpacity
Type: number | ExprRef

The stroke opacity. Value between 0 and 1.

strokeWidth
Type: number | ExprRef

The stroke width in pixels.

style
Type: string | string[]

Named style reference(s) resolved from config.style. If an array is provided, later styles override earlier ones.

tooltip
Type: HandledTooltip | null | boolean

Tooltip handler. If null, no tooltip is shown. If string, specifies the tooltip handler to use.

x
Type: number | ExprRef

Position on the x axis.

x2
Type: number | ExprRef

The secondary position on the x axis.

xOffset
Type: number

Offsets of the x and x2 coordinates in pixels. The offset is applied after the viewport scaling and translation.

Default value: 0

y
Type: number | ExprRef

Position on the y axis.

y2
Type: number | ExprRef

The secondary position on the y axis.

yOffset
Type: number

Offsets of the y and y2 coordinates in pixels. The offset is applied after the viewport scaling and translation.

Default value: 0

Examples

Built-in Styles

Built-in styles provide common arrow shapes:

  • "arrow-transcript" draws a thin transcript-like line with repeated heads.
  • "arrow-block" draws a thick filled segment with an arrowhead.
  • "arrow-block-notch" draws a thick filled segment with an arrowhead and a start notch. Its arrowhead is placed outside the encoded segment, leaving the block span available for the notched stem.
{
  "description": "Built-in arrow mark styles.",

  "data": { "values": [{ "band": "arrow", "start": 10, "end": 90 }] },

  "encoding": {
    "x": {
      "field": "start",
      "type": "quantitative",
      "scale": { "domain": [0, 100] },
      "axis": null
    },
    "x2": { "field": "end" }
  },

  "vconcat": [
    { "title": "Default style", "mark": { "type": "arrow" } },
    {
      "title": "arrow-transcript",
      "mark": { "type": "arrow", "style": "arrow-transcript" }
    },
    {
      "title": "arrow-block",
      "mark": { "type": "arrow", "style": "arrow-block" }
    },
    {
      "title": "arrow-block-notch",
      "mark": { "type": "arrow", "style": "arrow-block-notch" }
    }
  ]
}

Arrow Playground

The arrow shape parameters can be adjusted interactively:

{
  "description": "Interactive playground for the arrow mark shape parameters.",

  "params": [
    {
      "name": "headShape",
      "value": "triangle",
      "bind": {
        "input": "select",
        "options": ["triangle", "open"],
        "name": "Head shape"
      }
    },
    {
      "name": "headAngle",
      "value": 45,
      "bind": {
        "input": "range",
        "min": 1,
        "max": 90,
        "step": 1,
        "name": "Head angle"
      }
    },
    {
      "name": "headNotchAngle",
      "value": 90,
      "bind": {
        "input": "range",
        "min": 1,
        "max": 90,
        "step": 1,
        "name": "Head notch angle"
      }
    },
    {
      "name": "headWidth",
      "value": 3,
      "bind": {
        "input": "range",
        "min": 0,
        "max": 10,
        "step": 0.05,
        "name": "Head width"
      }
    },
    {
      "name": "size",
      "value": 28,
      "bind": {
        "input": "range",
        "min": 0,
        "max": 80,
        "step": 0.5,
        "name": "Size"
      }
    },
    {
      "name": "minSize",
      "value": 1,
      "bind": {
        "input": "range",
        "min": 0,
        "max": 20,
        "step": 0.5,
        "name": "Min size"
      }
    },
    {
      "name": "startNotch",
      "value": false,
      "bind": { "input": "checkbox", "name": "Start notch" }
    },
    {
      "name": "stem",
      "value": true,
      "bind": { "input": "checkbox", "name": "Stem" }
    },
    {
      "name": "repeatHeads",
      "value": false,
      "bind": { "input": "checkbox", "name": "Repeat heads" }
    },
    {
      "name": "headSpacing",
      "value": 3,
      "bind": {
        "input": "range",
        "min": 1,
        "max": 30,
        "step": 0.1,
        "name": "Head spacing"
      }
    },
    {
      "name": "minStemLength",
      "value": 0,
      "bind": {
        "input": "range",
        "min": 0,
        "max": 100,
        "step": 1,
        "name": "Min stem length"
      }
    },
    {
      "name": "strokeWidth",
      "value": 1,
      "bind": {
        "input": "range",
        "min": 0,
        "max": 8,
        "step": 0.5,
        "name": "Stroke width"
      }
    },
    {
      "name": "headPlacement",
      "value": "inside",
      "bind": {
        "input": "radio",
        "options": ["inside", "outside"],
        "name": "Head placement"
      }
    }
  ],

  "data": {
    "values": [
      { "band": "pair", "start": 10, "end": 20 },
      { "band": "pair", "start": 40, "end": 80 },
      { "band": "single", "start": 20, "end": 90 }
    ]
  },

  "mark": {
    "type": "arrow",
    "headShape": { "expr": "headShape" },
    "headAngle": { "expr": "headAngle" },
    "headNotchAngle": { "expr": "headNotchAngle" },
    "size": { "expr": "size" },
    "minSize": { "expr": "minSize" },
    "stem": { "expr": "stem" },
    "headWidth": { "expr": "headWidth" },
    "startNotch": { "expr": "startNotch" },
    "headSpacing": { "expr": "repeatHeads ? headSpacing : null" },
    "minStemLength": { "expr": "minStemLength" },
    "headPlacement": { "expr": "headPlacement" },
    "fill": "#5B8DEF",
    "stroke": "black",
    "strokeWidth": { "expr": "strokeWidth" }
  },

  "encoding": {
    "x": {
      "field": "start",
      "type": "quantitative",
      "scale": { "domain": [0, 100], "zoom": true },
      "axis": { "title": "Position", "grid": true }
    },
    "x2": { "field": "end" },
    "y": {
      "field": "band",
      "type": "nominal",
      "scale": {
        "type": "band",
        "domain": ["pair", "single"],
        "padding": 0.25
      },
      "axis": { "title": null }
    }
  },

  "view": { "stroke": "lightgray" }
}