Merge branch 'master' of github.com:systemed/iD

This commit is contained in:
Tom MacWright
2013-01-17 18:20:57 -05:00
13 changed files with 189 additions and 23 deletions
+4
View File
@@ -154,6 +154,10 @@ path.multipolygon {
fill-rule: evenodd;
}
path.area.member-type-multipolygon {
fill: none;
}
path.area.selected {
stroke-width:4 !important;
}
+1
View File
@@ -43,6 +43,7 @@
<script src="js/id/svg.js"></script>
<script src="js/id/svg/areas.js"></script>
<script src="js/id/svg/lines.js"></script>
<script src="js/id/svg/member_classes.js"></script>
<script src="js/id/svg/midpoints.js"></script>
<script src="js/id/svg/multipolygons.js"></script>
<script src="js/id/svg/points.js"></script>
+2 -1
View File
@@ -52,7 +52,8 @@ iD.svg.Areas = function(projection) {
paths
.order()
.attr('d', lineString)
.call(iD.svg.TagClasses());
.call(iD.svg.TagClasses())
.call(iD.svg.MemberClasses(graph));
paths.exit()
.remove();
+20 -20
View File
@@ -33,27 +33,27 @@ iD.svg.Lines = function(projection) {
return as - bs;
}
function drawPaths(group, lines, filter, classes, lineString) {
var paths = group.selectAll('path')
.filter(filter)
.data(lines, iD.Entity.key);
paths.enter()
.append('path')
.attr('class', classes);
paths
.order()
.attr('d', lineString)
.call(iD.svg.TagClasses());
paths.exit()
.remove();
return paths;
}
return function drawLines(surface, graph, entities, filter) {
function drawPaths(group, lines, filter, classes, lineString) {
var paths = group.selectAll('path')
.filter(filter)
.data(lines, iD.Entity.key);
paths.enter()
.append('path')
.attr('class', classes);
paths
.order()
.attr('d', lineString)
.call(iD.svg.TagClasses())
.call(iD.svg.MemberClasses(graph));
paths.exit()
.remove();
return paths;
}
if (!alength) {
var arrow = surface.append('text').text(arrowtext);
+32
View File
@@ -0,0 +1,32 @@
iD.svg.MemberClasses = function(graph) {
var tagClassRe = /^member-?/;
return function memberClassesSelection(selection) {
selection.each(function memberClassesEach(d, i) {
var classes, value = this.className;
if (value.baseVal !== undefined) value = value.baseVal;
classes = value.trim().split(/\s+/).filter(function(name) {
return name.length && !tagClassRe.test(name);
}).join(' ');
var relations = graph.parentRelations(d);
if (relations.length) {
classes += ' member';
}
relations.forEach(function (relation) {
classes += ' member-type-' + relation.tags.type;
classes += ' member-role-' + _.find(relation.members, function (member) { return member.id == d.id; }).role;
});
classes = classes.trim();
if (classes !== value) {
d3.select(this).attr('class', classes);
}
});
};
};
+2 -1
View File
@@ -40,7 +40,8 @@ iD.svg.Multipolygons = function(projection) {
paths
.order()
.attr('d', lineString)
.call(iD.svg.TagClasses());
.call(iD.svg.TagClasses())
.call(iD.svg.MemberClasses(graph));
paths.exit()
.remove();
+2 -1
View File
@@ -45,7 +45,8 @@ iD.svg.Points = function(projection) {
.attr('transform', 'translate(-8, -8)');
groups.attr('transform', iD.svg.PointTransform(projection))
.call(iD.svg.TagClasses());
.call(iD.svg.TagClasses())
.call(iD.svg.MemberClasses(graph));
// Selecting the following implicitly
// sets the data (point entity) on the element
+1
View File
@@ -31,6 +31,7 @@ iD.svg.Vertices = function(projection) {
groups.attr('transform', iD.svg.PointTransform(projection))
.call(iD.svg.TagClasses())
.call(iD.svg.MemberClasses(graph))
.classed('shared', function(entity) { return graph.parentWays(entity).length > 1; });
// Selecting the following implicitly
+3
View File
@@ -45,6 +45,7 @@
<script src="../js/id/svg.js"></script>
<script src="../js/id/svg/areas.js"></script>
<script src="../js/id/svg/lines.js"></script>
<script src="../js/id/svg/member_classes.js"></script>
<script src="../js/id/svg/midpoints.js"></script>
<script src="../js/id/svg/multipolygons.js"></script>
<script src="../js/id/svg/points.js"></script>
@@ -159,6 +160,8 @@
<script src="spec/svg.js"></script>
<script src="spec/svg/areas.js"></script>
<script src="spec/svg/lines.js"></script>
<script src="spec/svg/member_classes.js"></script>
<script src="spec/svg/multipolygons.js"></script>
<script src="spec/svg/points.js"></script>
<script src="spec/svg/vertices.js"></script>
+2
View File
@@ -64,6 +64,8 @@
<script src="spec/svg.js"></script>
<script src="spec/svg/areas.js"></script>
<script src="spec/svg/lines.js"></script>
<script src="spec/svg/member_classes.js"></script>
<script src="spec/svg/multipolygons.js"></script>
<script src="spec/svg/points.js"></script>
<script src="spec/svg/vertices.js"></script>
+12
View File
@@ -28,6 +28,18 @@ describe("iD.svg.Areas", function () {
expect(surface.select('.area')).to.be.classed('tag-building-yes');
});
it("adds member classes", function () {
var area = iD.Way({tags: {area: 'yes'}}),
relation = iD.Relation({members: [{id: area.id, role: 'outer'}], tags: {type: 'multipolygon'}}),
graph = iD.Graph([area, relation]);
surface.call(iD.svg.Areas(projection), graph, [area], filter);
expect(surface.select('.area')).to.be.classed('member');
expect(surface.select('.area')).to.be.classed('member-role-outer');
expect(surface.select('.area')).to.be.classed('member-type-multipolygon');
});
it("preserves non-area paths", function () {
var area = iD.Way({tags: {area: 'yes'}}),
graph = iD.Graph([area]);
+54
View File
@@ -0,0 +1,54 @@
describe("iD.svg.Lines", function () {
var surface,
projection = Object,
filter = d3.functor(true);
beforeEach(function () {
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.call(iD.svg.Surface());
});
it("adds way and area classes", function () {
var line = iD.Way(),
graph = iD.Graph([line]);
surface.call(iD.svg.Lines(projection), graph, [line], filter);
expect(surface.select('path')).to.be.classed('way');
expect(surface.select('path')).to.be.classed('line');
});
it("adds tag classes", function () {
var line = iD.Way({tags: {highway: 'residential'}}),
graph = iD.Graph([line]);
surface.call(iD.svg.Lines(projection), graph, [line], filter);
expect(surface.select('.line')).to.be.classed('tag-highway');
expect(surface.select('.line')).to.be.classed('tag-highway-residential');
});
it("adds member classes", function () {
var line = iD.Way(),
relation = iD.Relation({members: [{id: line.id}], tags: {type: 'route'}}),
graph = iD.Graph([line, relation]);
surface.call(iD.svg.Lines(projection), graph, [line], filter);
expect(surface.select('.line')).to.be.classed('member');
expect(surface.select('.line')).to.be.classed('member-type-route');
});
it("preserves non-line paths", function () {
var line = iD.Way(),
graph = iD.Graph([line]);
surface.select('.layer-fill')
.append('path')
.attr('class', 'other');
surface.call(iD.svg.Lines(projection), graph, [line], filter);
expect(surface.selectAll('.other')[0].length).to.equal(1);
});
});
+54
View File
@@ -0,0 +1,54 @@
describe("iD.svg.MemberClasses", function () {
var selection;
beforeEach(function () {
selection = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'g'));
});
it("adds no classes to elements that aren't a member of any relations", function() {
var node = iD.Node(),
graph = iD.Graph([node]);
selection
.datum(node)
.call(iD.svg.MemberClasses(graph));
expect(selection.attr('class')).to.equal(null);
});
it("adds tags for member, role, and type", function() {
var node = iD.Node(),
relation = iD.Relation({members: [{id: node.id, role: 'r'}], tags: {type: 't'}}),
graph = iD.Graph([node, relation]);
selection
.datum(node)
.call(iD.svg.MemberClasses(graph));
expect(selection.attr('class')).to.equal('member member-type-t member-role-r');
});
it('removes classes for tags that are no longer present', function() {
var node = iD.Entity(),
graph = iD.Graph([node]);
selection
.attr('class', 'member member-type-t member-role-r')
.datum(node)
.call(iD.svg.MemberClasses(graph));
expect(selection.attr('class')).to.equal('');
});
it("preserves existing non-'member-'-prefixed classes", function() {
var node = iD.Entity(),
graph = iD.Graph([node]);
selection
.attr('class', 'selected')
.datum(node)
.call(iD.svg.MemberClasses(graph));
expect(selection.attr('class')).to.equal('selected');
});
});