Question: The gist being, can anyone provide a toy example using dc.js + google maps where when I brush on a dc.js chart, the map's markers are updated according to what is selected/brushed in the chart?
What I have so far: pages.github. The full repo is here. I also found this cool snack dashboard example, but this uses leaflet. I was trying to avoid leaflet if possible.
I am trying to bind dc.js (crossfilter) to Google Maps. I have seen this video and I am able to to adapt the example.
However, when I attempt to adapt this to use dc.js
I am unable to bind crossfilter back to Google Maps. (I can still bind the map to crossfilter/dc.js, just not the other way around). That is, when scrolling on the map, the charts adjust, but when I brush the charts, I cannot seem to get my updateMarkers()
function to fire.
function init() {
initMap();
initCrossFilter();
// bind map bounds to lat/lng ndx dimensions
latDim = ndx.dimension(function(p) { return p.lat; });
lngDim = ndx.dimension(function(p) { return p.lng; });
google.maps.event.addListener(map, 'bounds_changed', function() {
var bounds = this.getBounds();
var northEast = bounds.getNorthEast();
var southWest = bounds.getSouthWest();
// NOTE: need to be careful with the dateline here
lngDim.filterRange([southWest.lng(), northEast.lng()]);
latDim.filterRange([southWest.lat(), northEast.lat()]);
// NOTE: may want to debounce here, perhaps on requestAnimationFrame
dc.renderAll();
});
// dimension and group for looking up currently selected markers
idDim = ndx.dimension(function(p, i) { return i; });
idGroup = idDim.group(function(id) { return id; });
renderAll();
}
function updateMarkers() {
var pointIds = idGroup.all();
for (var i = 0; i < pointIds.length; i++) {
var pointId = pointIds[i];
markers[pointId.key].setVisible(pointId.value > 0);
}
}
function renderAll() {
updateMarkers();
dc.renderAll();
}
It looks like you are missing the callback from dc.js back into the Google Maps. In the original example, they were using
domCharts = d3.selectAll(".chart")
.data(charts)
.each(function(chart) { chart.on("brush", renderAll).on("brushend", renderAll); });
which may or may not work with dc.js.
Although there are other ways to do it, the most idiomatic way to attach a non-dc.js chart to a set of dc.js charts is to register it in the chart registry.
Unfortunately this is undocumented, but take a look at this SO answer, along with the helpful comments that were added to it, to learn how to register your Google Map to hear the render events from the other charts when they are brushed:
dc.js - Listening for chart group render
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With