jens-ox/metrics-graphics

View on GitHub
packages/lib/src/js/components/rug.js

Summary

Maintainability
A
0 mins
Test Coverage
import constants from '../misc/constants'

/**
 * Set up a new rug.
 *
 * @param {Object} args argument object.
 * @param {Function} args.accessor accessor used to get the rug value for a given data point.
 * @param {Scale} args.scale scale function of the rug.
 * @param {Number} [args.tickLength=5] length of the rug's ticks.
 * @param {Array} [args.colors=schemeCategory10] color scheme of the rug ticks.
 * @param {String} [args.orientation='horizontal'] orientation of the rug, either vertical or horizontal.
 * @param {Number} [args.left=0] left margin of the rug.
 * @param {Number} [args.top=0] top margin of the rug.
 */
export default class Rug {
  rugObject = null
  data = []
  left = 0
  top = 0
  tickLength = 5
  colors = constants.defaultColors
  orientation = constants.orientation.horizontal

  constructor ({ accessor, scale, data, tickLength, colors, orientation, left, top }) {
    this.accessor = accessor ?? this.accessor
    this.scale = scale ?? this.scale
    this.data = data ?? this.data
    this.tickLength = tickLength ?? this.tickLength
    this.colors = colors ?? this.colors
    this.orientation = orientation ?? this.orientation
    this.left = left ?? this.left
    this.top = top ?? this.top
  }

  get isVertical () { return this.orientation === constants.orientation.vertical }

  /**
   * Mount the rug to the given node.
   *
   * @param {Object} svg d3 node to mount the rug to.
   * @returns {void}
   */
  mountTo (svg) {
    // add container
    const top = this.isVertical ? this.top : this.top - this.tickLength
    const container = svg.append('g')
      .attr('transform', `translate(${this.left},${top})`)

    // add lines
    this.data.forEach((dataArray, i) => dataArray.forEach(datum => {
      const value = this.scale.scaleObject(this.accessor(datum))
      container.append('line')
        .attr(this.isVertical ? 'y1' : 'x1', value)
        .attr(this.isVertical ? 'y2' : 'x2', value)
        .attr(this.isVertical ? 'x1' : 'y1', 0)
        .attr(this.isVertical ? 'x2' : 'y2', this.tickLength)
        .attr('stroke', this.colors[i])
    }))
  }
}