d2b
Version:
142 lines (112 loc) • 3.79 kB
JavaScript
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;
}