import * as d3 from "d3" ; import Map from "../map" ; import Node from "../models/node" ; import { Event } from "./events" ; import { DragBehavior } from "d3-drag" ; /**
 * Manage the drag events of the nodes.
 */ export default class Drag { private map : Map ; private dragBehavior : DragBehavior < any , any , any > ; private dragging : boolean ; private orientation : boolean ; private descendants : Node [ ] ; param { Map } map constructor ( map ) { this . map = map ; this . dragBehavior = d3 . drag ( ) . on ( "start" , ( node ) => this . started ( node ) ) . on ( "drag" , ( node ) => this . dragged ( node ) ) . on ( "end" , ( node ) => this . ended ( node ) ) ; } returns { DragBehavior } public getDragBehavior ( ) { return this . dragBehavior ; } param { Node } node private started ( node ) { d3 . event . sourceEvent . preventDefault ( ) ; this . orientation = this . map . nodes . getOrientation ( node ) ; this . descendants = this . map . nodes . getDescendants ( node ) ; this . map . nodes . selectNode ( node . id ) ; } param { Node } node private dragged ( node ) { let dy = d3 . event . dy , dx = d3 . event . dx ; let x = node . coordinates . x += dx , y = node . coordinates . y += dy ; node . dom . setAttribute ( "transform" , "translate(" + [ x , y ] + ")" ) ; if ( node . locked ) { let newOrientation = this . map . nodes . getOrientation ( node ) , orientationIsChanged = newOrientation !== this . orientation , root = node ; for ( let node of this . descendants ) { let x = node . coordinates . x += dx , y = node . coordinates . y += dy ; if ( orientationIsChanged ) { x = node . coordinates . x += ( root . coordinates . x - node . coordinates . x ) * 2 ; } node . dom . setAttribute ( "transform" , "translate(" + [ x , y ] + ")" ) ; } if ( orientationIsChanged ) { this . orientation = newOrientation ; } } d3 . selectAll ( "." + this . map . id + "_branch" ) . attr ( "d" , ( node ) => { return < any > this . map . draw . drawBranch ( node ) ; } ) ; this . dragging = true ; } param { Node } node private ended ( node ) { if ( this . dragging ) { this . dragging = false ; this . map . history . save ( ) ; this . map . events . call ( Event . nodeUpdate , node . dom , this . map . nodes . getNodeProperties ( node ) ) ; } } }