我一直在尝试将这个项目与平行坐标从 d3 V3 转换为 V4。遇到的问题是当我尝试在 Y 轴上为每个维度应用刷子时。
我无法更改刷牙时应用的覆盖的宽度。它始终具有 1000 个单位的宽度。一旦我实施刷牙,它就会发生。
这是我到目前为止的代码:
// main.js
var margin = { top: 30, right: 10, bottom: 10, left: 40 },
width = 1000 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// The first element in domain will be mapped to the first point, the second domain value to the second point, and so on.
var x = d3.scalePoint()
.range([0, width])
var y = {}; // Store linear scales for each dimension here!
var line = d3.line(); // https://github.com/d3/d3-shape#line
var axis = d3.axisLeft();
var background;
var foreground;
var dragging = {};
var dimensions = {};
// Create the main svg
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("cars.csv", function (error, cars) {
if (error) throw error;
//// ==== Set Dimensions START ==== ////
// d3.keys will get the field "names": { cylinders: 8 } cylinders is the key in this case. All the keys will be recieved!
// For each car variable! d is the variable
dimensions = d3.keys(cars[0]).filter(function (d) {
if (d === "name") return false; // Exclude the dimension "name"
return true;
});
// Set the x-axis domain to the dimensions
x.domain(dimensions);
// Create a linear y scale for each dimension.
dimensions.forEach(function (d) {
y[d] = d3.scaleLinear()
.domain(d3.extent(cars, function (data) {
// Return each cars value for specfied dimension d.
return +data[d];
}))
.range([height, 0]);
})
//// ==== Set Dimensions END ==== ////
//// ==== Draw Lines START ==== ////
background = svg.append("g")
.attr("class", "background")
.selectAll("path")
.data(cars).enter()
.append("path")
.attr("d", path)
foreground = svg.append("g")
.attr("class", "foreground")
.selectAll("path")
.data(cars).enter()
.append("path")
.attr("d", path)
//// ==== Draw Lines END ==== ////
//// ==== Draw Axis START ==== ////
var g = svg.selectAll(".dimension")
.data(dimensions).enter() // g's data is the dimensions
.append("g")
.attr("class", "dimension")
// Give the axis it's propper x pos
.attr("transform", function(d) {return "translate("+x(d)+ ")"; });
g.append("g") // The Axis
.attr("class", "axis")
.each(function(d) { d3.select(this).call(axis.scale(y[d])); });
g.append("text") // Axis Label
.attr("class", "title")
.style("text-anchor", "middle")
.attr("y", -10)
.attr("font-size", 15)
.text(function(d) { return d; });
//// ==== Draw Axis END ==== ////
//// ==== Axis dragging START ==== ////
g.call(d3.drag()
.on("start", function(d) {
dragging[d] = x(d);
background.attr("visibility", "hidden");
})
.on("drag", function(d) {
// Make sure the dragging is within the range.
dragging[d] = Math.min(width, Math.max(0, d3.event.x));
foreground.attr("d", path) // Redraw the lines when draging an axis
dimensions.sort(function(a,b) {return xPosition(a) - xPosition(b)});
// Set the domain to the new order of the dimension
x.domain(dimensions);
// Translate the axis to mouse position
g.attr("transform", function(d) { return "translate("+ xPosition(d) +")";
})
})
.on("end", function(d) {
delete dragging[d];
d3.select(this)
.transition().duration(200)
.attr("transform", "translate("+x(d)+")");
foreground
.transition().duration(200)
.attr("d", path)
background
.attr("d", path)
.transition().delay(200).duration(0)
.attr("visibility", null);
}));
//// ==== Axis dragging END ==== ////
//// ==== Brushing START ==== ////
g.append("g")
.attr("class", "brush")
.each(function(d){
d3.select(this).call(d3.brushY()
.on("start", function(){ d3.event.sourceEvent.stopPropagation(); })
.on("brush", function(d, i){ console.log(d) }))
})
.selectAll("rect")
.attr("width", 20) // This part doesn't do anything!
//// ==== Brushing END ==== ////
});
function xPosition(d) {
var v = dragging[d]; // This array holds the temporary positions when dragging.
if(v == null) return x(d);
return v;
}
function path(data) {
return line(dimensions.map(function(dim){
return [xPosition(dim), y[dim](data[dim])]
}))
}
这是错误的屏幕截图,如果有帮助的话。在其中,我刷了最左边的维度,它一直延伸到右边。
当我尝试刷任何其他维度时,也会发生同样的事情,除了覆盖从那个特定维度开始,然后一直延伸到右侧。