@carbon/charts
Version:
Carbon charting components
205 lines • 9.07 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 { 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