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!
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744307113a4567769.html
评论列表(0条)