如何计算总销售额并使显示的总金额动态化? [英] How to calculate the total sales and make the displayed totals dynamic?

查看:68
本文介绍了如何计算总销售额并使显示的总金额动态化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要显示我的数据对卖方和城市的总销售额.但是,总计中显示的值必须是动态的.

PS .我的表格允许用户选择行,这是因为值是根据所做的每次选择呈现的.(表之间的这种动态性已经很好地发挥了作用.)

总计"的初始状态是使用所有卖方和城市的总和得出的,下面我显示了具有各自总计的表格,但是,如图所示,这些值是静态的而不是动态的.

我需要保持diahanic性,因为例如,如果我选择卖方JoãoLuis Miguel ,则要在总计中显示的值必须是这些值的总和两个卖家.

不久前我问了一个有关

默认格式 .2s ,但 numberDisplay 接受任何 d3格式实例.

如果您不喜欢动画,可以设置 .transitionDuration(0)

  var复合= dc.compositeChart('#composite');var vendedorTable = dc.dataTable(#vendedores");var citysTable = dc.dataTable(#cities");函数remove_empty_bins(source_group){返回 {顶部:function(N){返回source_group.all().filter(function(d){返回d.value.totalAno>1e-3 ||d.value.totalHomologo>1e-3;}).slice(0,N);}};}var AdjustX = 10,AdjustY = 40;var url ='https://gist.githubusercontent.com/bernalvinicius/3cece295bc37de1697e7f83418e7fcc9/raw/a5820379ec6eae76ee792495cc5dd1685c977a73/vendedores.json';d3.json(url).then(function(data){data.forEach(d =>Object.assign(d,{邮件:d.Month,单位:d.Vendas_Ano,passado:d.Vendas_Ant}));var cf = crossfilter(data);vendedorDim = cf.dimension(function(d){返回d.vendnm;});var vendedorGroup = vendedorDim.group().reduce(reduceAdd,reduceRemove,reduceInitial);cityDim = cf.dimension(function(d){返回d.zona;});var cityGroup = cityDim.group().reduce(reduceAdd,reduceRemove,reduceInitial);const totalAll = cf.groupAll().reduce(reduceAdd,reduceRemove,reduceInitial);调试器;var dim = cf.dimension(dc.pluck('mes')),grp1 = dim.group().reduceSum(dc.pluck('atual')),grp2 = dim.group().reduceSum(dc.pluck('passado'));var minMonth = dim.bottom(1)[0] .mes;var maxMonth = dim.top(1)[0] .mes;var all = cf.groupAll();dc.dataCount(.dc-data-count").dimension(cf).group(all);函数reduceAdd(p,v){p.totalAno + = + v.Vendas_Ano;p.totalHomologo + = + v.Vendas_Ant;返回p;}函数reduceRemove(p,v){p.totalAno-= v.Vendas_Ano;p.totalHomologo-= v.Vendas_Ant;返回p;}函数reduceInitial(){返回 {totalAno:0,totalHomologo:0,};}//伪尺寸等级=函数(p){返回 ""};//每月图表合成的.width(window.innerWidth-AdjustX).height(300).x(d3.scaleLinear().domain([1,12])).yAxisLabel(").xAxisLabel(月").legend(dc.legend().x(500).y(0).itemHeight(13).gap(5)).renderHorizo​​ntalGridLines(true).撰写([dc.lineChart(复合).dimension(dim).colors('steelblue').group(grp1,当前年份"),dc.lineChart(复合).dimension(dim).colors('darkorange').group(grp2,去年")]).brushOn(true);Composite.brush().extent([-0.5,data.length + 1.5])Composite.extendBrush = function(brushSelection){如果(brushSelection){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);const point = Math.round((brushSelection [0] + brushSelection [1])/2);返回 [点-0.5,点+ 0.5];}};//销售表vendedorTable.width(500).height(480).dimension(remove_empty_bins(vendedorGroup)).group(等级).columns([function(d){返回d.key;},功能(d){返回Number(Math.round(d.value.totalAno * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';},功能(d){返回Number(Math.round(d.value.totalHomologo * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';}]).sortBy(function(d){返回d.value.totalAno}).order(d3.descending)//供应商总计const totalCYDisplay = dc.numberDisplay('#total-current-year').group(totalAll).valueAccessor(d => d.totalAno)const totalLYDisplay = dc.numberDisplay('#total-last-year').group(totalAll).valueAccessor(d => d.totalHomologo)//城市表城市表.width(500).height(480).dimension(remove_empty_bins(citiesGroup)).group(等级).columns([function(d){返回d.key;},功能(d){返回Number(Math.round(d.value.totalAno * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';},功能(d){返回Number(Math.round(d.value.totalHomologo * 100)/100).toLocaleString("es-ES",{minimumFractionDigits:2})+'€';}]).controlsUseVisibility(true).sortBy(function(d){返回d.value.totalAno}).order(d3.descending)//销售点击事件vendedorTable.on('pretransition',function(table){table.selectAll('td.dc-table-column').on('click',function(d){让滤镜= table.filters().slice();如果(filters.indexOf(d.key)=== -1)filter.push(d.key);别的过滤器= filters.filter(k => k!= d.key);如果(filters.length === 0)vendedorDim.filter(null);别的vendedorDim.filterFunction(function(d){返回filters.indexOf(d)!== -1;})table.replaceFilter([filters]);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});让滤镜= table.filters();table.selectAll('tr.dc-table-row').classed('sel-rows',d => filters.indexOf(d.key)!== -1);});//城市点击事件cityTable.on('pretransition',function(table){table.selectAll('td.dc-table-column').on('click',function(d){让滤镜= table.filters().slice();如果(filters.indexOf(d.key)=== -1)filter.push(d.key);别的过滤器= filters.filter(k => k!= d.key);如果(filters.length === 0)cityDim.filter(null);别的cityDim.filterFunction(function(d){返回filters.indexOf(d)!== -1;})table.replaceFilter([filters]);vendedorTable.filter(null);vendedorDim.filter(null);Composite.filter(null);dc.redrawAll();});让滤镜= table.filters();table.selectAll('tr.dc-table-row').classed('sel-rows',d => filters.indexOf(d.key)!== -1);});dc.renderAll();//重置功能$('#reset').on('click',function(){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});$('#resetTable').on('click',function(){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});$('#resetTable2').on('click',function(){vendedorTable.filter(null);vendedorDim.filter(null);cityTable.filter(null);cityDim.filter(null);Composite.filter(null);dc.redrawAll();});/*********************************************************************************///处理响应的函数apply_resizing(composite,adjustX,adjustY,function(composite){Composite.legend().x(window.innerWidth-200);});var find_query = function(){var _map = window.location.search.substr(1).split('&').map(function(a){返回a.split('=');}).reduce(function(p,v){如果(v.length> 1)p [v [0]] = encodeURIComponent(v [1] .replace(/\ +/g,"));别的p [v [0]] = true;返回p;},{});返回函数(字段){返回_map [field] ||空值;};}();var resizeMode = find_query('resize')||'widhei';函数apply_resizing(composite,adjustX,adjustY,onresize){如果(resizeMode ==='viewbox'){合成的.width(300).height(200).useViewBoxResizing(true);d3.select(composite.anchor()).classed('fullsize',false);} 别的 {AdjustX = AdjustX ||0;AdjustY = AdjustY ||AdjustX ||0;合成的.width(window.innerWidth-AdjustX).height(300);window.onresize = function(){如果(调整大小){onresize(composite);}合成的.width(window.innerWidth-AdjustX).height(300);如果(composite.rescale){Composite.rescale();}Composite.redraw();};}}});  

  #composite {内边距:10px;}.dc-table-group {能见度:崩溃;}tr.dc-table-row.sel-rows {背景颜色:浅蓝色;}.brush .custom-brush-handle {显示:无;}  

 < head><!-网站图标->< link rel =快捷方式图标" href ="https://img.icons8.com/nolan/64/puzzle.png"><!-bootstrap.css->< link rel ="stylesheet" href ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"完整性="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va + PmSTszz/K68vbdEgin>< ;!-bootstrap-theme.css->< link rel ="stylesheet" href ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"完整性="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPpQbGYginan"><!-dc.css->< link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css"><!-jquery.js->< script src ="https://code.jquery.com/jquery-3.4.1.js"完整性="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU =" crossorigin ="anonymous"></script>< ;!-bootstrap.js->< script src ="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"完整性="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7T< ous"<!-d3.v5.js->< script src ="https://d3js.org/d3.v5.js"></script><!-crossfilter.js->< script src ="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"</script><!-dc.js->< script src ="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"</script>< title>图表</title></head><身体>< div id ="composite"></div>< div class ="container-fluid">< div class ="row content">< div class ="col-md-12">< div class ="col-md-6">< table class ="table" id ="totaisVendedores">< thead>< tr><总销售量</th><当前年</th>< th>去年</th></tr></thead></table></div>< div class ="col-md-6">< table class ="table" id ="totaisCities">< thead>< tr>< th; Total City</th><当前年</th>< th>去年</th></tr></thead></table></div>< div class ="col-md-6">< table class ="table" id ="vendedores">< thead>< tr>< th; Sales</th><当前年</th>< th>去年</th></tr></thead>< tfoot>< tr>< total</th>< th id =总当前年"</th>< th id ="total-last-year-year"></th></tr></tfoot></table></div>< div class ="col-md-6">< table class ="table" id ="cities">< thead>< tr>< th> City< th><当前年</th>< th>去年</th></tr></thead></table></div></div></div></div></body>  

I need to show the total sales of my data to both sellers and cities. However, the values shown in the totals must be dynamic.

P.S. My table allows the user to select the rows, this is because the values are rendered according to each selection made. (This dynamism between the tables is already working perfectly).

The initial state of the Total is rendered with the general sum of all sellers and cities, below I show the tables with their respective totals, however, as shown in the image, the values are static and not dynamic.

I need it to be diahanic because if I select for example the seller João Luis and Miguel, the value to be shown in the total must be the sum of these two sellers.

I asked a question a while ago about How to add row in datatable - DC.js, a friend (@Gordon) who is helping me a lot in doubts with DC.js and Crossfilter told me to use crossfilter.add(). Unfortunately I couldn't do it the way suggested, so I'm here again with practically the same question (sorry for my stupidity).

var composite = dc.compositeChart('#composite');
var vendedorTable = dc.dataTable("#vendedores");
var citiesTable = dc.dataTable("#cities");

function remove_empty_bins(source_group) {
  return {
    top: function(N) {
      return source_group.all().filter(function(d) {
        return d.value.totalAno > 1e-3 ||
          d.value.totalHomologo > 1e-3;
      }).slice(0, N);
    }
  };
}
var adjustX = 10,
  adjustY = 40;

var url = 'https://gist.githubusercontent.com/bernalvinicius/3cece295bc37de1697e7f83418e7fcc9/raw/a5820379ec6eae76ee792495cc5dd1685c977a73/vendedores.json';
d3.json(url).then(function(data) {

  data.forEach(d =>
    Object.assign(d, {
      mes: d.Month,
      atual: d.Vendas_Ano,
      passado: d.Vendas_Ant
    })
  );
  var cf = crossfilter(data);

  vendedorDim = cf.dimension(function(d) {
    return d.vendnm;
  });
  var vendedorGroup = vendedorDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);

  citiesDim = cf.dimension(function(d) {
    return d.zona;
  });
  var citiesGroup = citiesDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);

  var dim = cf.dimension(dc.pluck('mes')),
    grp1 = dim.group().reduceSum(dc.pluck('atual')),
    grp2 = dim.group().reduceSum(dc.pluck('passado'));
  var minMonth = dim.bottom(1)[0].mes;
  var maxMonth = dim.top(1)[0].mes;

  var all = cf.groupAll();

  dc.dataCount(".dc-data-count")
    .dimension(cf)
    .group(all);

  function reduceAdd(p, v) {
    p.totalAno += +v.Vendas_Ano;
    p.totalHomologo += +v.Vendas_Ant;
    return p;
  }

  function reduceRemove(p, v) {
    p.totalAno -= v.Vendas_Ano;
    p.totalHomologo -= v.Vendas_Ant;
    return p;
  }

  function reduceInitial() {
    return {
      totalAno: 0,
      totalHomologo: 0,
    };
  }

  // Fake Dimension
  rank = function(p) {
    return ""
  };

  // Chart by months
  composite
    .width(window.innerWidth - adjustX)
    .height(300)
    .x(d3.scaleLinear().domain([1, 12]))
    .yAxisLabel("")
    .xAxisLabel("Month")
    .legend(dc.legend().x(500).y(0).itemHeight(13).gap(5))
    .renderHorizontalGridLines(true)
    .compose([
      dc.lineChart(composite)
      .dimension(dim)
      .colors('steelblue')
      .group(grp1, "Currently Year"),
      dc.lineChart(composite)
      .dimension(dim)
      .colors('darkorange')
      .group(grp2, "Last Year")
    ])
    .brushOn(true);

  composite.brush().extent([-0.5, data.length + 1.5])
  composite.extendBrush = function(brushSelection) {
    if (brushSelection) {
      vendedorTable.filter(null);
      vendedorDim.filter(null);
      citiesTable.filter(null);
      citiesDim.filter(null);
      const point = Math.round((brushSelection[0] + brushSelection[1]) / 2);
      return [
        point - 0.5,
        point + 0.5
      ];
    }
  };

  // Sales Table
  vendedorTable.width(500)
    .height(480)
    .dimension(remove_empty_bins(vendedorGroup))
    .group(rank)
    .columns([function(d) {
        return d.key;
      },
      function(d) {
        return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      },
      function(d) {
        return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      }
    ])
    .sortBy(function(d) {
      return d.value.totalAno
    })
    .order(d3.descending)

  // Cities Table
  citiesTable
    .width(500)
    .height(480)
    .dimension(remove_empty_bins(citiesGroup))
    .group(rank)
    .columns([function(d) {
        return d.key;
      },
      function(d) {
        return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      },
      function(d) {
        return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      }
    ])
    .controlsUseVisibility(true)
    .sortBy(function(d) {
      return d.value.totalAno
    })
    .order(d3.descending)

  // Sales click events
  vendedorTable.on('pretransition', function(table) {
    table.selectAll('td.dc-table-column')
      .on('click', function(d) {
        let filters = table.filters().slice();
        if (filters.indexOf(d.key) === -1)
          filters.push(d.key);
        else
          filters = filters.filter(k => k != d.key);
        if (filters.length === 0)
          vendedorDim.filter(null);
        else
          vendedorDim.filterFunction(function(d) {
            return filters.indexOf(d) !== -1;
          })
        table.replaceFilter([filters]);

        citiesTable.filter(null);
        citiesDim.filter(null);
        composite.filter(null);

        dc.redrawAll();
      });
    let filters = table.filters();
    table.selectAll('tr.dc-table-row')
      .classed('sel-rows', d => filters.indexOf(d.key) !== -1);
  });

  // Cities click events
  citiesTable.on('pretransition', function(table) {
    table.selectAll('td.dc-table-column')
      .on('click', function(d) {
        let filters = table.filters().slice();
        if (filters.indexOf(d.key) === -1)
          filters.push(d.key);
        else
          filters = filters.filter(k => k != d.key);
        if (filters.length === 0)
          citiesDim.filter(null);
        else
          citiesDim.filterFunction(function(d) {
            return filters.indexOf(d) !== -1;
          })
        table.replaceFilter([filters]);

        vendedorTable.filter(null);
        vendedorDim.filter(null);
        composite.filter(null);

        dc.redrawAll();
      });
    let filters = table.filters();
    table.selectAll('tr.dc-table-row')
      .classed('sel-rows', d => filters.indexOf(d.key) !== -1);
  });


  dc.renderAll();

  // reset functions
  $('#reset').on('click', function() {
    vendedorTable.filter(null);
    vendedorDim.filter(null);
    citiesTable.filter(null);
    citiesDim.filter(null);
    composite.filter(null);

    dc.redrawAll();
  });

  $('#resetTable').on('click', function() {
    vendedorTable.filter(null);
    vendedorDim.filter(null);
    citiesTable.filter(null);
    citiesDim.filter(null);
    composite.filter(null);

    dc.redrawAll();
  });

  $('#resetTable2').on('click', function() {
    vendedorTable.filter(null);
    vendedorDim.filter(null);
    citiesTable.filter(null);
    citiesDim.filter(null);
    composite.filter(null);

    dc.redrawAll();
  });


  /****************************************************************************/
  // Functions to handle responsive
  apply_resizing(composite, adjustX, adjustY, function(composite) {
    composite.legend().x(window.innerWidth - 200);
  });

  var find_query = function() {
    var _map = window.location.search.substr(1).split('&').map(function(a) {
      return a.split('=');
    }).reduce(function(p, v) {
      if (v.length > 1)
        p[v[0]] = decodeURIComponent(v[1].replace(/\+/g, " "));
      else
        p[v[0]] = true;
      return p;
    }, {});
    return function(field) {
      return _map[field] || null;
    };
  }();

  var resizeMode = find_query('resize') || 'widhei';

  function apply_resizing(composite, adjustX, adjustY, onresize) {
    if (resizeMode === 'viewbox') {
      composite
        .width(300)
        .height(200)
        .useViewBoxResizing(true);
      d3.select(composite.anchor()).classed('fullsize', false);
    } else {
      adjustX = adjustX || 0;
      adjustY = adjustY || adjustX || 0;
      composite
        .width(window.innerWidth - adjustX)
        .height(300);
      window.onresize = function() {
        if (onresize) {
          onresize(composite);
        }
        composite
          .width(window.innerWidth - adjustX)
          .height(300);

        if (composite.rescale) {
          composite.rescale();
        }
        composite.redraw();
      };
    }
  }
});

#composite {
  padding: 10px;
}

.dc-table-group {
  visibility: collapse;
}

tr.dc-table-row.sel-rows {
  background-color: lightblue;
}

.brush .custom-brush-handle {
  display: none;
}

<head>
  <!-- favicon -->
  <link rel="shortcut icon" href="https://img.icons8.com/nolan/64/puzzle.png">
  <!-- bootstrap.css -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <!-- bootstrap-theme.css -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <!-- dc.css -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css">
  <!-- jquery.js -->
  <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
  <!-- bootstrap.js -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  <!-- d3.v5.js -->
  <script src="https://d3js.org/d3.v5.js"></script>
  <!-- crossfilter.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
  <!-- dc.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"></script>

  <title>Chart</title>
</head>

<body>
  <div id="composite"></div>
  <div class="container-fluid">
    <div class="row content">
      <div class="col-md-12">
        <div class="col-md-6">
          <table class="table" id="totaisVendedores">
            <thead>
              <tr>
                <th>Total Sales</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
        <div class="col-md-6">
          <table class="table" id="totaisCities">
            <thead>
              <tr>
                <th>Total City</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
        <div class="col-md-6">
          <table class="table" id="vendedores">
            <thead>
              <tr>
                <th>Sales</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
        <div class="col-md-6">
          <table class="table" id="cities">
            <thead>
              <tr>
                <th>City</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
      </div>
    </div>
  </div>
</body>

解决方案

Sorry, I completely misread your last question. It was nice of you to accept the answer, but you really didn't have to do that. :)

In order to add totals, you can add a tfoot section to your table

            <tfoot>
              <tr>
                <th>TOTAL</th>
                <th id="total-current-year"></th>
                <th id="total-last-year"></th>
              </tr>
            </tfoot>

and drive it with a NumberDisplay widget.

  const totalCYDisplay = dc.numberDisplay('#total-current-year')
    .group(totalAll)
    .valueAccessor(d => d.totalAno)

The default formatting is .2s but numberDisplay accepts any d3-format instance.

If you don't like the animation, you can set .transitionDuration(0)

var composite = dc.compositeChart('#composite');
var vendedorTable = dc.dataTable("#vendedores");
var citiesTable = dc.dataTable("#cities");

function remove_empty_bins(source_group) {
  return {
    top: function(N) {
      return source_group.all().filter(function(d) {
        return d.value.totalAno > 1e-3 ||
          d.value.totalHomologo > 1e-3;
      }).slice(0, N);
    }
  };
}
var adjustX = 10,
  adjustY = 40;

var url = 'https://gist.githubusercontent.com/bernalvinicius/3cece295bc37de1697e7f83418e7fcc9/raw/a5820379ec6eae76ee792495cc5dd1685c977a73/vendedores.json';
d3.json(url).then(function(data) {

  data.forEach(d =>
    Object.assign(d, {
      mes: d.Month,
      atual: d.Vendas_Ano,
      passado: d.Vendas_Ant
    })
  );
  var cf = crossfilter(data);

  vendedorDim = cf.dimension(function(d) {
    return d.vendnm;
  });
  var vendedorGroup = vendedorDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);

  citiesDim = cf.dimension(function(d) {
    return d.zona;
  });
  var citiesGroup = citiesDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
  const totalAll = cf.groupAll()
    .reduce(reduceAdd, reduceRemove, reduceInitial);
debugger;

  var dim = cf.dimension(dc.pluck('mes')),
    grp1 = dim.group().reduceSum(dc.pluck('atual')),
    grp2 = dim.group().reduceSum(dc.pluck('passado'));
  var minMonth = dim.bottom(1)[0].mes;
  var maxMonth = dim.top(1)[0].mes;

  var all = cf.groupAll();

  dc.dataCount(".dc-data-count")
    .dimension(cf)
    .group(all);

  function reduceAdd(p, v) {
    p.totalAno += +v.Vendas_Ano;
    p.totalHomologo += +v.Vendas_Ant;
    return p;
  }

  function reduceRemove(p, v) {
    p.totalAno -= v.Vendas_Ano;
    p.totalHomologo -= v.Vendas_Ant;
    return p;
  }

  function reduceInitial() {
    return {
      totalAno: 0,
      totalHomologo: 0,
    };
  }

  // Fake Dimension
  rank = function(p) {
    return ""
  };

  // Chart by months
  composite
    .width(window.innerWidth - adjustX)
    .height(300)
    .x(d3.scaleLinear().domain([1, 12]))
    .yAxisLabel("")
    .xAxisLabel("Month")
    .legend(dc.legend().x(500).y(0).itemHeight(13).gap(5))
    .renderHorizontalGridLines(true)
    .compose([
      dc.lineChart(composite)
      .dimension(dim)
      .colors('steelblue')
      .group(grp1, "Currently Year"),
      dc.lineChart(composite)
      .dimension(dim)
      .colors('darkorange')
      .group(grp2, "Last Year")
    ])
    .brushOn(true);

  composite.brush().extent([-0.5, data.length + 1.5])
  composite.extendBrush = function(brushSelection) {
    if (brushSelection) {
      vendedorTable.filter(null);
      vendedorDim.filter(null);
      citiesTable.filter(null);
      citiesDim.filter(null);
      const point = Math.round((brushSelection[0] + brushSelection[1]) / 2);
      return [
        point - 0.5,
        point + 0.5
      ];
    }
  };

  // Sales Table
  vendedorTable.width(500)
    .height(480)
    .dimension(remove_empty_bins(vendedorGroup))
    .group(rank)
    .columns([function(d) {
        return d.key;
      },
      function(d) {
        return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      },
      function(d) {
        return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      }
    ])
    .sortBy(function(d) {
      return d.value.totalAno
    })
    .order(d3.descending)

  // vendedors totals
  const totalCYDisplay = dc.numberDisplay('#total-current-year')
    .group(totalAll)
    .valueAccessor(d => d.totalAno)
  const totalLYDisplay = dc.numberDisplay('#total-last-year')
    .group(totalAll)
    .valueAccessor(d => d.totalHomologo)

  // Cities Table
  citiesTable
    .width(500)
    .height(480)
    .dimension(remove_empty_bins(citiesGroup))
    .group(rank)
    .columns([function(d) {
        return d.key;
      },
      function(d) {
        return Number(Math.round(d.value.totalAno * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      },
      function(d) {
        return Number(Math.round(d.value.totalHomologo * 100) / 100).toLocaleString("es-ES", {
          minimumFractionDigits: 2
        }) + '€';
      }
    ])
    .controlsUseVisibility(true)
    .sortBy(function(d) {
      return d.value.totalAno
    })
    .order(d3.descending)

  // Sales click events
  vendedorTable.on('pretransition', function(table) {
    table.selectAll('td.dc-table-column')
      .on('click', function(d) {
        let filters = table.filters().slice();
        if (filters.indexOf(d.key) === -1)
          filters.push(d.key);
        else
          filters = filters.filter(k => k != d.key);
        if (filters.length === 0)
          vendedorDim.filter(null);
        else
          vendedorDim.filterFunction(function(d) {
            return filters.indexOf(d) !== -1;
          })
        table.replaceFilter([filters]);

        citiesTable.filter(null);
        citiesDim.filter(null);
        composite.filter(null);

        dc.redrawAll();
      });
    let filters = table.filters();
    table.selectAll('tr.dc-table-row')
      .classed('sel-rows', d => filters.indexOf(d.key) !== -1);
  });

  // Cities click events
  citiesTable.on('pretransition', function(table) {
    table.selectAll('td.dc-table-column')
      .on('click', function(d) {
        let filters = table.filters().slice();
        if (filters.indexOf(d.key) === -1)
          filters.push(d.key);
        else
          filters = filters.filter(k => k != d.key);
        if (filters.length === 0)
          citiesDim.filter(null);
        else
          citiesDim.filterFunction(function(d) {
            return filters.indexOf(d) !== -1;
          })
        table.replaceFilter([filters]);

        vendedorTable.filter(null);
        vendedorDim.filter(null);
        composite.filter(null);

        dc.redrawAll();
      });
    let filters = table.filters();
    table.selectAll('tr.dc-table-row')
      .classed('sel-rows', d => filters.indexOf(d.key) !== -1);
  });


  dc.renderAll();

  // reset functions
  $('#reset').on('click', function() {
    vendedorTable.filter(null);
    vendedorDim.filter(null);
    citiesTable.filter(null);
    citiesDim.filter(null);
    composite.filter(null);

    dc.redrawAll();
  });

  $('#resetTable').on('click', function() {
    vendedorTable.filter(null);
    vendedorDim.filter(null);
    citiesTable.filter(null);
    citiesDim.filter(null);
    composite.filter(null);

    dc.redrawAll();
  });

  $('#resetTable2').on('click', function() {
    vendedorTable.filter(null);
    vendedorDim.filter(null);
    citiesTable.filter(null);
    citiesDim.filter(null);
    composite.filter(null);

    dc.redrawAll();
  });


  /****************************************************************************/
  // Functions to handle responsive
  apply_resizing(composite, adjustX, adjustY, function(composite) {
    composite.legend().x(window.innerWidth - 200);
  });

  var find_query = function() {
    var _map = window.location.search.substr(1).split('&').map(function(a) {
      return a.split('=');
    }).reduce(function(p, v) {
      if (v.length > 1)
        p[v[0]] = decodeURIComponent(v[1].replace(/\+/g, " "));
      else
        p[v[0]] = true;
      return p;
    }, {});
    return function(field) {
      return _map[field] || null;
    };
  }();

  var resizeMode = find_query('resize') || 'widhei';

  function apply_resizing(composite, adjustX, adjustY, onresize) {
    if (resizeMode === 'viewbox') {
      composite
        .width(300)
        .height(200)
        .useViewBoxResizing(true);
      d3.select(composite.anchor()).classed('fullsize', false);
    } else {
      adjustX = adjustX || 0;
      adjustY = adjustY || adjustX || 0;
      composite
        .width(window.innerWidth - adjustX)
        .height(300);
      window.onresize = function() {
        if (onresize) {
          onresize(composite);
        }
        composite
          .width(window.innerWidth - adjustX)
          .height(300);

        if (composite.rescale) {
          composite.rescale();
        }
        composite.redraw();
      };
    }
  }
});

#composite {
  padding: 10px;
}

.dc-table-group {
  visibility: collapse;
}

tr.dc-table-row.sel-rows {
  background-color: lightblue;
}

.brush .custom-brush-handle {
  display: none;
}

<head>
  <!-- favicon -->
  <link rel="shortcut icon" href="https://img.icons8.com/nolan/64/puzzle.png">
  <!-- bootstrap.css -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <!-- bootstrap-theme.css -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <!-- dc.css -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css">
  <!-- jquery.js -->
  <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
  <!-- bootstrap.js -->
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  <!-- d3.v5.js -->
  <script src="https://d3js.org/d3.v5.js"></script>
  <!-- crossfilter.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
  <!-- dc.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"></script>

  <title>Chart</title>
</head>

<body>
  <div id="composite"></div>
  <div class="container-fluid">
    <div class="row content">
      <div class="col-md-12">
        <div class="col-md-6">
          <table class="table" id="totaisVendedores">
            <thead>
              <tr>
                <th>Total Sales</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
        <div class="col-md-6">
          <table class="table" id="totaisCities">
            <thead>
              <tr>
                <th>Total City</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
        <div class="col-md-6">
          <table class="table" id="vendedores">
            <thead>
              <tr>
                <th>Sales</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
            <tfoot>
              <tr>
                <th>TOTAL</th>
                <th id="total-current-year"></th>
                <th id="total-last-year"></th>
              </tr>
            </tfoot>
          </table>
        </div>
        <div class="col-md-6">
          <table class="table" id="cities">
            <thead>
              <tr>
                <th>City</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
      </div>
    </div>
  </div>
</body>

这篇关于如何计算总销售额并使显示的总金额动态化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆