Как добавить строку в datatable - D C. js - PullRequest
1 голос
/ 27 января 2020

У меня есть файл json, который загружает данные о продажах для продавцов на основе текущего года и предыдущего года.

Я создал таблицу, в которой я показываю общие продажи за каждый год для каждого продавца и , в последнем ряду, мне нужно загрузить итоги для всех суммированных продавцов. Как показано на рисунке ниже:

enter image description here

Я использую dc.dataTable для создания моей таблицы.

Можете ли вы сказать мне, если есть ли в D C. js какой-либо способ создать строку в моей таблице, чтобы поместить общий объем продаж?

Вот мой код, спасибо заранее.

var vendedorTable = dc.dataTable("#Vendedores");

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

  data.forEach(function(d) {

    var 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();
  });

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

1 Ответ

1 голос
/ 28 января 2020

d c. js - это интерфейс для перекрестного фильтра, который представляет собой базу данных в памяти для JavaScript, настроенную для таких панелей мониторинга.

Вы всегда хотите добавить данные в сторона базы данных. Таким образом, правильное место для поиска находится в API перекрестного фильтра, и вот оно: crossfilter.add ()

Возможно, я только что оставил комментарий, но так как вы были достаточно хороши, чтобы включить запускаем код, давайте попробуем!

Сначала давайте зарезервируем одного из поставщиков из набора данных:

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

Затем, когда нажата кнопка Добавить строку, давайте добавим эти данные и перерисовать все связанные графики:

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

Обратите внимание, что если вы нажмете Добавить строку несколько раз, продажи для этого поставщика вырастут в два, а затем в три раза, потому что мы отображаем агрегированную группу, так что поставщик получает больше и добавлены дополнительные продажи.

Вот и все!

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>
...