private createHierarchyItemElem()

in src/UXClient/Components/HierarchyNavigation/HierarchyNavigation.ts [1078:1208]


    private createHierarchyItemElem(hORi, key) {
        let self = this;
        let isHierarchyNode = hORi instanceof HierarchyNode;
        let hierarchyItemElem = d3.create('div').classed('tsi-hierarchyItem', true)
            .attr('style', `padding-left: ${hORi.isLeaf ? hORi.level * 18 + 20 : (hORi.level + 1) * 18 + 20}px`)
            .attr('tabindex', 0)
            .attr('arialabel', isHierarchyNode ? key : Utils.getTimeSeriesIdString(hORi))
            .attr('title', isHierarchyNode ? key : Utils.getTimeSeriesIdString(hORi))
            .attr("role", "treeitem").attr('aria-expanded', hORi.isExpanded)
            .on('click keydown', async function() {
                if (Utils.isKeyDownAndNotEnter(d3.event)) {return; }
                if (!isHierarchyNode) { // means it is an instance
                    d3.event.stopPropagation();
                    self.closeContextMenu();
                    let mouseElt = d3.mouse(this as any);
                    let target = self.hierarchyElem.select(function() { return this.parentNode});
                    let mouseWrapper = d3.mouse(target.node());
                    self.prepareForContextMenu(hORi, target, mouseWrapper[1], mouseElt[1]);
                    self.chartOptions.onInstanceClick(hORi);
                } else {
                    if (hORi.isExpanded) {
                        hORi.collapse();
                    } else {
                        await hORi.expand();
                    }
                }
            })
            .on('mouseover focus', function() {
                if (isHierarchyNode) {
                    if (d3.event.relatedTarget != d3.select(this.parentNode).select('.tsi-filter-icon').node()) {
                        (d3.select(this.parentNode).select('.tsi-filter-icon').node() as any).style.visibility = 'visible';
                    }
                }
            })
            .on('mouseleave blur', function() {
                if (isHierarchyNode) {
                    if (d3.event.relatedTarget != d3.select(this.parentNode).select('.tsi-filter-icon').node()) {
                        (d3.select(this.parentNode).select('.tsi-filter-icon').node() as any).style.visibility = 'hidden';
                    }
                }
            });

        if (isHierarchyNode) {
            hierarchyItemElem.append('span').classed('tsi-caret-icon', true).attr('style', `left: ${(hORi.level) * 18 + 20}px`);
            hierarchyItemElem.append('span').classed('tsi-name', true).text(key);
            hierarchyItemElem.append('span').classed('tsi-instanceCount', true).text(hORi.cumulativeInstanceCount);
            hierarchyItemElem.append('span').classed('tsi-hitCount', true).text(''); // hit count is the number of hierarchy nodes below, it is filled after expand is clicked for this node (after search is done for this path)

            hierarchyItemElem.append('div').classed('tsi-filter-icon', true).attr('title', this.getString('Add to Filter Path'))
                .attr('tabindex', 0)
                .attr('arialabel', this.getString('Add to Filter Path'))
                .attr('role', 'button')
                .on('click keydown', function() {
                    if (Utils.isKeyDownAndNotEnter(d3.event)) {return; }
                    self.path = hORi.path;
                    let pathListElem = d3.select('.tsi-path-list');
                    pathListElem.text('');
                    let pathToLoop = self.selectedHierarchyName !== HierarchySelectionValues.All ? hORi.path.slice(1) : hORi.path;
                    pathToLoop.forEach((a, i) => {
                        if (i > 0) {
                            pathListElem.append('span').text(' / ');
                        }
                        let pathName = self.hierarchyNodeIdentifier(a);
                        pathListElem.append('span').classed('tsi-path', true)
                            .text(pathName)
                            .attr('title', pathName)
                            .attr('tabindex', 0)
                            .attr('arialabel', pathName)
                            .on('click keydown', function () {
                                if (Utils.isKeyDownAndNotEnter(d3.event)) {return; }
                                self.path = self.path.slice(0, i + (self.selectedHierarchyName === HierarchySelectionValues.All ? 1 : 2));
                                d3.selectAll(pathListElem.selectAll('span').nodes().splice((i * 2) + 1, pathListElem.selectAll('span').nodes().length)).remove();
                                self.clearAndGetResults();
                            });
                    });
                    d3.select('.tsi-filter-clear').style('display', 'inline-block');
                    self.filterPathElem.classed('visible', true);
                    self.clearAndGetResults();
                }).on('mouseleave blur', function() {
                    if (d3.event.relatedTarget != d3.select((this as HTMLElement).parentNode)) {
                        (this as any).style.visibility = 'hidden';
                    }
                });
        } else {
            let spanElem = hierarchyItemElem.append('span').classed('tsi-name', true);
            Utils.appendFormattedElementsFromString(spanElem, this.instanceNodeStringToDisplay(hORi));
            
            if (hORi.highlights) {
                let hitsExist = false;
                let highlightDetails = hierarchyItemElem.append('div').classed('tsi-highlights-detail', true);
                if (hORi.highlights.description && this.hasHits(hORi.highlights.description)) {
                    hitsExist = true;
                    Utils.appendFormattedElementsFromString(highlightDetails, hORi.highlights.description);
                }
                let hitTuples = [];
                if (hORi.highlights.name && this.hasHits(Utils.getHighlightedTimeSeriesIdToDisplay(hORi))) {
                    hitsExist = true;
                    hitTuples.push([this.getString("Time Series ID"), Utils.getHighlightedTimeSeriesIdToDisplay(hORi)])
                }
                hORi.highlights.instanceFieldNames.forEach((ifn, idx) => {
                    var val = hORi.highlights.instanceFieldValues[idx];
                    if (this.hasHits(ifn) || this.hasHits(val)) {
                        hitsExist = true;
                        hitTuples.push([ifn, hORi.highlights.instanceFieldValues[idx]])
                    }
                });
                let rows = highlightDetails.append('table').selectAll("tr")
                    .data(hitTuples)
                    .enter()
                    .append("tr");
                let cells = rows.selectAll("td")
                    .data(function(d) {
                        return d;
                    });
                cells.enter()
                    .append("td")
                    .each(function(d) {
                        Utils.appendFormattedElementsFromString(d3.select(this), d);
                    })
                    .merge(cells);
                cells.exit().remove();
                rows.exit().remove();

                if (hitsExist) {
                    highlightDetails.style("display", "block");
                }
            }
        }

        return hierarchyItemElem;
    }