UNPKG

tsiclient

Version:

--- [//]: <> (This content is similar to https://github.com/MicrosoftDocs/azure-docs/edit/main/includes/tsi-retirement.md)

498 lines (495 loc) 28.8 kB
import { a as __extends } from './tslib.es6-f952ba6f.js'; import { D as DataTypes, U as Utils, a as EventElementTypes } from './Utils-38a0872e.js'; import { select } from 'd3'; import { C as Component } from './Component-5173b5ea.js'; var NUMERICSPLITBYHEIGHT = 44; var NONNUMERICSPLITBYHEIGHT = 24; var Legend = /** @class */ (function (_super) { __extends(Legend, _super); function Legend(drawChart, renderTarget, legendWidth) { var _this = _super.call(this, renderTarget) || this; _this.renderSplitBys = function (aggKey, aggSelection, dataType, noSplitBys) { var splitByLabelData = Object.keys(_this.chartComponentData.timeArrays[aggKey]); var firstSplitBy = _this.chartComponentData.displayState[aggKey].splitBys[Object.keys(_this.chartComponentData.displayState[aggKey].splitBys)[0]]; var firstSplitByType = firstSplitBy ? firstSplitBy.visibleType : null; var isSame = Object.keys(_this.chartComponentData.displayState[aggKey].splitBys).reduce(function (isSame, curr) { return (firstSplitByType == _this.chartComponentData.displayState[aggKey].splitBys[curr].visibleType) && isSame; }, true); var showMoreSplitBys = function () { var oldShownSplitBys = _this.chartComponentData.displayState[aggKey].shownSplitBys; _this.chartComponentData.displayState[aggKey].shownSplitBys = Math.min(oldShownSplitBys + 20, splitByLabelData.length); if (oldShownSplitBys != _this.chartComponentData.displayState[aggKey].shownSplitBys) { _this.renderSplitBys(aggKey, aggSelection, dataType, noSplitBys); } }; var splitByContainer = aggSelection.selectAll(".tsi-splitByContainer").data([aggKey]); var splitByContainerEntered = splitByContainer.enter().append("div") .merge(splitByContainer) .classed("tsi-splitByContainer", true); var splitByLabels = splitByContainerEntered.selectAll('.tsi-splitByLabel') .data(splitByLabelData.slice(0, _this.chartComponentData.displayState[aggKey].shownSplitBys), function (d) { return d; }); var self = _this; var splitByLabelsEntered = splitByLabels .enter() .append("div") .merge(splitByLabels) .attr('role', _this.legendState === 'compact' ? 'button' : 'presentation') .attr('tabindex', _this.legendState === 'compact' ? '0' : '-1') .on('keypress', function (event, splitBy) { if (_this.legendState === 'compact' && (event.keyCode === 13 || event.keyCode === 32)) { //space or enter _this.toggleSplitByVisible(aggKey, splitBy); _this.drawChart(); event.preventDefault(); } }) .on("click", function (event, splitBy) { if (self.legendState == "compact") { self.toggleSplitByVisible(aggKey, splitBy); } else { self.toggleSticky(aggKey, splitBy); } self.drawChart(); }) .on("mouseover", function (event, splitBy) { event.stopPropagation(); self.labelMouseover(aggKey, splitBy); }) .on("mouseout", function (event) { event.stopPropagation(); self.svgSelection.selectAll(".tsi-valueElement") .attr("stroke-opacity", 1) .attr("fill-opacity", 1); self.labelMouseout(self.svgSelection, aggKey); }) .attr("class", function (splitBy, i) { var compact = (dataType !== DataTypes.Numeric) ? 'tsi-splitByLabelCompact' : ''; var shown = Utils.getAgVisible(self.chartComponentData.displayState, aggKey, splitBy) ? 'shown' : ''; return "tsi-splitByLabel tsi-splitByLabel " + compact + " " + shown; }) .classed("stickied", function (splitBy, i) { if (self.chartComponentData.stickiedKey != null) { return aggKey == self.chartComponentData.stickiedKey.aggregateKey && splitBy == self.chartComponentData.stickiedKey.splitBy; } }); var colors = Utils.createSplitByColors(self.chartComponentData.displayState, aggKey, self.chartOptions.keepSplitByColor); splitByLabelsEntered.each(function (splitBy, j) { var color = (self.chartComponentData.isFromHeatmap) ? self.chartComponentData.displayState[aggKey].color : colors[j]; if (dataType === DataTypes.Numeric || noSplitBys || self.legendState === 'compact') { var colorKey = select(this).selectAll('.tsi-colorKey').data([color]); var colorKeyEntered = colorKey.enter() .append("div") .attr("class", 'tsi-colorKey') .merge(colorKey); if (dataType === DataTypes.Numeric) { colorKeyEntered.style('background-color', function (d) { return d; }); } else { self.createNonNumericColorKey(dataType, colorKeyEntered, aggKey); } select(this).classed('tsi-nonCompactNonNumeric', (dataType === DataTypes.Categorical || dataType === DataTypes.Events) && this.legendState !== 'compact'); colorKey.exit().remove(); } else { select(this).selectAll('.tsi-colorKey').remove(); } if (select(this).select('.tsi-eyeIcon').empty()) { select(this).append("button") .attr("class", "tsi-eyeIcon") .attr('aria-label', function () { var showOrHide = self.chartComponentData.displayState[aggKey].splitBys[splitBy].visible ? self.getString('hide series') : self.getString('show series'); return showOrHide + " " + splitBy + " " + self.getString('in group') + " " + self.chartComponentData.displayState[aggKey].name; }) .attr('title', function () { return self.getString('Show/Hide values'); }) .on("click", function (event) { event.stopPropagation(); self.toggleSplitByVisible(aggKey, splitBy); select(this) .classed("shown", Utils.getAgVisible(self.chartComponentData.displayState, aggKey, splitBy)); self.drawChart(); }); } if (select(this).select('.tsi-seriesName').empty()) { var seriesName = select(this) .append('div') .attr('class', 'tsi-seriesName'); Utils.appendFormattedElementsFromString(seriesName, noSplitBys ? (self.chartComponentData.displayState[aggKey].name) : splitBy); } if (dataType === DataTypes.Numeric) { if (select(this).select('.tsi-seriesTypeSelection').empty()) { select(this).append("select") .attr('aria-label', self.getString("Series type selection for") + " " + splitBy + " " + self.getString('in group') + " " + self.chartComponentData.displayState[aggKey].name) .attr('class', 'tsi-seriesTypeSelection') .on("change", function (data) { var seriesType = select(this).property("value"); self.chartComponentData.displayState[aggKey].splitBys[splitBy].visibleType = seriesType; self.drawChart(); }) .on("click", function (event) { event.stopPropagation(); }); } select(this).select('.tsi-seriesTypeSelection') .each(function (d) { var typeLabels = select(this).selectAll('option') .data(function (data) { return self.chartComponentData.displayState[aggKey].splitBys[splitBy].types.map(function (type) { return { type: type, aggKey: aggKey, splitBy: splitBy, visibleMeasure: Utils.getAgVisibleMeasure(self.chartComponentData.displayState, aggKey, splitBy) }; }); }); typeLabels .enter() .append("option") .attr("class", "seriesTypeLabel") .merge(typeLabels) .property("selected", function (data) { return ((data.type == Utils.getAgVisibleMeasure(self.chartComponentData.displayState, data.aggKey, data.splitBy)) ? " selected" : ""); }) .text(function (data) { return data.type; }); typeLabels.exit().remove(); }); } else { select(this).selectAll('.tsi-seriesTypeSelection').remove(); } }); splitByLabels.exit().remove(); var shouldShowMore = self.chartComponentData.displayState[aggKey].shownSplitBys < splitByLabelData.length; splitByContainerEntered.selectAll('.tsi-legendShowMore').remove(); if (_this.legendState === 'shown' && shouldShowMore) { splitByContainerEntered.append('button') .text(_this.getString('Show more')) .attr('class', 'tsi-legendShowMore') .style('display', (_this.legendState === 'shown' && shouldShowMore) ? 'block' : 'none') .on('click', showMoreSplitBys); } splitByContainerEntered.on("scroll", function () { if (self.chartOptions.legend === 'shown') { if (this.scrollTop + this.clientHeight + 40 > this.scrollHeight) { showMoreSplitBys(); } } }); splitByContainer.exit().remove(); }; _this.toggleSticky = function (aggregateKey, splitBy) { //don't do anything if not visible if (!_this.chartComponentData.displayState[aggregateKey].visible || !_this.chartComponentData.displayState[aggregateKey].splitBys[splitBy].visible) return; if (_this.chartComponentData.stickiedKey != null && _this.chartComponentData.stickiedKey.aggregateKey == aggregateKey && _this.chartComponentData.stickiedKey.splitBy == splitBy) { _this.chartComponentData.stickiedKey = null; } else { if (_this.stickySeriesAction) { _this.stickySeriesAction(aggregateKey, splitBy); } } }; _this.drawChart = drawChart; _this.legendWidth = legendWidth; _this.legendElement = select(renderTarget).insert("div", ":first-child") .attr("class", "tsi-legend") .style("left", "0px") .style("width", (_this.legendWidth) + "px"); // - 16 for the width of the padding return _this; } Legend.prototype.labelMouseoutWrapper = function (labelMouseout, svgSelection, event) { return function (svgSelection, aggKey) { event === null || event === void 0 ? void 0 : event.stopPropagation(); svgSelection.selectAll(".tsi-valueElement") .filter(function () { return !select(this).classed("tsi-valueEnvelope"); }) .attr("stroke-opacity", 1) .attr("fill-opacity", 1); svgSelection.selectAll(".tsi-valueEnvelope") .attr("fill-opacity", .2); labelMouseout(svgSelection, aggKey); }; }; Legend.prototype.toggleSplitByVisible = function (aggregateKey, splitBy) { var _this = this; var newState = !this.chartComponentData.displayState[aggregateKey].splitBys[splitBy].visible; this.chartComponentData.displayState[aggregateKey].splitBys[splitBy].visible = newState; this.chartComponentData.displayState[aggregateKey].visible = Object.keys(this.chartComponentData.displayState[aggregateKey].splitBys) .reduce(function (prev, curr) { return _this.chartComponentData.displayState[aggregateKey]["splitBys"][curr]["visible"] || prev; }, false); //turn off sticky if making invisible if (newState == false && (this.chartComponentData.stickiedKey != null && this.chartComponentData.stickiedKey.aggregateKey == aggregateKey && this.chartComponentData.stickiedKey.splitBy == splitBy)) { this.chartComponentData.stickiedKey = null; } }; Legend.prototype.triggerSplitByFocus = function (aggKey, splitBy) { if (this.chartOptions.legend == "hidden") { return; } this.legendElement.selectAll('.tsi-splitByLabel').classed("inFocus", false); this.legendElement.selectAll('.tsi-splitByLabel').filter(function (labelData) { return (select(this.parentNode).datum() == aggKey) && (labelData == splitBy); }).classed("inFocus", true); var indexOfSplitBy = Object.keys(this.chartComponentData.displayState[aggKey].splitBys).indexOf(splitBy); if (indexOfSplitBy != -1) { var splitByNode = this.legendElement.selectAll('.tsi-splitByContainer').filter(function (d) { return d == aggKey; }).node(); var prospectiveScrollTop = Math.max((indexOfSplitBy - 1) * this.getHeightPerSplitBy(aggKey), 0); if (splitByNode.scrollTop < prospectiveScrollTop - (splitByNode.clientHeight - 40) || splitByNode.scrollTop > prospectiveScrollTop) { splitByNode.scrollTop = prospectiveScrollTop; } } }; Legend.prototype.getHeightPerSplitBy = function (aggKey) { return (this.chartComponentData.displayState[aggKey].dataType === DataTypes.Numeric ? NUMERICSPLITBYHEIGHT : NONNUMERICSPLITBYHEIGHT); }; Legend.prototype.createGradient = function (gradientKey, svg, values) { var gradient = svg.append('defs').append('linearGradient') .attr('id', gradientKey).attr('x1', '0%').attr('x2', '0%').attr('y1', '0%').attr('y2', '100%'); var catCount = Object.keys(values).length; Object.keys(values).forEach(function (category, i) { var currentStop = i / catCount * 100; var nextStop = (i + 1) / catCount * 100; var color = values[category].color; gradient.append('stop') .attr("offset", currentStop + "%") .attr("stop-color", color) .attr("stop-opacity", 1); gradient.append('stop') .attr("offset", nextStop + "%") .attr("stop-color", color) .attr("stop-opacity", 1); }); }; Legend.prototype.isNonNumeric = function (aggKey) { var dataType = this.chartComponentData.displayState[aggKey].dataType; return (dataType === DataTypes.Categorical || dataType === DataTypes.Events); }; Legend.prototype.createNonNumericColorKey = function (dataType, colorKey, aggKey) { if (dataType === DataTypes.Categorical) { this.createCategoricalColorKey(colorKey, aggKey); } if (dataType === DataTypes.Events) { this.createEventsColorKey(colorKey, aggKey); } }; Legend.prototype.createCategoricalColorKey = function (colorKey, aggKey) { var categories = this.chartComponentData.displayState[aggKey].aggregateExpression.valueMapping; colorKey.classed('tsi-categoricalColorKey', true); colorKey.selectAll('*').remove(); var svg = colorKey.append('svg') .attr('width', colorKey.style('width')) .attr('height', colorKey.style('height')); var rect = svg.append('rect') .attr('width', '100%') .attr('height', '100%') .attr('fill', 'black'); var gradientKey = Utils.guid(); this.createGradient(gradientKey, svg, categories); rect.attr('fill', "url(#" + gradientKey + ")"); }; Legend.prototype.createEventsColorKey = function (colorKey, aggKey) { var categories = this.chartComponentData.displayState[aggKey].aggregateExpression.valueMapping; var eventElementType = this.chartComponentData.displayState[aggKey].aggregateExpression.eventElementType; colorKey.classed('tsi-eventsColorKey', true); colorKey.selectAll('*').remove(); var colorKeyWidth = colorKey.node().getBoundingClientRect().width; var colorKeyHeight = colorKey.node().getBoundingClientRect().height; var colorKeyUnitLength = Math.floor(colorKeyHeight / Math.sqrt(2)); var svg = colorKey.append('svg') .attr('width', colorKeyWidth + "px") .attr('height', colorKeyHeight + "px"); var gradientKey = Utils.guid(); this.createGradient(gradientKey, svg, categories); if (eventElementType === EventElementTypes.Teardrop) { svg.append('path') .attr('transform', function (d) { return 'translate(' + (colorKeyWidth * .75) + ',' + (colorKeyHeight * .75) + ') rotate(180)'; }) .attr('d', this.teardropD(colorKeyWidth / 2, colorKeyHeight / 2)) .attr('stroke-width', Math.min(colorKeyUnitLength / 2.25, 8)) .style('fill', 'none') .style('stroke', "url(#" + gradientKey + ")"); } else { var rect = svg.append('rect') .attr('width', colorKeyUnitLength) .attr('height', colorKeyUnitLength) .attr('transform', "translate(" + (colorKeyWidth / 2) + ",0)rotate(45)") .attr('fill', 'black'); rect.attr('fill', "url(#" + gradientKey + ")"); } }; Legend.prototype.draw = function (legendState, chartComponentData, labelMouseover, svgSelection, options, labelMouseoutAction, stickySeriesAction, event) { var _this = this; if (labelMouseoutAction === void 0) { labelMouseoutAction = null; } if (stickySeriesAction === void 0) { stickySeriesAction = null; } this.chartOptions.setOptions(options); this.chartComponentData = chartComponentData; this.legendState = legendState; this.stickySeriesAction = stickySeriesAction; this.labelMouseover = labelMouseover; this.labelMouseout = this.labelMouseoutWrapper(labelMouseoutAction, svgSelection, event); this.svgSelection = svgSelection; var legend = this.legendElement; var self = this; _super.prototype.themify.call(this, this.legendElement, this.chartOptions.theme); legend.style('visibility', this.legendState != 'hidden') .classed('compact', this.legendState == 'compact') .classed('hidden', this.legendState == 'hidden'); var seriesNames = Object.keys(this.chartComponentData.displayState); var seriesLabels = legend.selectAll(".tsi-seriesLabel") .data(seriesNames, function (d) { return d; }); var seriesLabelsEntered = seriesLabels.enter() .append("div") .merge(seriesLabels) .attr("class", function (d, i) { return "tsi-seriesLabel " + (_this.chartComponentData.displayState[d]["visible"] ? " shown" : ""); }) .style("min-width", function () { return Math.min(124, _this.legendElement.node().clientWidth / seriesNames.length) + 'px'; }) .style("border-color", function (d, i) { if (select(this).classed("shown")) return self.chartComponentData.displayState[d].color; return "lightgray"; }); var self = this; var heightPerNameLabel = 25; var usableLegendHeight = legend.node().clientHeight; var prospectiveAggregateHeight = Math.ceil(Math.max(201, (usableLegendHeight / seriesLabelsEntered.size()))); var contentHeight = 0; seriesLabelsEntered.each(function (aggKey, i) { var heightPerSplitBy = self.getHeightPerSplitBy(aggKey); var splitByLabelData = Object.keys(self.chartComponentData.timeArrays[aggKey]); var noSplitBys = splitByLabelData.length == 1 && splitByLabelData[0] == ""; var seriesNameLabel = select(this).selectAll(".tsi-seriesNameLabel").data([aggKey]); select(this).classed('tsi-nsb', noSplitBys); var enteredSeriesNameLabel = seriesNameLabel.enter().append("button") .merge(seriesNameLabel) .attr("class", function (agg, i) { return "tsi-seriesNameLabel" + (self.chartComponentData.displayState[agg].visible ? " shown" : ""); }) .attr("aria-label", function (agg) { var showOrHide = self.chartComponentData.displayState[agg].visible ? self.getString('hide group') : self.getString('show group'); return showOrHide + " " + self.getString('group') + " " + Utils.stripNullGuid(self.chartComponentData.displayState[agg].name); }) .on("click", function (event, d) { var newState = !self.chartComponentData.displayState[d].visible; self.chartComponentData.displayState[d].visible = newState; //turn off sticky if making invisible if (newState == false && (self.chartComponentData.stickiedKey != null && self.chartComponentData.stickiedKey.aggregateKey == d)) { self.chartComponentData.stickiedKey = null; } self.drawChart(); }) .on("mouseover", function (event, d) { labelMouseover(d); }) .on("mouseout", function (event, d) { self.labelMouseout(svgSelection, d); }); var dataType = self.chartComponentData.displayState[aggKey].dataType; if (dataType === DataTypes.Categorical || dataType === DataTypes.Events) { enteredSeriesNameLabel.classed('tsi-nonCompactNonNumeric', true); var colorKey = enteredSeriesNameLabel.selectAll('.tsi-colorKey').data(['']); var colorKeyEntered = colorKey.enter() .append("div") .attr("class", 'tsi-colorKey') .merge(colorKey); self.createNonNumericColorKey(dataType, colorKeyEntered, aggKey); colorKey.exit().remove(); } var seriesNameLabelText = enteredSeriesNameLabel.selectAll("h4").data([aggKey]); seriesNameLabelText.enter() .append("h4") .merge(seriesNameLabelText) .attr("title", function (d) { return Utils.stripNullGuid(self.chartComponentData.displayState[d].name); }) .each(function () { Utils.appendFormattedElementsFromString(select(this), self.chartComponentData.displayState[aggKey].name); }); seriesNameLabelText.exit().remove(); seriesNameLabel.exit().remove(); var splitByContainerHeight; if (splitByLabelData.length > (prospectiveAggregateHeight / heightPerSplitBy)) { splitByContainerHeight = prospectiveAggregateHeight - heightPerNameLabel; contentHeight += splitByContainerHeight + heightPerNameLabel; } else if (splitByLabelData.length > 1 || (splitByLabelData.length === 1 && splitByLabelData[0] !== "")) { splitByContainerHeight = splitByLabelData.length * heightPerSplitBy + heightPerNameLabel; contentHeight += splitByContainerHeight + heightPerNameLabel; } else { splitByContainerHeight = heightPerSplitBy; contentHeight += splitByContainerHeight; } if (self.chartOptions.legend == "shown") { select(this).style("height", splitByContainerHeight + "px"); } else { select(this).style("height", "unset"); } var splitByContainer = select(this).selectAll(".tsi-splitByContainer").data([aggKey]); var splitByContainerEntered = splitByContainer.enter().append("div") .merge(splitByContainer) .classed("tsi-splitByContainer", true); var aggSelection = select(this); var sBs = self.renderSplitBys(aggKey, aggSelection, dataType, noSplitBys); splitByContainerEntered.on("scroll", function () { if (self.chartOptions.legend == "shown") { if (this.scrollTop + this.clientHeight + 40 > this.scrollHeight) { var oldShownSplitBys = self.chartComponentData.displayState[aggKey].shownSplitBys; self.chartComponentData.displayState[aggKey].shownSplitBys = Math.min(oldShownSplitBys + 20, splitByLabelData.length); if (oldShownSplitBys != self.chartComponentData.displayState[aggKey].shownSplitBys) { self.renderSplitBys(aggKey, aggSelection, dataType, noSplitBys); } } } }); select(this).on('scroll', function () { if (self.chartOptions.legend == "compact") { if (this.scrollLeft + this.clientWidth + 40 > this.scrollWidth) { var oldShownSplitBys = self.chartComponentData.displayState[aggKey].shownSplitBys; self.chartComponentData.displayState[aggKey].shownSplitBys = Math.min(oldShownSplitBys + 20, splitByLabelData.length); if (oldShownSplitBys != self.chartComponentData.displayState[aggKey].shownSplitBys) { this.renderSplitBys(dataType); } } } }); splitByContainer.exit().remove(); }); if (this.chartOptions.legend == 'shown') { var legendHeight = legend.node().clientHeight; //minSplitBysForFlexGrow: the minimum number of split bys for flex-grow to be triggered if (contentHeight < usableLegendHeight) { this.legendElement.classed("tsi-flexLegend", true); seriesLabelsEntered.each(function (d) { var heightPerSplitBy = self.getHeightPerSplitBy(d); var minSplitByForFlexGrow = (prospectiveAggregateHeight - heightPerNameLabel) / heightPerSplitBy; var splitBysCount = Object.keys(self.chartComponentData.displayState[String(select(this).data()[0])].splitBys).length; if (splitBysCount > minSplitByForFlexGrow) { select(this).style("flex-grow", 1); } }); } else { this.legendElement.classed("tsi-flexLegend", false); } } seriesLabels.exit().remove(); }; return Legend; }(Component)); export { Legend as L };