Javascript 带复选框的平行坐标

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

我有一些数据,我想用平行坐标将它们可视化

我的数据由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_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;
}