UNPKG

gramex-weighted-tree

Version:

Horizontal tree with weights and click functionality and data configuration. This chart takes maximum number of children to be shown,all other values will be clubbed together and shown as others.

1,018 lines (965 loc) 31.9 kB
/* exported weighted_tree_comp */ /* global d3,g1 */ var url = parse_url_wt(), max_child, img_folder, config, asset_path; const debounce = (func, delay) => { let debounceTimer; return function () { const context = this; const args = arguments; clearTimeout(debounceTimer); debounceTimer = setTimeout(() => func.apply(context, args), delay); }; }; function weighted_tree_comp( treeData, selector, hier_ord, org_data, metric, ord_map, c_config, i_asset_path ) { config = c_config, asset_path = i_asset_path; var separation = config.separation || 65, node_sep = 32, base_sep = 20; var sizing = config.sizing || "large"; max_child = config.max_child; var actual_data = treeData; var it_condition = true; img_folder = asset_path; while (it_condition) { if ( actual_data["children"] == undefined || actual_data["children"].length === 0 ) { it_condition = false; } else { actual_data = _.minBy(actual_data.children, function (o) { return o.acc_counts; }); } } var tree_clicked_url = "Promoter-NA-Tier1"; var g_redrw = true, depth_var = 5; $(selector).empty(); if (treeData.length == 0) { treeData = { // "name": "Top Level", children: [ { name: "Tier -1", children: [ { name: "EA", children: [ { name: "Direct", children: [ { name: "Top", children: [ { name: "Promoter", size: 5, color: "red" }, { name: "Passive", size: 2, color: "red" }, { name: "Detractor", size: 0, color: "red" }, { name: "Non Respondents", size: 1, color: "red" }, { name: "Non surveyed", size: 7, color: "red" }, ], size: 2, color: "red", }, { name: "Non Top", size: 4, color: "red" }, ], size: 2, color: "red", }, { name: "Channel", children: [{ name: "Top", size: 0, color: "red" }], size: 5, color: "red", }, ], size: 20, color: "red", }, { name: "APJ", size: 8, color: "red" }, ], size: 20, color: "red", }, { name: "Tier - 2", children: [], size: 10, color: "green", }, ], }; } // Set the dimensions and margins of the diagram var margin = config.margin || { top: 0, right: 10, bottom: 0, left: 10 }, parent_width = $(selector).width() || config.width || 600, // parent_height = 400, parent_height = $(selector).height() || config.height || 500, // width = 1260 - margin.left - margin.right, // height = 400 - margin.top - margin.bottom; width = parent_width - margin.left - margin.right, height = parent_height - margin.top - margin.bottom; $(".cx-tooltip").remove(); var svg = d3 .select(selector) .append("svg") .attr("id", "weightd_tree") .attr("viewBox", "0 0 " + width + " " + (height + node_sep)) .attr("preserveAspectRatio", "xMidYMid meet") .attr("width", "100%") // .attr("width", width + margin.right + margin.left) .attr("height", height) .append("g") .attr("class", "svg-g-class") // .attr("transform", "translate(" // + margin.left + "," + margin.top + ")"); .attr("transform", "translate(" + (110 - 30) + "," + (height + node_sep) / 2 + ")"); // var sizing = // treeData.children.length > 10 // ? "small" // : treeData.children.length > 4 // ? "medium" // : "large", var size_mapping = { small: { link: [6, 20], bubble: [2, 10], nSizeMax: 2.5, nSizeMin: 2.5 }, medium: { link: [8, 30], bubble: [3, 15], nSizeMax: 3.5, nSizeMin: 3.5 }, large: { link: [10, 47], bubble: [6, 25], nSizeMax: 9, nSizeMin: 5 }, }; var nSize = window.screen.availWidth > 1366 ? size_mapping[sizing]["nSizeMax"] : size_mapping[sizing]["nSizeMin"]; while (((size_mapping[sizing]["bubble"][1] + size_mapping[sizing]["bubble"][0]) / 2 + base_sep * nSize) * (treeData.children.length - 1) >= height) { base_sep -= 1; node_sep -= 1; nSize -= 1; separation -= 5; size_mapping[sizing]["bubble"] = [size_mapping[sizing]["bubble"][0] - 1, size_mapping[sizing]["bubble"][1] - 1] } var min_path = actual_data.acc_counts, max_path = _.maxBy(treeData["children"], "acc_counts").acc_counts, i = 0, duration = 750, root, // d3.scaleSqrt().domain([1000, 29061202882.962242]).range([5,30]) link_width = d3 .scaleSqrt() .domain([min_path, max_path]) .range(size_mapping[sizing]["link"]) .clamp(true); var bubble_width = d3 .scaleSqrt() .domain([min_path, max_path]) .range(size_mapping[sizing]["bubble"]); // declares a tree layout and assigns the size var treemap = d3 .tree() .size([height, width]) .nodeSize([nSize, 10]) //make node space .separation(function (a, b) { var spe; if (a.depth != 0 && a.depth != 1) { if (a.depth == 4 || a.depth == 5) { spe = a.parent == b.parent ? node_sep : separation; } else { spe = a.parent == b.parent ? node_sep : separation; } } else { spe = a.parent == b.parent ? base_sep : separation; } console.log(spe) return spe; }); // make separation accessor 1; var nodes, links; // Assigns parent, children, height, depth root = d3.hierarchy(treeData, function (d) { return d.children; }); root.x0 = height / 2; root.y0 = 0; // Collapse after the second level root.children.forEach(collapse); update(root); // Collapse the node and all it's children function collapse(d) { if (d.children) { d._children = d.children; d._children.forEach(collapse); d.children = null; } } function mouseover() { // var hovered_classes = d.data.id.split("-"); // d3.selectAll(`path`).style("stroke-opacity", 0.25); // d3.selectAll(`circle`).style("fill-opacity", 0.25); // _.each(hovered_classes, function (hc) { // // d3.selectAll(`path:not(.${hc})`).style('stroke-opacity', 0.25) // d3.select("path." + hc).style("stroke-opacity", 1); // d3.select("circle." + hc).style("fill-opacity", 1); // }); } function mouseout() { // d3.selectAll(".link").style("stroke-opacity", 1); // d3.selectAll(".node").style("fill-opacity", 1); // d3.selectAll("circle").style("fill-opacity", 0.5); // d3.select("circle#overall").style("fill-opacity", 1); } function update(source) { // Assigns the x and y position for the nodes var treeData = treemap(root); // Compute the new tree layout. links = treeData.descendants().slice(1); nodes = treeData.descendants(); // Highlight the category legend var all_btns = $(".weighted-tree-hirer li").find("button"); all_btns.removeClass("bg-info"); all_btns.find(".cx-hier-num").removeClass("text-info bg-white"); all_btns.find(".cx-hier-name").removeClass("text-white"); all_btns.find("img").remove(); all_btns.prepend('<img src="' + img_folder + 'drag-grey.svg" alt="drag">'); all_btns.addClass("bg-white"); all_btns.find(".cx-hier-num").addClass("bg-color4 text-white"); all_btns.find(".cx-hier-name").addClass("text-color34"); var _depth = _.chain(nodes).map("depth").max().value(); var next_section = $(".weighted-tree-hirer li") .eq(_depth) .prevAll() .find("button"); if (next_section.length === 0) { next_section = $(".weighted-tree-hirer li").find("button"); } next_section.find("img").remove(); next_section.prepend('<img src="' + img_folder + 'drag-white.svg" alt="drag">'); next_section.toggleClass("bg-info bg-white"); next_section.find(".cx-hier-num").toggleClass("bg-color4 bg-white"); next_section.find(".cx-hier-num").toggleClass("text-white text-info"); next_section.find(".cx-hier-name").toggleClass("text-color34 text-white"); // Normalize for fixed-depth. nodes.forEach(function (d) { d.y = window.screen.availWidth > 1366 ? d.depth * 360 : d.depth * 240; // if (prev_pos) { d.x = d.x / 10 } }); // Store the old positions for transition. nodes.forEach(function (d) { d.x0 = d.x; d.y0 = d.y; }); // ****************** links section *************************** // Update the links... var link = svg.selectAll("path.link").data(links, function (d) { return d.id; }); // Enter any new links at the parent's previous position. var linkEnter = link .enter() .insert("path", "g") .attr("class", function (d, i) { if (d.data.name != null) { return `link link-${i} ${d.data.name .toString() .replace(/ /g, "_") .replace(/[0-9]-/, "")}`; } }) .attr("d", function () { var o; o = { x: source.x, y: source.y }; // if (d.depth != 1 && d.depth != 0) { // // if() // path = diagonal(o, o) // } else { // path = diagonal(o, o) // } return diagonal(o, o); }) .attr("stroke", function (d) { return d.data.color || "#00447C"; }) .attr("stroke-width", function (d) { return (link_width(d.data.acc_counts) || 1) + "px"; }) .style("fill", "none") .style("opacity", "0.3") .style("pointer-events", "none") .attr("stroke-linecap", "round"); // UPDATE var linkUpdate = linkEnter.merge(link); // Transition back to the parent element position linkUpdate .transition() .duration(duration) .attr("d", function (d) { var path; if (d.depth != 1 && d.depth != 0) { path = diagonal0(d, d.parent, d.depth, d.children); } else { path = diagonal(d, d.parent); } return path; }); // Remove any exiting links link .exit() .transition() .duration(duration) .attr("d", function () { var o = { x: source.x, y: source.y }; return diagonal(o, o); }) .remove(); // Creates a curved (diagonal) path from parent to the child nodes function diagonal(s, d) { return `M ${s.y} ${s.x} C ${(s.y + d.y) / 2} ${s.x}, ${(s.y + d.y) / 2} ${d.x}, ${d.y} ${d.x}`; } function diagonal0(s, d, depth) { // var x = 400/children.length; if (depth == 2) { s.x = s.x * 0.38; } else if (depth == 3) { s.x = s.x * 0.25; } else if (depth == 4) { s.x = s.x * 0.18; } else if (depth == 5) { s.x = s.x * 0.17; } // return `M ${s.y} ${s.x} // L ${d.y} ${d.x}` return `M ${s.y} ${s.x} C ${(s.y + d.y) / 2} ${s.x}, ${(s.y + d.y) / 2} ${d.x}, ${d.y} ${d.x}`; } // var ly = svg.layout.diagonal.projection() // ****************** Nodes section *************************** // Update the nodes... var node = svg.selectAll("g.node").data(nodes, function (d) { return d.id || (d.id = ++i); }); // Enter any new modes at the parent's previous position. var nodeEnter = node .enter() .append("g") .attr("class", "node") .attr("id", function (d) { return `g_${d.data.name}`; }) .attr("transform", function () { // trans = "translate(" + source.y0 + "," + (source.x0) + ")"; return "translate(" + source.y + "," + source.x + ")"; }) .on( "click", debounce(function (event, d) { if (d.data == undefined) { d = event; } if (d.id > 1) { click(d, this); } }, 500) ); // .on("contextmenu", dbl_click) // .on("mouseover", mouseover) // Add Circle for the nodes nodeEnter .append("circle") .attr("class", function (d) { return `node tooltip-class ${d.data.name != undefined ? d.data.name .toString() .replace(/ /g, "_") .replace(/[0-9]-/, "") : "" }`; }) .attr("id", function (d) { return d.data.id; }) .attr("r", function (d) { return bubble_width(d.data.acc_counts) || 10; }) .style("fill", function (d) { return d.data.color || "#00447C"; // return d._children ? "lightsteelblue" : "#fff"; }) .style("fill-opacity", function (d) { return d.id == 1 ? 1 : 0.5; }) .on("mouseover", mouseover) .on("mouseout", mouseout); var lab = parse_url_wt().searchKey.labels || "on"; nodeEnter .append("text") .attr("class", "bubble-text text-capitalize") .attr("dy", ".35em") .attr("x", function (d) { // return -25; return d.id == 1 ? -bubble_width(d.data.acc_counts) - 20 : bubble_width(d.data.acc_counts) + 5; }) .attr("y", function () { return 0; // return d.id == 1 ? 0 : bubble_width(d.data.size) + 5 || 20; }) .attr("text-anchor", function (d) { // return "end"; return d.id == 1 ? "end" : "start"; }) .attr("font-size", 11) .text(function (d) { var disp_txt = d.data.name == undefined ? "overall" : d.data.name; if (d.depth == 0) { var prev_id = parse_url_wt().searchKey.prev_id || "overall"; update_url_wt({ prev_id: prev_id != "overall" && disp_txt != "overall" ? _.join([prev_id, disp_txt], "-") : disp_txt, }); } if (d.depth == 4) { return window.screen.availWidth >= 1920 ? disp_txt : truncateString(disp_txt, 6); } else { return window.screen.availWidth >= 1920 ? disp_txt : truncateString(disp_txt, 16); } }) .style("display", function () { return lab == "on" ? "" : "none"; }); // .text(function (d) { return d.data.name || ((parse_url_wt().searchKey.parent_tree || "overall")+ " : "+format_revenue_number(max_path)); }); nodeEnter .append("text") .attr("class", "bubble-text text-capitalize") .attr("dy", ".35em") .attr("x", function (d) { // return -25; return d.id == 1 ? -bubble_width(d.data.acc_counts) - 15 : bubble_width(d.data.acc_counts) + 5; }) .attr("y", function (d) { // return 0; return d.id == 1 ? 15 : sizing == "small" ? 10 : sizing == "medium" ? 12 : 15 || 20; }) .attr("text-anchor", function (d) { // return "start"; return d.id == 1 ? "end" : "start"; }) .attr("font-weight", "bold") .attr("font-size", function (d) { return d.id == 1 ? 16 : sizing == "small" ? 8 : sizing == "medium" ? 10 : 11; }) .text(function (d) { var disp_txt = format_revenue_number(d.data.acc_counts); // if (d.depth == 0) { // var prev_id = parse_url_wt().searchKey.prev_id || "overall" // update_url_wt({ "prev_id": (prev_id != "overall" && disp_txt != "overall") ? _.join([prev_id, disp_txt], "-") : disp_txt }) // } var prefixx = metric.toLowerCase() == "revenue" ? "$" : ""; return sizing == "small" ? "" : prefixx + `${disp_txt.replace(/\.0$/, "")}`; }) .style("display", function () { return lab == "on" ? "" : "none"; }); // } // Add labels for the nodes // UPDATE var nodeUpdate = nodeEnter.merge(node); // Transition to the proper position for the node nodeUpdate .transition() .duration(duration) .attr("transform", function (d) { return "translate(" + d.y + "," + d.x + ")"; }); // Update the node attributes and style nodeUpdate .select("circle.node") // .attr("r", 10) .attr("r", function (d) { return "name" in d.data ? bubble_width(d.data.acc_counts) : bubble_width(d.data.acc_counts) + 15; }) .style("fill", function (d) { var names = d.data.name != undefined ? d.data.name .toString() .replace(/ /g, "_") .replace(/[0-9]-/, "") : d.data.name; var url_strs = tree_clicked_url ? tree_clicked_url.split("-") : ""; if (_.includes(url_strs, names) && (g_redrw || depth_var < d.depth)) { g_redrw = false; depth_var = d.depth; click(d, $(this).parent()); } return d.data.color || "#00447C"; // return d._children ? "lightsteelblue" : "#fff"; }) .attr("cursor", "pointer"); // Remove any exiting nodes var nodeExit = node .exit() .transition() .duration(duration) .attr("class", "pointer-events-none") .attr("transform", function () { return "translate(" + source.y + "," + source.x + ")"; }) .remove(); // On exit reduce the node circles size to 0 nodeExit.select("circle").attr("r", function (d) { return bubble_width(d.data.acc_counts) || 10; }); // .attr("r", 1e-6); // On exit reduce the opacity of text labels nodeExit.select("text").style("fill-opacity", 1e-6); } // Toggle children on click. function click(d, c) { var curr_id = $(c).find("circle")[0].id; // If the node has a parent, then collapse its child nodes // except for this clicked node. if (d.parent) { d.parent.children.forEach(function (element) { if (d !== element) { collapse(element); } }); } if (d.children) { d._children = d.children; d.children = null; var curr_url_id = _.filter( parse_url_wt().searchKey.tree_clicked.split("-"), (k) => k != d.data.name ); curr_url_id = curr_url_id.length == 0 ? null : curr_url_id.join("-"); update_url_wt({ tree_clicked: curr_url_id }); update_png_url(); } else { d.children = d._children; d._children = null; update_url_wt({ tree_clicked: curr_id }); update_png_url(); } update(d); } function update_png_url() { let sectional_name = get_sectional_name([ $("#dropdownMenuButton-2-b2b").text().trim(), ]); let sec2_file_name = sectional_name; let download_png_url = "/capture?ext=png&width=1366&height=800&delay=2000&selector=.sec2_charts&url=" + encodeURIComponent(location.href) + "&dwnld=true&file=Leads Summary_" + sec2_file_name; $("#sec2_png").attr("href", download_png_url); } $("g.node").insertBefore(".link-0"); $(document).ready(function () { $(".map-tree-hirer").dragndrop({ onDrop: function (element, droppedElement) { var url = update_url_wt(params); let ind = 1; let sel_id = $(droppedElement).find("button").attr("id"); let def_ord = parse_url_wt().searchKey.def_ord; _.each($(".map-tree-hirer .cx-hier-num"), function (d) { $(d).text(ind++); }); // metric_map = url.searchKey.metric_tp || "gtm" let _ord = _.map($("span.cx-hier-name "), (d) => _.toLower($(d).text()) ); // loading_section("show", "sec5"); let metric_tp_5 = sel_id; // if(!reverted){ if ( metric_tp_5 != _ord .join(",") .replace(def_ord + ",", "") .split(",")[0] ) { metric_tp_5 = _ord .join(",") .replace(def_ord + ",", "") .split(",")[0]; } var params = { map_ord: _ord, metric_tp_5: metric_tp_5 }, l_type = url.searchKey.l_type; // Removing comparision if it is already in place if (l_type != undefined) { params["l_type"] = null; let compre_key = def_ord.split(","); compre_key = compre_key[compre_key.length - 1]; let cmpre_val = url.searchKey[[compre_key + "_id"]]; params[[compre_key + "_5"]] = cmpre_val; params["def_view"] = "sublevel"; } url = update_url_wt(params); redraw_chart_wt(_.cloneDeep(treeData), selector, sizing); // button_highlight(_.indexOf(_ord, metric_tp_5) + 1); $(".map-tree-hirer").dragndrop("reload"); // } }, }); }); function redraw_chart_wt(data, selector) { var hier_data = { children: hirerachial_struct(data, hier_ord, metric, max_child), type: "overall", id: "overall", }; console.log(hier_data) hier_data["size"] = _.sumBy(hier_data["children"], "acc_counts") / 100; hier_data["acc_counts"] = _.sumBy(hier_data["children"], "acc_counts"); weighted_tree_comp(hier_data, selector, hier_ord, org_data, metric, ord_map, config, asset_path); } $(".weighted-tree-hirer").dragndrop({ onDrop: function () { update_url_wt({ tree_clicked: null }); var hier_ord = [], index = 1; _.each($(".jqdndLoaded").children(), function (i) { $(i).find("img").remove(); $(i).find(".tree-index").html(index); $(i) .find("button") .removeClass("custom-color-btn-selected") .addClass("custom-color-btn-deselected"); $(i).prepend('<img src="' + img_folder + 'drag-white.svg" alt="drag">'); if (index != $(".jqdndLoaded").children().length) $(i).append('<img src="' + img_folder + 'arrow.svg" alt="arrow">'); index = index + 1; update_url_wt({ tree_ord: hier_ord, tree_clicked: url.searchKey.tree_clicked || "Converted-Inquiry-New", }); return hier_ord.push($(i).find("button").val()); }); // $(i).last().find('figure').css('display', 'none') hier_ord = _.filter(hier_ord); var segment = parse_url_wt().searchKey.segment || "1"; if (segment !== "1") { hier_ord = _.unionWith(hier_ord, ["top_nontop"], _.isEqual); } if (segment == "1") { hier_ord = _.without(hier_ord, "top_nontop"); } update_url_wt({ tree_ord: hier_ord, tree_clicked: url.searchKey.tree_clicked || "Converted-Inquiry-New", }); var all_nodes = $(".weighted-tree-hirer li button"); all_nodes.removeClass("bg-info"); all_nodes.prepend('<img src="' + img_folder + 'drag-grey.svg" alt="drag">'); all_nodes.find(".cx-hier-num").removeClass("bg-white text-info"); all_nodes.find(".cx-hier-name").removeClass("text-white"); all_nodes.addClass("bg-white"); all_nodes.find(".cx-hier-num").addClass("bg-color4 text-white"); all_nodes.find(".cx-hier-name").addClass("text-color34"); var _first_node = $(".weighted-tree-hirer li button").first(); _first_node.find("img").first().remove(); _first_node.toggleClass("bg-info bg-white"); _first_node.prepend('<img src="' + img_folder + 'drag-white.svg" alt="drag">'); _first_node.find(".cx-hier-num").toggleClass("bg-color4 bg-white"); _first_node.find(".cx-hier-num").toggleClass("text-white text-info"); _first_node.find(".cx-hier-name").toggleClass("text-color34 text-white"); render_weighted_tree( selector, hier_ord, org_data, false, sizing, metric, ord_map ); }, }); } function render_weighted_tree( comp_id, hier_ord, data_set, drag_val = true, sizing, metric, ord_map ) { console.log(hier_ord) var def_hier_ord = hier_ord; $("button[value='rtms']").show(); var uri = parse_url_wt().update({ tree_ord: def_hier_ord, tree_clicked: drag_val ? url.searchKey.tree_clicked || "0-AZ-85705" : null, }); history.pushState({}, "", "?" + uri.search); let data = data_set; if (data.length != 0) { var filt_data = data_set, hirer_ord = hier_ord.length > 0 ? hier_ord : def_hier_ord; var hier_data = { children: hirerachial_struct(data, hirer_ord, metric, max_child), type: "overall", id: "overall", }; hier_data["size"] = _.sumBy(hier_data["children"], "size") / 100; hier_data["acc_counts"] = _.sumBy(hier_data["children"], "acc_counts"); weighted_tree_comp( hier_data, comp_id, hirer_ord, filt_data, metric, ord_map, config, asset_path ); } else { $(".cx_toggle").addClass("invisible").removeClass("visible"); $(comp_id + " img").width("1000"); } } function truncateString(str, n) { if (str.length > n) { return str.substring(0, n) + "..."; } else { return str; } } function parse_url_wt() { return g1.url.parse(location.href); } function update_url_wt(obj) { _.each(obj, function (d, i) { if (d != null && Array.isArray(d)) if (d.length > 1) obj[i] = d.join(","); }); var url = parse_url_wt().update(obj); history.pushState({}, "", "?" + url.search); return url; } const formatter = new Intl.NumberFormat("en", { notation: "compact", }); function format_revenue_number(num) { return formatter.format(Math.round(num / 10) * 10); } function get_sectional_name(required_params) { if (required_params.length != 0) { let f_name = ""; for (let q_param in required_params) { f_name = f_name !== "" ? "_" + f_name + "_" + required_params[q_param] : f_name + required_params[q_param]; } return f_name; } } function hirerachial_struct(data, hirer_ord, metric, max_chl) { max_child = max_chl; data = _.each(data, function (d) { //d.nps = full_name[d.nps] d.conversion_status == "unknown" ? "Others" : d.conversion_status; }); var first_breadcrumb = hirer_ord[0]; var bubble_colr = first_breadcrumb == "lead_conversion" ? { Promoter: "#06a241", Passive: "#f06f1a", Detractor: "#940311", "Non Respondents": "#b7dcdb", "Non Surveyed": "#D9D9D9", } : ["#60386C", "#1676cd", "#e373a2", "#ee6410", "#2cc0bb"]; // data = _.filter(data, d => d[metric] != 0) var lev_1_data = max_groupby_technique(data, hirer_ord[0], max_child, metric), lev_1_keys = _.keys(lev_1_data); // _.some(values, (el) => _.includes(text, el)) return _.filter( _.map(lev_1_data, function (lev_1, i) { var bub_colr = first_breadcrumb == "lead_conversion" ? bubble_colr[lev_1[0]["lead_conversion"]] : bubble_colr[_.indexOf(lev_1_keys, i)]; //nps segment data i = i.replace(/ /g, "_").replace(/[0-9]-/, ""); return { name: lev_1[0][hirer_ord[0]], children: _.filter( _.map( max_groupby_technique(lev_1, hirer_ord[1], max_child, metric), function (l3, j) { //tier data j = j.replace(/ /g, "_").replace(/[0-9]-/, ""); return { name: l3[0][hirer_ord[1]], children: _.filter( _.map( max_groupby_technique(l3, hirer_ord[2], max_child, metric), function (l5, k) { //regions data k = k.replace(/ /g, "_").replace(/[0-9]-/, ""); return { name: l5[0][hirer_ord[2]], size: _.sumBy(l5, metric), acc_counts: _.sumBy(l5, metric), color: bub_colr, type: hirer_ord[2], id: _.join([i, j, k], "-"), children: _.filter( _.map( max_groupby_technique( l5, hirer_ord[3], max_child, metric ), function (l6, l) { //regions data k = k.replace(/ /g, "_").replace(/[0-9]-/, ""); return { name: l6[0][hirer_ord[3]], size: _.sumBy(l6, metric), acc_counts: _.sumBy(l6, metric), color: bub_colr, type: hirer_ord[3], id: _.join([j, k, l], "-"), }; } ), "name" ), }; } ), "name" ), size: _.sumBy(l3, metric), acc_counts: _.sumBy(l3, metric), color: bub_colr, type: hirer_ord[1], id: _.join([i, j], "-"), }; } ), "name" ), size: _.sumBy(lev_1, metric), acc_counts: _.sumBy(lev_1, metric), color: bub_colr, type: hirer_ord[0], id: i, }; }) ); } const pickHighest_tree = (obj, num = 1) => { const requiredObj = {}; if (num > Object.keys(obj).length) { return false; } Object.keys(obj) .sort((a, b) => obj[b] - obj[a]) .forEach((key, ind) => { if (ind < num) { requiredObj[key] = obj[key]; } }); return requiredObj; }; function max_groupby_technique(grdata, grp_column, max_child, metric) { var grp_data = _.cloneDeep(grdata); if ( max_child == undefined || _.uniq(_.map(grp_data, grp_column)).length <= max_child || grp_column == undefined ) { return _.groupBy(grp_data, function (gd) { return gd[grp_column]; }); } var grpd_obj, topN_rev = {}; grpd_obj = _.groupBy(grp_data, function (gd) { return gd[grp_column]; }); _.each(grpd_obj, function (a, k) { var tot = _.sumBy(a, metric); topN_rev[k.toString()] = tot; }); var obj_len = Object.keys(topN_rev).length; var topN = Object.keys( pickHighest_tree(topN_rev, obj_len < max_child ? obj_len : max_child) ); _.each(grp_data, function (d) { if (!topN.includes(d[grp_column].toString())) { d[grp_column] = "Others"; } }); var out_data = _.groupBy(grp_data, function (gd) { return gd[grp_column]; }); topN.push("Others"); var sorteddata = topN.reduce((objEntries, key) => { objEntries[key] = out_data[key]; return objEntries; }, {}); return sorteddata; } $("body") .on("mouseover", ".drag_btn", function () { var drag_fn = $(this).parent().parent().hasClass("map-tree-hirer"); if (drag_fn) { $(this).prepend( '<img src="' + img_folder + 'left-arrow.svg" class="drag_img pr-1" alt="left arrow" height="11" width="13">' ); $(this).append( '<img src="' + img_folder + 'right-arrow.svg" class="drag_img pl-1" alt="right arrow" height="11" width="13">' ); } }) .on("mouseout", ".drag_btn", function () { $(".drag_img").remove(); });