UNPKG

@carbon/charts

Version:
205 lines 9.07 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 { Component } from '../component'; import { LayoutDirection, LayoutGrowth, } from '../../interfaces/index'; import { Tools } from '../../tools'; import { DOMUtils } from '../../services'; // D3 Imports import { select } from 'd3-selection'; import { hierarchy, treemap, treemapSlice, treemapDice } from 'd3-hierarchy'; // TODO - What if there is no "growth" object? var LayoutComponent = /** @class */ (function (_super) { __extends(LayoutComponent, _super); function LayoutComponent(model, services, children, configs) { var _this = _super.call(this, model, services, configs) || this; _this.type = 'layout'; _this.configs = configs; _this.children = children; _this._instanceID = LayoutComponent.instanceID++; // Pass children data to the hierarchy layout // And calculate sum of sizes var directionIsReversed = _this.configs.direction === LayoutDirection.ROW_REVERSE || _this.configs.direction === LayoutDirection.COLUMN_REVERSE; if (directionIsReversed) { _this.children = _this.children.reverse(); } _this.init(); return _this; } LayoutComponent.prototype.init = function () { this.children.forEach(function (child) { child.components.forEach(function (component) { component.init(); }); }); }; LayoutComponent.prototype.getPreferedAndFixedSizeSum = function () { var svg = this.parent; var sum = 0; svg.selectAll("svg.layout-child-" + this._instanceID) .filter(function (d) { var growth = Tools.getProperty(d, 'data', 'growth', 'x'); return (growth === LayoutGrowth.PREFERRED || growth === LayoutGrowth.FIXED); }) .each(function (d) { sum += d.data.size; }); return sum; }; LayoutComponent.prototype.getNumOfStretchChildren = function () { var svg = this.parent; return svg .selectAll("svg.layout-child-" + this._instanceID) .filter(function (d) { var growth = Tools.getProperty(d, 'data', 'growth', 'x'); return growth === LayoutGrowth.STRETCH; }) .size(); }; LayoutComponent.prototype.render = function (animate) { var _this = this; if (animate === void 0) { animate = true; } // Get parent SVG to render inside of var svg = this.parent; var _a = DOMUtils.getSVGElementSize(svg, { useAttrs: true, }), width = _a.width, height = _a.height; var root = hierarchy({ children: this.children, }).sum(function (d) { return d.size; }); // Grab the correct treemap tile function based on direction var tileType = this.configs.direction === LayoutDirection.ROW || this.configs.direction === LayoutDirection.ROW_REVERSE ? treemapDice : treemapSlice; // Compute the position of all elements within the layout treemap().tile(tileType).size([width, height])(root); // TODORF - Remove var horizontal = this.configs.direction === LayoutDirection.ROW || this.configs.direction === LayoutDirection.ROW_REVERSE; // Add new SVGs to the DOM for each layout child var updatedSVGs = svg .selectAll("svg.layout-child-" + this._instanceID) .data(root.leaves(), function (d) { return d.data.id; }); updatedSVGs .attr('width', function (d) { return d.x1 - d.x0; }) .attr('height', function (d) { return d.y1 - d.y0; }); var enteringSVGs = updatedSVGs .enter() .append('svg') .attr('class', function (d) { return "layout-child layout-child-" + _this._instanceID + " " + d.data.id; }) .attr('x', function (d) { return d.x0; }) .attr('y', function (d) { return d.y0; }); enteringSVGs .merge(svg.selectAll("svg.layout-child-" + this._instanceID)) .each(function (d) { var _this = this; // Set parent component for each child d.data.components.forEach(function (itemComponent) { itemComponent.setParent(select(_this)); // Render preffered & fixed items var growth = Tools.getProperty(d, 'data', 'growth', 'x'); if (growth === LayoutGrowth.PREFERRED || growth === LayoutGrowth.FIXED) { itemComponent.render(animate); } }); }); svg.selectAll("svg.layout-child-" + this._instanceID).each(function (d) { // Calculate preffered children sizes after internal rendering var growth = Tools.getProperty(d, 'data', 'growth', 'x'); var matchingSVGDimensions = DOMUtils.getSVGElementSize(select(this), { useBBox: true }); if (d.data.id === 'legend') { var svgSize = DOMUtils.getSVGElementSize(select(this), { useAttrs: true, }); if (svgSize.height < 40) { matchingSVGDimensions.height = svgSize.height; } } if (growth === LayoutGrowth.PREFERRED) { var matchingSVGWidth = horizontal ? matchingSVGDimensions.width : matchingSVGDimensions.height; var svgWidth = horizontal ? width : height; d.data.size = (matchingSVGWidth / svgWidth) * 100; } }); updatedSVGs.exit().remove(); // Run through stretch x-items this.children .filter(function (child) { var growth = Tools.getProperty(child, 'growth', 'x'); return growth === LayoutGrowth.STRETCH; }) .forEach(function (child, i) { child.size = (100 - +_this.getPreferedAndFixedSizeSum()) / +_this.getNumOfStretchChildren(); }); // Pass children data to the hierarchy layout // And calculate sum of sizes root = hierarchy({ children: this.children, }).sum(function (d) { return d.size; }); // Compute the position of all elements within the layout treemap().tile(tileType).size([width, height]).padding(0)(root); // Add new SVGs to the DOM for each layout child svg.selectAll("svg.layout-child-" + this._instanceID) .data(root.leaves(), function (d) { return d.data.id; }) .attr('x', function (d) { return d.x0; }) .attr('y', function (d) { return d.y0; }) .attr('width', function (d) { return d.x1 - d.x0; }) .attr('height', function (d) { return d.y1 - d.y0; }) .each(function (d, i) { d.data.components.forEach(function (itemComponent) { var growth = Tools.getProperty(d, 'data', 'growth', 'x'); if (growth === LayoutGrowth.STRETCH) { itemComponent.render(animate); } }); }); }; // Pass on model to children as well LayoutComponent.prototype.setModel = function (newObj) { _super.prototype.setModel.call(this, newObj); this.children.forEach(function (child) { child.components.forEach(function (component) { return component.setModel(newObj); }); }); }; // Pass on essentials to children as well LayoutComponent.prototype.setServices = function (newObj) { _super.prototype.setServices.call(this, newObj); this.children.forEach(function (child) { child.components.forEach(function (component) { return component.setServices(newObj); }); }); }; LayoutComponent.prototype.destroy = function () { this.children.forEach(function (child) { child.components.forEach(function (component) { return component.destroy(); }); }); }; // Give every layout component a distinct ID // so they don't interfere when querying elements LayoutComponent.instanceID = Math.floor(Math.random() * 99999999999); return LayoutComponent; }(Component)); export { LayoutComponent }; //# sourceMappingURL=../../../src/components/layout/layout.js.map