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

时间:2018-10-11 10:44:29

标签: javascript css d3.js

我正在使用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>

必须更改的功能。我需要重置每次点击时都猜到的CSS,然后再次为所选li更改颜色:

  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 个答案:

答案 0 :(得分:1)

与其使用style属性内联应用CSS,不如将CSS类应用于元素;然后,您可以轻松更改显示“活动”元素的方式,而无需深入研究JS代码。

假设您要向当前选择的元素中添加类active

激活dropdownChange时,要删除任何现有的active类,并添加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>