function arrowSvg()

in ui-modules/app-inspector/app/components/workflow/workflow-steps.directive.js [99:165]


        function arrowSvg(y1, y2, opts) {
            var start = y1==='start/end';
            var end = y2==='start/end';

            if (y1==null || y2==null || (start&&end)) {
                // ignore if out of bounds
                return "";
            }

            if (!opts) opts = {};
            const color = opts.class ? '' : opts.color || (opts.colorEnd && opts.colorEnd==opts.colorStart ? opts.colorEnd : '#000');

            const rightFarEdge = sectionWidth;
            const rightArrowheadStart = rightFarEdge - arrowheadLength;
            const leftFarEdge = 10;
            const leftActive = rightArrowheadStart + (leftFarEdge - rightArrowheadStart) * (opts.width || 1);

            const curveX = opts.curveX || 1;
            const curveY = opts.curveY || 1;

            // const controlPointRightFarEdge = rightFarEdge + (leftActive - rightFarEdge) * curveX;
            const controlPointRightArrowheadStart = rightArrowheadStart + (leftActive - rightArrowheadStart) * curveX;
            // average of above two, to see which works best
            // const controlPointRightIntermediate = (rightFarEdge+rightArrowheadStart)/2 + (leftActive - (rightFarEdge+rightArrowheadStart)/2) * curveX;
            // const controlPointRightExaggerated = rightArrowheadStart + (leftActive - rightFarEdge) * curveX;
            const controlPointStart = controlPointRightArrowheadStart;
            const controlPointEnd = controlPointRightArrowheadStart;

            const strokeConstant = color ? 'stroke="'+color+'"' : ''

            let standard =
                'stroke-width="'+(opts.lineWidth || strokeWidth)+'" '+
                'fill="transparent" '+
                '/>';
            if (opts.class) standard = 'class="'+opts.class+'" '+standard;
            if (!opts.hideArrowhead) standard = 'marker-end="url(#'+(opts.arrowheadId || 'arrowhead')+')" ' +standard;
            if (opts.dashLength) standard = 'stroke-dasharray="'+opts.dashLength+'" '+standard;

            if (start) {
                return '<path d="M ' + leftFarEdge + ' ' + y2 +
                    ' L ' + rightArrowheadStart + ' ' + y2 + '" '+
                    strokeConstant+' '+standard;
            }
            if (end) {
                return '<path d="M ' + rightFarEdge + ' ' + y1 +
                    ' L ' + (leftFarEdge+arrowheadLength) + ' ' + y1 + '" '+
                    strokeConstant+' '+standard;
            }

            const yMCH = ((y2 - y1) / 2) * curveY;
            const yM = (y1 + y2) / 2;

            if (!opts.colorEnd || opts.colorEnd==opts.colorStart || y2==y1) {
                standard = strokeConstant + ' ' + standard;
            } else {
                const gradientId = 'gradient'+(gradientCount++);
                const gradY = y2>=y1 ? 'y2="1"' : 'y1="1"';
                defs.push('<linearGradient id="'+gradientId+'" x2="0" '+gradY+'><stop offset="0" stop-color="'+opts.colorStart+'"/><stop offset="1" stop-color="'+opts.colorEnd+'"/></linearGradient>');
                standard = 'stroke="url(#'+gradientId+')" ' + standard;
            }

            const result = '<path d="M ' + rightFarEdge + ' ' + y1 +
                // ' L ' + r0 + ' ' + y1 + ' ' +
                ' C ' + controlPointStart + ' ' + y1 + ', ' + leftActive + ' ' + (yM - yMCH) + ', ' + leftActive + ' ' + yM + ' ' +
                ' S ' + controlPointEnd + ' ' + y2 + ', ' + rightArrowheadStart + ' ' + y2 + '" '+standard;
            return result;
        }