且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在数据表中添加行-DC.js

更新时间:2023-12-01 19:35:10

dc.js是crossfilter的前端,crossfilter是针对此类仪表板调整的JavaScript内存数据库.

dc.js is the frontend for crossfilter, which is an in-memory database for JavaScript that is tuned for these kinds of dashboards.

您始终想在数据库端添加数据.因此,正确的位置是在crossfilter API中,这里是: crossfilter.add()

You always want to add data on the database side. So the right place to look is in the crossfilter API, and here it is: crossfilter.add()

我可能刚刚发表了评论,但是由于您足够乐于包含正在运行的代码,因此让我们尝试一下!

I might have just left a comment, but since you were nice enough to include running code, let's try it out!

首先,让我们从数据集中保留一个供应商:

First, let's reserve one of the vendors out of the dataset:

  rows = data0.filter(d => d.vendnm === 'JOÃO LUIS');
  var data = data0.filter(d => d.vendnm !== 'JOÃO LUIS');

然后,当单击添加行"按钮时,让我们添加该数据并重绘所有关联的图表:

Then, when the Add Row button is clicked, let's add that data and redraw all the associated charts:

  $('#addRow').on('click', function() {
    myCrossfilter.add(rows);
    dc.redrawAll();
  });

请注意,如果多次单击添加行",该供应商的销售额将翻倍,然后翻三倍,因为我们正在显示一个汇总的组,因此该供应商将获得越来越多的销售额.

Notice that if you click Add Row multiple times, the sales for that vendor will double, then triple, because we are displaying an aggregated group, so that vendor gets more and more sales added in.

仅此而已!

var vendedorTable = dc.dataTable("#Vendedores");
// lift crossfilter and row so they are visible to addRow handler
var myCrossfilter, rows;

var url = 'http://www.json-generator.com/api/json/get/cgsUhkPSjS?indent=2';
d3.json(url).then(function(data0) {

  // save Joao for later
  rows = data0.filter(d => d.vendnm === 'JOÃO LUIS');
  var data = data0.filter(d => d.vendnm !== 'JOÃO LUIS');

  data.forEach(function(d) {

    myCrossfilter = crossfilter(data);
    var all = myCrossfilter.groupAll();

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

    vendedorDim = myCrossfilter.dimension(function(d) {
      return d.vendnm;
    });

    var vendedorGroup = vendedorDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);

    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,
      };
    }

    // formatter = d3.format(".3s");
    // formatter2 = d3.format(".0%");

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

    function checkRows(d) {
      if (d.value.totalAno <= 0 || isNaN(d.value.totalAno) || d.value.totalHomologo <= 0 || isNaN(d.value.totalHomologo)) {
        return 0;
      }
      return d;
    }

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

    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]);
          dc.redrawAll();
        });
      let filters = 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)

    dc.redrawAll();
  });

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

    dc.redrawAll();
  });

  $('#addRow').on('click', function() {
    myCrossfilter.add(rows);
    dc.redrawAll();
  });

});

<head>
  <style>
    .dc-table-group {
      visibility: collapse;
    }
    
    tr.dc-table-row.sel-rows {
      background-color: lightblue;
    }
  </style>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/2.1.8/dc.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
  <script src="https://d3js.org/d3.v5.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.1.8/dc.js"></script>

  <title>Vendedores</title>
</head>

<body>


  <div class="container-fluid">
    <div class="row content">
      <div class="col-md-8" style="padding-left: 20px;">
        <div class="row marginClass">
          <h4 class="pull-left" id="Introduction"><small>Dados fictícios da empresa | Exemplo de Pesquisa
                            Detalhada |
                        </small></h4>
          <h6 class="dc-data-count" style="float: left;margin-left:5px;">
            <span>
                            <span class="filter-count"></span> selected out of
            <span class="total-count"></span> records |
            <a id="reset"> Reset All </a>
            </span>
          </h6>
        </div>

        <div>
            <a id="addRow"> Add Row </a>
        </div>

        <div class="col-md-6">
          <br>
          <a id="resetTable"> Reset</a>
          <table class="table" id="Vendedores">
            <thead>
              <tr>
                <th>Sales</th>
                <th>Current Year</th>
                <th>Last Year</th>
              </tr>
            </thead>
          </table>
        </div>
      </div>
    </div>
  </div>
</body>