我正在尝试用d3附加表以创建嵌套表。我已经注意到一个有趣的错误,但是我很困惑。在表的第一个绘制上,一切看起来都很好,但是在第二个绘制上,它仅显示最后一个元素。第三,它将按预期绘制。每隔一个图就这样。经过大量的反复试验,确定append('tbody')
是所有这些的原因。
const data = [{
date: "2018-10-18",
id: "1234",
spend: 5.00,
revenue: .75,
cpc: .12,
rpc: .50,
rpa: .05,
profit: -5.1,
Clicks: 34,
Conversions: 4,
profitMargin: -2,
Campaign_Name: "Test campaign",
affiliate: "test affiliate"
},
{
date: "2018-10-18",
id: "9876",
spend: 1.00,
revenue: 5.00,
cpc: .02,
rpc: .10,
rpa: .15,
profit: 4.1,
profitMargin: 7,
Campaign_Name: "Reed",
affiliate: "Store",
Clicks: 34,
Conversions: 4,
advertiser: "skdjfh"
},
{
date: "2018-10-18",
id: "4567",
spend: .40,
revenue: .5,
cpc: .1,
rpc: .01,
rpa: .01,
profit: .1,
profitMargin: 0,
Campaign_Name: "Driver",
affiliate: "Insurance",
Clicks: 34,
Conversions: 4,
advertiser: "skdjfh"
},
{
date: "2018-10-17",
id: "1234",
spend: .30,
revenue: .50,
cpc: .03,
rpc: .40,
rpa: .02,
profit: .13,
profitMargin: 2,
Campaign_Name: "Test campaign",
Clicks: 34,
Conversions: 4,
affiliate: "test affiliate",
advertiser: "skdjfh"
},
{
date: "2018-10-17",
id: "9876",
spend: 4.00,
revenue: .5,
cpc: .13,
rpc: .07,
Clicks: 34,
Conversions: 4,
rpa: .01,
profit: .71,
profitMargin: 4,
Campaign_Name: "Reed",
affiliate: "Store",
advertiser: "skdjfh"
},
{
date: "2018-10-17",
Clicks: 34,
Conversions: 4,
id: "4567",
spend: .64,
revenue: 5.44,
cpc: .12,
rpc: .76,
rpa: .88,
profit: -5.1,
profitMargin: -7,
Campaign_Name: "Driver",
affiliate: "Insurance",
advertiser: "skdjfh"
},
{
date: "2018-10-16",
Clicks: 34,
Conversions: 4,
id: "1234",
spend: .11,
revenue: 7.0,
cpc: .12,
rpc: .67,
rpa: .05,
profit: .64,
profitMargin: 0,
Campaign_Name: "Test campaign",
affiliate: "test affiliate",
advertiser: "skdjfh"
},
{
date: "2018-10-16",
Clicks: 34,
Conversions: 4,
id: "9876",
spend: .70,
revenue: 5.5,
cpc: .99,
rpc: .98,
rpa: .52,
profit: 4.2,
profitMargin: -3,
Campaign_Name: "Reed",
affiliate: "Store",
advertiser: "skdjfh"
},
{
date: "2018-10-16",
Clicks: 34,
Conversions: 4,
id: "4567",
spend: .10,
revenue: .34,
cpc: .47,
rpc: .50,
rpa: .12,
profit: 1.3,
profitMargin: -1,
Campaign_Name: "Driver",
affiliate: "Insurance",
advertiser: "skdjfh"
},
{
date: "2018-10-18",
Clicks: 34,
Conversions: 4,
id: "3344",
spend: 5.00,
revenue: .33,
cpc: .24,
rpc: .52,
rpa: .34,
profit: -0.5,
profitMargin: 9,
Campaign_Name: "action campaign",
affiliate: "camera affiliate",
advertiser: "skdjfh"
},
{
date: "2018-10-18",
Clicks: 34,
Conversions: 4,
id: "2233",
spend: 2.00,
revenue: .5,
cpc: .2,
rpc: .70,
rpa: .46,
profit: 0.1,
profitMargin: 2,
Campaign_Name: "Boogie campaign",
affiliate: "oogie affiliate",
advertiser: "skdjfh"
}
];
// // // This is a subtotal reducer so each id has its total
const summary = merged.reduce(function (val, acc) {
if (!val[acc.id]) val[acc.id] = {
id: acc.id,
spend: 0,
revenue: 0,
profit: 0,
Clicks: 0,
rpa: 0,
cpc: 0,
rpc: 0,
Conversions: 0
};
val[acc.id].Clicks += Number.isFinite(acc.Clicks) ? Number.parseFloat(acc.Clicks) : 0;
val[acc.id].Conversions += Number.isFinite(acc.Conversions) ? Number.parseFloat(acc.Conversions) : 0;
val[acc.id].spend += Number.isFinite(acc.spend) ? Number.parseFloat(acc.spend) : 0;
val[acc.id].revenue += Number.isFinite(acc.revenue) ? Number.parseFloat(acc.revenue) : 0;
val[acc.id].profit += Number.isFinite(acc.profit) ? Number.parseFloat(acc.profit) : 0;
val[acc.id].Campaign_Name = acc.Campaign_Name;
val[acc.id].affiliate = acc.affiliate;
val[acc.id].advertiser = acc.advertiser;
val[acc.id].cpc = Number.isFinite(val[acc.id].spend / val[acc.affiliateId].Clicks) ? Number.parseFloat(acc.cpc) : 0;
val[acc.id].rpc = Number.isFinite(val[acc.id].revenue / val[acc.id].Clicks) ? Number.parseFloat(acc.rpc) : 0;
val[acc.id].rpa = Number.isFinite(val[acc.id].revenue / val[acc.id].Conversions) ? Number.parseFloat(acc.rpa) : 0;
val[acc.id].profitMargin = Number.isFinite(val[acc.id].profit / val[acc.id].revenue) ? Number.parseFloat(acc.profitMargin) : 0;
return val;
}, {});
const nestedData = d3.nest()
.key(d => d.id)
.entries(data)
.map(d => {
d.header = summary[d.key];
return d
});
console.log(nestedData);// shows the nested data we should be seeing each draw
var tbody = table.selectAll('tbody')
.data(nestedData)
.remove()
.enter()
.append('tbody'); //this is the source of the bug
var summaryRow = tbody
.selectAll('tr.summary')
.data(d => [d.header])
.remove()
.enter()
.append('tr')
.attr("class", "tableexport-ignore")
.on("click", function (d) {
var entryDetails = $(this).nextUntil(".summary");
entryDetails.toggle();
})
.classed('summary', true);
addCells(summaryRow);
// create a row for each object in the data
var rows = tbody.selectAll('tr.entry')
.data(d => {
return d.values
})
.remove()
.enter()
.append('tr')
.attr("class", "detail-row")
.classed('entry', true)
addCells(rows);
答案 0 :(得分:0)
答案比最初想的要简单得多。我只需要删除并重新绘制整个表,因为d3中似乎存在某些问题。这是我解决此问题的方法:
// clear existing table
d3.select('#table').select('table').remove();
// create new table
const table = d3.select('#table').append('table');
// // // remove old headers then append new ones in case this is a new date range
const thead = table.selectAll('thead').data([null]).enter().append('thead');