Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds remove method to layer (#63). #103

Closed
3 changes: 1 addition & 2 deletions examples/scripts/bar-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ d3.chart("BarChart", {

function onExitTrans() {
this.duration(1000)
.attr("x", function(d, i) { return chart.x(i - 1) - .5; })
.remove();
.attr("x", function(d, i) { return chart.x(i - 1) - .5; });
}

function dataBind(data) {
Expand Down
20 changes: 17 additions & 3 deletions src/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ Layer.prototype.insert = function() {
d3cAssert(false, "Layers must specify an `insert` method.");
};

/**
* Invoked by {@link Layer#draw} in order to remove exiting DOM nodes from
* this layer's `base`. This default implementation may be overridden by
* Layer instances.
*/
Layer.prototype.remove = function() {
this.remove();
};

/**
* Subscribe a handler to a "lifecycle event". These events (and only these
* events) are triggered when {@link Layer#draw} is invoked--see that method
Expand Down Expand Up @@ -113,9 +122,12 @@ Layer.prototype.off = function(eventName, handler) {

/**
* Render the layer according to the input data: Bind the data to the layer
* (according to {@link Layer#dataBind}, insert new elements (according to
* {@link Layer#insert}, make lifecycle selections, and invoke all relevant
* handlers (as attached via {@link Layer#on}) with the lifecycle selections.
* (according to {@link Layer#dataBind}), insert new elements (according to
* {@link Layer#insert}), make lifecycle selections, invoke all relevant
* handlers (as attached via {@link Layer#on}) with the lifecycle selections,
* then remove exiting elements (according to {@link Layer#remove}).
*
* The lifecycle selections are:
*
* - update
* - update:transition
Expand Down Expand Up @@ -216,4 +228,6 @@ Layer.prototype.draw = function(data) {
}
}
}

this.remove.call(selection);
};
6 changes: 6 additions & 0 deletions test/tests/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ suite("d3.layer", function() {
this.layer.draw([]);
assert(this.insert.calledOn(this.dataBind.returnValues[0].enter.returnValues[0]));
});
test("invokes the provided `remove` method", function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test description is a little inaccurate now since in this case, there is no provided remove method.

this.layer.draw([1]);
assert.equal(this.layer.selectAll('g')[0].length, 1);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a more elegant way to get this? this.layer.selectAll('g') will return a length-1 array even in after the elements have been removed, since it's the selection length rather than the length of the actual DOM elements.

this.layer.draw([]);
assert.equal(this.layer.selectAll('g')[0].length, 0);
});

suite("event triggering", function() {
test("invokes event handlers with the correct selection", function() {
Expand Down