Javascript 带复选框的平行坐标
我有一些数据,我想用平行坐标将它们可视化 我的数据由200行(案例)和100列(特征)组成。我只需要可视化部分数据(200x8),包括feature1、feature2、…、feature8。我还有4列数据(A、B、C和D),它们的值是0或1。例如,如果一个案例(行)的列A的值为1,则表示数据的案例类型为A 我已经有了绘制平行坐标的代码:Javascript 带复选框的平行坐标,javascript,checkbox,d3.js,parallel-coordinates,Javascript,Checkbox,D3.js,Parallel Coordinates,我有一些数据,我想用平行坐标将它们可视化 我的数据由200行(案例)和100列(特征)组成。我只需要可视化部分数据(200x8),包括feature1、feature2、…、feature8。我还有4列数据(A、B、C和D),它们的值是0或1。例如,如果一个案例(行)的列A的值为1,则表示数据的案例类型为A 我已经有了绘制平行坐标的代码: <div class="filter_options"> <input class="filter_button" id="a_bu
<div class="filter_options">
<input class="filter_button" id="a_button" type="checkbox">A</input><br>
<input class="filter_button" id="b_button" type="checkbox">B</input><br>
<input class="filter_button" id="c_button" type="checkbox">C</input><br>
<input class="filter_button" id="d_button" type="checkbox">D</input><br>
</div>
<body>
<script type="text/javascript">
var m = [30, 10, 10, 10],
w = 1300 - m[1] - m[3],
h = 500 - m[0] - m[2];
var x = d3.scale.ordinal().rangePoints([0, w], 1),
y = {},
dragging = {};
var line = d3.svg.line(),
axis = d3.svg.axis().orient("left"),
background,
foreground;
var svg = d3.select("body").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
d3.csv("myData.csv")
.row(function(d) {
return {
// Features that are needed to be visualize
feature1 : d.feature1,
feature2 : d.feature2,
feature3 : d.feature3,
feature4 : d.feature4,
feature5 : d.feature5,
feature6 : d.feature6,
feature7 : d.feature7,
feature8 : d.feature8,
A : d.A,
B : d.B,
C : d.C,
D : d.D
};
})
.get(function(e, data) {
x.domain(
dimensions = d3.keys(data[0])
.filter(function(d) {
return d != "source" &&
(y[d] = d3.scale.linear()
.domain(d3.extent(data, function(p) { return +p[d]; }))
.range([h, 0]));
}
));
// Add grey background lines for context.
background = svg.append("svg:g")
.attr("class", "background")
.selectAll("path")
.data(data)
.enter().append("svg:path")
.attr("d", path);
// Add blue foreground lines for focus.
foreground = svg.append("svg:g")
.attr("class", "foreground")
.selectAll("path")
.data(data)
.enter().append("svg:path")
.attr("d", path);
// Add a group element for each dimension.
var g = svg.selectAll(".dimension")
.data(dimensions)
.enter().append("svg:g")
.attr("class", "dimension")
.attr("transform", function(d) { return "translate(" + x(d) + ")"; })
.call(d3.behavior.drag()
.on("dragstart", function(d) {
dragging[d] = this.__origin__ = x(d);
background.attr("visibility", "hidden");
})
.on("drag", function(d) {
dragging[d] = Math.min(w, Math.max(0, this.__origin__ += d3.event.dx));
foreground.attr("d", path);
dimensions.sort(function(a, b) { return position(a) - position(b); });
x.domain(dimensions);
g.attr("transform", function(d) { return "translate(" + position(d) + ")"; })
})
.on("dragend", function(d) {
delete this.__origin__;
delete dragging[d];
transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")");
transition(foreground)
.attr("d", path);
background
.attr("d", path)
.transition()
.delay(500)
.duration(0)
.attr("visibility", null);
}));
// Add an axis and title.
g.append("svg:g")
.attr("class", "axis")
.each(function(d) { d3.select(this).call(axis.scale(y[d])); })
.append("svg:text")
.attr("text-anchor", "middle")
.attr("y", -9)
.text(String);
// Add and store a brush for each axis.
g.append("svg:g")
.attr("class", "brush")
.each(function(d) { d3.select(this).call(y[d].brush = d3.svg.brush().y(y[d]).on("brush", brush)); })
.selectAll("rect")
.attr("x", -8)
.attr("width", 16);
});
function position(d) {
var v = dragging[d];
return v == null ? x(d) : v;
}
function transition(g) {
return g.transition().duration(500);
}
// Returns the path for a given data point.
function path(d) {
return line(dimensions.map(function(p) { return [position(p), y[p](d[p])]; }));
}
// Handles a brush event, toggling the display of foreground lines.
function brush() {
var actives = dimensions.filter(function(p) { return !y[p].brush.empty(); }),
extents = actives.map(function(p) { return y[p].brush.extent(); });
foreground.style("display", function(d) {
return actives.every(function(p, i) {
return extents[i][0] <= d[p] && d[p] <= extents[i][1];
}) ? null : "none";
});
}
</script>
</body>
在不了解您的数据和代码组织的情况下,给您提供建议或解决方案是相当困难的,因此我将尝试使用其他人类似的好例子最终,您的问题的解决方案可能看起来完全不同,但我将此答案作为指南发布给您,希望它能对您有所帮助。 看看这个:(它具有选择和取消选择项目组的功能——这正是您需要的功能) 本例的JavaScript代码为 数据位于csv文件中,前几行如下所示:
"name","group","protein (g)","calcium (g)","sodium (g)","fiber (g)","vitaminc (g)","potassium (g)","carbohydrate (g)","sugars (g)","fat (g)","water (g)","calories","saturated (g)","monounsat (g)","polyunsat (g)","id"
"Beverage, instant breakfast powder, chocolate, not reconstituted","Dairy and Egg Products",19.9,0.285,0.385,0.4,0.07690000000000001,0.947,66.2,65.8,1.4,7.4,357,0.56,0.314,0.278,27481
"Beverage, instant breakfast powder, chocolate, sugar-free, not reconstituted","Dairy and Egg Products",35.8,0.5,0.717,2,0.138,1.705,41,39,5.1,7.4,358,2.162,1.189,1.027,27482
"Beverage, milkshake mix, dry, not chocolate","Dairy and Egg Products",23.5,0.88,0.78,1.6,0.0012,2.2,52.9,51.3,2.6,12.8,329,2.059,0.332,0.06,27483
"Butter oil, anhydrous","Dairy and Egg Products",0.28,0.004,0.002,,0,0.005,,,99.48,0.24,876,61.924,28.732,3.694,27484
"Butter, salted","Dairy and Egg Products",0.85,0.024,0.714,,0,0.024,0.06,0.06,81.11,15.87,717,51.368,21.021,3.043,27485
"Butter, whipped, with salt","Dairy and Egg Products",0.85,0.024,0.827,,0,0.026,0.06,0.06,81.11,15.87,717,50.489,23.426,3.012,27486
"Butter, without salt","Dairy and Egg Products",0.85,0.024,0.011,,0,0.024,0.06,0.06,81.11,17.94,717,51.368,21.021,3.043,27487
"Cheese fondue","Dairy and Egg Products",14.23,0.476,0.132,,0,0.105,3.77,,13.47,61.61,229,8.721,3.563,0.484,27488
"Cheese food, cold pack, american","Dairy and Egg Products",19.66,0.497,0.966,,0,0.363,8.32,,24.46,43.12,331,15.355,7.165,0.719,27489
"Cheese food, imitation","Dairy and Egg Products",22.4,0.552,1.239,,0,0.336,8.8,8.21,1.3,63.8,137,0.81,0.38,0.048,27490
第二列为“组”,该字段用于物料分类。在本例中,还有用于每个组的颜色定义:
var colors = {
"Baby Foods": [185,56,73],
"Baked Products": [37,50,75],
"Beef Products": [325,50,39],
"Beverages": [10,28,67],
"Breakfast Cereals": [271,39,57],
"Cereal Grains and Pasta": [56,58,73],
"Dairy and Egg Products": [28,100,52],
"Ethnic Foods": [41,75,61],
"Fast Foods": [60,86,61],
"Fats and Oils": [30,100,73],
"Finfish and Shellfish Products": [318,65,67],
"Fruits and Fruit Juices": [274,30,76],
"Lamb, Veal, and Game Products": [20,49,49],
"Legumes and Legume Products": [334,80,84],
"Meals, Entrees, and Sidedishes": [185,80,45],
"Nut and Seed Products": [10,30,42],
"Pork Products": [339,60,49],
"Poultry Products": [359,69,49],
"Restaurant Foods": [204,70,41],
"Sausages and Luncheon Meats": [1,100,79],
"Snacks": [189,57,75],
"Soups, Sauces, and Gravies": [110,57,70],
"Spices and Herbs": [214,55,79],
"Sweets": [339,60,75],
"Vegetables and Vegetable Products": [120,56,40]
};
在图表中间创建列表“食物组”的函数是CuraTyLeField():
如您所见,该列表是作为一系列div实现的,这些div具有工具提示“Show group”或“Hide group”,具体取决于所涉及的组是否在“excluded_groups”列表中。此外,“onclick”事件会将有问题的组从“排除的组”列表中删除或添加到列表中。在重新绘制平行坐标的代码中,列表“排除的组”用于过滤。您可以在代码中执行类似的操作。仅此而已本例将下划线.js用于各种用途,如果您不希望这样做,可能需要重写和调整一些代码部分 将复选框添加到页面中,并在更改处理程序中相应地过滤数据。感谢您的评论。我更新了我的问题并添加了代码。我不是一个专业的程序员,所以我很难用其他代码来调整我的代码。我需要根据代码中的内容添加复选框。如果您能根据我的代码、我需要更改的内容、我需要添加复选框函数的内容和位置等给我一些提示,我将不胜感激。@sara_123您能附上一些数据样本吗?我添加了一些数据样本。(抱歉,首先我错误地将其添加到了您的答案中)嗨,如果有人可以帮助解决这些平行坐标的问题-或者。这会有很大的帮助。提前谢谢。
var colors = {
"Baby Foods": [185,56,73],
"Baked Products": [37,50,75],
"Beef Products": [325,50,39],
"Beverages": [10,28,67],
"Breakfast Cereals": [271,39,57],
"Cereal Grains and Pasta": [56,58,73],
"Dairy and Egg Products": [28,100,52],
"Ethnic Foods": [41,75,61],
"Fast Foods": [60,86,61],
"Fats and Oils": [30,100,73],
"Finfish and Shellfish Products": [318,65,67],
"Fruits and Fruit Juices": [274,30,76],
"Lamb, Veal, and Game Products": [20,49,49],
"Legumes and Legume Products": [334,80,84],
"Meals, Entrees, and Sidedishes": [185,80,45],
"Nut and Seed Products": [10,30,42],
"Pork Products": [339,60,49],
"Poultry Products": [359,69,49],
"Restaurant Foods": [204,70,41],
"Sausages and Luncheon Meats": [1,100,79],
"Snacks": [189,57,75],
"Soups, Sauces, and Gravies": [110,57,70],
"Spices and Herbs": [214,55,79],
"Sweets": [339,60,75],
"Vegetables and Vegetable Products": [120,56,40]
};
function create_legend(colors,brush) {
// create legend
var legend_data = d3.select("#legend")
.html("")
.selectAll(".row")
.data( _.keys(colors).sort() )
// filter by group
var legend = legend_data
.enter().append("div")
.attr("title", "Hide group")
.on("click", function(d) {
// toggle food group
if (_.contains(excluded_groups, d)) {
d3.select(this).attr("title", "Hide group")
excluded_groups = _.difference(excluded_groups,[d]);
brush();
} else {
d3.select(this).attr("title", "Show group")
excluded_groups.push(d);
brush();
}
});
legend
.append("span")
.style("background", function(d,i) { return color(d,0.85)})
.attr("class", "color-bar");
legend
.append("span")
.attr("class", "tally")
.text(function(d,i) { return 0});
legend
.append("span")
.text(function(d,i) { return " " + d});
return legend;
}