diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index 8420a07f8d2..67245728b47 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -114,7 +114,7 @@ drawing.lineGroupStyle = function(s, lw, lc, ld) { drawing.dashLine = function(s, dash, lineWidth) { lineWidth = +lineWidth || 0; - dash = Lib.dash(dash, lineWidth); + dash = drawing.dashStyle(dash, lineWidth); s.style({ 'stroke-dasharray': dash, @@ -122,6 +122,25 @@ drawing.dashLine = function(s, dash, lineWidth) { }); }; +drawing.dashStyle = function(dash, lineWidth) { + lineWidth = +lineWidth || 1; + var dlw = Math.max(lineWidth, 3); + + if(dash === 'solid') dash = ''; + else if(dash === 'dot') dash = dlw + 'px,' + dlw + 'px'; + else if(dash === 'dash') dash = (3 * dlw) + 'px,' + (3 * dlw) + 'px'; + else if(dash === 'longdash') dash = (5 * dlw) + 'px,' + (5 * dlw) + 'px'; + else if(dash === 'dashdot') { + dash = (3 * dlw) + 'px,' + dlw + 'px,' + dlw + 'px,' + dlw + 'px'; + } + else if(dash === 'longdashdot') { + dash = (5 * dlw) + 'px,' + (2 * dlw) + 'px,' + dlw + 'px,' + (2 * dlw) + 'px'; + } + // otherwise user wrote the dasharray themselves - leave it be + + return dash; +}; + drawing.fillGroupStyle = function(s) { s.style('stroke-width', 0) .each(function(d) { diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index c618dfe88c1..8c3a1028795 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -177,18 +177,20 @@ function handleCartesian(gd, ev) { astr = button.getAttribute('data-attr'), val = button.getAttribute('data-val') || true, fullLayout = gd._fullLayout, - aobj = {}; + aobj = {}, + axList = Axes.list(gd, null, true), + ax, + allEnabled = 'on', + i; if(astr === 'zoom') { var mag = (val === 'in') ? 0.5 : 2, r0 = (1 + mag) / 2, - r1 = (1 - mag) / 2, - axList = Axes.list(gd, null, true), - allEnabled = 'on'; + r1 = (1 - mag) / 2; - var ax, axName; + var axName; - for(var i = 0; i < axList.length; i++) { + for(i = 0; i < axList.length; i++) { ax = axList[i]; if(!ax.fixedrange) { @@ -235,8 +237,15 @@ function handleCartesian(gd, ev) { button.setAttribute('data-val', val); if(val !== 'closest') { fullLayout._cartesianSpikesEnabled = 'off'; - aobj = setSpikelineVisibility(gd); } + } else if(astr === 'hovermode' && val === 'closest') { + for(i = 0; i < axList.length; i++) { + ax = axList[i]; + if(allEnabled === 'on' && !ax.showspike) { + allEnabled = 'off'; + } + } + fullLayout._cartesianSpikesEnabled = allEnabled; } aobj[astr] = val; diff --git a/src/lib/index.js b/src/lib/index.js index 360a923ee23..e1b6475a29b 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -636,31 +636,3 @@ lib.numSeparate = function(value, separators, separatethousands) { return x1 + x2; }; - -/** - * Accepts a named dash style or stroke-dasharray string - * and returns a dasharray representing the named type. - * - * @param {string} dash named dash format, or dasharray - * @param {number} lineWidth width of the line, used to scale the dashes - * - * @returns {string} SVG stroke-dasharray formatted string - */ -lib.dash = function(dash, lineWidth) { - lineWidth = +lineWidth || 1; - var dlw = Math.max(lineWidth, 3); - - if(dash === 'solid') dash = ''; - else if(dash === 'dot') dash = dlw + 'px,' + dlw + 'px'; - else if(dash === 'dash') dash = (3 * dlw) + 'px,' + (3 * dlw) + 'px'; - else if(dash === 'longdash') dash = (5 * dlw) + 'px,' + (5 * dlw) + 'px'; - else if(dash === 'dashdot') { - dash = (3 * dlw) + 'px,' + dlw + 'px,' + dlw + 'px,' + dlw + 'px'; - } - else if(dash === 'longdashdot') { - dash = (5 * dlw) + 'px,' + (2 * dlw) + 'px,' + dlw + 'px,' + (2 * dlw) + 'px'; - } - // otherwise user wrote the dasharray themselves - leave it be - - return dash; -}; diff --git a/src/plots/cartesian/graph_interact.js b/src/plots/cartesian/graph_interact.js index 5893dfa7b98..6127edc7473 100644 --- a/src/plots/cartesian/graph_interact.js +++ b/src/plots/cartesian/graph_interact.js @@ -868,8 +868,8 @@ function createDroplines(hoverData, opts) { '#000' : Color.background, xThickness = c0.xa.spikethickness, yThickness = c0.ya.spikethickness, - xDash = Lib.dash(c0.xa.spikedash, xThickness), - yDash = Lib.dash(c0.xa.spikedash, yThickness), + xDash = Drawing.dashStyle(c0.xa.spikedash, xThickness), + yDash = Drawing.dashStyle(c0.xa.spikedash, yThickness), xMarker = c0.xa.spikemode.indexOf('marker') !== -1, yMarker = c0.ya.spikemode.indexOf('marker') !== -1, xSpikeLine = c0.xa.spikemode.indexOf('toaxis') !== -1 || c0.xa.spikemode.indexOf('across') !== -1, @@ -886,33 +886,42 @@ function createDroplines(hoverData, opts) { if(ySpikeLine) { // Background horizontal Line (to y-axis) container.append('line') - .attr('x1', xBase) - .attr('x2', xEndSpike) - .attr('y1', yPoint) - .attr('y2', yPoint) - .attr('stroke-width', yThickness + 2) - .attr('stroke', yContrastColor) - .attr('class', 'dropline'); + .attr({ + 'x1': xBase, + 'x2': xEndSpike, + 'y1': yPoint, + 'y2': yPoint, + 'stroke-width': yThickness + 2, + 'stroke': yContrastColor + }) + .classed('dropline', true) + .classed('crisp', true); // Foreground horizontal line (to y-axis) container.append('line') - .attr('x1', xBase) - .attr('x2', xEndSpike) - .attr('y1', yPoint) - .attr('y2', yPoint) - .attr('stroke-width', yThickness) - .attr('stroke', yColor) - .attr('stroke-dasharray', yDash) - .attr('class', 'dropline'); + .attr({ + 'x1': xBase, + 'x2': xEndSpike, + 'y1': yPoint, + 'y2': yPoint, + 'stroke-width': yThickness, + 'stroke': yColor, + 'stroke-dasharray': yDash + }) + .classed('dropline', true) + .classed('crisp', true); } // Y axis marker if(yMarker) { container.append('circle') - .attr('cx', xAnchoredBase) - .attr('cy', yPoint) - .attr('r', yThickness) - .attr('fill', yColor) - .attr('class', 'dropline'); + .attr({ + 'cx': xAnchoredBase, + 'cy': yPoint, + 'r': yThickness, + 'fill': yColor + }) + .classed('dropline', true) + .classed('crisp', true); } } @@ -920,34 +929,43 @@ function createDroplines(hoverData, opts) { if(xSpikeLine) { // Background vertical line (to x-axis) container.append('line') - .attr('x1', xPoint) - .attr('x2', xPoint) - .attr('y1', yEndSpike) - .attr('y2', yBase) - .attr('stroke-width', xThickness + 2) - .attr('stroke', xContrastColor) - .attr('class', 'dropline'); + .attr({ + 'x1': xPoint, + 'x2': xPoint, + 'y1': yEndSpike, + 'y2': yBase, + 'stroke-width': xThickness + 2, + 'stroke': xContrastColor + }) + .classed('dropline', true) + .classed('crisp', true); // Foreground vertical line (to x-axis) container.append('line') - .attr('x1', xPoint) - .attr('x2', xPoint) - .attr('y1', yEndSpike) - .attr('y2', yBase) - .attr('stroke-width', xThickness) - .attr('stroke', xColor) - .attr('stroke-dasharray', xDash) - .attr('class', 'dropline'); + .attr({ + 'x1': xPoint, + 'x2': xPoint, + 'y1': yEndSpike, + 'y2': yBase, + 'stroke-width': xThickness, + 'stroke': xColor, + 'stroke-dasharray': xDash + }) + .classed('dropline', true) + .classed('crisp', true); } // X axis marker if(xMarker) { container.append('circle') - .attr('cx', xPoint) - .attr('cy', yAnchoredBase) - .attr('r', xThickness) - .attr('fill', xColor) - .attr('class', 'dropline'); + .attr({ + 'cx': xPoint, + 'cy': yAnchoredBase, + 'r': xThickness, + 'fill': xColor + }) + .classed('dropline', true) + .classed('crisp', true); } } }