@progress/kendo-charts
Version:
Kendo UI platform-independent Charts library
134 lines (106 loc) • 4.14 kB
JavaScript
import { drawing as draw } from '@progress/kendo-drawing';
import { alignPathToPixel } from '../common';
import { ChartElement } from '../core';
import { Box } from '../core';
class ChartContainer extends ChartElement {
constructor(options, pane) {
super(options);
this.pane = pane;
}
shouldClip() {
const children = this.children;
const length = children.length;
for (let i = 0; i < length; i++) {
if (children[i].options.clip === true) {
return true;
}
}
return false;
}
_clipBox() {
return this.pane.chartsBox();
}
createVisual() {
this.visual = new draw.Group({
zIndex: 0
});
if (this.shouldClip()) {
const clipBox = this.clipBox = this._clipBox();
const clipRect = clipBox.toRect();
const clipPath = draw.Path.fromRect(clipRect);
alignPathToPixel(clipPath);
this.visual.clip(clipPath);
this.unclipLabels();
}
}
stackRoot() {
return this;
}
unclipLabels() {
const { children: charts, clipBox } = this;
for (let i = 0; i < charts.length; i++) {
const points = charts[i].points || [];
const length = points.length;
for (let j = 0; j < length; j++) {
const point = points[j];
if (point && point.visible !== false && point.overlapsBox) {
if (point.overlapsBox(clipBox)) {
if (point.unclipElements) {
point.unclipElements();
} else {
const { label, note } = point;
if (label && label.options.visible) {
if (label.alignToClipBox) {
label.alignToClipBox(clipBox);
}
label.options.noclip = true;
}
if (note && note.options.visible) {
note.options.noclip = true;
}
}
}
}
}
}
}
unclipBox() {
const { children: charts } = this;
const clipBox = this._clipBox();
const box = clipBox.clone();
for (let i = 0; i < charts.length; i++) {
const points = charts[i].points || [];
const length = points.length;
for (let j = 0; j < length; j++) {
const point = points[j];
if (point && point.unclipBox && point.overlapsBox && point.visible !== false) {
if (!point.overlapsBox(clipBox)) {
// Hide points outside of the viewport (clipBox)
if (point.clipElements) {
point.clipElements();
}
continue;
}
// Extend viewport to include all point elements, including labels
const unclipBox = point.unclipBox();
if (box.overlaps(unclipBox)) {
const labelBox = point.labelBox ? point.labelBox() : new Box();
const noteBox = point.noteBox ? point.noteBox() : new Box();
const heightLimit = Math.max(labelBox.height(), noteBox.height());
const widthLimit = Math.max(labelBox.width(), noteBox.width());
// Limit the size change of the viewport to the label and note boxes dimensions
// to avoid extending it too much.
box.wrapLimit(unclipBox, widthLimit, heightLimit);
}
}
}
}
return box;
}
destroy() {
super.destroy();
delete this.parent;
}
}
ChartContainer.prototype.isStackRoot = true;
export default ChartContainer;