UNPKG

d2b

Version:

A d3-based reusable chart library.

142 lines (112 loc) 3.79 kB
import { symbol as d3Symbol, symbolCircle } from 'd3-shape'; import { rgb } from 'd3-color'; import { select } from 'd3-selection'; import 'd3-transition'; import base from '../model/base'; // point svg generator export default function () { const $$ = {}; /* Update Function */ const point = function (context) { const selection = context.selection? context.selection() : context; // point background let back = selection.selectAll('path.d2b-point-back').data(d => [d]); back.enter() .append('path') .attr('class', 'd2b-point-back') .attr('d', symbolNormal) .style('fill-opacity', 0) .style('stroke', $$.stroke) .style('stroke-width', $$.strokeWidth); if (context !== selection) { back = back.transition(context); } back .attr('d', symbolNormal) .style('stroke', $$.stroke) .style('stroke-width', $$.strokeWidth); // point foreground let front = selection.selectAll('path.d2b-point-front').data(d => [d]); front.enter() .append('path') .attr('class', 'd2b-point-front') .attr('d', symbolSmall) .style('opacity', frontOpacity) .style('fill', $$.fill) .style('stroke', $$.stroke) .style('stroke-width', $$.strokeWidth); if (context !== selection) { front = front.transition(context); } front .attr('d', symbolSmall) .style('opacity', frontOpacity) .style('fill', $$.fill) .style('stroke', $$.stroke) .style('stroke-width', $$.strokeWidth); // set mouse events if active selection .each(function (d, i) { const active = $$.active.call(this, d, i); select(this) .on('mouseover.d2b-point', (active)? mouseover : null ) .on('mouseout.d2b-point', (active)? mouseout : null ); }); selection.dispatch('point-updated', {bubbles: true}); return point; }; const symbol = d3Symbol(); /* Inherit from base model */ base(point, $$) .addPropFunctor('size', 150, null, d => symbol.size(d)) .addPropFunctor('type', symbolCircle, null, d => symbol.type(d)) .addPropFunctor('active', false) .addPropFunctor('empty', false) .addPropFunctor('fill', 'steelblue') .addPropFunctor('stroke', function (d, i) { return rgb($$.fill.call(this, d, i)).darker(0.3); }) .addPropFunctor('strokeWidth', '1px'); function frontOpacity (d, i) { return ($$.empty.call(this, d, i))? 0 : 1; } function symbolBig (d, i) { const size = $$.size.call(this, d, i), empty = $$.empty.call(this, d, i); return symbol.size(empty? size : 2.5 * size).call(this, d, i); } function symbolSmall (d, i) { const size = $$.size.call(this, d, i), empty = $$.empty.call(this, d, i); return symbol.size(empty? size / 3 : size).call(this, d, i); } function symbolNormal (d, i) { const size = $$.size.call(this, d, i); return symbol.size(size).call(this, d, i); } function mouseover (d, i) { const empty = $$.empty.call(this, d, i); select(this).select('path.d2b-point-back') .transition() .duration(100) .attr('d', symbolBig); select(this).select('path.d2b-point-front') .transition() .duration(100) .style('opacity', (empty)? 0.5 : 1) .attr('d', symbolSmall); } function mouseout(d, i) { const empty = $$.empty.call(this, d, i); select(this).select('path.d2b-point-back') .transition() .duration(100) .attr('d', symbolNormal); select(this).select('path.d2b-point-front') .transition() .duration(100) .style('opacity', (empty)? 0 : 1) .attr('d', symbolSmall); } return point; }