UNPKG

@carbon/charts

Version:
175 lines 8.52 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); // Internal Imports import { Title } from './title'; import { DOMUtils } from '../../services'; import { Tools } from '../../tools'; import { Statuses } from './../../interfaces/enums'; import * as Configuration from '../../configuration'; var MeterTitle = /** @class */ (function (_super) { __extends(MeterTitle, _super); function MeterTitle() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = 'meter-title'; return _this; } MeterTitle.prototype.render = function () { var dataset = this.model.getDisplayData(); var options = this.getOptions(); var svg = this.getContainerSVG(); var groupMapsTo = options.data.groupMapsTo; // the title for a meter, is the label for that dataset var title = svg .selectAll('text.meter-title') .data([dataset[groupMapsTo]]); title .enter() .append('text') .classed('meter-title', true) .merge(title) .attr('x', 0) .attr('y', '1em') .text(function (d) { return d; }); title.exit().remove(); // appends the associated percentage after title this.appendPercentage(); // if status ranges are provided (custom or default), display indicator this.displayStatus(); // get the max width of a title (with consideration for the status/percentage) var maxWidth = this.getMaxTitleWidth(); var titleElement = DOMUtils.appendOrSelect(svg, 'text.meter-title'); if (maxWidth > 0 && titleElement.node().getComputedTextLength() > maxWidth) { this.truncateTitle(titleElement, maxWidth); } }; /** * Appends the corresponding status based on the value and the peak. */ MeterTitle.prototype.displayStatus = function () { var self = this; var svg = this.getContainerSVG(); var options = this.getOptions(); var containerBounds = DOMUtils.getSVGElementSize(this.services.domUtils.getMainSVG(), { useAttr: true }); // need to check if the width is 0, and try to use the parent attribute // this can happen if the chart is toggled on/off and the height is 0 for the parent, it wont validateDimensions var containerWidth = containerBounds.width ? containerBounds.width : this.parent.node().getAttribute('width'); // get the status from the model var status = this.model.getStatus(); var radius = Configuration.meter.status.indicatorSize / 2; // create a group for the icon/inner path var statusGroup = DOMUtils.appendOrSelect(svg, "g.status-indicator") .attr('class', status !== null ? "status-indicator status--" + status : '') .attr('transform', "translate(" + (containerWidth - radius) + ", 0)"); var data = status ? [status] : []; var icon = statusGroup.selectAll('circle.status').data(data); icon.enter() .append('circle') .merge(icon) .attr('class', 'status') .attr('r', radius) .attr('cx', 0) .attr('cy', "calc(1em / 2)"); var innerIcon = statusGroup.selectAll('path.innerFill').data(data); innerIcon .enter() .append('path') .merge(innerIcon) .attr('d', self.getStatusIconPathString(status)) .attr('transform', "translate(-" + radius + ", 0)") .attr('class', 'innerFill'); innerIcon.exit().remove(); icon.exit().remove(); }; /** * Appends the associated percentage to the end of the title */ MeterTitle.prototype.appendPercentage = function () { var dataValue = this.model.getDisplayData().value; // use the title's position to append the percentage to the end var svg = this.getContainerSVG(); var title = DOMUtils.appendOrSelect(svg, 'text.meter-title'); // check if it is enabled var data = Tools.getProperty(this.getOptions(), 'meter', 'statusBar', 'percentageIndicator', 'enabled') === true ? [dataValue] : []; // append a percentage if it is enabled, update it var percentage = svg.selectAll('text.percent-value').data(data); // the horizontal offset of the percentage value from the title var offset = Configuration.meter.statusBar.paddingRight; percentage .enter() .append('text') .classed('percent-value', true) .merge(percentage) .text(function (d) { return d + "%"; }) .attr('x', +title.attr('x') + title.node().getComputedTextLength() + offset) // set the position to after the title .attr('y', title.attr('y')); percentage.exit().remove(); }; /** * Uses the parent class truncate logic * @param title d3 selection of title element that will be truncated * @param titlestring the original string that needs truncation * @param maxWidth the max width the title can take */ MeterTitle.prototype.truncateTitle = function (title, maxWidth) { _super.prototype.truncateTitle.call(this, title, maxWidth); // update the position on the percentage to be inline with the title var tspan = DOMUtils.appendOrSelect(this.parent, 'tspan'); var offset = Configuration.meter.statusBar.paddingRight; var tspanLength = Math.ceil(tspan.node().getComputedTextLength()); var percentage = DOMUtils.appendOrSelect(this.parent, 'text.percent-value'); percentage.attr('x', +title.attr('x') + title.node().getComputedTextLength() + tspanLength + offset); }; // computes the maximum space a title can take MeterTitle.prototype.getMaxTitleWidth = function () { // get a reference to the title elements to calculate the size the title can be var containerBounds = DOMUtils.getSVGElementSize(this.services.domUtils.getMainSVG(), { useAttr: true }); // need to check if the width is 0, and try to use the parent attribute var containerWidth = containerBounds.width ? containerBounds.width : this.parent.node().getAttribute('width'); var percentage = DOMUtils.appendOrSelect(this.parent, 'text.percent-value'); // the title needs to fit the width of the container without crowding the status, and percentage value var offset = Configuration.meter.statusBar.paddingRight; var percentageWidth = percentage.node().getComputedTextLength(); var statusGroup = DOMUtils.appendOrSelect(this.parent, 'g.status-indicator').node(); var statusWidth = DOMUtils.getSVGElementSize(statusGroup, { useBBox: true }).width + Configuration.meter.status.paddingLeft; return containerWidth - percentageWidth - offset - statusWidth; }; /** * Get the associated status icon for the data * @param status the active status for the meter chart */ MeterTitle.prototype.getStatusIconPathString = function (status) { switch (status) { case Statuses.SUCCESS: return 'M6.875 11.3125 3.75 8.1875 4.74375 7.25 6.875 9.34375 11.50625 4.75 12.5 5.7375 Z'; case Statuses.DANGER: return 'M10.7 11.5 4.5 5.3 5.3 4.5 11.5 10.7 Z'; case Statuses.WARNING: return 'M7.9375,11.125 C7.41973305,11.125 7,11.544733 7,12.0625 C7,12.580267 7.41973305,13 7.9375,13 C8.45526695,13 8.875,12.580267 8.875,12.0625 C8.875,11.544733 8.45526695,11.125 7.9375,11.125 M7.3125, 3 8.5625, 3 8.5625, 9.875 7.3125, 9.875, 7.3125, 3 Z'; } }; return MeterTitle; }(Title)); export { MeterTitle }; //# sourceMappingURL=../../../src/components/essentials/title-meter.js.map