module.exports = function ( graph ){ /** variable defs **/ var Range_dragger = {}; Range_dragger.nodeId = 10002; Range_dragger.parent = undefined; Range_dragger.x = 0; Range_dragger.y = 0; Range_dragger.rootElement = undefined; Range_dragger.rootNodeLayer = undefined; Range_dragger.pathLayer = undefined; Range_dragger.mouseEnteredVar = false; Range_dragger.mouseButtonPressed = false; Range_dragger.nodeElement = undefined; Range_dragger.draggerObject = undefined; Range_dragger.pathElement = undefined; Range_dragger.typus = "Range_dragger"; Range_dragger.type = function (){ return Range_dragger.typus; }; // TODO: We need the endPoint of the Link here! Range_dragger.parentNode = function (){ return Range_dragger.parent; }; Range_dragger.hide_dragger = function ( val ){ Range_dragger.pathElement.classed("hidden", val); Range_dragger.nodeElement.classed("hidden", val); Range_dragger.draggerObject.classed("hidden", val); }; Range_dragger.hideDragger = function ( val ){ if ( Range_dragger.pathElement ) Range_dragger.pathElement.classed("hidden", val); if ( Range_dragger.nodeElement ) Range_dragger.nodeElement.classed("hidden", val); if ( Range_dragger.draggerObject ) Range_dragger.draggerObject.classed("hidden", val); }; Range_dragger.reDrawEverthing = function (){ Range_dragger.setParentProperty(Range_dragger.parent); }; Range_dragger.updateRange = function ( newRange ){ if ( graph.genericPropertySanityCheck(Range_dragger.parent.domain(), newRange, Range_dragger.parent.type(), "Could not update range", "Restoring previous range") === false ) return; // check for triple duplicates! if ( graph.propertyCheckExistenceChecker(Range_dragger.parent, Range_dragger.parent.domain(), newRange) === false ) return; if ( Range_dragger.parent.labelElement() === undefined ) return; if ( Range_dragger.parent.labelElement().attr("transform") === "translate(0,15)" || Range_dragger.parent.labelElement().attr("transform") === "translate(0,-15)" ) { var prop = Range_dragger.parent; Range_dragger.parent.inverse().inverse(null); Range_dragger.parent.inverse(null); prop.range(newRange); } else { Range_dragger.parent.range(newRange); } // update the position of the new range var rX = newRange.x; var rY = newRange.y; var dX = Range_dragger.parent.domain().x; var dY = Range_dragger.parent.domain().y; // center var cX = 0.49 * (dX + rX); var cY = 0.49 * (dY + rY); // put position there; Range_dragger.parent.labelElement().x = cX; Range_dragger.parent.labelElement().px = cX; Range_dragger.parent.labelElement().y = cY; Range_dragger.parent.labelElement().py = cY; }; Range_dragger.setParentProperty = function ( parentProperty, inversed ){ Range_dragger.parent = parentProperty; var iP; var renElem; Range_dragger.isLoopProperty = false; if ( parentProperty.domain() === parentProperty.range() ) Range_dragger.isLoopProperty = true; Range_dragger.parent = parentProperty; renElem = parentProperty.labelObject(); if ( inversed === true ) { if ( parentProperty.labelElement() && parentProperty.labelElement().attr("transform") === "translate(0,15)" ) { iP = renElem.linkDomainIntersection; if ( renElem.linkDomainIntersection ) { Range_dragger.x = iP.x; Range_dragger.y = iP.y; } } else { iP = renElem.linkRangeIntersection; if ( renElem.linkRangeIntersection ) { Range_dragger.x = iP.x; Range_dragger.y = iP.y; } } } else { iP = renElem.linkRangeIntersection; if ( renElem.linkRangeIntersection ) { Range_dragger.x = iP.x; Range_dragger.y = iP.y; } } Range_dragger.updateElement(); }; /** BASE HANDLING FUNCTIONS ------------------------------------------------- **/ Range_dragger.id = function ( index ){ if ( !arguments.length ) { return Range_dragger.nodeId; } Range_dragger.nodeId = index; }; Range_dragger.svgPathLayer = function ( layer ){ Range_dragger.pathLayer = layer.append('g'); }; Range_dragger.svgRoot = function ( root ){ if ( !arguments.length ) return Range_dragger.rootElement; Range_dragger.rootElement = root; Range_dragger.rootNodeLayer = Range_dragger.rootElement.append('g'); Range_dragger.addMouseEvents(); }; /** DRAWING FUNCTIONS ------------------------------------------------- **/ Range_dragger.drawNode = function (){ Range_dragger.pathElement = Range_dragger.pathLayer.append('line') .classed("classNodeDragPath", true); Range_dragger.pathElement.attr("x1", 0) .attr("y1", 0) .attr("x2", 0) .attr("y2", 0); // var lineData = [ // {"x": 0, "y": 0}, // {"x": 0, "y": 40}, // {"x": -40, "y": 0}, // {"x": 0, "y": -40}, // {"x": 0, "y": 0} // ]; var lineData = [ { "x": -40, "y": 0 }, // start { "x": -20, "y": -10 }, { "x": 20, "y": -50 }, { "x": -10, "y": 0 }, // center { "x": 20, "y": 50 }, { "x": -20, "y": 10 }, { "x": -40, "y": 0 } ]; var lineFunction = d3.svg.line() .x(function ( d ){ return d.x; }) .y(function ( d ){ return d.y; }) .interpolate("basis-closed"); var pathData = "M 61,40 C 41,15 41,-15 61,-40 L 1,0 Z"; Range_dragger.nodeElement = Range_dragger.rootNodeLayer.append('path').attr("d", pathData); Range_dragger.nodeElement.classed("classDraggerNode", true); if ( graph.options().useAccuracyHelper() ) { Range_dragger.draggerObject = Range_dragger.rootNodeLayer.append("circle"); Range_dragger.draggerObject.attr("r", 40) .attr("cx", 0) .attr("cy", 0) .classed("superHiddenElement", true); Range_dragger.draggerObject.classed("superOpacityElement", !graph.options().showDraggerObject()); } }; Range_dragger.updateElementViaDomainDragger = function ( x, y ){ var range_x = x; var range_y = y; var dex = Range_dragger.parent.range().x; var dey = Range_dragger.parent.range().y; var dir_X = x - dex; var dir_Y = y - dey; var len = Math.sqrt(dir_X * dir_X + dir_Y * dir_Y); var nX = dir_X / len; var nY = dir_Y / len; var ep_range_x = dex + nX * Range_dragger.parent.range().actualRadius(); var ep_range_y = dey + nY * Range_dragger.parent.range().actualRadius(); var dx = range_x - ep_range_x; var dy = range_y - ep_range_y; len = Math.sqrt(dx * dx + dy * dy); nX = dx / len; nY = dy / len; var angle = Math.atan2(ep_range_y - range_y, ep_range_x - range_x) * 180 / Math.PI + 180; Range_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); var doX = ep_range_x + nX * 40; var doY = ep_range_y + nY * 40; Range_dragger.draggerObject.attr("transform", "translate(" + doX + "," + doY + ")"); }; Range_dragger.updateElement = function (){ if ( Range_dragger.mouseButtonPressed === true || Range_dragger.parent === undefined ) return; var range = Range_dragger.parent.range(); var iP = Range_dragger.parent.labelObject().linkRangeIntersection; if ( Range_dragger.parent.labelElement() === undefined ) return; var offsetForLoop = 48; if ( Range_dragger.parent.labelElement().attr("transform") === "translate(0,15)" ) { range = Range_dragger.parent.inverse().domain(); iP = Range_dragger.parent.labelObject().linkDomainIntersection; offsetForLoop = -48; } if ( iP === undefined ) return; var range_x = range.x; var range_y = range.y; var ep_range_x = iP.x; var ep_range_y = iP.y; // offset for dragger object var dx = range_x - ep_range_x; var dy = range_y - ep_range_y; var len = Math.sqrt(dx * dx + dy * dy); var nX = dx / len; var nY = dy / len; var angle = Math.atan2(ep_range_y - range_y, ep_range_x - range_x) * 180 / Math.PI; var doX = ep_range_x - nX * 40; var doY = ep_range_y - nY * 40; if ( Range_dragger.isLoopProperty === true ) angle -= offsetForLoop; Range_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); Range_dragger.draggerObject.attr("transform", "translate(" + doX + "," + doY + ")"); }; /** MOUSE HANDLING FUNCTIONS ------------------------------------------------- **/ Range_dragger.addMouseEvents = function (){ var rootLayer = Range_dragger.rootNodeLayer.selectAll("*"); rootLayer.on("mouseover", Range_dragger.onMouseOver) .on("mouseout", Range_dragger.onMouseOut) .on("click", function (){ }) .on("dblclick", function (){ }) .on("mousedown", Range_dragger.mouseDown) .on("mouseup", Range_dragger.mouseUp); }; Range_dragger.mouseDown = function (){ Range_dragger.nodeElement.style("cursor", "move"); Range_dragger.nodeElement.classed("classDraggerNodeHovered", true); Range_dragger.mouseButtonPressed = true; }; Range_dragger.mouseUp = function (){ Range_dragger.nodeElement.style("cursor", "auto"); Range_dragger.nodeElement.classed("classDraggerNodeHovered", false); Range_dragger.mouseButtonPressed = false; }; Range_dragger.mouseEntered = function ( p ){ if ( !arguments.length ) return Range_dragger.mouseEnteredVar; Range_dragger.mouseEnteredVar = p; return Range_dragger; }; Range_dragger.selectedViaTouch = function ( val ){ Range_dragger.nodeElement.classed("classDraggerNode", !val); Range_dragger.nodeElement.classed("classDraggerNodeHovered", val); }; Range_dragger.onMouseOver = function (){ if ( Range_dragger.mouseEntered() ) { return; } Range_dragger.nodeElement.classed("classDraggerNode", false); Range_dragger.nodeElement.classed("classDraggerNodeHovered", true); var selectedNode = Range_dragger.rootElement.node(), nodeContainer = selectedNode.parentNode; nodeContainer.appendChild(selectedNode); Range_dragger.mouseEntered(true); }; Range_dragger.onMouseOut = function (){ if ( Range_dragger.mouseButtonPressed === true ) return; Range_dragger.nodeElement.classed("classDraggerNodeHovered", false); Range_dragger.nodeElement.classed("classDraggerNode", true); Range_dragger.mouseEntered(false); }; Range_dragger.setPosition = function ( x, y ){ var range_x = Range_dragger.parent.domain().x; var range_y = Range_dragger.parent.domain().y; // var position of the rangeEndPoint var ep_range_x = x; var ep_range_y = y; // offset for dragger object var dx = range_x - ep_range_x; var dy = range_y - ep_range_y; var len = Math.sqrt(dx * dx + dy * dy); var nX = dx / len; var nY = dy / len; var angle = Math.atan2(dy, dx) * 180 / Math.PI; var doX = ep_range_x + nX * 40; var doY = ep_range_y + nY * 40; Range_dragger.nodeElement.attr("transform", "translate(" + ep_range_x + "," + ep_range_y + ")" + "rotate(" + angle + ")"); Range_dragger.draggerObject.attr("transform", "translate(" + doX + "," + doY + ")"); Range_dragger.x = x; Range_dragger.y = y; }; Range_dragger.setAdditionalClassForClass_dragger = function ( name, val ){ }; return Range_dragger; };