UNPKG

d3-visualize

Version:

d3-view components for data visualization

167 lines (136 loc) 4.48 kB
import {map} from 'd3-collection'; import {pop} from 'd3-let'; import globalOptions from '../core/options'; import {vizPrototype} from '../core/chart'; import warn from '../utils/warn'; globalOptions.legend = { location: "top-right", orient: "vertical", fontSize: '3%', title: '', titleWidth: "20%", labelFormat: null, titleMinWidth: 30, titleMaxWidth: 60, minFontSize: 10, maxFontSize: 20, offset: [10, 10], shapeWidth: 15, shapeHeight: 15, hide: 300, // specify a pixel size below which tick labels are not displayed }; vizPrototype.getLegend = function (name) { return this.getD3('legend', name); }; // // Legend method // ========================== vizPrototype.legend = function (cfg, box) { var vizModel = this.getModel(), model = this.getModel('legend'), font = this.getModel('font'), name = pop(cfg, 'type') || vizModel.legendType, vizSize = Math.max(box.vizHeight, box.vizWidth), fontSize = this.dim(model.fontSize, vizSize, model.minFontSize, model.maxFontSize), legend = this.getLegend(name); if (!model.location) return; if (!legend) return warn(`Could not load legend ${name}`); legend = legend().orient(model.orient); if (model.title) { legend.title(model.title); if (model.titleWidth) { var width = this.dim(model.titleWidth, vizSize, model.titleMinWidth, model.titleMaxWidth); legend.titleWidth(width); } } if (model.labelFormat) legend.labelFormat(model.labelFormat); legend.shapeWidth(model.shapeWidth).shapeHeight(model.shapeHeight); // apply cfg parameters for (let key in cfg) legend[key](cfg[key]); var gl = this.group('legend') .style('font-size', `${fontSize}px`) .html('') .call(legend), bb = gl.node().getBBox(), offset = locations.get(model.location).call(this, bb, box, model), transform = this.translate(offset.x, offset.y); gl.selectAll('text').style('fill', model.stroke || font.stroke); this.applyTransform(gl, transform); // // // if the legend needs to be hidden below a certain size if (model.hide) { if (vizSize < model.hide) gl.style('opacity', 0); else gl.style('opacity', 1); } }; export const locations = map({ top, bottom, right, left, 'top-left': topLeft, 'top-right': topRight, 'bottom-left': bottomLeft, 'bottom-right': bottomRight }); function top (bb, box, options) { var offsetY = this.dim(options.offset[1], box.vizHeight); return { x: box.margin.left + (box.innerWidth - bb.width)/2, y: offsetY }; } function bottom (bb, box, options) { var offsetY = this.dim(options.offset[1], box.vizHeight); return { x: box.margin.left + (box.innerWidth - bb.width)/2, y: box.vizHeight - bb.height - offsetY }; } function right (bb, box, options) { var offsetX = this.dim(options.offset[0], box.vizWidth); return { x: box.vizWidth - bb.width - offsetX, y: box.margin.top + (box.innerHeight - bb.height)/2 }; } function left (bb, box, options) { var offsetX = this.dim(options.offset[0], box.vizWidth); return { x: box.margin.left - offsetX, y: box.margin.top + (box.innerHeight - bb.height)/2 }; } function topLeft (bb, box, options) { var offsetX = this.dim(options.offset[0], box.vizWidth), offsetY = this.dim(options.offset[1], box.vizHeight); return { x: box.margin.left + (box.innerWidth - bb.width)/2 + offsetX, y: offsetY }; } function topRight (bb, box, options) { var offsetX = this.dim(options.offset[0], box.vizWidth), offsetY = this.dim(options.offset[1], box.vizHeight); return { x: box.vizWidth - bb.width - offsetX, y: offsetY }; } function bottomLeft (bb, box, options) { var offsetX = this.dim(options.offset[0], box.vizWidth), offsetY = this.dim(options.offset[1], box.vizHeight); return { x: bb.width + offsetX, y: box.vizHeight - bb.height - offsetY }; } function bottomRight (bb, box, options) { var offsetX = this.dim(options.offset[0], box.vizWidth), offsetY = this.dim(options.offset[1], box.vizHeight); return { x: box.vizWidth - bb.width - offsetX, y: box.vizHeight - bb.height - offsetY }; }