import * as d3 from 'd3'; import { LabelStyle } from '../../styles/LabelStyle'; import { Node } from '../../types/Node'; import { Renderer } from '../Renderer'; class LabelRenderer extends Renderer { static defaultColor = '#333333'; static defaultFont = '14px sans-serif'; // Nodes to render protected _nodes: Node[]; // Styling protected color: string | null; protected font: string; constructor (style?: LabelStyle) { super(); this._nodes = []; this.color = LabelRenderer.defaultColor; this.font = LabelRenderer.defaultFont; if (style) { if (style.color) this.color = style.color; if (style.font) this.font = style.font; } } nodes (): Node[]; nodes (points: Node[]): this; nodes (points?: Node[]): Node[] | this { return arguments.length ? (this._nodes = points!, this) : this._nodes; } render (context: CanvasRenderingContext2D, x: d3.ScaleLinear, y: d3.ScaleLinear): void { if (!this._nodes.length) return; context.save(); context.beginPath(); if (this.color) context.fillStyle = this.color; context.font = this.font; context.textAlign = 'center'; context.textBaseline = 'middle'; this._nodes.forEach(node => { if (!node.labels) { context.fillText( node.id, x(node.x) + (node.dx ? node.dx : 0), y(node.y) + (node.dy ? node.dy : 0) ); } else { const match = this.font.match(/(\d*)px/); const size = match ? match.length > 1 ? parseInt(match[1]) : 12 : 12; const text = [node.id, ...node.labels]; const base = Math.floor((text.length * size) / 2 - size / 2) - 1; text.forEach((label, index) => { context.fillText( label, x(node.x) + (node.dx ? node.dx : 0), y(node.y) + (node.dy ? node.dy : 0) - base + index * size ); }); } }); context.restore(); } } export { LabelRenderer }