/** * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ var mxMarker = { /** * Class: mxMarker * * A static class that implements all markers for VML and SVG using a * registry. NOTE: The signatures in this class will change. * * Variable: markers * * Maps from markers names to functions to paint the markers. */ markers: [], /** * Function: addMarker * * Adds a factory method that updates a given endpoint and returns a * function to paint the marker onto the given canvas. */ addMarker: function(type, funct) { mxMarker.markers[type] = funct; }, /** * Function: createMarker * * Returns a function to paint the given marker. */ createMarker: function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) { var funct = mxMarker.markers[type]; return (funct != null) ? funct(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) : null; } }; /** * Adds the classic and block marker factory method. */ (function() { function createArrow(widthFactor) { widthFactor = (widthFactor != null) ? widthFactor : 2; return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) { // The angle of the forward facing arrow sides against the x axis is // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for // only half the strokewidth is processed ). var endOffsetX = unitX * sw * 1.118; var endOffsetY = unitY * sw * 1.118; unitX = unitX * (size + sw); unitY = unitY * (size + sw); var pt = pe.clone(); pt.x -= endOffsetX; pt.y -= endOffsetY; var f = (type != mxConstants.ARROW_CLASSIC && type != mxConstants.ARROW_CLASSIC_THIN) ? 1 : 3 / 4; pe.x += -unitX * f - endOffsetX; pe.y += -unitY * f - endOffsetY; return function() { canvas.begin(); canvas.moveTo(pt.x, pt.y); canvas.lineTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor); if (type == mxConstants.ARROW_CLASSIC || type == mxConstants.ARROW_CLASSIC_THIN) { canvas.lineTo(pt.x - unitX * 3 / 4, pt.y - unitY * 3 / 4); } canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor); canvas.close(); if (filled) { canvas.fillAndStroke(); } else { canvas.stroke(); } }; } }; mxMarker.addMarker('classic', createArrow(2)); mxMarker.addMarker('classicThin', createArrow(3)); mxMarker.addMarker('block', createArrow(2)); mxMarker.addMarker('blockThin', createArrow(3)); function createOpenArrow(widthFactor) { widthFactor = (widthFactor != null) ? widthFactor : 2; return function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) { // The angle of the forward facing arrow sides against the x axis is // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for // only half the strokewidth is processed ). var endOffsetX = unitX * sw * 1.118; var endOffsetY = unitY * sw * 1.118; unitX = unitX * (size + sw); unitY = unitY * (size + sw); var pt = pe.clone(); pt.x -= endOffsetX; pt.y -= endOffsetY; pe.x += -endOffsetX * 2; pe.y += -endOffsetY * 2; return function() { canvas.begin(); canvas.moveTo(pt.x - unitX - unitY / widthFactor, pt.y - unitY + unitX / widthFactor); canvas.lineTo(pt.x, pt.y); canvas.lineTo(pt.x + unitY / widthFactor - unitX, pt.y - unitY - unitX / widthFactor); canvas.stroke(); }; } }; mxMarker.addMarker('open', createOpenArrow(2)); mxMarker.addMarker('openThin', createOpenArrow(3)); mxMarker.addMarker('oval', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) { var a = size / 2; var pt = pe.clone(); pe.x -= unitX * a; pe.y -= unitY * a; return function() { canvas.ellipse(pt.x - a, pt.y - a, size, size); if (filled) { canvas.fillAndStroke(); } else { canvas.stroke(); } }; }); function diamond(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled) { // The angle of the forward facing arrow sides against the x axis is // 45 degrees, 1/sin(45) = 1.4142 / 2 = 0.7071 ( / 2 allows for // only half the strokewidth is processed ). Or 0.9862 for thin diamond. // Note these values and the tk variable below are dependent, update // both together (saves trig hard coding it). var swFactor = (type == mxConstants.ARROW_DIAMOND) ? 0.7071 : 0.9862; var endOffsetX = unitX * sw * swFactor; var endOffsetY = unitY * sw * swFactor; unitX = unitX * (size + sw); unitY = unitY * (size + sw); var pt = pe.clone(); pt.x -= endOffsetX; pt.y -= endOffsetY; pe.x += -unitX - endOffsetX; pe.y += -unitY - endOffsetY; // thickness factor for diamond var tk = ((type == mxConstants.ARROW_DIAMOND) ? 2 : 3.4); return function() { canvas.begin(); canvas.moveTo(pt.x, pt.y); canvas.lineTo(pt.x - unitX / 2 - unitY / tk, pt.y + unitX / tk - unitY / 2); canvas.lineTo(pt.x - unitX, pt.y - unitY); canvas.lineTo(pt.x - unitX / 2 + unitY / tk, pt.y - unitY / 2 - unitX / tk); canvas.close(); if (filled) { canvas.fillAndStroke(); } else { canvas.stroke(); } }; }; mxMarker.addMarker('diamond', diamond); mxMarker.addMarker('diamondThin', diamond); })();