Skip to content

Commit

Permalink
Ability to aggregate over any point property
Browse files Browse the repository at this point in the history
This needed a change in the supercluster npm module, a PR was placed here:
mapbox/supercluster#12
  • Loading branch information
georgeke committed Jun 20, 2016
1 parent b4b2c38 commit 6efffc9
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
2 changes: 1 addition & 1 deletion caravel/assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"select2": "3.5",
"select2-bootstrap-css": "^1.4.6",
"style-loader": "^0.13.0",
"supercluster": "^2.1.0",
"supercluster": "https://github.com/georgeke/supercluster/tarball/ac3492737e7ce98e07af679623aad452373bbc40",
"topojson": "^1.6.22",
"transform-loader": "^0.2.3",
"viewport-mercator-project": "^2.1.0",
Expand Down
16 changes: 11 additions & 5 deletions caravel/assets/visualizations/mapbox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ScatterPlotGlowOverlay extends ScatterPlotOverlay {
ctx.beginPath();

if (location.get("properties").get("cluster")) {
var scaledRadius = d3.round(
var scaledRadius = maxCount === minCount ? radius : d3.round(
(location.get("properties").get("point_count") - minCount) /
(maxCount - minCount) * radius + radius / 2, 1
),
Expand All @@ -69,7 +69,9 @@ class ScatterPlotGlowOverlay extends ScatterPlotOverlay {

ctx.textAlign = "center";
ctx.fillText(
location.get("properties").get("point_count_abbreviated"),
location.get("properties").get("metric")
? location.get("properties").get("metric")
: location.get("properties").get("point_count_abbreviated"),
pixelRounded[0],
pixelRounded[1] + d3.round((scaledRadius - fontHeight) / 2, 1)
);
Expand Down Expand Up @@ -136,6 +138,7 @@ class MapboxViz extends React.Component {
locations={Immutable.fromJS(clusters)}
dotRadius={this.props.clusterRadius * 0.6}
globalOpacity={1}
metricKey={this.props.metricKey}
compositeOperation="screen"
renderWhileDragging={true}
lngLatAccessor={function (location) {
Expand All @@ -148,11 +151,13 @@ class MapboxViz extends React.Component {
}

function mapbox(slice) {
const clusterRadius = 60;
const clusterRadius = 60,
metricKey = "metric";
var div = d3.select(slice.selector),
clusterer = supercluster({
radius: clusterRadius,
maxZoom: 16
maxZoom: 16,
metricKey: metricKey
});

var render = function () {
Expand All @@ -171,7 +176,8 @@ function mapbox(slice) {
sliceWidth={slice.width()}
clusterer={clusterer}
mapStyle={json.data.mapStyle}
clusterRadius={clusterRadius}/>,
clusterRadius={clusterRadius}
metricKey={metricKey}/>,
div.node()
);

Expand Down
2 changes: 2 additions & 0 deletions caravel/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ def load_long_lat_data():
with gzip.open(os.path.join(DATA_FOLDER, 'san_francisco.csv.gz')) as f:
pdf = pd.read_csv(f, encoding="utf-8")
pdf['date'] = datetime.datetime.now().date()
pdf['value'] = [random.randint(-100, -1) for _ in range(len(pdf))]
pdf.to_sql(
'long_lat',
db.engine,
Expand All @@ -967,6 +968,7 @@ def load_long_lat_data():
'postcode': Float(),
'id': String(100),
'date': Date(),
'value': Float(),
},
index=False)
print("Done loading table!")
Expand Down
30 changes: 28 additions & 2 deletions caravel/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -1672,34 +1672,60 @@ class MapboxViz(BaseViz):
'label': None,
'fields': (
('longitude', 'latitude'),
'all_columns',
'mapbox_style',
)
},)

form_overrides = {
'all_columns': {
'label': 'Column for numbers on clusters',
'description': ("Column that defines the way the number on each cluster "
"is counted. Leave empty to just display the number of points"),
},
}

def query_obj(self):
d = super(MapboxViz, self).query_obj()
fd = self.form_data
all_columns = fd.get('all_columns')
d['columns'] = [fd.get('longitude'), fd.get('latitude')]
if len(all_columns) >= 1:
if (all_columns[0] != fd.get('longitude') and
all_columns[0] != fd.get('latitude')):
d['columns'].append(fd.get('all_columns')[0])
d['groupby'] = []
return d

def get_data(self):
df = self.get_df()
fd = self.form_data
all_columns = fd.get('all_columns')
metric_col = [None] * len(df.index)
if (len(all_columns)) >= 1:
if all_columns[0] == fd.get('longitude'):
metric_col = df[fd.get('longitude')]
elif all_columns[0] == fd.get('latitude'):
metric_col = df[fd.get('latitude')]
else:
metric_col = df[fd.get('all_columns')[0]]

# using geoJSON formatting
geo_json = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"properties": {
"metric": metric
},
"geometry": {
"type": "Point",
"coordinates": [lon, lat]
}
}
for lon, lat in zip(df[fd.get('longitude')], df[fd.get('latitude')])
for lon, lat, metric
in zip(df[fd.get('longitude')], df[fd.get('latitude')], metric_col)
]
}

Expand Down

0 comments on commit 6efffc9

Please sign in to comment.