@carbon/charts
Version:
Carbon charting components
175 lines • 8.52 kB
JavaScript
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