编程语言
首页 > 编程语言> > javascript-具有复选框的平行坐标

javascript-具有复选框的平行坐标

作者:互联网

我有一些要使用平行坐标可视化的数据.

我的数据由200行(案例)和100列(功能)组成.我只需要可视化部分数据(200×8),包括feature1,feature2,…,feature8.另外,我有4列数据(A,B,C和D),它们的值为0或1.例如,如果一个案例(行)的A列的值为1,则表示数据的案例是类型一种.

我已经有了绘制平行坐标的代码:

    <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>

现在,我想添加4复选框,用户可以选择要在平行坐标中查看的类型.例如,如果用户检查A型,则应可视化其A列中值为1的案例(行).

我应该怎么做?

我非常感谢您可以提供的任何帮助:)

这块(5×31)数据类似于我的数据:

path,Ktype,label,CGX,CGY,C_1,C_2,C_3,C_4,total1,total2,totalI3,total4,feature1,feature2,feature3,feature4,feature5,feature6,feature7,feature8,feature9,feature10,feature11,feature12,A,B,C,D,feature13,feature14,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.\Mydata\Case1,k1,1,42,33,0,57.44534,0,52597,71,16,10,276,4038,3789.631,0.6173469,0.6499337,2.103316,0.6661285,1.065539,248.3694,0.630161,0.000192848,0.9999996,0.000642777,1,0,0,1,9.60E-05,3136.698,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.\Mydata\Case2,k1,2,163,29,0,43.28862,0,49050,71,16,10,248,2944,2587.956,0.5726808,0.5681185,2.130387,0.601512,1.137578,356.0444,0.6335613,0.000327267,1.000029,0.001271235,1,0,0,1,0.00010854,2676.418,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.\Mydata\Case3,k1,3,774,19,0,45.26291,0,53455,71,16,10,212,2366,1982.547,0.408179,0.4579566,1.994296,0.6615351,1.193415,383.4534,0.7153812,0.000264522,1.000031,0.001210507,1,1,0,0,9.54E-05,3221.289,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.\Mydata\Case4,k1,4,1116,25,0,80.76469,0,57542,71,16,10,284,3908,3453.988,0.3549117,0.4811547,1.982244,0.6088744,1.131446,454.0122,0.6166388,0.000314288,0.9999836,0.00129846,0,1,1,0,0.000140592,2143.42,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.\Mydata\Case5,k1,5,1364,59,1,52.96776,0,49670,71,16,10,228,2725,2642.675,0.4328255,0.475517,1.859871,0.6587288,1.031152,82.32471,0.5775694,0.000466264,0.9999803,0.001765345,0,1,1,0,0.00012014,2439.636,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

解决方法:

在不了解您的数据和代码组织的情况下,很难为您提供建议或解决方案,因此,我将尝试使用其他人的相似且很好的示例.最终,您问题的解决方案可能看起来完全不同,但是我将此答案作为指南发布给您,希望对您有所帮助.

看一下这个fine example of usage of parallel coordinates :(它具有选择和取消选择项目组的功能-您需要的确切功能)

此示例的JavaScript代码是here.

数据在一个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]
};

在图的中间创建列表“食物组”的函数是create_legend():

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;
}

如您所见,该列表被实现为一系列div,这些div具有工具提示“显示组”或“隐藏组”,具体取决于相关组是否在列表“ excluded_groups”中.同样,“ onclick”事件从“ excluded_groups”列表中删除有问题的组或将其添加到列表中.在重绘平行坐标的代码中,列表“ excluded_groups”用于过滤.您可以在代码中执行类似的操作.就这些.

本示例出于各种目的使用underscore.js,如果您不希望这样做,则可能需要重写和调整一些代码部分.

标签:d3-js,parallel-coordinates,javascript,checkbox
来源: https://codeday.me/bug/20191121/2052327.html