简体   繁体   中英

How to change color scheme?

I have a piechart and two links. I want to change pie chart color scheme with click on a link. I tried to use IF condition (if link has class 'active', scheme has to change), but it doesn't work.
Any help are appreciated.
My code:

const width = 480
const height = 480

const chart = document.querySelector(".result")
const input = document.querySelectorAll(".input-block__item");
const inputBlock = document.querySelector(".input-block");
const filtersBtn = document.querySelectorAll(".filters__item");
const colorDefault = d3.scaleOrdinal(d3.schemeSet3); 
const colorHaiku = d3.scaleOrdinal(['#756f25', '#c7c15d', '#00473f', '#237782', '#349085', '#98baa1', '#206284', '#517c82', '#2f94c6', '#00a6bc'])
const colorSet = [colorDefault, colorHaiku];
let data = [1,2,3,4,5];




function piechart() {
  var radius = Math.min(width, height) / 2;
  var arc = d3.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

  var pie = d3.pie()
      .sort(null)
      .value(function(d,i) { return d; });

  var svg = d3.select(".result__output-chart").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  // join
  var block = svg.selectAll(".arc")
      .data(pie(data));

  // enter
  block.enter()
      .append("g")
      .attr("class", "arc")
      .append("path")
      .attr("d", arc)
      .style("fill", function(d,i) { 
        var btn1 = document.querySelector(".filters__item--1")
        var btn2 = document.querySelector(".filters__item--2")
        if(btn1.classList.contains(".active")) {
          return colorSet[1](i);  
        } else {
          return colorSet[0](i);
        }         
  }); 
}

 //remove active class from all links
 function removeActive() {
   filtersBtn.forEach(function(item) {
     item.classList.remove('active')
   })
 }

 //add active class to the clicked link
 filtersBtn.forEach(function(item) {
    item.addEventListener('click', function() {
     removeActive();
     this.classList.add('active')
   })
 })

 piechart()

Link to codepen: https://codepen.io/AlxFedorov/pen/YLBdzr

Your event listener is simply changing the classes of the "buttons", nothing else. The enter selection only looks for those classes when the arcs are painted for the first time.

This can be way more simple. For instance:

filtersBtn.on("click", function(_,i){
  d3.selectAll(".arc path").style("fill", function(_,j){
    return colorSet[i](j)
  })
});

Here is the code with that change:

 const width = 480 const height = 480 const chart = document.querySelector(".result") const input = document.querySelectorAll(".input-block__item"); const inputBlock = document.querySelector(".input-block"); const filtersBtn = d3.selectAll(".filters__item"); const colorDefault = d3.scaleOrdinal(d3.schemeSet3); const colorHaiku = d3.scaleOrdinal(['#756f25', '#c7c15d', '#00473f', '#237782', '#349085', '#98baa1', '#206284', '#517c82', '#2f94c6', '#00a6bc']) const colorSet = [colorDefault, colorHaiku]; let data = [1, 2, 3, 4, 5]; function piechart() { var radius = Math.min(width, height) / 2; var arc = d3.arc() .outerRadius(radius - 10) .innerRadius(0); var pie = d3.pie() .sort(null) .value(function(d, i) { return d; }); var svg = d3.select(".result__output-chart").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // join var block = svg.selectAll(".arc") .data(pie(data)); // enter block.enter() .append("g") .attr("class", "arc") .append("path") .attr("d", arc) .style("fill", function(d, i) { var btn1 = document.querySelector(".filters__item--1") var btn2 = document.querySelector(".filters__item--2") if (btn1.classList.contains(".active")) { return colorSet[1](i); } else { return colorSet[0](i); } }); } filtersBtn.on("click", function(_, i) { d3.selectAll(".arc path").style("fill", function(_, j) { return colorSet[i](j) }) }); piechart() 
 * { box-sizing: border-box; margin: 0; padding: 0; } body { min-width: 320px; margin: 0; } .active { background: green; } .container { max-width: 1200px; margin: 0 auto; padding-left: 15px; padding-right: 15px; padding-bottom: 10px; padding-top: 10px; } .chart { &__container { display: flex; flex-direction: row; justify-content: space-between; } } .filters { margin-top: 20px; &__items-block { display: flex; flex-direction: space-around; width: 100%; margin-left: -10px; margin-right: -10px; } &__item { flex: 1; margin-left: 10px; margin-right: 10px; display: block; background-color: #dcdee2; } } .result { background-color: #fff; flex: 5; padding-right: 15px; padding-left: 15px; padding-top: 15px; padding-bottom: 15px; &__output { background-color: #fff; } &__output-chart { flex: 3; } &__legend { flex: 2; } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script> <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> <main> <section class="chart"> <div class="chart__container container" id="container"> <div class="input-block"> <div class="input-block__names-block filters"> <h4 class="input-block__title">Colors</h2> <div class="filters__items-block"> <a href="#" class="filters__item filters__item--1 active">1</a> <a href="#" class="filters__item filters__item--2">2</a> </div> </div> </div> <div class="result" id="result"> <div class="result__output" id="result__output"> <h3 class="result__output-title"></h3> <div class="result__chart-legend-block"> <div class="result__output-chart"></div> <div class="result__legend legend"> <div class="legend__item"> <span class="legend__item-color legend__item-color--1"></span> <p class="legend__item-name legend__item-name--1"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--2"></span> <p class="legend__item-name legend__item-name--2"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--3"></span> <p class="legend__item-name legend__item-name--3"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--4"></span> <p class="legend__item-name legend__item-name--4"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--5"></span> <p class="legend__item-name legend__item-name--5"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--6"></span> <p class="legend__item-name legend__item-name--6"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--7"></span> <p class="legend__item-name legend__item-name--7"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--8"></span> <p class="legend__item-name legend__item-name--8"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--9"></span> <p class="legend__item-name legend__item-name--9"></p> </div> <div class="legend__item"> <span class="legend__item-color legend__item-color--10"></span> <p class="legend__item-name legend__item-name--10"></p> </div> </div> </div> </div> </div> </div> </section> </main> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM