最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to distribute percentage of amount provided upward five levels of the tree from a child node - Stack Overflow

programmeradmin5浏览0评论

I previously asked a question on Stack Overflow about totaling mapped data and displaying it as a tree structure. With the help of an answer (link to the original question), I was able to solve the initial problem.

Now, I’ve made a few changes to the code where I want to distribute particular percentage of amount of given data. 10% of amount should be given to the 1st right above parent of the child node, let's take id 6 with amount 9870, then 10% amount should be for id 5. 5% of amount of id 6 should be for id 4, 4% of amount should be for id 3, 3% of amount should be for id 2 and lastly 1% of amount goes to id 1.

Now suppose there is even an id above id 1 then that id gets nothing. The distribution only goes up 5 parent nodes.

This is the updated code with additional functions for distribution of percentages. The backend and data are the same as in linked question-

<script>
    // Function to transform the flat list of sponsors into a tree structure
    function buildSponsorTree(sponsors, amn) {
        console.log(sponsors, amn);
        const sponsorMap = new Map();

        // Map each sponsor by its ID for easy access
        sponsors.forEach(sponsor => {
            sponsorMap.set(sponsor.id, {...sponsor, children: [], parent: -1, distributedAmount: 0});
        });

        const rootSponsors = [];
        // Build the tree structure where sponsor_id is the child and id is the parent
        sponsors.forEach(sponsor => {
            if(sponsor.sponsor_id !== -1) {
                // If the sponsor has a sponsor_id, it's a child of another sponsor (id is parent)
                const parent = sponsorMap.get(sponsor.sponsor_id);
                if(parent) {
                    parent.children.push(sponsorMap.get(sponsor.id));
                    sponsorMap.get(sponsor.id).parent = parent;
                }
            } else {
                // If sponsor_id is null, it is a root sponsor (top-level)
                rootSponsors.push(sponsorMap.get(sponsor.id));
            }
        });
        amn.forEach(amount => {
            sponsorMap.get(amount._id).amount = amount.totalAmount;
        });
        function calculateTotalAmount(sponsor) {
            // Calculate total amount for this sponsor
            let total = sponsor.amount || 0;
            // Recursively calculate the total for all children
            sponsor.children.forEach(child => {
                total += calculateTotalAmount(child);
            });
            // Add the total amount to the sponsor
            sponsor.totalAmount = total;
            return total;
        }
        function findParent(sponsor) {
            let parentChain = [];
            let currentSponsor = sponsor;
            while(currentSponsor.parent !== -1 && parentChain.length < 5) {
                currentSponsor = currentSponsor.parent;  // Move up the parent chain
                parentChain.push(currentSponsor);  // Add parent to the chain
            }
            if(currentSponsor.parent === -1) {
                return -1;
            }
            return parentChain;
        }
        // Calculate total amount for all root sponsors
        rootSponsors.forEach(sponsor => {
            calculateTotalAmount(sponsor);  // Calculate total for the sponsor and descendants
            const parentChain = findParent(sponsor);
            if(parentChain === -1) {
                return sponsor.distributedAmount = 0;
            } else {
                parentChain.forEach((parent, index) => {
                    const distributeAmount = 0;
                    switch(index) {
                        case 0:
                            distributeAmount = parent.amount * 0.10;
                            break;
                        case 1:
                            distributeAmount = parent.amount * 0.05; // 5% to the second parent
                            break;
                        case 2:
                            distributeAmount = parent.amount * 0.04; // 4% to the third parent
                            break;
                        case 3:
                            distributeAmount = parent.amount * 0.03; // 3% to the fourth parent
                            break;
                        case 4:
                            distributeAmount = parent.amount * 0.01; // 1% to the fifth parent
                            break;
                    }
                    console.log(distributeAmount, parent, index);
                    parent.distributedAmount += distributeAmount;  // Add to parent's distributed amount
                });
            }
        });
        return rootSponsors;  // Return the root nodes which form the tree
    }

    // Function to recursively render the sponsor tree
    function renderSponsorTree(sponsors) {
        let html = '<ul>';
        sponsors.forEach(sponsor => {
            html += `
                <li>
                    <strong>${sponsor.name}</strong> (ID: ${sponsor.id}) Amount - <strong>${sponsor.amount}</strong>
                    <ul style="list-style-type:none">
                        <li>TotalAmount - <strong>${sponsor.totalAmount}</strong></li>
                        <li>DistributedAmount - <strong>${sponsor.distributedAmount}</strong></li>
                    </ul>
                    ${sponsor.children.length > 0 ? renderSponsorTree(sponsor.children) : ''}
                </li>
            `;
        });
        html += '</ul>';
        return html;  // Return the HTML representation of the tree
    }
// Fetch sponsor data from the server and process it into a tree structure
    window.onload = function() {
        axios.get("http://localhost:5000/show").then((response) => {
            const sponsors = response.data[0];  // Extract the sponsor data from the response
            const amn = response.data[1];
            const sponsorTree = buildSponsorTree(sponsors, amn);  // Build the tree from the flat list
            const treeHtml = renderSponsorTree(sponsorTree);  // Render the tree into HTML
            console.log(sponsorTree);
            document.getElementById("show").innerHTML = treeHtml;  // Display the tree on the page
        }).catch((error) => {
            console.error('Error fetching data:', error);  // Handle any errors
            alert('Error loading sponsor data.');
        });
    };
</script>

First of all, if I console.log(parentChain) in rootSponsors.forEach() function then the only value I get is -1 that is for the first id. The parent is being set correctly, that's why, I think it is safe to assume that the function is not getting the array of parent, so I think there's a fault in findParent() function.

Below is the updated output-

Raj (ID: 1) Amount - 500
    TotalAmount - 72682
    DistributedAmount - 0
    Ali (ID: 2) Amount - 500
        TotalAmount - 72182
        DistributedAmount - 0
        Riya (ID: 3) Amount - 1850
            TotalAmount - 44004
            DistributedAmount - 0
            Piya (ID: 4) Amount - 300
                TotalAmount - 42054
                DistributedAmount - 0
                Sana (ID: 5) Amount - 900
                    TotalAmount - 39424
                    DistributedAmount - 0
                    Dani (ID: 6) Amount - 9870
                        TotalAmount - 28290
                        DistributedAmount - 0
                        Uri (ID: 7) Amount - 6100
                            TotalAmount - 6100
                            DistributedAmount - 0
                        Pari (ID: 10) Amount - 1480
                            TotalAmount - 1480
                            DistributedAmount - 0
                        Lara (ID: 11) Amount - 6540
                            TotalAmount - 6540
                            DistributedAmount - 0
                        Rai (ID: 16) Amount - 1300
                            TotalAmount - 1300
                            DistributedAmount - 0
                        abv (ID: 21) Amount - 3000
                            TotalAmount - 3000
                            DistributedAmount - 0
                    Isha (ID: 14) Amount - 10000
                        TotalAmount - 10000
                        DistributedAmount - 0
                    Jass (ID: 23) Amount - 234
                        TotalAmount - 234
                        DistributedAmount - 0
                Faliz (ID: 9) Amount - 140
                    TotalAmount - 140
                    DistributedAmount - 0
                Ravi (ID: 15) Amount - 1000
                    TotalAmount - 2190
                    DistributedAmount - 0
                    Harsh (ID: 18) Amount - 890
                        TotalAmount - 1190
                        DistributedAmount - 0
                        Jake (ID: 20) Amount - 300
                            TotalAmount - 300
                            DistributedAmount - 0
            Lily (ID: 8) Amount - 100
                TotalAmount - 100
                DistributedAmount - 0
        Daya (ID: 12) Amount - 3158
            TotalAmount - 10813
            DistributedAmount - 0
            Goli (ID: 22) Amount - 7655
                TotalAmount - 7655
                DistributedAmount - 0
        Navi (ID: 13) Amount - 7865
            TotalAmount - 16865
            DistributedAmount - 0
            Isha (ID: 17) Amount - 100
                TotalAmount - 100
                DistributedAmount - 0
            Jay (ID: 19) Amount - 8900
                TotalAmount - 8900
                DistributedAmount - 0

This is the backend-

app.get("/show", async (req, res) => {
    try {
        const data = await sponsorModel.find();
        const amount = await amountModel.aggregate([
            {
                $group:
                {
                    _id: "$id",
                    totalAmount: { $sum: "$amount" }
                }
            }
        ]);
        res.status(200).json([data, amount]);
    } catch (error) {
        res.status(500).json(error);
    }
});

Below is the json format of [data, amount]. I would like to share the rootSponsors array but I can't JSON.stringify() cause of error "cyclic object" which is caused by the parent object in the array. TotalAmount is the sponsor.amount to be used for percentage distribution.

     [

  [
    {
      "_id": "67caa8142b8e8b77b654f8a3",
      "sponsor_id": -1,
      "id": 1,
      "name": "Raj"
    },
    {
      "_id": "67cab8c6fd720cf98ab076b3",
      "sponsor_id": 1,
      "id": 2,
      "name": "Ali",
      "createdAt": "2025-03-07T09:13:42.570Z",
      "updatedAt": "2025-03-07T09:13:42.570Z",
      "__v": 0
    },
    {
      "_id": "67cab909fd720cf98ab076b5",
      "sponsor_id": 2,
      "id": 3,
      "name": "Riya",
      "createdAt": "2025-03-07T09:14:49.888Z",
      "updatedAt": "2025-03-07T09:14:49.888Z",
      "__v": 0
    },
    {
      "_id": "67cab94afd720cf98ab076b7",
      "sponsor_id": 3,
      "id": 4,
      "name": "Piya",
      "createdAt": "2025-03-07T09:15:54.239Z",
      "updatedAt": "2025-03-07T09:15:54.239Z",
      "__v": 0
    },
    {
      "_id": "67cab958fd720cf98ab076b9",
      "sponsor_id": 4,
      "id": 5,
      "name": "Sana",
      "createdAt": "2025-03-07T09:16:08.782Z",
      "updatedAt": "2025-03-07T09:16:08.782Z",
      "__v": 0
    },
    {
      "_id": "67cab963fd720cf98ab076bb",
      "sponsor_id": 5,
      "id": 6,
      "name": "Dani",
      "createdAt": "2025-03-07T09:16:19.290Z",
      "updatedAt": "2025-03-07T09:16:19.290Z",
      "__v": 0
    },
    {
      "_id": "67cab96dfd720cf98ab076bd",
      "sponsor_id": 6,
      "id": 7,
      "name": "Uri",
      "createdAt": "2025-03-07T09:16:29.569Z",
      "updatedAt": "2025-03-07T09:16:29.569Z",
      "__v": 0
    },
    {
      "_id": "67caba08b5fe93097d767c0f",
      "sponsor_id": 3,
      "id": 8,
      "name": "Lily",
      "createdAt": "2025-03-07T09:19:04.331Z",
      "updatedAt": "2025-03-07T09:19:04.331Z",
      "__v": 0
    },
    {
      "_id": "67cae4d682d0f91204972d62",
      "sponsor_id": 6,
      "id": 10,
      "name": "Pari",
      "createdAt": "2025-03-07T12:21:42.269Z",
      "updatedAt": "2025-03-07T12:21:42.269Z",
      "__v": 0
    },
    {
      "_id": "67cae91d3aa5b379a3fe8c8c",
      "sponsor_id": 6,
      "id": 11,
      "name": "Lara",
      "createdAt": "2025-03-07T12:39:57.814Z",
      "updatedAt": "2025-03-07T12:39:57.814Z",
      "__v": 0
    },
    {
      "_id": "67ce8e966ae3e25a6a3a6cde",
      "sponsor_id": 4,
      "id": 9,
      "name": "Faliz",
      "createdAt": "2025-03-10T07:02:46.896Z",
      "updatedAt": "2025-03-10T07:02:46.896Z",
      "__v": 0
    },
    {
      "_id": "67ce9783805c7f87d9743983",
      "sponsor_id": 2,
      "id": 12,
      "name": "Daya",
      "createdAt": "2025-03-10T07:40:51.458Z",
      "updatedAt": "2025-03-10T07:40:51.458Z",
      "__v": 0
    },
    {
      "_id": "67ce9955d6777143ce661d99",
      "sponsor_id": 2,
      "id": 13,
      "name": "Navi",
      "createdAt": "2025-03-10T07:48:37.775Z",
      "updatedAt": "2025-03-10T07:48:37.775Z",
      "__v": 0
    },
    {
      "_id": "67ce9dec87d539ba4f03916b",
      "sponsor_id": 5,
      "id": 14,
      "name": "Isha",
      "createdAt": "2025-03-10T08:08:12.330Z",
      "updatedAt": "2025-03-10T08:08:12.330Z",
      "__v": 0
    },
    {
      "_id": "67ce9e2d87d539ba4f039172",
      "sponsor_id": 4,
      "id": 15,
      "name": "Ravi",
      "createdAt": "2025-03-10T08:09:17.160Z",
      "updatedAt": "2025-03-10T08:09:17.160Z",
      "__v": 0
    },
    {
      "_id": "67ce9ea587d539ba4f03917e",
      "sponsor_id": 6,
      "id": 16,
      "name": "Rai",
      "createdAt": "2025-03-10T08:11:17.992Z",
      "updatedAt": "2025-03-10T08:11:17.992Z",
      "__v": 0
    },
    {
      "_id": "67cea95daebde8fa92581fb3",
      "sponsor_id": 13,
      "id": 17,
      "name": "Isha",
      "createdAt": "2025-03-10T08:57:01.371Z",
      "updatedAt": "2025-03-10T08:57:01.371Z",
      "__v": 0
    },
    {
      "_id": "67cea9a3aebde8fa92581fb7",
      "sponsor_id": 15,
      "id": 18,
      "name": "Harsh",
      "createdAt": "2025-03-10T08:58:11.272Z",
      "updatedAt": "2025-03-10T08:58:11.272Z",
      "__v": 0
    },
    {
      "_id": "67ceaa3faebde8fa92581fba",
      "sponsor_id": 13,
      "id": 19,
      "name": "Jay",
      "createdAt": "2025-03-10T09:00:47.578Z",
      "updatedAt": "2025-03-10T09:00:47.578Z",
      "__v": 0
    },
    {
      "_id": "67ceaa75aebde8fa92581fc1",
      "sponsor_id": 18,
      "id": 20,
      "name": "Jake",
      "createdAt": "2025-03-10T09:01:41.900Z",
      "updatedAt": "2025-03-10T09:01:41.900Z",
      "__v": 0
    },
    {
      "_id": "67ceb1d24fd3bf80b72d84e7",
      "sponsor_id": 6,
      "id": 21,
      "name": "abv",
      "createdAt": "2025-03-10T09:33:06.983Z",
      "updatedAt": "2025-03-10T09:33:06.983Z",
      "__v": 0
    },
    {
      "_id": "67cebe105b9e6efa0dadbc88",
      "sponsor_id": 12,
      "id": 22,
      "name": "Goli",
      "createdAt": "2025-03-10T10:25:20.968Z",
      "updatedAt": "2025-03-10T10:25:20.968Z",
      "__v": 0
    },
    {
      "_id": "67d12ce9a6c9160098726b07",
      "sponsor_id": 5,
      "id": 23,
      "name": "Jass",
      "createdAt": "2025-03-12T06:42:49.386Z",
      "updatedAt": "2025-03-12T06:42:49.386Z",
      "__v": 0
    }
  ],
  [
    {
      "_id": 10,
      "totalAmount": 1480
    },
    {
      "_id": 20,
      "totalAmount": 300
    },
    {
      "_id": 8,
      "totalAmount": 100
    },
    {
      "_id": 21,
      "totalAmount": 3000
    },
    {
      "_id": 5,
      "totalAmount": 900
    },
    {
      "_id": 16,
      "totalAmount": 1300
    },
    {
      "_id": 3,
      "totalAmount": 1850
    },
    {
      "_id": 14,
      "totalAmount": 10000
    },
    {
      "_id": 9,
      "totalAmount": 140
    },
    {
      "_id": 23,
      "totalAmount": 234
    },
    {
      "_id": 18,
      "totalAmount": 890
    },
    {
      "_id": 4,
      "totalAmount": 300
    },
    {
      "_id": 6,
      "totalAmount": 9870
    },
    {
      "_id": 2,
      "totalAmount": 500
    },
    {
      "_id": 17,
      "totalAmount": 100
    },
    {
      "_id": 19,
      "totalAmount": 8900
    },
    {
      "_id": 11,
      "totalAmount": 6540
    },
    {
      "_id": 15,
      "totalAmount": 1000
    },
    {
      "_id": 1,
      "totalAmount": 500
    },
    {
      "_id": 12,
      "totalAmount": 3158
    },
    {
      "_id": 13,
      "totalAmount": 7865
    },
    {
      "_id": 7,
      "totalAmount": 6100
    },
    {
      "_id": 22,
      "totalAmount": 7655
    }
  ]
]

I can't grasp the exact problem here, kindly guide me through this. Thank you!

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论