UNPKG

@carbon/charts

Version:
293 lines 12.1 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 { Service } from '../service'; import { Events, Alignments } from './../../interfaces'; // D3 Imports import { select } from 'd3-selection'; import { Tools } from '../../tools'; // import the settings for the css prefix import settings from 'carbon-components/es/globals/js/settings'; // MISC import ResizeObserver from 'resize-observer-polyfill'; var CSS_VERIFIER_ELEMENT_CLASSNAME = 'DONT_STYLE_ME_css_styles_verifier'; var DOMUtils = /** @class */ (function (_super) { __extends(DOMUtils, _super); function DOMUtils() { return _super !== null && _super.apply(this, arguments) || this; } DOMUtils.getSVGElementSize = function (svgSelector, options) { if (!svgSelector.attr) { svgSelector = select(svgSelector); } var finalDimensions = { width: 0, height: 0, }; var validateAndSetDimensions = function (dimensions) { if (dimensions) { Object.keys(finalDimensions).forEach(function (dimensionKey) { if (dimensions[dimensionKey]) { var dimension = dimensions[dimensionKey]; var dimensionNumber = parseFloat(dimension); if (dimension && dimensionNumber > finalDimensions[dimensionKey] && ('' + dimension).indexOf('%') === -1) { finalDimensions[dimensionKey] = dimensionNumber; } } }); } }; var attrDimensions = { width: svgSelector.attr('width'), height: svgSelector.attr('height'), }; var bbox, bboxDimensions, boundingRect, boundingRectDimensions; // In many versions of Firefox // getBBox will cause an "NSFailure" error try { bbox = svgSelector.node().getBBox(); bboxDimensions = { width: bbox.width, height: bbox.height, }; } catch (e) { } try { boundingRect = svgSelector.node().getBoundingClientRect(); boundingRectDimensions = { width: boundingRect.width, height: boundingRect.height, }; } catch (e) { } var clientDimensions = { width: svgSelector.node().clientWidth, height: svgSelector.node().clientHeight, }; // If both attribute values are numbers // And not percentages or NaN if (options) { if (options.useAttrs) { validateAndSetDimensions(attrDimensions); if (finalDimensions.width > 0 && finalDimensions.height > 0) { return finalDimensions; } } if (options.useClientDimensions) { validateAndSetDimensions(clientDimensions); if (finalDimensions.width > 0 && finalDimensions.height > 0) { return clientDimensions; } } if (options.useBBox) { validateAndSetDimensions(bboxDimensions); if (finalDimensions.width > 0 && finalDimensions.height > 0) { return bboxDimensions; } } if (options.useBoundingRect) { validateAndSetDimensions(boundingRectDimensions); if (finalDimensions.width > 0 && finalDimensions.height > 0) { return boundingRectDimensions; } } } try { var nativeDimensions = { width: Tools.getProperty(svgSelector.node(), 'width', 'baseVal', 'value'), height: Tools.getProperty(svgSelector.node(), 'height', 'baseVal', 'value'), }; validateAndSetDimensions(nativeDimensions); } catch (e) { validateAndSetDimensions(clientDimensions); validateAndSetDimensions(bboxDimensions); validateAndSetDimensions(attrDimensions); } return finalDimensions; }; DOMUtils.appendOrSelect = function (parent, query) { var selection = parent.select("" + query); if (selection.empty()) { // see if there is an id var querySections = query.split('#'); var elementToAppend = void 0; var id = void 0; // if there is an id if (querySections.length === 2) { // take out the element to append elementToAppend = querySections[0]; // split it by classes querySections = querySections[1].split('.'); // the first string is the id id = querySections[0]; } else { querySections = query.split('.'); elementToAppend = querySections[0]; } return parent .append(elementToAppend) .attr('id', id) .attr('class', querySections.slice(1).join(' ')); } return selection; }; DOMUtils.getAlignmentOffset = function (alignment, svg, parent) { var svgDimensions = DOMUtils.getSVGElementSize(svg, { useBBox: true, }); var width = DOMUtils.getSVGElementSize(parent, { useAttr: true }).width; var alignmentOffset = 0; if (alignment === Alignments.CENTER) { alignmentOffset = Math.floor((width - svgDimensions.width) / 2); } else if (alignment === Alignments.RIGHT) { alignmentOffset = width - svgDimensions.width; } return alignmentOffset; }; DOMUtils.prototype.init = function () { // Add width & height to the chart holder if necessary, and add a classname this.styleHolderElement(); // Add main SVG this.addSVGElement(); this.verifyCSSStylesBeingApplied(); if (this.model.getOptions().resizable) { this.addResizeListener(); } this.addHolderListeners(); }; DOMUtils.prototype.update = function () { this.styleHolderElement(); }; DOMUtils.prototype.styleHolderElement = function () { var holderElement = this.getHolder(); // Add class to chart holder select(this.getHolder()).classed(settings.prefix + "--chart-holder", true); // In order for resize events to not clash with these updates // We'll check if the width & height values passed in options // Have changed, before setting them to the holder var _a = this.model.getOptions(), width = _a.width, height = _a.height; if (width !== this.width) { // Apply formatted width attribute to chart holderElement.style.width = width; this.width = width; } if (height !== this.height) { // Apply formatted width attribute to chart holderElement.style.height = height; this.height = height; } }; DOMUtils.prototype.getHolder = function () { return this.model.get('holder'); }; DOMUtils.prototype.addSVGElement = function () { var options = this.model.getOptions(); var chartsprefix = Tools.getProperty(options, 'style', 'prefix'); var svg = select(this.getHolder()) .append('svg') .classed(settings.prefix + "--" + chartsprefix + "--chart-svg", true) .attr('height', '100%') .attr('width', '100%'); svg.append('g').attr('class', CSS_VERIFIER_ELEMENT_CLASSNAME); this.svg = svg.node(); }; DOMUtils.prototype.verifyCSSStylesBeingApplied = function () { var _this = this; // setTimeout is needed here since in `addSVGElement()` we're appending the // CSS verifier element, and need to allow some time for it to become available // in the DOM setTimeout(function () { var cssVerifierElement = select(_this.svg) .select("g." + CSS_VERIFIER_ELEMENT_CLASSNAME) .node(); var computedStyles = getComputedStyle(cssVerifierElement); if (computedStyles.getPropertyValue('overflow') !== 'hidden' || computedStyles.getPropertyValue('opacity') !== '0') { console.error('Missing CSS styles for Carbon Charts. Please read the Carbon Charts getting started guide.'); } }); }; DOMUtils.prototype.setSVGMaxHeight = function () { // if there is a set height on the holder, leave the chart svg height at 100% if (!this.model.getOptions().height) { var chartHeight = DOMUtils.getSVGElementSize(select(this.svg), { useBBox: true }).height; var chartSVGSelector = select(this.svg).attr('class'); var children = select(this.svg).selectAll("." + chartSVGSelector + " > svg"); // get the height of the children SVGs (spacers, titles, etc) var childrenHeight_1 = 0; children.nodes().forEach(function (childSVG) { childrenHeight_1 += Number(DOMUtils.getSVGElementSize(select(childSVG), { useBBox: true, }).height); }); // set the chart svg height to the children height // forcing the chart not to take up any more space than it requires childrenHeight_1 <= chartHeight ? select(this.svg).attr('height', childrenHeight_1) : select(this.svg).attr('height', '100%'); } }; DOMUtils.prototype.getMainSVG = function () { return this.svg; }; DOMUtils.prototype.addHolderListeners = function () { var _this = this; var holder = this.getHolder(); if (!holder) { return; } select(holder) .on('mouseover', function () { // Dispatch event _this.services.events.dispatchEvent(Events.Chart.MOUSEOVER); }) .on('mouseout', function () { // Dispatch event _this.services.events.dispatchEvent(Events.Chart.MOUSEOUT); }); }; DOMUtils.prototype.addResizeListener = function () { var _this = this; var holder = this.getHolder(); if (!holder) { return; } // Grab current dimensions of the chart holder var containerWidth = holder.clientWidth; var containerHeight = holder.clientHeight; // The resize callback function var resizeCallback = Tools.debounce(function (entries, observer) { if (!holder) { return; } if (Math.abs(containerWidth - holder.clientWidth) > 1 || Math.abs(containerHeight - holder.clientHeight) > 1) { containerWidth = holder.clientWidth; containerHeight = holder.clientHeight; _this.services.events.dispatchEvent(Events.Chart.RESIZE); } }, 12.5); // Observe the behaviour of resizing on the holder var resizeObserver = new ResizeObserver(resizeCallback); resizeObserver.observe(holder); }; return DOMUtils; }(Service)); export { DOMUtils }; //# sourceMappingURL=../../../src/services/essentials/dom-utils.js.map