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>