Support data area filling (full/partial/wireframe), shadow strokes

This commit is contained in:
Bryan Housel
2018-08-24 14:07:00 -04:00
parent 48e233e4a3
commit 7714e88f3d
4 changed files with 102 additions and 13 deletions

View File

@@ -59,16 +59,33 @@
pointer-events: none;
}
.layer-mapdata path {
.layer-mapdata path.shadow {
stroke: #f6634f;
stroke-width: 16;
stroke-opacity: 0;
fill: none;
}
.layer-mapdata path.shadow.related:not(.selected),
.layer-mapdata path.shadow.hover:not(.selected) {
stroke-opacity: 0.4;
}
.layer-mapdata path.shadow.selected {
stroke-opacity: 0.7;
}
.layer-mapdata path.stroke {
stroke: #ff26d4;
stroke-width: 2;
fill: none;
}
.layer-mapdata path.MultiPolygon,
.layer-mapdata path.Polygon {
stroke-width: 1;
.layer-mapdata path.fill {
stroke-width: 0;
stroke-opacity: 0.3;
stroke: #ff26d4;
fill: #ff26d4;
fill-opacity: 0.2;
fill-opacity: 0.3;
fill-rule: evenodd;
}
.layer-mapdata text.label-halo,

View File

@@ -7,6 +7,11 @@
stroke-dasharray: none !important;
fill: none !important;
}
.low-zoom.fill-wireframe .layer-mapdata path.stroke,
.fill-wireframe .layer-mapdata path.stroke {
stroke-width: 2 !important;
stroke-opacity: 1 !important;
}
.low-zoom.fill-wireframe path.shadow,
.fill-wireframe path.shadow {

View File

@@ -132,7 +132,7 @@ export function svgAreas(projection, context) {
fill: areas
};
var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath-osm')
.filter(filter)
.data(data.clip, osmEntity.key);
@@ -141,7 +141,7 @@ export function svgAreas(projection, context) {
var clipPathsEnter = clipPaths.enter()
.append('clipPath')
.attr('class', 'clipPath')
.attr('class', 'clipPath-osm')
.attr('id', function(entity) { return entity.id + '-clippath'; });
clipPathsEnter

View File

@@ -151,6 +151,21 @@ export function svgData(projection, context, dispatch) {
}
function featureKey(d) {
return d.__featurehash__;
}
function isPolygon(d) {
return d.geometry.type === 'Polygon' || d.geometry.type === 'MultiPolygon';
}
function clipPathID(d) {
return 'data-' + d.__featurehash__ + '-clippath';
}
function featureClasses(d) {
return [
'data' + d.__featurehash__,
@@ -176,8 +191,12 @@ export function svgData(projection, context, dispatch) {
.attr('class', 'layer-mapdata')
.merge(layer);
var surface = context.surface();
if (!surface || surface.empty()) return; // not ready to draw yet, starting up
var geoData;
// Gather data
var geoData, polygonData;
if (_template && vtService) { // fetch data from vector tile service
var sourceID = _template;
vtService.loadTiles(sourceID, _template, projection);
@@ -186,11 +205,50 @@ export function svgData(projection, context, dispatch) {
geoData = getFeatures(_geojson);
}
geoData = geoData.filter(getPath);
polygonData = geoData.filter(isPolygon);
var paths = layer
// Draw clip paths for polygons
var clipPaths = surface.selectAll('defs').selectAll('.clipPath-data')
.data(polygonData, featureKey);
clipPaths.exit()
.remove();
var clipPathsEnter = clipPaths.enter()
.append('clipPath')
.attr('class', 'clipPath-data')
.attr('id', clipPathID);
clipPathsEnter
.append('path');
clipPaths.merge(clipPathsEnter)
.selectAll('path')
.attr('d', getPath);
// Draw fill, shadow, stroke layers
var datagroups = layer
.selectAll('g.datagroup')
.data(['fill', 'shadow', 'stroke']);
datagroups = datagroups.enter()
.append('g')
.attr('class', function(d) { return 'datagroup datagroup-' + d; })
.merge(datagroups);
// Draw paths
var pathData = {
shadow: geoData,
stroke: geoData,
fill: polygonData
};
var paths = datagroups
.selectAll('path')
.data(geoData, function(d) { return d.__featurehash__; });
.data(function(layer) { return pathData[layer]; }, featureKey);
// exit
paths.exit()
@@ -199,11 +257,20 @@ export function svgData(projection, context, dispatch) {
// enter/update
paths = paths.enter()
.append('path')
.attr('class', function(d) { return 'pathdata ' + featureClasses(d); })
.attr('class', function(d) {
var datagroup = this.parentNode.__data__;
var area = (datagroup === 'fill' ? 'area ' : '');
return 'pathdata ' + area + datagroup + ' ' + featureClasses(d);
})
.attr('clip-path', function(d) {
var datagroup = this.parentNode.__data__;
return datagroup === 'fill' ? ('url(#' + clipPathID(d) + ')') : null;
})
.merge(paths)
.attr('d', getPath);
// Draw labels
layer
.call(drawLabels, 'label-halo', geoData)
.call(drawLabels, 'label', geoData);
@@ -216,7 +283,7 @@ export function svgData(projection, context, dispatch) {
});
var labels = selection.selectAll('text.' + textClass)
.data(labelData, function(d) { return d.__featurehash__; });
.data(labelData, featureKey);
// exit
labels.exit()
@@ -312,7 +379,7 @@ export function svgData(projection, context, dispatch) {
drawData.hasData = function() {
return !!(_template || _geojson);
return !!(_template || !_isEmpty(_geojson));
};