RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 962939
Accepted
Aleksandr Krais
Aleksandr Krais
Asked:2020-03-29 17:17:26 +0000 UTC2020-03-29 17:17:26 +0000 UTC 2020-03-29 17:17:26 +0000 UTC

如何使饼图依赖于复选框?

  • 772

有必要根据选中的复选框填充图表。我怎样才能做到这一点?

在此处输入图像描述

javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Stranger in the Q
    2020-03-29T19:02:58Z2020-03-29T19:02:58Z

    UPD:带有圆形扇区的版本可能如下所示

    在此处输入图像描述

    svg我在+上编译了一个示例d3.js,为了生成svg路径d3,有一个模块d3-shape,它具有各种形状的生成器,包括d3.pie()和d3.arc(),此示例依次组装。

    所有转换都是使用d3.interpoalte()计算的,它知道如何插入颜色、字符串、对象 =)

    UPD:完成签名行的初始动画

    代码中更详细的注释

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    
    <span id="checkboxes">
      <label><input type="checkbox" val="111" checked></label>
      <label><input type="checkbox" val="222"></label>
      <label><input type="checkbox" val="333" checked></label>
      <label><input type="checkbox" val="444"></label>
      <label><input type="checkbox" val="555" checked></label>
    </span>
    
    <span id="donut"></span>
    
    <script>
      let rawData = [...document.querySelectorAll('#checkboxes input')].map(cb => 
         ({ value: +cb.getAttribute('val'), selected: cb.checked }));
    
      // базовый размер и время анимации
      let size = 175, time = 500; 
      
      // цветовая шкала 
      // (функция которая принимает на вход число и возвращает цвет, тут их 10)
      let colors = d3.scaleOrdinal(d3.schemeCategory10);
    
      // чекбоксы
      d3.select('#checkboxes').selectAll('label').data(rawData)
        .style('background-color', (d, i) => colors(i))
        
      d3.select('#checkboxes').selectAll('input').data(rawData)  
        .on("change", function (d) { 
          update(d.selected = this.checked); 
        });
    
      // добавим svg
      let svg = d3.select('#donut').append("svg").attr("height", size)
                  .attr("viewBox", `-${size} -${size/2} ${size*2} ${size}`);
    
      // инициализируем генератор данных для передачи в генератор arc()
      let pie = d3.pie().value(d => d.selected ? d.value : 0).sort(null);
    
      let pieData = pie(rawData);
    
      // инициализируем генератор дуг для секторов
      let arc = d3.arc().innerRadius(size/3.1-30).outerRadius(size/3.1);
    
      // инициализируем генератор дуг для подсчета линий подписей
      let arc2 = d3.arc().innerRadius(size/2.7).outerRadius(size/2.7);
    
      // инициализируем генератор дуг для подсчета центров текста подписей
      let arc3 = d3.arc().innerRadius(size/2.2).outerRadius(size/2.2);
    
      // инициализируем генератор линий
      let line = d3.line();
    
      // создаем выборку (групп) элементов и привязываем к ней данные
      let groups = svg.selectAll("g").data(rawData)
                      .enter().append("g").attr('opacity', (d,i) => pieData[i].value);
    
      // добавляем пути для секторов в группы, 
      // данные привязанные к группам тут нам достаются по наследству
      let sectors = groups.data(pieData).append("path").classed("sector", true)
                          .attr("fill", (d, i) => colors(i));
    
      // пути для линий подписей
      let titlesPaths = groups.data(pieData).append("path").classed("label", true);
    
      // тексты подписей
      let titlesTexts = groups.data(pieData).append("text")
                              .text((d,i) => rawData[i].value);
    
      // текст в центре 
      let totalText = svg.append('text').style('font-size', 22).attr('y', 2);
    
      // начальная анимация путей секторов                 
      sectors.transition().duration(time).attrTween('d', growSectorsPaths); 
    
      // начальная анимация путей для подписей
      titlesPaths.transition().duration(time).attr('opacity', 1)
                 .attrTween('d', growTitlesPaths); 
    
      // начальная анимация текста подписей
      titlesTexts.transition().duration(time)
              .attrTween("x", tweenTitlesTextsX)
              .attrTween("y", tweenTitlesTextsY);
              
      // начальная анимация текста по центру
      totalText.datum(calcTotal()).transition().duration(time)
               .tween("text", interpolateTotal)
    
      function update() {
          let d = pie(rawData);
    
          // задаем анимацию перехода путям секторов 
          sectors.data(d).transition().duration(time)
              .attrTween("d", tweenSectorsPaths);
    
          groups.data(d).transition().duration(time)
              .attr('opacity', d => d.value ? 1 : 0)
    
          // задаем анимацию перехода путям для подписей
          titlesPaths.data(d).transition().duration(time)
              .attrTween("d", tweenTitlesPaths);
    
          // задаем анимацию перехода путям для подписей
          titlesTexts.data(d).transition().duration(time)
              .attrTween("x", tweenTitlesTextsX)
              .attrTween("y", tweenTitlesTextsY);
              
          // анимация текста по центру
          totalText.datum(calcTotal()).transition().duration(time)
               .tween("text", interpolateTotal) 
      }
    
      function growTitlesPaths(d) {
          let i = d3.interpolate(size/4, size/2.7);
          return t => {
            let r = i(t);
            arc2.innerRadius(r).outerRadius(r);
            return line([arc.centroid(this._current = d),arc2.centroid(d)]);
          }
      }
    
      function growSectorsPaths(d) {
         let c = (d.startAngle+d.endAngle)/2;
         let il = d3.interpolate(c, d.startAngle);
         let ir = d3.interpolate(c, d.endAngle)
         return t => {
           d.startAngle = il(t);
           d.endAngle = ir(t);
           return arc(this._current = d);
         }; 
      }
    
      function tweenSectorsPaths(d) {
        let i = lerp(this, d);
        return t => arc(i(t));
      }
    
      function tweenTitlesPaths(d) {
        let i = lerp(this, d);
        return t => line([arc.centroid(i(t)), arc2.centroid(i(t))]);
      }
    
      function tweenTitlesTextsX(d) {
        let i = lerp(this, d, '_currentX');
        return t => arc3.centroid(i(t))[0];
      }
    
      function tweenTitlesTextsY(d) {
        let i = lerp(this, d, '_currentY');
        return t => arc3.centroid(i(t))[1];
      }
    
      function interpolateTotal(d) {
        let i = lerp(this, d);
        return t => Math.round(i(t));
      }
    
      function lerp(el, d, key){
        key = key || '_current';
        return d3.interpolate(el[key] || 0, el[key] = d);
      }
    
      function calcTotal() {
        return rawData.map(d => d.selected ? d.value : 0).reduce((a,v) => a + v, 0)
      }
    
      function interpolateTotal(d) {
        let that = d3.select(this);
        let i = lerp(this, d);
        return t => that.text(Math.floor(i(t)))
      }
    </script>
    
    <style>
      label {
        display: block;
      }
      span {
        display: inline-block;
      }
      path.label {
        stroke-width: 1.4;
        stroke: black;
      }
      text {
        font-size: 12px;
        font-family: arial;
        dominant-baseline: middle;
        text-anchor: middle;  
      }
    </style>

    • 20

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5