-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Scattergeo BADNUM #1538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scattergeo BADNUM #1538
Changes from 1 commit
bfe0211
18091e8
a705ed1
64cbf2f
f84627d
e85fba5
6a7e2a4
aec6248
1abbd90
3e64aa0
785bade
5c2393a
b5cd573
248b760
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- use BADNUM to normalize non-numeric lon/lat handling - and instead remove BADNUM pts in plot step - this is consistent with all other d3 plot type (!!) - allows us to reuse scatter/arrays_to_calcdata - and cleans up locations -> lonlat logic!
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,17 +15,28 @@ var Drawing = require('../../components/drawing'); | |
var Color = require('../../components/color'); | ||
|
||
var Lib = require('../../lib'); | ||
var BADNUM = require('../../constants/numerical').BADNUM; | ||
var getTopojsonFeatures = require('../../lib/topojson_utils').getTopojsonFeatures; | ||
var locationToFeature = require('../../lib/geo_location_utils').locationToFeature; | ||
var geoJsonUtils = require('../../lib/geojson_utils'); | ||
var arrayToCalcItem = require('../../lib/array_to_calc_item'); | ||
var subTypes = require('../scatter/subtypes'); | ||
|
||
|
||
module.exports = function plot(geo, calcData) { | ||
|
||
function keyFunc(d) { return d[0].trace.uid; } | ||
|
||
function removeBADNUM(d, node) { | ||
var lonlat = d.lonlat; | ||
if(lonlat[0] === BADNUM || lonlat[1] === BADNUM) { | ||
d3.select(node).remove(); | ||
} | ||
} | ||
|
||
for(var i = 0; i < calcData.length; i++) { | ||
fillLocationLonLat(calcData[i], geo.topojson); | ||
} | ||
|
||
var gScatterGeoTraces = geo.framework.select('.scattergeolayer') | ||
.selectAll('g.trace.scattergeo') | ||
.data(calcData, keyFunc); | ||
|
@@ -39,27 +50,11 @@ module.exports = function plot(geo, calcData) { | |
gScatterGeoTraces.selectAll('*').remove(); | ||
|
||
gScatterGeoTraces.each(function(calcTrace) { | ||
var s = d3.select(this), | ||
trace = calcTrace[0].trace, | ||
convertToLonLatFn = makeConvertToLonLatFn(trace, geo.topojson); | ||
|
||
// skip over placeholder traces | ||
if(calcTrace[0].placeholder) s.remove(); | ||
|
||
// just like calcTrace but w/o not-found location datum | ||
var _calcTrace = []; | ||
|
||
for(var i = 0; i < calcTrace.length; i++) { | ||
var _calcPt = convertToLonLatFn(calcTrace[i]); | ||
|
||
if(_calcPt) { | ||
arrayItemToCalcdata(trace, calcTrace[i], i); | ||
_calcTrace.push(_calcPt); | ||
} | ||
|
||
var s = d3.select(this); | ||
var trace = calcTrace[0].trace; | ||
|
||
if(subTypes.hasLines(trace) || trace.fill !== 'none') { | ||
var lineCoords = geoJsonUtils.calcTraceToLineCoords(_calcTrace); | ||
var lineCoords = geoJsonUtils.calcTraceToLineCoords(calcTrace); | ||
|
||
var lineData = (trace.fill !== 'none') ? | ||
geoJsonUtils.makePolygon(lineCoords, trace) : | ||
|
@@ -72,66 +67,39 @@ module.exports = function plot(geo, calcData) { | |
} | ||
|
||
if(subTypes.hasMarkers(trace)) { | ||
s.selectAll('path.point').data(_calcTrace) | ||
.enter().append('path') | ||
.classed('point', true); | ||
s.selectAll('path.point') | ||
.data(Lib.identity) | ||
.enter().append('path') | ||
.classed('point', true) | ||
.each(function(calcPt) { removeBADNUM(calcPt, this); }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the record, I just had a discussion with @etpinard about this where my gut reaction was that we should do s.selectAll('path.point')
.data(filterOutBadPoints)
.enter().append('path')
... instead of creating all the nodes and then deleting the bad ones. The conclusion we came to though is that the way it is here is actually better, despite being a bit less "d3-idiomatic." The rationale is that bad points should be considered an edge case, so we don't worry about the overhead of creating and deleting their nodes (which will happen on every replot), just about how the |
||
} | ||
|
||
if(subTypes.hasText(trace)) { | ||
s.selectAll('g').data(_calcTrace) | ||
s.selectAll('g') | ||
.data(Lib.identity) | ||
.enter().append('g') | ||
.append('text'); | ||
.append('text') | ||
.each(function(calcPt) { removeBADNUM(calcPt, this); }); | ||
} | ||
}); | ||
|
||
// call style here within topojson request callback | ||
style(geo); | ||
}; | ||
|
||
function makeConvertToLonLatFn(trace, topojson) { | ||
if(!Array.isArray(trace.locations)) return Lib.identity; | ||
|
||
var features = getTopojsonFeatures(trace, topojson), | ||
locationmode = trace.locationmode; | ||
function fillLocationLonLat(calcTrace, topojson) { | ||
var trace = calcTrace[0].trace; | ||
|
||
return function(calcPt) { | ||
var feature = locationToFeature(locationmode, calcPt.loc, features); | ||
if(!Array.isArray(trace.locations)) return; | ||
|
||
if(feature) { | ||
calcPt.lonlat = feature.properties.ct; | ||
return calcPt; | ||
} | ||
else { | ||
// mutate gd.calcdata so that hoverPoints knows to skip this datum | ||
calcPt.lonlat = [null, null]; | ||
return false; | ||
} | ||
}; | ||
} | ||
var features = getTopojsonFeatures(trace, topojson); | ||
var locationmode = trace.locationmode; | ||
|
||
function arrayItemToCalcdata(trace, calcItem, i) { | ||
var marker = trace.marker; | ||
|
||
function merge(traceAttr, calcAttr) { | ||
arrayToCalcItem(traceAttr, calcItem, calcAttr, i); | ||
} | ||
|
||
merge(trace.text, 'tx'); | ||
merge(trace.textposition, 'tp'); | ||
if(trace.textfont) { | ||
merge(trace.textfont.size, 'ts'); | ||
merge(trace.textfont.color, 'tc'); | ||
merge(trace.textfont.family, 'tf'); | ||
} | ||
for(var i = 0; i < calcTrace.length; i++) { | ||
var calcPt = calcTrace[i]; | ||
var feature = locationToFeature(locationmode, calcPt.loc, features); | ||
|
||
if(marker && marker.line) { | ||
var markerLine = marker.line; | ||
merge(marker.opacity, 'mo'); | ||
merge(marker.symbol, 'mx'); | ||
merge(marker.color, 'mc'); | ||
merge(marker.size, 'ms'); | ||
merge(markerLine.color, 'mlc'); | ||
merge(markerLine.width, 'mlw'); | ||
calcPt.lonlat = feature ? feature.properties.ct : [BADNUM, BADNUM]; | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably all we'd need to do for https://github.com/plotly/plotly.js/pull/1538/files#r109043439 to work is change this to something like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! Thanks for taking a 👁️