@progress/kendo-charts
Version:
Kendo UI platform-independent Charts library
384 lines (322 loc) • 12.2 kB
JavaScript
import { drawing as draw, geometry as geom } from '@progress/kendo-drawing';
import { ChartElement, ShapeBuilder, TextBox, Box, createPatternFill } from '../../core';
import PointEventsMixin from '../mixins/point-events-mixin';
import { OUTSIDE_END, INSIDE_END, PIE, FADEIN, TOOLTIP_OFFSET, CHART_POINT_ROLE, CHART_POINT_CLASSNAME, CHART_POINT_ROLE_DESCRIPTION } from '../constants';
import hasGradientOverlay from '../utils/has-gradient-overlay';
import { TOP, BOTTOM, LEFT, RIGHT, DEFAULT_FONT, CIRCLE, WHITE, CENTER, DEFAULT_PRECISION } from '../../common/constants';
import { autoTextColor, setDefaultOptions, getSpacing, getTemplate, deepExtend, round, rad } from '../../common';
import AccessibilityAttributesMixin from '../mixins/accessibility-attributes-mixin';
var PieSegment = (function (ChartElement) {
function PieSegment(value, sector, options) {
ChartElement.call(this, options);
this.value = value;
this.sector = sector;
}
if ( ChartElement ) PieSegment.__proto__ = ChartElement;
PieSegment.prototype = Object.create( ChartElement && ChartElement.prototype );
PieSegment.prototype.constructor = PieSegment;
PieSegment.prototype.render = function render () {
if (this._rendered || this.visible === false) {
return;
}
this._rendered = true;
this.createLabel();
};
PieSegment.prototype.createLabel = function createLabel () {
var labels = this.options.labels;
var chartService = this.owner.chartService;
var labelText = this.getLabelText(labels);
if (labels.visible && (labelText || labelText === 0)) {
if (labels.position === CENTER || labels.position === INSIDE_END) {
if (!labels.color) {
labels.color = autoTextColor(this.options.color);
}
if (!labels.background) {
labels.background = this.options.color;
}
} else {
var themeLabels = chartService.theme.seriesDefaults.labels;
labels.color = labels.color || themeLabels.color;
labels.background = labels.background || themeLabels.background;
}
this.label = new TextBox(labelText, deepExtend({}, labels, {
align: CENTER,
vAlign: "",
animation: {
type: FADEIN,
delay: this.animationDelay
}
}), this.pointData());
this.append(this.label);
}
};
PieSegment.prototype.getLabelText = function getLabelText (options) {
var labelTemplate = getTemplate(options);
if (labelTemplate) {
return labelTemplate(this.pointData());
}
return this.owner.chartService.format.auto(options.format, this.value);
};
PieSegment.prototype.reflow = function reflow (targetBox) {
this.render();
this.box = targetBox;
this.reflowLabel();
};
PieSegment.prototype.reflowLabel = function reflowLabel () {
var ref = this;
var labelsOptions = ref.options.labels;
var label = ref.label;
var sector = this.sector.clone();
var labelsDistance = labelsOptions.distance;
var angle = sector.middle();
if (label) {
var labelHeight = label.box.height();
var labelWidth = label.box.width();
var lp;
if (labelsOptions.position === CENTER) {
sector.radius = Math.abs((sector.radius - labelHeight) / 2) + labelHeight;
lp = sector.point(angle);
label.reflow(new Box(lp.x, lp.y - labelHeight / 2, lp.x, lp.y));
} else if (labelsOptions.position === INSIDE_END) {
sector.radius = sector.radius - labelHeight / 2;
lp = sector.point(angle);
label.reflow(new Box(lp.x, lp.y - labelHeight / 2, lp.x, lp.y));
} else {
var x1;
lp = sector.clone().expand(labelsDistance).point(angle);
if (lp.x >= sector.center.x) {
x1 = lp.x + labelWidth;
label.orientation = RIGHT;
} else {
x1 = lp.x - labelWidth;
label.orientation = LEFT;
}
label.reflow(new Box(x1, lp.y - labelHeight, lp.x, lp.y));
}
}
};
PieSegment.prototype.createVisual = function createVisual () {
var this$1 = this;
var ref = this;
var sector = ref.sector;
var options = ref.options;
ChartElement.prototype.createVisual.call(this);
this.addAccessibilityAttributesToVisual();
if (this.value) {
if (options.visual) {
var startAngle = (sector.startAngle + 180) % 360;
var visual = options.visual({
category: this.category,
dataItem: this.dataItem,
value: this.value,
series: this.series,
percentage: this.percentage,
center: new geom.Point(sector.center.x, sector.center.y),
radius: sector.radius,
innerRadius: sector.innerRadius,
startAngle: startAngle,
endAngle: startAngle + sector.angle,
options: options,
sender: this.getSender(),
createVisual: function () {
var group = new draw.Group();
this$1.createSegmentVisual(group);
return group;
}
});
if (visual) {
this.visual.append(visual);
}
} else {
this.createSegmentVisual(this.visual);
}
}
};
PieSegment.prototype.createSegmentVisual = function createSegmentVisual (group) {
var ref = this;
var sector = ref.sector;
var options = ref.options;
var borderOptions = options.border || {};
var border = borderOptions.width > 0 ? {
stroke: {
color: borderOptions.color,
width: borderOptions.width,
opacity: borderOptions.opacity,
dashType: borderOptions.dashType
}
} : {};
var color = options.color;
var fill = createPatternFill(options.pattern, {
color: color,
opacity: options.opacity
});
var visual = this.createSegment(sector, deepExtend({
fill: fill,
stroke: {
opacity: options.opacity
},
zIndex: options.zIndex
}, border));
group.append(visual);
if (hasGradientOverlay(options)) {
group.append(this.createGradientOverlay(visual, {
baseColor: color,
fallbackFill: fill
}, deepExtend({
center: [ sector.center.x, sector.center.y ],
innerRadius: sector.innerRadius,
radius: sector.radius,
userSpace: true
}, options.overlay)));
}
};
PieSegment.prototype.createSegment = function createSegment (sector, options) {
if (options.singleSegment) {
return new draw.Circle(new geom.Circle(new geom.Point(sector.center.x, sector.center.y), sector.radius), options);
}
return ShapeBuilder.current.createRing(sector, options);
};
PieSegment.prototype.createAnimation = function createAnimation () {
var ref = this;
var options = ref.options;
var center = ref.sector.center;
deepExtend(options, {
animation: {
center: [ center.x, center.y ],
delay: this.animationDelay
}
});
ChartElement.prototype.createAnimation.call(this);
};
PieSegment.prototype.createHighlight = function createHighlight (options) {
var highlight = this.options.highlight || {};
var border = highlight.border || {};
return this.createSegment(this.sector, deepExtend({}, options, {
fill: {
color: highlight.color,
opacity: highlight.opacity
},
stroke: {
opacity: border.opacity,
width: border.width,
color: border.color
}
}));
};
PieSegment.prototype.highlightVisual = function highlightVisual () {
return this.visual.children[0];
};
PieSegment.prototype.highlightVisualArgs = function highlightVisualArgs () {
var sector = this.sector;
return {
options: this.options,
radius: sector.radius,
innerRadius: sector.innerRadius,
center: new geom.Point(sector.center.x, sector.center.y),
startAngle: sector.startAngle,
endAngle: sector.angle + sector.startAngle,
visual: this.visual
};
};
PieSegment.prototype.createFocusHighlight = function createFocusHighlight (style) {
var borderWidth = this.options.focusHighlight.border.width;
var result = this.createSegment(this.sector, deepExtend({}, style, {
stroke: {
width: borderWidth * 2
}
}));
var clipPath = new draw.MultiPath();
clipPath.paths.push(draw.Path.fromRect(result.bbox()));
clipPath.paths.push(this.createSegment(this.sector, {}));
result.clip(clipPath);
return result;
};
PieSegment.prototype.tooltipAnchor = function tooltipAnchor () {
var sector = this.sector.clone().expand(TOOLTIP_OFFSET);
var midAndle = sector.middle();
var midPoint = sector.point(midAndle);
return {
point: midPoint,
align: tooltipAlignment(midAndle + 180)
};
};
PieSegment.prototype.formatValue = function formatValue (format) {
return this.owner.formatPointValue(this, format);
};
PieSegment.prototype.pointData = function pointData () {
return {
dataItem: this.dataItem,
category: this.category,
value: this.value,
series: this.series,
percentage: this.percentage
};
};
PieSegment.prototype.getIndex = function getIndex () {
return this.index;
};
return PieSegment;
}(ChartElement));
var RAD_30 = round(rad(30), DEFAULT_PRECISION);
var RAD_60 = round(rad(60), DEFAULT_PRECISION);
function tooltipAlignment(angle) {
var radians = rad(angle);
var sine = round(Math.sin(radians), DEFAULT_PRECISION);
var cosine = round(Math.cos(radians), DEFAULT_PRECISION);
var horizontal;
if (Math.abs(sine) > RAD_60) {
horizontal = CENTER;
} else if (cosine < 0) {
horizontal = RIGHT;
} else {
horizontal = LEFT;
}
var vertical;
if (Math.abs(sine) < RAD_30) {
vertical = CENTER;
} else if (sine < 0) {
vertical = BOTTOM;
} else {
vertical = TOP;
}
return {
horizontal: horizontal,
vertical: vertical
};
}
setDefaultOptions(PieSegment, {
color: WHITE,
overlay: {
gradient: "roundedBevel"
},
border: {
width: 0.5
},
labels: {
visible: false,
distance: 35,
font: DEFAULT_FONT,
margin: getSpacing(0.5),
align: CIRCLE,
zIndex: 1,
position: OUTSIDE_END
},
animation: {
type: PIE
},
highlight: {
visible: true,
border: {
width: 1
}
},
visible: true,
accessibility: {
role: CHART_POINT_ROLE,
className: CHART_POINT_CLASSNAME,
ariaRoleDescription: CHART_POINT_ROLE_DESCRIPTION
}
});
deepExtend(PieSegment.prototype, PointEventsMixin);
deepExtend(PieSegment.prototype, AccessibilityAttributesMixin);
export default PieSegment;