代码之家  ›  专栏  ›  技术社区  ›  Datacrawler

用D3/JavaScript更改所选li选项的颜色

  •  4
  • Datacrawler  · 技术社区  · 7 年前

    我正在使用D3.js创建一个惟一值列表(来自一个JSON查询),我想更改所选li的文本颜色。在代码段下面给出了执行该操作的函数。我的问题是,当我单击列表中的另一个值时,颜色不会重置。

    //JSON Data
    const data = [
    {
        "date": "2008-11",
        "Value": "A",
        "num": 7.8
      },
      {
        "date": "2007-11",
        "Value": "B",
        "num": 7.8
      }
    ];
    
    //Parses date for correct time format
    var parseDate = d3.time.format("%Y-%m").parse;
    
    //Format data for the filter list (or dropdown) function
    function formatData(data) {
    
      var valueMap = {}; 
      var mainFields = ["date", "num"]; 
      data.forEach(function(d) {
        d.num = +d.num;
    
        var Value = d.Value; 
        valueMap[Value] = []; 
        mainFields.forEach(function(field) { 
          valueMap[Value].push(d[field]); 
        }); 
      });
    
      return valueMap;
    }
    
    //Dropdown creation function
    function dropDown() {
    
      // Handler for dropdown value change
      const valueMap = formatData(data);
      var dropdownChange = function(d) {
      
        d3.select("svg").remove();
        const newData = data.filter(function(item){
       			return item.Value == d;
      	});
        
        //Changes text color for the selected li option
        d3.select(this).style("color", "#c7003b");
     
      };
    
      // Get names of Values, for dropdown 
      var campaigns = Object.keys(valueMap).sort(); 
    
      var dropdown = d3.select("#dropdown") 
        .insert("ul", "svg") 
        .classed('selector', true) 
    
    
      dropdown.selectAll("li") 
        .data(campaigns) 
        .enter().append("li") 
         .attr("id", (function(d) { 
          return d[0].toUpperCase() + d.replace(/_/g, ' ').slice(1, d.length); 
        }))
        .text(function(d) { 
          return d[0].toUpperCase() + d.replace(/_/g, ' ').slice(1, d.length); 
        }) 
        .on("click", dropdownChange);
        
    
    
      var initialData = valueMap[campaigns[0]]; 
    
      
    }
    
    
    dropDown();
    /*css to go here*/
    
      body {
        font-family: 'Proxima-Nova', sans-serif;
        font-size: 12px;
      }
    
      .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 {
        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;
      }
    
      .g-hed {
        text-align: left;
        text-transform: uppercase;
        font-weight: bold;
        font-size: 22px;
        margin: 3px 0;
      }
    
      .g-source-bold {
        text-align: left;
        font-size: 10px;
        font-weight: bold;
      }
    
      .g-source {
        margin: 10px 0;
      }
    
      .g-source-bold {
        text-align: left;
        font-size: 10px;
      }
    
      .g-intro {
        font-size: 16px;
        margin: 0px 0px 10px 0px;
      }
    
      .g-labels {
        font-family: 'Proxima-Nova', sans-serif;
        fill: white;
        font-weight: bold;
        font-size: 14px;
      }
      .g-chart {
          height: 100%;
      }
      .g-chart svg {
        width: 100%;
        height: 100%;
      }
    
      .axis line {
        fill: none;
        stroke: #ccc;
        stroke-dasharray: 2px 3px;
        shape-rendering: crispEdges;
        stroke-width: 1px;
      }
    
      .axis text {
        font-family: 'Proxima-Nova', sans-serif;
        font-size: 13px;
        pointer-events: none;
        fill: #7e7e7e;
      }
    
      .y.axis text {
        text-anchor: end !important;
        font-size: 14px;
        fill: #7e7e7e;
      }
    
      .domain {
        display: none;
      }
    
      .line {
        stroke: #2f5491;
        stroke-width: 3px;
        fill: none;
      }
    
      .overlay {
        fill: none;
        pointer-events: all;
      }
    
      .focus {
        font-size: 14px;
      }
    
      .focus circle {
        fill: #5e8dc9;
      }
    
      ul {
        padding: 0;
        list-style-type: none;
      }
    
      .selector li {
      padding: 20px 0 20px 0;
    	border-top: 1px solid #ffffff;
    	border-bottom:3px solid #e0e0e0;
    	background: #fff;
     
      }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
    <script src="https://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
    
    
    <ul class="flex-container">
      <li class="flex-item1">
        <div id="dropdown"></div>
      </li>
      <li class="flex-item2">
    
        <h5 class="g-hed"></h5>
        <p class="g-intro"></p>
        <div class="g-chart"></div>
        <div class="g-source"><span class="g-source-bold"></span><span class="g-source-reg"></span>
        </div>
    
      </li>
    </ul>

      var dropdownChange = function(d) {
    
        d3.select("svg").remove();
        const newData = data.filter(function(item){
                return item.Value == d;
        });
    
        //Changes text color for the selected li option
        d3.select(this).style("color", "#c7003b");
    
      };
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   i alarmed alien    7 年前

    style 属性,最好对元素应用css类;然后,您就可以轻松地更改“活动”元素的显示方式,而无需深入研究JS代码。

    假设您要添加一个类 active 到当前选定的元素。

    当你激活 dropdownChange ,您要删除任何现有的 积极的 类和添加 触发的元素 . 很高兴, this 设置为触发事件的元素,因此您可以轻松地从那里开始工作:

    // get the parent ul element, remove the `active` class from all children
    this.parentNode.childNodes.forEach( (e) => {
      e.classList.remove('active');
    } );
    // add `active` to the element that triggered the function
    this.classList.add('active');
    

    //JSON Data
    const data = [{
        "date": "2008-11",
        "Value": "A",
        "num": 7.8
      },
      {
        "date": "2007-11",
        "Value": "B",
        "num": 7.8
      }
    ];
    
    //Parses date for correct time format
    var parseDate = d3.time.format("%Y-%m").parse;
    
    //Format data for the filter list (or dropdown) function
    function formatData(data) {
    
      var valueMap = {};
      var mainFields = ["date", "num"];
      data.forEach(function(d) {
        d.num = +d.num;
    
        var Value = d.Value;
        valueMap[Value] = [];
        mainFields.forEach(function(field) {
          valueMap[Value].push(d[field]);
        });
      });
    
      return valueMap;
    }
    
    //Dropdown creation function
    function dropDown() {
    
      // Handler for dropdown value change
      const valueMap = formatData(data);
      var dropdownChange = function(d) {
    
        d3.select("svg").remove();
        const newData = data.filter(function(item) {
          return item.Value == d;
        });
    
        // get the parent ul element, remove `active` class from children
        this.parentNode.childNodes.forEach( (e) => {
          e.classList.remove('active');
        } );
        // mark this node as active
        this.classList.add('active');
    
      };
    
      // Get names of Values, for dropdown 
      var campaigns = Object.keys(valueMap).sort();
    
      var dropdown = d3.select("#dropdown")
        .insert("ul", "svg")
        .classed('selector', true)
    
    
      dropdown.selectAll("li")
        .data(campaigns)
        .enter().append("li")
        .attr("id", (function(d) {
          return d[0].toUpperCase() + d.replace(/_/g, ' ').slice(1, d.length);
        }))
        .text(function(d) {
          return d[0].toUpperCase() + d.replace(/_/g, ' ').slice(1, d.length);
        })
        .on("click", dropdownChange);
    
    
    
      var initialData = valueMap[campaigns[0]];
    
    
    }
    
    
    dropDown();
    /*css to go here*/
    
    body {
      font-family: 'Proxima-Nova', sans-serif;
      font-size: 12px;
    }
    
    .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 {
      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;
    }
    
    .g-hed {
      text-align: left;
      text-transform: uppercase;
      font-weight: bold;
      font-size: 22px;
      margin: 3px 0;
    }
    
    .g-source-bold {
      text-align: left;
      font-size: 10px;
      font-weight: bold;
    }
    
    .g-source {
      margin: 10px 0;
    }
    
    .g-source-bold {
      text-align: left;
      font-size: 10px;
    }
    
    .g-intro {
      font-size: 16px;
      margin: 0px 0px 10px 0px;
    }
    
    .g-labels {
      font-family: 'Proxima-Nova', sans-serif;
      fill: white;
      font-weight: bold;
      font-size: 14px;
    }
    
    .g-chart {
      height: 100%;
    }
    
    .g-chart svg {
      width: 100%;
      height: 100%;
    }
    
    .axis line {
      fill: none;
      stroke: #ccc;
      stroke-dasharray: 2px 3px;
      shape-rendering: crispEdges;
      stroke-width: 1px;
    }
    
    .axis text {
      font-family: 'Proxima-Nova', sans-serif;
      font-size: 13px;
      pointer-events: none;
      fill: #7e7e7e;
    }
    
    .y.axis text {
      text-anchor: end !important;
      font-size: 14px;
      fill: #7e7e7e;
    }
    
    .domain {
      display: none;
    }
    
    .line {
      stroke: #2f5491;
      stroke-width: 3px;
      fill: none;
    }
    
    .overlay {
      fill: none;
      pointer-events: all;
    }
    
    .focus {
      font-size: 14px;
    }
    
    .focus circle {
      fill: #5e8dc9;
    }
    
    ul {
      padding: 0;
      list-style-type: none;
    }
    
    .selector li {
      padding: 20px 0 20px 0;
      border-top: 1px solid #ffffff;
      border-bottom: 3px solid #e0e0e0;
      background: #fff;
    }
    .active {
      color: #c7003b
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
    <script src="https://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
    
    
    <ul class="flex-container">
      <li class="flex-item1">
        <div id="dropdown"></div>
      </li>
      <li class="flex-item2">
    
        <h5 class="g-hed"></h5>
        <p class="g-intro"></p>
        <div class="g-chart"></div>
        <div class="g-source"><span class="g-source-bold"></span><span class="g-source-reg"></span>
        </div>
    
      </li>
    </ul>