Draw selected items last, so halos are more visible

(see #2914)
This commit is contained in:
Bryan Housel
2017-03-21 02:17:04 -04:00
parent 33e9b2ab7e
commit 4903d495b7
4 changed files with 106 additions and 37 deletions
+2
View File
@@ -477,6 +477,8 @@ export function modeSelect(context, selectedIDs) {
var loc = extent.center();
context.map().centerEase(loc);
} else {
context.map().pan([0,0]);
}
timeout = window.setTimeout(function() {
+1 -1
View File
@@ -42,7 +42,7 @@ export function rendererMap(context) {
drawLayers = svgLayers(projection, context),
drawPoints = svgPoints(projection, context),
drawVertices = svgVertices(projection, context),
drawLines = svgLines(projection),
drawLines = svgLines(projection, context),
drawAreas = svgAreas(projection, context),
drawMidpoints = svgMidpoints(projection, context),
drawLabels = svgLabels(projection, context),
+92 -25
View File
@@ -11,7 +11,7 @@ import { osmEntity, osmSimpleMultipolygonOuterMember } from '../osm/index';
import { utilDetect } from '../util/detect';
export function svgLines(projection) {
export function svgLines(projection, context) {
var detected = utilDetect();
var highway_stack = {
@@ -29,15 +29,45 @@ export function svgLines(projection) {
footway: 11
};
function waystack(a, b) {
var as = 0, bs = 0;
if (a.tags.highway) { as -= highway_stack[a.tags.highway]; }
if (b.tags.highway) { bs -= highway_stack[b.tags.highway]; }
return as - bs;
var selected = context.selectedIDs(),
scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0,
scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
if (a.tags.highway) { scoreA -= highway_stack[a.tags.highway]; }
if (b.tags.highway) { scoreB -= highway_stack[b.tags.highway]; }
return scoreA - scoreB;
}
return function drawLines(selection, graph, entities, filter) {
function drawLineGroup(selection, klass, data) {
var lines = selection
.selectAll('path')
.filter(filter)
.data(data, osmEntity.key);
lines.exit()
.remove();
// Optimization: call simple TagClasses only on enter selection. This
// works because osmEntity.key is defined to include the entity v attribute.
lines.enter()
.append('path')
.attr('class', function(d) { return 'way line ' + klass + ' ' + d.id; })
.call(svgTagClasses())
.merge(lines)
.sort(waystack)
.attr('d', getPath)
.call(svgTagClasses().tags(svgRelationMemberTags(graph)));
return selection;
}
var ways = [], pathdata = {}, onewaydata = {},
getPath = svgPath(projection, graph);
@@ -77,7 +107,7 @@ export function svgLines(projection) {
var linegroup = layergroup
.selectAll('g.linegroup')
.data(['shadow', 'casing', 'stroke']);
.data(['shadow', 'casing', 'stroke', 'shadow2', 'casing2', 'stroke2']);
linegroup = linegroup.enter()
.append('g')
@@ -85,27 +115,64 @@ export function svgLines(projection) {
.merge(linegroup);
var lines = linegroup
.selectAll('path')
.filter(filter)
.data(
function() { return pathdata[this.parentNode.__data__] || []; },
osmEntity.key
);
layergroup.selectAll('g.line-shadow')
.call(drawLineGroup, 'shadow', function() {
var data = pathdata[this.parentNode.__data__] || [];
return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) === -1; });
});
layergroup.selectAll('g.line-casing')
.call(drawLineGroup, 'casing', function() {
var data = pathdata[this.parentNode.__data__] || [];
return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) === -1; });
});
layergroup.selectAll('g.line-stroke')
.call(drawLineGroup, 'stroke', function() {
var data = pathdata[this.parentNode.__data__] || [];
return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) === -1; });
});
layergroup.selectAll('g.line-shadow2')
.call(drawLineGroup, 'shadow', function() {
var data = pathdata[this.parentNode.__data__] || [];
return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) !== -1; });
});
layergroup.selectAll('g.line-casing2')
.call(drawLineGroup, 'casing', function() {
var data = pathdata[this.parentNode.__data__] || [];
return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) !== -1; });
});
layergroup.selectAll('g.line-stroke2')
.call(drawLineGroup, 'stroke', function() {
var data = pathdata[this.parentNode.__data__] || [];
return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) !== -1; });
});
// var lines = linegroup
// .selectAll('path')
// .filter(filter)
// .data(
// function() {
// var data = pathdata[this.parentNode.__data__] || [];
// return data.filter(function(d) { return context.selectedIDs().indexOf(d.id) === -1; });
// },
// osmEntity.key
// );
// lines.exit()
// .remove();
// // Optimization: call simple TagClasses only on enter selection. This
// // works because osmEntity.key is defined to include the entity v attribute.
// lines.enter()
// .append('path')
// .attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
// .call(svgTagClasses())
// .merge(lines)
// .sort(waystack)
// .attr('d', getPath)
// .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
lines.exit()
.remove();
// Optimization: call simple TagClasses only on enter selection. This
// works because osmEntity.key is defined to include the entity v attribute.
lines.enter()
.append('path')
.attr('class', function(d) { return 'way line ' + this.parentNode.__data__ + ' ' + d.id; })
.call(svgTagClasses())
.merge(lines)
.sort(waystack)
.attr('d', getPath)
.call(svgTagClasses().tags(svgRelationMemberTags(graph)));
var onewaygroup = layergroup
+11 -11
View File
@@ -22,7 +22,7 @@ describe('iD.svgLines', function () {
line = iD.Way({nodes: [a.id, b.id]}),
graph = iD.Graph([a, b, line]);
surface.call(iD.svgLines(projection), graph, [line], all);
surface.call(iD.svgLines(projection, context), graph, [line], all);
expect(surface.select('path.way')).to.be.classed('way');
expect(surface.select('path.line')).to.be.classed('line');
@@ -34,7 +34,7 @@ describe('iD.svgLines', function () {
line = iD.Way({nodes: [a.id, b.id], tags: {highway: 'residential'}}),
graph = iD.Graph([a, b, line]);
surface.call(iD.svgLines(projection), graph, [line], all);
surface.call(iD.svgLines(projection, context), graph, [line], all);
expect(surface.select('.line')).to.be.classed('tag-highway');
expect(surface.select('.line')).to.be.classed('tag-highway-residential');
@@ -47,7 +47,7 @@ describe('iD.svgLines', function () {
relation = iD.Relation({members: [{id: line.id}], tags: {type: 'multipolygon', natural: 'wood'}}),
graph = iD.Graph([a, b, line, relation]);
surface.call(iD.svgLines(projection), graph, [line], all);
surface.call(iD.svgLines(projection, context), graph, [line], all);
expect(surface.select('.stroke')).to.be.classed('tag-natural-wood');
});
@@ -60,7 +60,7 @@ describe('iD.svgLines', function () {
r = iD.Relation({members: [{id: w.id}], tags: {type: 'multipolygon'}}),
graph = iD.Graph([a, b, c, w, r]);
surface.call(iD.svgLines(projection), graph, [w], all);
surface.call(iD.svgLines(projection, context), graph, [w], all);
expect(surface.select('.stroke')).to.be.classed('tag-natural-wood');
});
@@ -74,7 +74,7 @@ describe('iD.svgLines', function () {
r = iD.Relation({members: [{id: o.id, role: 'outer'}, {id: i.id, role: 'inner'}], tags: {type: 'multipolygon'}}),
graph = iD.Graph([a, b, c, o, i, r]);
surface.call(iD.svgLines(projection), graph, [i], all);
surface.call(iD.svgLines(projection, context), graph, [i], all);
expect(surface.select('.stroke')).to.be.classed('tag-natural-wood');
});
@@ -90,7 +90,7 @@ describe('iD.svgLines', function () {
]);
it('stacks higher lines above lower ones in a single render', function () {
surface.call(iD.svgLines(projection), graph, [graph.entity('lo'), graph.entity('hi')], none);
surface.call(iD.svgLines(projection, context), graph, [graph.entity('lo'), graph.entity('hi')], none);
var selection = surface.selectAll('g.line-stroke > path.line');
expect(selection.nodes()[0].__data__.id).to.eql('lo');
@@ -98,7 +98,7 @@ describe('iD.svgLines', function () {
});
it('stacks higher lines above lower ones in a single render (reverse)', function () {
surface.call(iD.svgLines(projection), graph, [graph.entity('hi'), graph.entity('lo')], none);
surface.call(iD.svgLines(projection, context), graph, [graph.entity('hi'), graph.entity('lo')], none);
var selection = surface.selectAll('g.line-stroke > path.line');
expect(selection.nodes()[0].__data__.id).to.eql('lo');
@@ -106,8 +106,8 @@ describe('iD.svgLines', function () {
});
it('stacks higher lines above lower ones in separate renders', function () {
surface.call(iD.svgLines(projection), graph, [graph.entity('lo')], none);
surface.call(iD.svgLines(projection), graph, [graph.entity('hi')], none);
surface.call(iD.svgLines(projection, context), graph, [graph.entity('lo')], none);
surface.call(iD.svgLines(projection, context), graph, [graph.entity('hi')], none);
var selection = surface.selectAll('g.line-stroke > path.line');
expect(selection.nodes()[0].__data__.id).to.eql('lo');
@@ -115,8 +115,8 @@ describe('iD.svgLines', function () {
});
it('stacks higher lines above lower in separate renders (reverse)', function () {
surface.call(iD.svgLines(projection), graph, [graph.entity('hi')], none);
surface.call(iD.svgLines(projection), graph, [graph.entity('lo')], none);
surface.call(iD.svgLines(projection, context), graph, [graph.entity('hi')], none);
surface.call(iD.svgLines(projection, context), graph, [graph.entity('lo')], none);
var selection = surface.selectAll('g.line-stroke > path.line');
expect(selection.nodes()[0].__data__.id).to.eql('lo');