Home Reference Source Repository

src/svg/components/canvasPointset.js

import {select, nest} from 'd3';
import {symbol, symbolCircle, symbolCross, symbolDiamond, symbolSquare, symbolStar, symbolTriangle, symbolWye} from 'd3';

export class CanvasPointset {
  constructor(x, y, config) {
    this.xAxis = x.xAxis;
    this.yAxis = y.yAxis;
    this.canvas = select(config.selector).append('canvas')
      .attr('id', 'point-set-canvas')
      .attr('width', config.width)
      .attr('height', config.height)
      .style('position', 'absolute')
      .style('z-index', 2)
      .style('transform', `translate(${config.marginLeft}px, ${config.marginTop}px)`);
  }

  update(svg, config, data) {
    let markerShape = config.markerShape,
      markerSize = config.markerSize,
      colorScale = config.colorScale,
      points = null,
      series = null,
      dataContainer = null;

    let canvasCtx = this.canvas.node().getContext('2d');

    let shape = symbol()
      .size(markerSize)
      .context(canvasCtx);

    switch (markerShape) {
      case 'dot':
        shape.type(symbolCircle);
        break;
      case 'ring':
        shape.type(symbolCircle);
        break;
      case 'cross':
        shape.type(symbolCross);
        break;
      case 'diamond':
        shape.type(symbolDiamond);
        break;
      case 'square':
        shape.type(symbolSquare);
        break;
      case 'star':
        shape.type(symbolStar);
        break;
      case 'triangle':
        shape.type(symbolTriangle);
        break;
      case 'wye':
        shape.type(symbolWye);
        break;
      case 'circle':
        shape.type(symbolCircle);
        break;
      default:
        shape.type(symbolCircle);
    }

    // Custom DOM element, this won't be rendered
    dataContainer = svg.append('proteic');
    series = dataContainer.selectAll('proteic.g.points');

    series
      .data(data, (d) => d.key)
      .enter()
      .call((s) => {
        let self = this;
        console.log(s);
        s.each(function (d) {
          canvasCtx.save();
          canvasCtx.translate(self.xAxis.scale()(d.x), self.yAxis.scale()(d.y));
          canvasCtx.beginPath();
          canvasCtx.strokeStyle = colorScale(d.key);
          canvasCtx.fillStyle = colorScale(d.key);
          shape();
          canvasCtx.closePath();
          canvasCtx.stroke();
          if (markerShape !== 'ring') {
            canvasCtx.fill();
          }
          canvasCtx.restore();
        });
      });
  }

  render(svg, config) {
    //Do nothing, since points render only when new data is received.
  }
}