首页 > 解决方案 > 过滤列表而不是 D3 中的选择下拉列表

问题描述

我正在使用 flexbox 来呈现一个过滤器和一个 D3 图表。我已经进行了所有更改以使 D3 图表响应。目前作为过滤器,我正在使用下拉菜单。我想要实现的是有一个列表而不是下拉列表。在任何选择中,D3 图表的数据都会发生变化。

我想我必须在这里做出改变:

        var dropdown = d3.select("#vis-container")
            .insert("select", "svg")
            .on("change", dropdownChange);

请参阅下面的完整片段:

var nutritionFields = ["calories", "protein", "fat", "sodium", "fiber",
                                   "carbs", "sugars", "potassium", "vitamins"];

var data = [
  {
    "cereal": "100%_Bran",
    "manufacturer": "Nabisco",
    "type": "C",
    "calories": 70,
    "protein": 4,
    "fat": 1,
    "sodium": 130,
    "fiber": 10,
    "carbs": 5,
    "sugars": 6,
    "shelf": 3,
    "potassium": 280,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.33
  },
  {
    "cereal": "100%_Natural_Bran",
    "manufacturer": "Quaker Oats",
    "type": "C",
    "calories": 120,
    "protein": 3,
    "fat": 5,
    "sodium": 15,
    "fiber": 2,
    "carbs": 8,
    "sugars": 8,
    "shelf": 3,
    "potassium": 135,
    "vitamins": 0,
    "serving size weight": 1,
    "cups per serving": -1
  },
  {
    "cereal": "All-Bran",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 70,
    "protein": 4,
    "fat": 1,
    "sodium": 260,
    "fiber": 9,
    "carbs": 7,
    "sugars": 5,
    "shelf": 3,
    "potassium": 320,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.33
  },
  {
    "cereal": "All-Bran_with_Extra_Fiber",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 50,
    "protein": 4,
    "fat": 0,
    "sodium": 140,
    "fiber": 14,
    "carbs": 8,
    "sugars": 0,
    "shelf": 3,
    "potassium": 330,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.5
  },
  {
    "cereal": "Almond_Delight",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 2,
    "sodium": 200,
    "fiber": 1,
    "carbs": 14,
    "sugars": 8,
    "shelf": 3,
    "potassium": -1,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Apple_Cinnamon_Cheerios",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 2,
    "sodium": 180,
    "fiber": 1.5,
    "carbs": 10.5,
    "sugars": 10,
    "shelf": 1,
    "potassium": 70,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Apple_Jacks",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 0,
    "sodium": 125,
    "fiber": 1,
    "carbs": 11,
    "sugars": 14,
    "shelf": 2,
    "potassium": 30,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Basic_4",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 130,
    "protein": 3,
    "fat": 2,
    "sodium": 210,
    "fiber": 2,
    "carbs": 18,
    "sugars": 8,
    "shelf": 3,
    "potassium": 100,
    "vitamins": 25,
    "serving size weight": 1.33,
    "cups per serving": 0.75
  },
  {
    "cereal": "Bran_Chex",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 90,
    "protein": 2,
    "fat": 1,
    "sodium": 200,
    "fiber": 4,
    "carbs": 15,
    "sugars": 6,
    "shelf": 1,
    "potassium": 125,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.67
  },
  {
    "cereal": "Bran_Flakes",
    "manufacturer": "Post",
    "type": "C",
    "calories": 90,
    "protein": 3,
    "fat": 0,
    "sodium": 210,
    "fiber": 5,
    "carbs": 13,
    "sugars": 5,
    "shelf": 3,
    "potassium": 190,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.67
  },
  {
    "cereal": "Cap'n'Crunch",
    "manufacturer": "Quaker Oats",
    "type": "C",
    "calories": 120,
    "protein": 1,
    "fat": 2,
    "sodium": 220,
    "fiber": 0,
    "carbs": 12,
    "sugars": 12,
    "shelf": 2,
    "potassium": 35,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Cheerios",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 6,
    "fat": 2,
    "sodium": 290,
    "fiber": 2,
    "carbs": 17,
    "sugars": 1,
    "shelf": 1,
    "potassium": 105,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1.25
  },
  {
    "cereal": "Cinnamon_Toast_Crunch",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 120,
    "protein": 1,
    "fat": 3,
    "sodium": 210,
    "fiber": 0,
    "carbs": 13,
    "sugars": 9,
    "shelf": 2,
    "potassium": 45,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Clusters",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 3,
    "fat": 2,
    "sodium": 140,
    "fiber": 2,
    "carbs": 13,
    "sugars": 7,
    "shelf": 3,
    "potassium": 105,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.5
  },
  {
    "cereal": "Cocoa_Puffs",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 180,
    "fiber": 0,
    "carbs": 12,
    "sugars": 13,
    "shelf": 2,
    "potassium": 55,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Corn_Chex",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 0,
    "sodium": 280,
    "fiber": 0,
    "carbs": 22,
    "sugars": 3,
    "shelf": 1,
    "potassium": 25,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Corn_Flakes",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 0,
    "sodium": 290,
    "fiber": 1,
    "carbs": 21,
    "sugars": 2,
    "shelf": 1,
    "potassium": 35,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Corn_Pops",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 0,
    "sodium": 90,
    "fiber": 1,
    "carbs": 13,
    "sugars": 12,
    "shelf": 2,
    "potassium": 20,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Count_Chocula",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 180,
    "fiber": 0,
    "carbs": 12,
    "sugars": 13,
    "shelf": 2,
    "potassium": 65,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Cracklin'_Oat_Bran",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 3,
    "fat": 3,
    "sodium": 140,
    "fiber": 4,
    "carbs": 10,
    "sugars": 7,
    "shelf": 3,
    "potassium": 160,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.5
  },
  {
    "cereal": "Cream_of_Wheat_(Quick)",
    "manufacturer": "Nabisco",
    "type": "H",
    "calories": 100,
    "protein": 3,
    "fat": 0,
    "sodium": 80,
    "fiber": 1,
    "carbs": 21,
    "sugars": 0,
    "shelf": 2,
    "potassium": -1,
    "vitamins": 0,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Crispix",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 0,
    "sodium": 220,
    "fiber": 1,
    "carbs": 21,
    "sugars": 3,
    "shelf": 3,
    "potassium": 30,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Crispy_Wheat_&_Raisins",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 1,
    "sodium": 140,
    "fiber": 2,
    "carbs": 11,
    "sugars": 10,
    "shelf": 3,
    "potassium": 120,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Double_Chex",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 0,
    "sodium": 190,
    "fiber": 1,
    "carbs": 18,
    "sugars": 5,
    "shelf": 3,
    "potassium": 80,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Froot_Loops",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 1,
    "sodium": 125,
    "fiber": 1,
    "carbs": 11,
    "sugars": 13,
    "shelf": 2,
    "potassium": 30,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Frosted_Flakes",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 0,
    "sodium": 200,
    "fiber": 1,
    "carbs": 14,
    "sugars": 11,
    "shelf": 1,
    "potassium": 25,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Frosted_Mini-Wheats",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 100,
    "protein": 3,
    "fat": 0,
    "sodium": 0,
    "fiber": 3,
    "carbs": 14,
    "sugars": 7,
    "shelf": 2,
    "potassium": 100,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.8
  },
  {
    "cereal": "Fruitful_Bran",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 120,
    "protein": 3,
    "fat": 0,
    "sodium": 240,
    "fiber": 5,
    "carbs": 14,
    "sugars": 12,
    "shelf": 3,
    "potassium": 190,
    "vitamins": 25,
    "serving size weight": 1.33,
    "cups per serving": 0.67
  },
  {
    "cereal": "Fruity_Pebbles",
    "manufacturer": "Post",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 135,
    "fiber": 0,
    "carbs": 13,
    "sugars": 12,
    "shelf": 2,
    "potassium": 25,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Golden_Crisp",
    "manufacturer": "Post",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 0,
    "sodium": 45,
    "fiber": 0,
    "carbs": 11,
    "sugars": 15,
    "shelf": 1,
    "potassium": 40,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.88
  },
  {
    "cereal": "Golden_Grahams",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 280,
    "fiber": 0,
    "carbs": 15,
    "sugars": 9,
    "shelf": 2,
    "potassium": 45,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Grape_Nuts_Flakes",
    "manufacturer": "Post",
    "type": "C",
    "calories": 100,
    "protein": 3,
    "fat": 1,
    "sodium": 140,
    "fiber": 3,
    "carbs": 15,
    "sugars": 5,
    "shelf": 3,
    "potassium": 85,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.88
  },
  {
    "cereal": "Grape-Nuts",
    "manufacturer": "Post",
    "type": "C",
    "calories": 110,
    "protein": 3,
    "fat": 0,
    "sodium": 170,
    "fiber": 3,
    "carbs": 17,
    "sugars": 3,
    "shelf": 3,
    "potassium": 90,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.25
  },
  {
    "cereal": "Great_Grains_Pecan",
    "manufacturer": "Post",
    "type": "C",
    "calories": 120,
    "protein": 3,
    "fat": 3,
    "sodium": 75,
    "fiber": 3,
    "carbs": 13,
    "sugars": 4,
    "shelf": 3,
    "potassium": 100,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.33
  },
  {
    "cereal": "Wheaties_Honey_Gold",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 1,
    "sodium": 200,
    "fiber": 1,
    "carbs": 16,
    "sugars": 8,
    "shelf": 1,
    "potassium": 60,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  }
];

                var cerealMap = {};
                data.forEach(function(d) {
                    var cereal = d.cereal;
                    cerealMap[cereal] = [];

                    // { cerealName: [ bar1Val, bar2Val, ... ] }
                    nutritionFields.forEach(function(field) {
                        cerealMap[cereal].push( +d[field] );
                    });
                });
                
      

            var makeVis = function(cerealMap) {
                // Define dimensions of vis
                var margin = { top: 30, right: 50, bottom: 30, left: 50 },
                    width  = 550 - margin.left - margin.right,
                    height = 250 - margin.top  - margin.bottom;

                // Make x scale
                var xScale = d3.scale.ordinal()
                    .domain(nutritionFields)
                    .rangeRoundBands([0, width], 0.1);

                // Make y scale, the domain will be defined on bar update
                var yScale = d3.scale.linear()
                    .range([height, 0]);

                // Create canvas
                var canvas = d3.select("#dropdown")
                .append("svg")
                .attr("width","100%")
                .attr("height","100%")
                .attr("viewBox","0 0 "+
                    (width+margin.left+margin.right)+
                    " "+
                    (height+margin.top+margin.bottom) )
                .append("g")
                .attr("transform","translate("+
                    margin.left+","+margin.top+")");

                // Make x-axis and add to canvas
                var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .orient("bottom");

                canvas.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);

                // Make y-axis and add to canvas
                var yAxis = d3.svg.axis()
                    .scale(yScale)
                    .orient("left");

                var yAxisHandleForUpdate = canvas.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);

                yAxisHandleForUpdate.append("text")
                    .attr("transform", "rotate(-90)")
                    .attr("y", 6)
                    .attr("dy", ".71em")
                    .style("text-anchor", "end")
                    .text("Value");

                var updateBars = function(data) {
                    // First update the y-axis domain to match data
                    yScale.domain( d3.extent(data) );
                    yAxisHandleForUpdate.call(yAxis);

                    var bars = canvas.selectAll(".bar").data(data);

                    // Add bars for new data
                    bars.enter()
                      .append("rect")
                        .attr("class", "bar")
                        .attr("x", function(d,i) { return xScale( nutritionFields[i] ); })
                        .attr("width", xScale.rangeBand())
                        .attr("y", function(d,i) { return yScale(d); })
                        .attr("height", function(d,i) { return height - yScale(d); });

                    // Update old ones, already have x / width from before
                    bars
                        .transition().duration(250)
                        .attr("y", function(d,i) { return yScale(d); })
                        .attr("height", function(d,i) { return height - yScale(d); });

                    // Remove old ones
                    bars.exit().remove();
                };

                // Handler for dropdown value change
                var dropdownChange = function() {
                    var newCereal = d3.select(this).property('value'),
                        newData   = cerealMap[newCereal];

                    updateBars(newData);
                };

                // Get names of cereals, for dropdown
                var cereals = Object.keys(cerealMap).sort();

                var dropdown = d3.select("#vis-container")
                    .insert("select", "svg")
                    .on("change", dropdownChange);

                dropdown.selectAll("option")
                    .data(cereals)
                  .enter().append("option")
                    .attr("value", function (d) { return d; })
                    .text(function (d) {
                        return d[0].toUpperCase() + d.slice(1,d.length); // capitalize 1st letter
                    });

                var initialData = cerealMap[ cereals[0] ];
                updateBars(initialData);
            };
            
            makeVis(cerealMap);
.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row wrap;
  justify-content: space-around;
}

.flex-item1 {
  background: #f1f1f1;
  width: 33%;
  height: auto;
  margin-top: 10px;
  font-weight: bold;
  text-align: center;
}


.flex-item2 {
  width: 67%;
  height: auto;
  margin-top: 10px;
  font-weight: bold;
  text-align: center;
}


body {
            font: 10px sans-serif;
        }
        select {
            display: block;
        }
        .bar {
            fill: purple;
            opacity: 0.8;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: #000;
            shape-rendering: crispEdges;
        }
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>




<ul class="flex-container">
   <li class="flex-item1"><div id='vis-container'></div></li>
   <li class="flex-item2" id="dropdown"></li>
</ul>

标签: javascriptcssd3.js

解决方案


如果你想使用列表而不是下拉列表,在相关代码中替换是相当容易的:

select通过将for anuloptions换成 s 来创建一个列表而不是 select 元素li

            var dropdown = d3.select("#vis-container")
                .insert("ul", "svg")
                .classed('selector', true);


            dropdown.selectAll("li")
                .data(cereals)
              .enter().append("li")
                .attr("id", function (d) { return d.cereal; }) 
                .text(function (d) {
                    return d[0].toUpperCase() + d.replace(/_/g, ' ').slice(1,d.length); // capitalize 1st letter
                })
                .on("click", dropdownChange); // add click event listener to each list element

事件处理函数将自动获取附加到每个项目的数据,因此只需dropdownChange稍微更改函数即可:

var dropdownChange = function(d) {
  var newData   = cerealMap[d];
  updateBars(newData);
};

完整示例:

var nutritionFields = ["calories", "protein", "fat", "sodium", "fiber",
                                   "carbs", "sugars", "potassium", "vitamins"];

var data = [
  {
    "cereal": "100%_Bran",
    "manufacturer": "Nabisco",
    "type": "C",
    "calories": 70,
    "protein": 4,
    "fat": 1,
    "sodium": 130,
    "fiber": 10,
    "carbs": 5,
    "sugars": 6,
    "shelf": 3,
    "potassium": 280,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.33
  },
  {
    "cereal": "100%_Natural_Bran",
    "manufacturer": "Quaker Oats",
    "type": "C",
    "calories": 120,
    "protein": 3,
    "fat": 5,
    "sodium": 15,
    "fiber": 2,
    "carbs": 8,
    "sugars": 8,
    "shelf": 3,
    "potassium": 135,
    "vitamins": 0,
    "serving size weight": 1,
    "cups per serving": -1
  },
  {
    "cereal": "All-Bran",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 70,
    "protein": 4,
    "fat": 1,
    "sodium": 260,
    "fiber": 9,
    "carbs": 7,
    "sugars": 5,
    "shelf": 3,
    "potassium": 320,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.33
  },
  {
    "cereal": "All-Bran_with_Extra_Fiber",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 50,
    "protein": 4,
    "fat": 0,
    "sodium": 140,
    "fiber": 14,
    "carbs": 8,
    "sugars": 0,
    "shelf": 3,
    "potassium": 330,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.5
  },
  {
    "cereal": "Almond_Delight",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 2,
    "sodium": 200,
    "fiber": 1,
    "carbs": 14,
    "sugars": 8,
    "shelf": 3,
    "potassium": -1,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Apple_Cinnamon_Cheerios",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 2,
    "sodium": 180,
    "fiber": 1.5,
    "carbs": 10.5,
    "sugars": 10,
    "shelf": 1,
    "potassium": 70,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Apple_Jacks",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 0,
    "sodium": 125,
    "fiber": 1,
    "carbs": 11,
    "sugars": 14,
    "shelf": 2,
    "potassium": 30,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Basic_4",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 130,
    "protein": 3,
    "fat": 2,
    "sodium": 210,
    "fiber": 2,
    "carbs": 18,
    "sugars": 8,
    "shelf": 3,
    "potassium": 100,
    "vitamins": 25,
    "serving size weight": 1.33,
    "cups per serving": 0.75
  },
  {
    "cereal": "Bran_Chex",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 90,
    "protein": 2,
    "fat": 1,
    "sodium": 200,
    "fiber": 4,
    "carbs": 15,
    "sugars": 6,
    "shelf": 1,
    "potassium": 125,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.67
  },
  {
    "cereal": "Bran_Flakes",
    "manufacturer": "Post",
    "type": "C",
    "calories": 90,
    "protein": 3,
    "fat": 0,
    "sodium": 210,
    "fiber": 5,
    "carbs": 13,
    "sugars": 5,
    "shelf": 3,
    "potassium": 190,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.67
  },
  {
    "cereal": "Cap'n'Crunch",
    "manufacturer": "Quaker Oats",
    "type": "C",
    "calories": 120,
    "protein": 1,
    "fat": 2,
    "sodium": 220,
    "fiber": 0,
    "carbs": 12,
    "sugars": 12,
    "shelf": 2,
    "potassium": 35,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Cheerios",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 6,
    "fat": 2,
    "sodium": 290,
    "fiber": 2,
    "carbs": 17,
    "sugars": 1,
    "shelf": 1,
    "potassium": 105,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1.25
  },
  {
    "cereal": "Cinnamon_Toast_Crunch",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 120,
    "protein": 1,
    "fat": 3,
    "sodium": 210,
    "fiber": 0,
    "carbs": 13,
    "sugars": 9,
    "shelf": 2,
    "potassium": 45,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Clusters",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 3,
    "fat": 2,
    "sodium": 140,
    "fiber": 2,
    "carbs": 13,
    "sugars": 7,
    "shelf": 3,
    "potassium": 105,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.5
  },
  {
    "cereal": "Cocoa_Puffs",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 180,
    "fiber": 0,
    "carbs": 12,
    "sugars": 13,
    "shelf": 2,
    "potassium": 55,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Corn_Chex",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 0,
    "sodium": 280,
    "fiber": 0,
    "carbs": 22,
    "sugars": 3,
    "shelf": 1,
    "potassium": 25,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Corn_Flakes",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 0,
    "sodium": 290,
    "fiber": 1,
    "carbs": 21,
    "sugars": 2,
    "shelf": 1,
    "potassium": 35,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Corn_Pops",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 0,
    "sodium": 90,
    "fiber": 1,
    "carbs": 13,
    "sugars": 12,
    "shelf": 2,
    "potassium": 20,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Count_Chocula",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 180,
    "fiber": 0,
    "carbs": 12,
    "sugars": 13,
    "shelf": 2,
    "potassium": 65,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Cracklin'_Oat_Bran",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 3,
    "fat": 3,
    "sodium": 140,
    "fiber": 4,
    "carbs": 10,
    "sugars": 7,
    "shelf": 3,
    "potassium": 160,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.5
  },
  {
    "cereal": "Cream_of_Wheat_(Quick)",
    "manufacturer": "Nabisco",
    "type": "H",
    "calories": 100,
    "protein": 3,
    "fat": 0,
    "sodium": 80,
    "fiber": 1,
    "carbs": 21,
    "sugars": 0,
    "shelf": 2,
    "potassium": -1,
    "vitamins": 0,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Crispix",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 0,
    "sodium": 220,
    "fiber": 1,
    "carbs": 21,
    "sugars": 3,
    "shelf": 3,
    "potassium": 30,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Crispy_Wheat_&_Raisins",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 1,
    "sodium": 140,
    "fiber": 2,
    "carbs": 11,
    "sugars": 10,
    "shelf": 3,
    "potassium": 120,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Double_Chex",
    "manufacturer": "Ralston Purina",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 0,
    "sodium": 190,
    "fiber": 1,
    "carbs": 18,
    "sugars": 5,
    "shelf": 3,
    "potassium": 80,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Froot_Loops",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 1,
    "sodium": 125,
    "fiber": 1,
    "carbs": 11,
    "sugars": 13,
    "shelf": 2,
    "potassium": 30,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 1
  },
  {
    "cereal": "Frosted_Flakes",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 0,
    "sodium": 200,
    "fiber": 1,
    "carbs": 14,
    "sugars": 11,
    "shelf": 1,
    "potassium": 25,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Frosted_Mini-Wheats",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 100,
    "protein": 3,
    "fat": 0,
    "sodium": 0,
    "fiber": 3,
    "carbs": 14,
    "sugars": 7,
    "shelf": 2,
    "potassium": 100,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.8
  },
  {
    "cereal": "Fruitful_Bran",
    "manufacturer": "Kelloggs",
    "type": "C",
    "calories": 120,
    "protein": 3,
    "fat": 0,
    "sodium": 240,
    "fiber": 5,
    "carbs": 14,
    "sugars": 12,
    "shelf": 3,
    "potassium": 190,
    "vitamins": 25,
    "serving size weight": 1.33,
    "cups per serving": 0.67
  },
  {
    "cereal": "Fruity_Pebbles",
    "manufacturer": "Post",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 135,
    "fiber": 0,
    "carbs": 13,
    "sugars": 12,
    "shelf": 2,
    "potassium": 25,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Golden_Crisp",
    "manufacturer": "Post",
    "type": "C",
    "calories": 100,
    "protein": 2,
    "fat": 0,
    "sodium": 45,
    "fiber": 0,
    "carbs": 11,
    "sugars": 15,
    "shelf": 1,
    "potassium": 40,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.88
  },
  {
    "cereal": "Golden_Grahams",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 1,
    "fat": 1,
    "sodium": 280,
    "fiber": 0,
    "carbs": 15,
    "sugars": 9,
    "shelf": 2,
    "potassium": 45,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  },
  {
    "cereal": "Grape_Nuts_Flakes",
    "manufacturer": "Post",
    "type": "C",
    "calories": 100,
    "protein": 3,
    "fat": 1,
    "sodium": 140,
    "fiber": 3,
    "carbs": 15,
    "sugars": 5,
    "shelf": 3,
    "potassium": 85,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.88
  },
  {
    "cereal": "Grape-Nuts",
    "manufacturer": "Post",
    "type": "C",
    "calories": 110,
    "protein": 3,
    "fat": 0,
    "sodium": 170,
    "fiber": 3,
    "carbs": 17,
    "sugars": 3,
    "shelf": 3,
    "potassium": 90,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.25
  },
  {
    "cereal": "Great_Grains_Pecan",
    "manufacturer": "Post",
    "type": "C",
    "calories": 120,
    "protein": 3,
    "fat": 3,
    "sodium": 75,
    "fiber": 3,
    "carbs": 13,
    "sugars": 4,
    "shelf": 3,
    "potassium": 100,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.33
  },
  {
    "cereal": "Wheaties_Honey_Gold",
    "manufacturer": "General Mills",
    "type": "C",
    "calories": 110,
    "protein": 2,
    "fat": 1,
    "sodium": 200,
    "fiber": 1,
    "carbs": 16,
    "sugars": 8,
    "shelf": 1,
    "potassium": 60,
    "vitamins": 25,
    "serving size weight": 1,
    "cups per serving": 0.75
  }
];

                var cerealMap = {};
                data.forEach(function(d) {
                    var cereal = d.cereal;
                    cerealMap[cereal] = [];

                    // { cerealName: [ bar1Val, bar2Val, ... ] }
                    nutritionFields.forEach(function(field) {
                        cerealMap[cereal].push( +d[field] );
                    });
                });
                
      

            var makeVis = function(cerealMap) {
                // Define dimensions of vis
                var margin = { top: 30, right: 50, bottom: 30, left: 50 },
                    width  = 550 - margin.left - margin.right,
                    height = 250 - margin.top  - margin.bottom;

                // Make x scale
                var xScale = d3.scale.ordinal()
                    .domain(nutritionFields)
                    .rangeRoundBands([0, width], 0.1);

                // Make y scale, the domain will be defined on bar update
                var yScale = d3.scale.linear()
                    .range([height, 0]);

                // Create canvas
                var canvas = d3.select("#dropdown")
                .append("svg")
                .attr("width","100%")
                .attr("height","100%")
                .attr("viewBox","0 0 "+
                    (width+margin.left+margin.right)+
                    " "+
                    (height+margin.top+margin.bottom) )
                .append("g")
                .attr("transform","translate("+
                    margin.left+","+margin.top+")");

                // Make x-axis and add to canvas
                var xAxis = d3.svg.axis()
                    .scale(xScale)
                    .orient("bottom");

                canvas.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);

                // Make y-axis and add to canvas
                var yAxis = d3.svg.axis()
                    .scale(yScale)
                    .orient("left");

                var yAxisHandleForUpdate = canvas.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);

                yAxisHandleForUpdate.append("text")
                    .attr("transform", "rotate(-90)")
                    .attr("y", 6)
                    .attr("dy", ".71em")
                    .style("text-anchor", "end")
                    .text("Value");

                var updateBars = function(data) {
                    // First update the y-axis domain to match data
                    yScale.domain( d3.extent(data) );
                    yAxisHandleForUpdate.call(yAxis);

                    var bars = canvas.selectAll(".bar").data(data);

                    // Add bars for new data
                    bars.enter()
                      .append("rect")
                        .attr("class", "bar")
                        .attr("x", function(d,i) { return xScale( nutritionFields[i] ); })
                        .attr("width", xScale.rangeBand())
                        .attr("y", function(d,i) { return yScale(d); })
                        .attr("height", function(d,i) { return height - yScale(d); });

                    // Update old ones, already have x / width from before
                    bars
                        .transition().duration(250)
                        .attr("y", function(d,i) { return yScale(d); })
                        .attr("height", function(d,i) { return height - yScale(d); });

                    // Remove old ones
                    bars.exit().remove();
                };

                // Handler for dropdown value change
                var dropdownChange = function(d) {
                    var newData   = cerealMap[d];
                    updateBars(newData);
                };

                // Get names of cereals, for dropdown
                var cereals = Object.keys(cerealMap).sort();

                var dropdown = d3.select("#vis-container")
                    .insert("ul", "svg")
                    .classed('selector', true);
                    

                dropdown.selectAll("li")
                    .data(cereals)
                  .enter().append("li")
                    .attr("id", function (d) { return d.cereal; })
                    .text(function (d) {
                        return d[0].toUpperCase() + d.replace(/_/g, ' ').slice(1,d.length); // capitalize 1st letter
                    })
                    .on("click", dropdownChange);

                var initialData = cerealMap[ cereals[0] ];
                updateBars(initialData);
            };
            
            makeVis(cerealMap);
.flex-container {
  padding: 0;
  margin: 0;
  list-style: none;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row wrap;
  justify-content: space-around;
}

.flex-item1 {
  background: #f1f1f1;
  width: 33%;
  height: auto;
  margin-top: 10px;
  font-weight: bold;
  text-align: center;
}


.flex-item2 {
  width: 67%;
  height: auto;
  margin-top: 10px;
  font-weight: bold;
  text-align: center;
}


body {
            font: 10px sans-serif;
        }
        select {
            display: block;
        }
        .bar {
            fill: purple;
            opacity: 0.8;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: #000;
            shape-rendering: crispEdges;
        }
        ul.selector {
          text-align: left;
        }
        .selector li {
          cursor: pointer;
         }
         .selector li:hover, .selector li:focus, .selector li:active {
          color: red;
         }
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>




<ul class="flex-container">
   <li class="flex-item1"><div id='vis-container'></div></li>
   <li class="flex-item2" id="dropdown"></li>
</ul>


推荐阅读