diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 8f6e6803d3b..76ae00f14dc 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2762,11 +2762,6 @@ function makePlotFramework(gd) { fullLayout._glcontainer.enter().append('div') .classed('gl-container', true); - fullLayout._geocontainer = fullLayout._paperdiv.selectAll('.geo-container') - .data([0]); - fullLayout._geocontainer.enter().append('div') - .classed('geo-container', true); - fullLayout._paperdiv.selectAll('.main-svg').remove(); fullLayout._paper = fullLayout._paperdiv.insert('svg', ':first-child') @@ -2810,6 +2805,9 @@ function makePlotFramework(gd) { // single ternary layer for the whole plot fullLayout._ternarylayer = fullLayout._paper.append('g').classed('ternarylayer', true); + // single geo layer for the whole plot + fullLayout._geolayer = fullLayout._paper.append('g').classed('geolayer', true); + // upper shape layer // (only for shapes to be drawn above the whole plot, including subplots) var layerAbove = fullLayout._paper.append('g') @@ -2824,7 +2822,6 @@ function makePlotFramework(gd) { // fill in image server scrape-svg fullLayout._glimages = fullLayout._paper.append('g').classed('glimages', true); - fullLayout._geoimages = fullLayout._paper.append('g').classed('geoimages', true); // lastly info (legend, annotations) and hover layers go on top // these are in a different svg element normally, but get collapsed into a single diff --git a/src/plot_api/subroutines.js b/src/plot_api/subroutines.js index ceb2a4dbf64..c66c7e77216 100644 --- a/src/plot_api/subroutines.js +++ b/src/plot_api/subroutines.js @@ -306,12 +306,6 @@ exports.doModeBar = function(gd) { // no need to do this for gl2d subplots, // Plots.linkSubplots takes care of it all. - subplotIds = Plots.getSubplotIds(fullLayout, 'geo'); - for(i = 0; i < subplotIds.length; i++) { - var geo = fullLayout[subplotIds[i]]._subplot; - geo.updateFx(fullLayout.hovermode); - } - return Plots.previousPromises(gd); }; diff --git a/src/plots/cartesian/graph_interact.js b/src/plots/cartesian/graph_interact.js index 835873e5e39..a1a26928d28 100644 --- a/src/plots/cartesian/graph_interact.js +++ b/src/plots/cartesian/graph_interact.js @@ -974,6 +974,8 @@ function createHoverText(hoverData, opts) { contrastColor = tinycolor(traceColor).getBrightness() > 128 ? '#000' : Color.background; + // to get custom 'name' labels pass cleanPoint + if(d.nameOverride !== undefined) d.name = d.nameOverride; if(d.name && d.zLabelVal === undefined) { // strip out our pseudo-html elements from d.name (if it exists at all) diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index 75bd8e37261..4d9549da7f2 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -25,7 +25,6 @@ var createGeoZoom = require('./zoom'); var createGeoZoomReset = require('./zoom_reset'); var constants = require('./constants'); -var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); var topojsonUtils = require('../../lib/topojson_utils'); var topojsonFeature = require('topojson-client').feature; @@ -33,14 +32,12 @@ var topojsonFeature = require('topojson-client').feature; addProjectionsToD3(d3); -function Geo(options, fullLayout) { +function Geo(options) { this.id = options.id; this.graphDiv = options.graphDiv; this.container = options.container; this.topojsonURL = options.topojsonURL; - this.hoverContainer = null; - this.topojsonName = null; this.topojson = null; @@ -54,11 +51,7 @@ function Geo(options, fullLayout) { this.zoom = null; this.zoomReset = null; - this.xaxis = null; - this.yaxis = null; - this.makeFramework(); - this.updateFx(fullLayout.hovermode); this.traceHash = {}; } @@ -178,15 +171,6 @@ proto.onceTopojsonIsLoaded = function(geoCalcData, geoLayout) { this.render(); }; -proto.updateFx = function(hovermode) { - this.showHover = (hovermode !== false); - - // TODO should more strict, any layout.hovermode other - // then false will make all geo subplot display hover text. - // Instead each geo should have its own geo.hovermode - // to control hover visibility independently of other subplots. -}; - proto.makeProjection = function(geoLayout) { var projLayout = geoLayout.projection, projType = projLayout.type, @@ -232,38 +216,30 @@ proto.makePath = function() { this.path = d3.geo.path().projection(this.projection); }; -/* - * <div this.container> - * <div this.geoDiv> - * <svg this.hoverContainer> - * <svg this.framework> - */ proto.makeFramework = function() { - var geoDiv = this.geoDiv = d3.select(this.container).append('div'); - geoDiv - .attr('id', this.id) - .style('position', 'absolute'); - - // only choropleth traces use this, - // scattergeo traces use Fx.hover and fullLayout._hoverlayer - var hoverContainer = this.hoverContainer = geoDiv.append('svg'); - hoverContainer - .attr(xmlnsNamespaces.svgAttrs) - .style({ - 'position': 'absolute', - 'z-index': 20, - 'pointer-events': 'none' - }); - - var framework = this.framework = geoDiv.append('svg'); + var fullLayout = this.graphDiv._fullLayout; + var clipId = 'clip' + fullLayout._uid + this.id; + + var defGroup = fullLayout._defs.selectAll('g.clips') + .data([0]); + defGroup.enter().append('g') + .classed('clips', true); + + var clipDef = this.clipDef = defGroup.selectAll('#' + clipId) + .data([0]); + + clipDef.enter().append('clipPath').attr('id', clipId) + .append('rect'); + + var framework = this.framework = d3.select(this.container).append('g'); + framework - .attr(xmlnsNamespaces.svgAttrs) - .attr({ - 'position': 'absolute', - 'preserveAspectRatio': 'none' - }); + .attr('class', 'geo ' + this.id) + .style('pointer-events', 'all') + .call(Drawing.setClipUrl, clipId); - framework.append('g').attr('class', 'bglayer') + framework.append('g') + .attr('class', 'bglayer') .append('rect'); framework.append('g').attr('class', 'baselayer'); @@ -274,8 +250,6 @@ proto.makeFramework = function() { // N.B. disable dblclick zoom default framework.on('dblclick.zoom', null); - // TODO use clip paths instead of nested SVG - this.xaxis = { _id: 'x' }; this.yaxis = { _id: 'y' }; }; @@ -286,28 +260,20 @@ proto.adjustLayout = function(geoLayout, graphSize) { var left = graphSize.l + graphSize.w * domain.x[0] + geoLayout._marginX, top = graphSize.t + graphSize.h * (1 - domain.y[1]) + geoLayout._marginY; - this.geoDiv.style({ - left: left + 'px', - top: top + 'px', - width: geoLayout._width + 'px', - height: geoLayout._height + 'px' - }); + Drawing.setTranslate(this.framework, left, top); - this.hoverContainer.attr({ + var dimsAttrs = { + x: 0, + y: 0, width: geoLayout._width, height: geoLayout._height - }); + }; - this.framework.attr({ - width: geoLayout._width, - height: geoLayout._height - }); + this.clipDef.select('rect') + .attr(dimsAttrs); this.framework.select('.bglayer').select('rect') - .attr({ - width: geoLayout._width, - height: geoLayout._height - }) + .attr(dimsAttrs) .call(Color.fill, geoLayout.bgcolor); this.xaxis._offset = left; diff --git a/src/plots/geo/index.js b/src/plots/geo/index.js index 03cfbdf3393..baac5e1cf42 100644 --- a/src/plots/geo/index.js +++ b/src/plots/geo/index.js @@ -48,16 +48,13 @@ exports.plot = function plotGeo(gd) { geoCalcData = Plots.getSubplotCalcData(calcData, 'geo', geoId), geo = fullLayout[geoId]._subplot; - // If geo is not instantiated, create one! if(!geo) { geo = new Geo({ id: geoId, graphDiv: gd, - container: fullLayout._geocontainer.node(), + container: fullLayout._geolayer.node(), topojsonURL: gd._context.topojsonURL - }, - fullLayout - ); + }); fullLayout[geoId]._subplot = geo; } @@ -74,31 +71,8 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) var oldGeo = oldFullLayout[oldGeoKey]._subplot; if(!newFullLayout[oldGeoKey] && !!oldGeo) { - oldGeo.geoDiv.remove(); + oldGeo.framework.remove(); + oldGeo.clipDef.remove(); } } }; - -exports.toSVG = function(gd) { - var fullLayout = gd._fullLayout, - geoIds = Plots.getSubplotIds(fullLayout, 'geo'), - size = fullLayout._size; - - for(var i = 0; i < geoIds.length; i++) { - var geoLayout = fullLayout[geoIds[i]], - domain = geoLayout.domain, - geoFramework = geoLayout._subplot.framework; - - geoFramework.attr('style', null); - geoFramework - .attr({ - x: size.l + size.w * domain.x[0] + geoLayout._marginX, - y: size.t + size.h * (1 - domain.y[1]) + geoLayout._marginY, - width: geoLayout._width, - height: geoLayout._height - }); - - fullLayout._geoimages.node() - .appendChild(geoFramework.node()); - } -}; diff --git a/src/plots/geo/zoom_reset.js b/src/plots/geo/zoom_reset.js index f022197219e..dc9a543d09f 100644 --- a/src/plots/geo/zoom_reset.js +++ b/src/plots/geo/zoom_reset.js @@ -9,9 +9,7 @@ 'use strict'; -var Fx = require('../cartesian/graph_interact'); - -function createGeoZoomReset(geo, geoLayout) { +module.exports = function createGeoZoomReset(geo, geoLayout) { var projection = geo.projection, zoom = geo.zoom; @@ -22,12 +20,8 @@ function createGeoZoomReset(geo, geoLayout) { zoom.scale(projection.scale()); zoom.translate(projection.translate()); - Fx.loneUnhover(geo.hoverContainer); - geo.render(); }; return zoomReset; -} - -module.exports = createGeoZoomReset; +}; diff --git a/src/traces/choropleth/event_data.js b/src/traces/choropleth/event_data.js new file mode 100644 index 00000000000..4721025d943 --- /dev/null +++ b/src/traces/choropleth/event_data.js @@ -0,0 +1,17 @@ +/** +* Copyright 2012-2017, Plotly, Inc. +* All rights reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + + +'use strict'; + +module.exports = function eventData(out, pt) { + out.location = pt.location; + out.z = pt.z; + + return out; +}; diff --git a/src/traces/choropleth/hover.js b/src/traces/choropleth/hover.js new file mode 100644 index 00000000000..b9b4962102e --- /dev/null +++ b/src/traces/choropleth/hover.js @@ -0,0 +1,68 @@ +/** +* Copyright 2012-2017, Plotly, Inc. +* All rights reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + + +'use strict'; + +var Axes = require('../../plots/cartesian/axes'); +var attributes = require('./attributes'); + +module.exports = function hoverPoints(pointData) { + var cd = pointData.cd; + var trace = cd[0].trace; + var geo = pointData.subplot; + + // set on choropleth paths 'mouseover' + var pt = geo.choroplethHoverPt; + + if(!pt) return; + + var centroid = geo.projection(pt.properties.ct); + + pointData.x0 = pointData.x1 = centroid[0]; + pointData.y0 = pointData.y1 = centroid[1]; + + pointData.index = pt.index; + pointData.location = pt.id; + pointData.z = pt.z; + + makeHoverInfo(pointData, trace, pt, geo.mockAxis); + + return [pointData]; +}; + +function makeHoverInfo(pointData, trace, pt, axis) { + var hoverinfo = trace.hoverinfo; + + var parts = (hoverinfo === 'all') ? + attributes.hoverinfo.flags : + hoverinfo.split('+'); + + var hasName = (parts.indexOf('name') !== -1), + hasLocation = (parts.indexOf('location') !== -1), + hasZ = (parts.indexOf('z') !== -1), + hasText = (parts.indexOf('text') !== -1), + hasIdAsNameLabel = !hasName && hasLocation; + + var text = []; + + function formatter(val) { + return Axes.tickText(axis, axis.c2l(val), 'hover').text; + } + + if(hasIdAsNameLabel) pointData.nameOverride = pt.id; + else { + if(hasName) pointData.nameOverride = trace.name; + if(hasLocation) text.push(pt.id); + } + + if(hasZ) text.push(formatter(pt.z)); + if(hasText) text.push(pt.tx); + + pointData.extraText = text.join('<br>'); +} diff --git a/src/traces/choropleth/index.js b/src/traces/choropleth/index.js index 15cfae98a54..f358369cfd3 100644 --- a/src/traces/choropleth/index.js +++ b/src/traces/choropleth/index.js @@ -15,10 +15,9 @@ Choropleth.attributes = require('./attributes'); Choropleth.supplyDefaults = require('./defaults'); Choropleth.colorbar = require('../heatmap/colorbar'); Choropleth.calc = require('./calc'); -Choropleth.plot = require('./plot').plot; - -// add dummy hover handler to skip Fx.hover w/o warnings -Choropleth.hoverPoints = function() {}; +Choropleth.plot = require('./plot'); +Choropleth.hoverPoints = require('./hover'); +Choropleth.eventData = require('./event_data'); Choropleth.moduleType = 'trace'; Choropleth.name = 'choropleth'; diff --git a/src/traces/choropleth/plot.js b/src/traces/choropleth/plot.js index 86d947a6fce..9f4ec41e87c 100644 --- a/src/traces/choropleth/plot.js +++ b/src/traces/choropleth/plot.js @@ -11,8 +11,6 @@ var d3 = require('d3'); -var Axes = require('../../plots/cartesian/axes'); -var Fx = require('../../plots/cartesian/graph_interact'); var Color = require('../../components/color'); var Drawing = require('../../components/drawing'); var Colorscale = require('../../components/colorscale'); @@ -22,42 +20,8 @@ var locationToFeature = require('../../lib/geo_location_utils').locationToFeatur var arrayToCalcItem = require('../../lib/array_to_calc_item'); var constants = require('../../plots/geo/constants'); -var attributes = require('./attributes'); -var plotChoropleth = module.exports = {}; - - -plotChoropleth.calcGeoJSON = function(trace, topojson) { - var cdi = [], - locations = trace.locations, - len = locations.length, - features = getTopojsonFeatures(trace, topojson), - markerLine = (trace.marker || {}).line || {}; - - var feature; - - for(var i = 0; i < len; i++) { - feature = locationToFeature(trace.locationmode, locations[i], features); - - if(!feature) continue; // filter the blank features here - - // 'data_array' attributes - feature.z = trace.z[i]; - if(trace.text !== undefined) feature.tx = trace.text[i]; - - // 'arrayOk' attributes - arrayToCalcItem(markerLine.color, feature, 'mlc', i); - arrayToCalcItem(markerLine.width, feature, 'mlw', i); - - cdi.push(feature); - } - - if(cdi.length > 0) cdi[0].trace = trace; - - return cdi; -}; - -plotChoropleth.plot = function(geo, calcData, geoLayout) { +module.exports = function plot(geo, calcData, geoLayout) { function keyFunc(d) { return d[0].trace.uid; } @@ -79,54 +43,20 @@ plotChoropleth.plot = function(geo, calcData, geoLayout) { gChoroplethTraces.each(function(calcTrace) { var trace = calcTrace[0].trace, - cdi = plotChoropleth.calcGeoJSON(trace, geo.topojson), - cleanHoverLabelsFunc = makeCleanHoverLabelsFunc(geo, trace), - eventDataFunc = makeEventDataFunc(trace); - - // keep ref to event data in this scope for plotly_unhover - var eventData = null; - - function handleMouseOver(pt, ptIndex) { - if(!geo.showHover) return; - - var xy = geo.projection(pt.properties.ct); - cleanHoverLabelsFunc(pt); - - Fx.loneHover({ - x: xy[0], - y: xy[1], - name: pt.nameLabel, - text: pt.textLabel - }, { - container: geo.hoverContainer.node() - }); - - eventData = eventDataFunc(pt, ptIndex); + cdi = calcGeoJSON(trace, geo.topojson); - geo.graphDiv.emit('plotly_hover', eventData); - } - - function handleClick(pt, ptIndex) { - geo.graphDiv.emit('plotly_click', eventDataFunc(pt, ptIndex)); - } - - var paths = d3.select(this).selectAll('path.choroplethlocation') - .data(cdi); + var paths = d3.select(this) + .selectAll('path.choroplethlocation') + .data(cdi); paths.enter().append('path') .classed('choroplethlocation', true) - .on('mouseover', handleMouseOver) - .on('click', handleClick) - .on('mouseout', function() { - Fx.loneUnhover(geo.hoverContainer); - - geo.graphDiv.emit('plotly_unhover', eventData); - }) - .on('mousedown', function() { - // to simulate the 'zoomon' event - Fx.loneUnhover(geo.hoverContainer); + .on('mouseover', function(pt) { + geo.choroplethHoverPt = pt; }) - .on('mouseup', handleMouseOver); // ~ 'zoomend' + .on('mouseout', function() { + geo.choroplethHoverPt = null; + }); paths.exit().remove(); }); @@ -141,87 +71,62 @@ plotChoropleth.plot = function(geo, calcData, geoLayout) { geo.styleLayer(gBaseLayerOverChoropleth, layerName, geoLayout); } - plotChoropleth.style(geo); + style(geo); }; -plotChoropleth.style = function(geo) { - geo.framework.selectAll('g.trace.choropleth') - .each(function(calcTrace) { - var trace = calcTrace[0].trace, - s = d3.select(this), - marker = trace.marker || {}, - markerLine = marker.line || {}; - - var sclFunc = Colorscale.makeColorScaleFunc( - Colorscale.extractScale( - trace.colorscale, - trace.zmin, - trace.zmax - ) - ); - - s.selectAll('path.choroplethlocation') - .each(function(pt) { - d3.select(this) - .attr('fill', function(pt) { return sclFunc(pt.z); }) - .call(Color.stroke, pt.mlc || markerLine.color) - .call(Drawing.dashLine, '', pt.mlw || markerLine.width || 0); - }); - }); -}; +function calcGeoJSON(trace, topojson) { + var cdi = [], + locations = trace.locations, + len = locations.length, + features = getTopojsonFeatures(trace, topojson), + markerLine = (trace.marker || {}).line || {}; -function makeCleanHoverLabelsFunc(geo, trace) { - var hoverinfo = trace.hoverinfo; + var feature; - if(hoverinfo === 'none' || hoverinfo === 'skip') { - return function cleanHoverLabelsFunc(pt) { - delete pt.nameLabel; - delete pt.textLabel; - }; - } + for(var i = 0; i < len; i++) { + feature = locationToFeature(trace.locationmode, locations[i], features); - var hoverinfoParts = (hoverinfo === 'all') ? - attributes.hoverinfo.flags : - hoverinfo.split('+'); + if(!feature) continue; // filter the blank features here - var hasName = (hoverinfoParts.indexOf('name') !== -1), - hasLocation = (hoverinfoParts.indexOf('location') !== -1), - hasZ = (hoverinfoParts.indexOf('z') !== -1), - hasText = (hoverinfoParts.indexOf('text') !== -1), - hasIdAsNameLabel = !hasName && hasLocation; + // 'data_array' attributes + feature.z = trace.z[i]; + if(trace.text !== undefined) feature.tx = trace.text[i]; - function formatter(val) { - var axis = geo.mockAxis; - return Axes.tickText(axis, axis.c2l(val), 'hover').text; - } + // 'arrayOk' attributes + arrayToCalcItem(markerLine.color, feature, 'mlc', i); + arrayToCalcItem(markerLine.width, feature, 'mlw', i); - return function cleanHoverLabelsFunc(pt) { - // put location id in name label container - // if name isn't part of hoverinfo - var thisText = []; + // for event data + feature.index = i; - if(hasIdAsNameLabel) pt.nameLabel = pt.id; - else { - if(hasName) pt.nameLabel = trace.name; - if(hasLocation) thisText.push(pt.id); - } + cdi.push(feature); + } - if(hasZ) thisText.push(formatter(pt.z)); - if(hasText) thisText.push(pt.tx); + if(cdi.length > 0) cdi[0].trace = trace; - pt.textLabel = thisText.join('<br>'); - }; + return cdi; } -function makeEventDataFunc(trace) { - return function(pt, ptIndex) { - return {points: [{ - data: trace._input, - fullData: trace, - curveNumber: trace.index, - pointNumber: ptIndex, - location: pt.id, - z: pt.z - }]}; - }; +function style(geo) { + geo.framework.selectAll('g.trace.choropleth').each(function(calcTrace) { + var trace = calcTrace[0].trace, + s = d3.select(this), + marker = trace.marker || {}, + markerLine = marker.line || {}; + + var sclFunc = Colorscale.makeColorScaleFunc( + Colorscale.extractScale( + trace.colorscale, + trace.zmin, + trace.zmax + ) + ); + + s.selectAll('path.choroplethlocation').each(function(pt) { + d3.select(this) + .attr('fill', function(pt) { return sclFunc(pt.z); }) + .call(Color.stroke, pt.mlc || markerLine.color) + .call(Drawing.dashLine, '', pt.mlw || markerLine.width || 0); + }); + }); } diff --git a/test/image/baselines/geo_bg-color.png b/test/image/baselines/geo_bg-color.png index 44df296e155..cebc25880d3 100644 Binary files a/test/image/baselines/geo_bg-color.png and b/test/image/baselines/geo_bg-color.png differ diff --git a/test/image/baselines/geo_big-frame.png b/test/image/baselines/geo_big-frame.png index cea96bd27b7..e4c849b971c 100644 Binary files a/test/image/baselines/geo_big-frame.png and b/test/image/baselines/geo_big-frame.png differ diff --git a/test/image/baselines/geo_bubbles-colorscales.png b/test/image/baselines/geo_bubbles-colorscales.png index 1f0fba6a561..642da7d688c 100644 Binary files a/test/image/baselines/geo_bubbles-colorscales.png and b/test/image/baselines/geo_bubbles-colorscales.png differ diff --git a/test/image/baselines/geo_bubbles-sizeref.png b/test/image/baselines/geo_bubbles-sizeref.png index 8a98a5b2f03..7c2e297f822 100644 Binary files a/test/image/baselines/geo_bubbles-sizeref.png and b/test/image/baselines/geo_bubbles-sizeref.png differ diff --git a/test/image/baselines/geo_choropleth-text.png b/test/image/baselines/geo_choropleth-text.png index 8ef3a928b00..015965b7a53 100644 Binary files a/test/image/baselines/geo_choropleth-text.png and b/test/image/baselines/geo_choropleth-text.png differ diff --git a/test/image/baselines/geo_conic-conformal.png b/test/image/baselines/geo_conic-conformal.png index eb8547b0b48..f5db3f93540 100644 Binary files a/test/image/baselines/geo_conic-conformal.png and b/test/image/baselines/geo_conic-conformal.png differ diff --git a/test/image/baselines/geo_connectgaps.png b/test/image/baselines/geo_connectgaps.png index a33c521dcdd..8526ed17636 100644 Binary files a/test/image/baselines/geo_connectgaps.png and b/test/image/baselines/geo_connectgaps.png differ diff --git a/test/image/baselines/geo_country-names-text-chart.png b/test/image/baselines/geo_country-names-text-chart.png index 259bba4bc9b..76b36ed7517 100644 Binary files a/test/image/baselines/geo_country-names-text-chart.png and b/test/image/baselines/geo_country-names-text-chart.png differ diff --git a/test/image/baselines/geo_country-names.png b/test/image/baselines/geo_country-names.png index 63f56d3e117..c81f6352039 100644 Binary files a/test/image/baselines/geo_country-names.png and b/test/image/baselines/geo_country-names.png differ diff --git a/test/image/baselines/geo_custom-colorscale.png b/test/image/baselines/geo_custom-colorscale.png index 0c3070d92b8..4277a04a27c 100644 Binary files a/test/image/baselines/geo_custom-colorscale.png and b/test/image/baselines/geo_custom-colorscale.png differ diff --git a/test/image/baselines/geo_europe-bubbles.png b/test/image/baselines/geo_europe-bubbles.png index 81b0f4df828..eb08662094d 100644 Binary files a/test/image/baselines/geo_europe-bubbles.png and b/test/image/baselines/geo_europe-bubbles.png differ diff --git a/test/image/baselines/geo_kavrayskiy7.png b/test/image/baselines/geo_kavrayskiy7.png index 0d5c26d9a85..9302a3c661d 100644 Binary files a/test/image/baselines/geo_kavrayskiy7.png and b/test/image/baselines/geo_kavrayskiy7.png differ diff --git a/test/image/baselines/geo_legendonly.png b/test/image/baselines/geo_legendonly.png index 658fe60eb7d..4eff55d0d65 100644 Binary files a/test/image/baselines/geo_legendonly.png and b/test/image/baselines/geo_legendonly.png differ diff --git a/test/image/baselines/geo_multi-geos.png b/test/image/baselines/geo_multi-geos.png index 6409d1099eb..6f0e5b43a5e 100644 Binary files a/test/image/baselines/geo_multi-geos.png and b/test/image/baselines/geo_multi-geos.png differ diff --git a/test/image/baselines/geo_multiple-usa-choropleths.png b/test/image/baselines/geo_multiple-usa-choropleths.png index 6d7caba2561..951982d2a30 100644 Binary files a/test/image/baselines/geo_multiple-usa-choropleths.png and b/test/image/baselines/geo_multiple-usa-choropleths.png differ diff --git a/test/image/baselines/geo_orthographic.png b/test/image/baselines/geo_orthographic.png index 0fd54ffd8ee..90835c2980e 100644 Binary files a/test/image/baselines/geo_orthographic.png and b/test/image/baselines/geo_orthographic.png differ diff --git a/test/image/baselines/geo_scattergeo-locations.png b/test/image/baselines/geo_scattergeo-locations.png index 60b48b26e15..6724ddebbac 100644 Binary files a/test/image/baselines/geo_scattergeo-locations.png and b/test/image/baselines/geo_scattergeo-locations.png differ diff --git a/test/image/baselines/geo_second.png b/test/image/baselines/geo_second.png index 3f7f9cfa7cd..d4aa1075cd0 100644 Binary files a/test/image/baselines/geo_second.png and b/test/image/baselines/geo_second.png differ diff --git a/test/image/baselines/geo_winkel-tripel.png b/test/image/baselines/geo_winkel-tripel.png index 9e14e104d1e..e0e864fdab9 100644 Binary files a/test/image/baselines/geo_winkel-tripel.png and b/test/image/baselines/geo_winkel-tripel.png differ diff --git a/test/jasmine/tests/geo_test.js b/test/jasmine/tests/geo_test.js index 244db755d2c..9adf58c87e7 100644 --- a/test/jasmine/tests/geo_test.js +++ b/test/jasmine/tests/geo_test.js @@ -404,7 +404,7 @@ describe('Test geo interactions', function() { } function countGeos() { - return d3.select('div.geo-container').selectAll('div').size(); + return d3.select('g.geolayer').selectAll('.geo').size(); } function countColorBars() { @@ -596,6 +596,7 @@ describe('Test geo interactions', function() { describe('choropleth hover labels', function() { beforeEach(function() { mouseEventChoropleth('mouseover'); + mouseEventChoropleth('mousemove'); }); it('should show one hover text group', function() { @@ -625,6 +626,7 @@ describe('Test geo interactions', function() { }); mouseEventChoropleth('mouseover'); + mouseEventChoropleth('mousemove'); }); it('should contain the correct fields', function() { @@ -650,6 +652,8 @@ describe('Test geo interactions', function() { ptData = eventData.points[0]; }); + mouseEventChoropleth('mouseover'); + mouseEventChoropleth('mousemove'); mouseEventChoropleth('click'); }); @@ -671,13 +675,18 @@ describe('Test geo interactions', function() { describe('choropleth unhover events', function() { var ptData; - beforeEach(function() { + beforeEach(function(done) { gd.on('plotly_unhover', function(eventData) { ptData = eventData.points[0]; }); mouseEventChoropleth('mouseover'); + mouseEventChoropleth('mousemove'); mouseEventChoropleth('mouseout'); + setTimeout(function() { + mouseEvent('mousemove', 300, 235); + done(); + }, HOVERMINTIME + 100); }); it('should contain the correct fields', function() {