UNPKG

escher-vis

Version:

Escher: A Web Application for Building, Sharing, and Embedding Data-Rich Visualizations of Biological Pathways

129 lines (119 loc) 4.09 kB
/** DirectionArrow. A constructor for an arrow that can be rotated and dragged, and supplies its direction. */ var utils = require('./utils'); var d3_drag = require('d3-drag').drag var d3_mouse = require('d3-selection').mouse var d3_selection = require('d3-selection') var DirectionArrow = utils.make_class(); DirectionArrow.prototype = { init: init, set_location: set_location, set_rotation: set_rotation, displace_rotation: displace_rotation, get_rotation: get_rotation, toggle: toggle, show: show, hide: hide, right: right, left: left, up: up, down: down, _setup_drag: _setup_drag }; module.exports = DirectionArrow; // definitions function init(sel) { this.arrow_container = sel.append('g') .attr('id', 'direction-arrow-container') .attr('transform', 'translate(0,0)rotate(0)'); this.arrow = this.arrow_container.append('path') .classed('direction-arrow', true) .attr('d', path_for_arrow()) .style('visibility', 'hidden') .attr('transform', 'translate(30,0)scale(2.5)'); this.sel = sel; this.center = { x: 0, y: 0 }; this._setup_drag(); this.dragging = false; this.is_visible = false; this.show(); // definitions function path_for_arrow() { return "M0 -5 L0 5 L20 5 L20 10 L30 0 L20 -10 L20 -5 Z"; } } function set_location(coords) { /** Move the arrow to coords. */ this.center = coords; var transform = utils.d3_transform_catch(this.arrow_container.attr('transform')); this.arrow_container.attr('transform', 'translate('+coords.x+','+coords.y+')rotate('+transform.rotate+')'); } function set_rotation(rotation) { /** Rotate the arrow to rotation. */ var transform = utils.d3_transform_catch(this.arrow_container.attr('transform')); this.arrow_container.attr('transform', 'translate('+transform.translate+')rotate('+rotation+')'); } function displace_rotation(d_rotation) { /** Displace the arrow rotation by a set amount. */ var transform = utils.d3_transform_catch(this.arrow_container.attr('transform')); this.arrow_container.attr('transform', 'translate('+transform.translate+')'+ 'rotate('+(transform.rotate+d_rotation)+')'); } function get_rotation() { /** Returns the arrow rotation. */ return utils.d3_transform_catch(this.arrow_container.attr('transform')).rotate; } function toggle(on_off) { if (on_off===undefined) this.is_visible = !this.is_visible; else this.is_visible = on_off; this.arrow.style('visibility', this.is_visible ? 'visible' : 'hidden'); } function show() { this.toggle(true); } function hide() { this.toggle(false); } function right() { this.set_rotation(0); } function down() { this.set_rotation(90); } function left() { this.set_rotation(180); } function up() { this.set_rotation(270); } function _setup_drag() { var b = d3_drag() .on("start", function(d) { // silence other listeners d3_selection.event.sourceEvent.stopPropagation(); this.dragging = true; }.bind(this)) .on("drag.direction_arrow", function(d) { var displacement = { x: d3_selection.event.dx, y: d3_selection.event.dy }, location = { x: d3_mouse(this.sel.node())[0], y: d3_mouse(this.sel.node())[1] }, d_angle = utils.angle_for_event(displacement, location, this.center); this.displace_rotation(utils.to_degrees(d_angle)); }.bind(this)) .on("end", function(d) { setTimeout(function() { this.dragging = false; }.bind(this), 200); }.bind(this)); this.arrow_container.call(b); }