score:0

Well, this could be way easier if you had a point scale for positioning the circles in the x axis. Since you have a linear scale, the function I wrote has some cumbersome parts...

First things first: you have to create a function that repaint the elements in the SVG. In the following demo, it's named `draw`, and we pass the `series` array to that function.

The most important part, however, is sorting the `series` array. This, for instance, is the function for sorting the blue dots and rearranging the orange ones accordingly:

``````d3.select("#button1").on("click", function() {
series[0] = series[0].sort(function(a, b) {
return d3.ascending(a.y, b.y)
}).map(function(e, i) {
return {
x: i,
fx: e.fx,
y: e.y,
u: e.u
}
});
series[1].forEach(function(d, i, arr) {
d.x = order0.indexOf(d.fx)
});
draw(series);
});
``````

As you can see, sorting alone won't work, because the `x` property will be sorted together. Thus, we have to sort according to `y` and then reassign `x` from 0 to 10.

For keeping the object constancy, I created an property named `u`, using `Math.random()`. There is a very little chance that two properties have the same value. However, I advise you to create your own unique property in each object (otherwise you cannot keep object constancy). The `fx` property is just to keep track of the original sequence, and `order0`/`order1` are arrays with the ordered sequence of each series.

Here is the demo, using most of your code but creating `draw` and reducing the SVG size, for better fit in a Stack snippet. Click the button to sort:

``````var data = d3.csvParse(d3.select("#csv").text());

var w = 600;
var h = 200;

//Define scale
var z = d3.scaleOrdinal(d3.schemeCategory10);

var xAxis = d3.axisBottom().scale(x).ticks(10);
var yAxis = d3.axisLeft().scale(y).ticks(5);

//Define Canvas
var svg = d3.select("body").append("svg")
.attr("width", w).attr("height", h)

//Define clipping path
svg.append("clipPath").attr("id", "chart-area").append("rect")

// Extract yn using key
var seriesNames = d3.keys(data[0])
.filter(function(d) {
return d !== "x";
})
.sort();

// Map data to cartesian tuple {x,y}
var series = seriesNames.map(function(series) {
return data.map(function(d, i) {
return {
x: +d.x,
fx: +d.x,
y: +d[series],
u: Math.random()
};
});
});

var order0 = series[0].sort(function(a, b) {
return d3.ascending(a.y, b.y)
}).map(function(e) {
return e.x
});

var order1 = series[1].sort(function(a, b) {
return d3.ascending(a.y, b.y)
}).map(function(e) {
return e.x
});

// Compute domains
x.domain(d3.extent(d3.merge(series), function(d) {
return d.x;
})).nice();
y.domain(d3.extent(d3.merge(series), function(d) {
return d.y;
})).nice();

// X axis.
svg.append("g").attr("class", "axis").attr("transform",
"translate(0," + (h - padding) + ")").call(xAxis)

// Y axis.
svg.append("g").attr("class", "axis").attr("transform",

draw(series);

function draw(data) {

// Append circles
var groups = svg.selectAll(".series")
.data(data);

var groupsEnter = groups.enter()
.append("g")
.attr("class", "series")
.style("fill", function(d, i) {
return z(i);
});

var circlesEnter = groupsEnter.selectAll(".point")
.data(function(d) {
return d;
}, function(e) {
return e.u
}).enter().append("circle")
.attr("class", "point")
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d) {
return y(d.y);
})
.attr("r", 4);

groups.selectAll(".point").data(function(d) {
return d;
}, function(e) {
return e.u
})
.transition()
.duration(2500)
.attr("cx", function(d) {
return x(d.x);
})
.attr("cy", function(d) {
return y(d.y);
})
.attr("r", 4);

}

//On click, update order
d3.select("#button1").on("click", function() {
series[0] = series[0].sort(function(a, b) {
return d3.ascending(a.y, b.y)
}).map(function(e, i) {
return {
x: i,
fx: e.fx,
y: e.y,
u: e.u
}
});
series[1].forEach(function(d, i, arr) {
d.x = order0.indexOf(d.fx)
});
draw(series);
});

d3.select("#button2").on("click", function() {
series[1] = series[1].sort(function(a, b) {
return d3.ascending(a.y, b.y)
}).map(function(e, i) {
return {
x: i,
fx: e.fx,
y: e.y,
u: e.u
}
});
series[0].forEach(function(d, i, arr) {
d.x = order1.indexOf(d.fx)
});
draw(series);
});``````
``````pre {
display: none;
}

button {
margin-right: 5px;
}``````
``````<script src="https://d3js.org/d3.v4.min.js"></script>
<button id="button1">Click to sort by Blue</button><button id="button2">Click to sort by Orange</button>
<pre id="csv">x,y1,y2
0,0.85337,0.10198
1,0,0.30274
2,0.85311,0.08623
3,0.82759,0.08711
4,0.89602,0.03472
5,0.8,0.16295
6,0,0.27028
7,0.76167,0.2155
8,0.75,0.08359
9,0.81775,0.16535
10,0,0.2311</pre>``````