D3每隔一个渲染奇怪地附加一个body

时间:2018-10-24 00:11:36

标签: javascript d3.js

我正在尝试用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);

1 个答案:

答案 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');