diff --git a/README.md b/README.md
index acfe066..07c0aa7 100644
--- a/README.md
+++ b/README.md
@@ -1101,6 +1101,10 @@ function offsetNone(series, order) {
Stack orders are typically not used directly, but are instead passed to [*stack*.order](#stack_order).
+# d3.stackOrderAppearance(series) [<>](https://github.com/d3/d3-shape/blob/master/src/order/appearance.js "Source")
+
+Returns a series order such that the earliest series (according to the first non-zero value) is at the bottom.
+
# d3.stackOrderAscending(series) [<>](https://github.com/d3/d3-shape/blob/master/src/order/ascending.js "Source")
Returns a series order such that the smallest series (according to the sum of values) is at the bottom.
diff --git a/src/index.js b/src/index.js
index c4078c1..b5347cf 100644
--- a/src/index.js
+++ b/src/index.js
@@ -38,6 +38,7 @@ export {default as stackOffsetDiverging} from "./offset/diverging";
export {default as stackOffsetNone} from "./offset/none";
export {default as stackOffsetSilhouette} from "./offset/silhouette";
export {default as stackOffsetWiggle} from "./offset/wiggle";
+export {default as stackOrderAppearance} from "./order/appearance";
export {default as stackOrderAscending} from "./order/ascending";
export {default as stackOrderDescending} from "./order/descending";
export {default as stackOrderInsideOut} from "./order/insideOut";
diff --git a/src/order/appearance.js b/src/order/appearance.js
index fb1f3d9..13e4f9b 100644
--- a/src/order/appearance.js
+++ b/src/order/appearance.js
@@ -1,10 +1,12 @@
+import none from "./none";
+
export default function(series) {
- var appearanceIndex = series.map(function(d,i){
- for(var k = 0, n = d.length;k < n;++k){
- if(d[k][1] > 0) break;
- }
- return [k, i];
- });
- appearanceIndex.sort(function(a,b){return a[0] - b[0];})
- return appearanceIndex.map(function(d){return d[1]});
+ var starts = series.map(start);
+ return none(series).sort(function(a, b) { return starts[a] - starts[b]; });
+}
+
+function start(series) {
+ var i = -1, n = series.length;
+ while (++i < n && !+series[i][1]);
+ return i;
}
diff --git a/test/order/appearance-test.js b/test/order/appearance-test.js
new file mode 100644
index 0000000..ebbe29c
--- /dev/null
+++ b/test/order/appearance-test.js
@@ -0,0 +1,20 @@
+var tape = require("tape"),
+ shape = require("../../");
+
+tape("stackOrderAppearance(series) returns an order by appearance", function(test) {
+ test.deepEqual(shape.stackOrderAppearance([
+ [[0, 0], [0, 0], [0, 0]],
+ [[0, 0], [0, 2], [0, 3]],
+ [[0, 0], [0, 0], [0, 4]]
+ ]), [1, 2, 0]);
+ test.end();
+});
+
+tape("stackOrderAppearance(series) treats NaN values as zero", function(test) {
+ test.deepEqual(shape.stackOrderAppearance([
+ [[0, 0], [0, NaN], [0, NaN]],
+ [[0, 0], [0, 2], [0, 3]],
+ [[0, 0], [0, NaN], [0, 4]]
+ ]), [1, 2, 0]);
+ test.end();
+});