UNPKG

angular-sunburst-radar-chart

Version:
948 lines (932 loc) 49.9 kB
import { __read, __assign, __spread, __decorate } from 'tslib'; import { Input, Component, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; function hashCode(obj) { var h = 0; obj = getOptionsOrEmpty(obj); var s = JSON.stringify(obj); for (var i = 0; i < s.length; i++) { h = Math.imul(31, h) + s.charCodeAt(i) | 0; } return h; } function getOptionsOrEmpty(options) { return options || {}; } function getItemTitle(item) { item = item || { name: '', value: '' }; var dash = item.name.length > 0 ? '-' : ''; return item.name + dash + item.value; } function clone(obj) { return JSON.parse(JSON.stringify(obj)); } function generateRandomColor() { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i < 6; i++) { color += letters[(Math.floor(Math.random() * 16))]; } return color; } function formatItems(items) { return items.map(function (item) { if (!!item.children && item.children.length > 0) { } else { item['children'] = []; item['children'].push({ name: '', value: 0 }); } return item; }); } function getFormattedAngle(angle, center) { var _a = __read([center.x, center.y], 2), centerX = _a[0], centerY = _a[1]; return 'rotate(' + angle + ' ' + centerX + ' ' + centerY + ')'; } function getCurrentPointFromEvent(evt) { var _a; var _b = __read([evt.clientX, evt.clientY], 2), x = _b[0], y = _b[1]; if (evt.targetTouches && evt.targetTouches[0]) { _a = __read([evt.targetTouches[0].pageX, evt.targetTouches[0].pageY], 2), x = _a[0], y = _a[1]; } return { x: x, y: y }; } function createCircle(options) { var defaults = { x: 0, y: 0, radius: 0, fillColor: 'none', 'stroke-width': '1', 'stroke': '#000000', 'stroke-dasharray': 'none', 'stroke-opacity': '1', 'title': '' }; options = __assign(__assign({}, defaults), (getOptionsOrEmpty(options))); var circle = { name: 'circle', options: options, children: [] }; return circle; } function createLine(options) { var defaults = { x1: 0, y1: 0, x2: 0, y2: 0, color: '#000000', width: '2', title: '' }; options = __assign(__assign({}, defaults), (getOptionsOrEmpty(options))); var line = { name: 'line', options: options, children: [] }; return line; } function createPath(options) { var defaults = { d: '', fill: 'none', stroke: 'none', 'stroke-width': '0', title: '', id: null }; options = __assign(__assign({}, defaults), (getOptionsOrEmpty(options))); var d = options.d, color = options.color, borderColor = options.borderColor; var path = { name: 'path', options: options, children: [] }; return path; } function createPathForBar(options) { var defaults = { d: '', fill: 'none', stroke: 'none', 'stroke-width': '0', 'stroke-opacity': '1.0', 'fill-opacity': '1.0', title: '', id: null }; options = __assign(__assign({}, defaults), (getOptionsOrEmpty(options))); var d = options.d, color = options.color, borderColor = options.borderColor; var gradName = options['fill']; gradName = gradName.replace('#', ''); options['gradientId'] = gradName; options['fillUrl'] = 'url(#' + gradName + ')'; var path = { name: 'path-bar', options: options, children: [] }; return path; } function polarToCartesian(centerX, centerY, radius, angleInDegrees) { var adjustedViewPortAngle = (angleInDegrees - 90); var angleInRadians = adjustedViewPortAngle * Math.PI / 180.0; return { x: centerX + (radius * Math.cos(angleInRadians)), y: centerY + (radius * Math.sin(angleInRadians)) }; } function getLargeArcFlag(startAngle, endAngle) { return (endAngle - startAngle) <= 180 ? '0' : '1'; } function distanceBetweenTwoPoints(centerX, centerY, radius, startAngle, endAngle) { var startPoint = polarToCartesian(centerX, centerY, radius, startAngle); var endPoint = polarToCartesian(centerX, centerY, radius, endAngle); var distFromStartToEnd = Math.sqrt(Math.pow((startPoint.x - endPoint.x), 2) + Math.pow((startPoint.y - endPoint.y), 2)); return Math.abs(distFromStartToEnd); } function calculateAngleRadian(_a) { var x = _a.x, y = _a.y, centerX = _a.centerX, centerY = _a.centerY, maxRad = _a.maxRad; var angleInRadian = Math.atan2(x - centerY, y - centerX); angleInRadian = adjustAngleRadianDifference(angleInRadian, maxRad); return angleInRadian; } function adjustAngleRadianDifference(input, maxRad) { var angleInRadian = input; angleInRadian += maxRad / 4; if (angleInRadian < 0) { angleInRadian += maxRad; } return angleInRadian; } function createArcToWriteText(_a) { var startPoint = _a.startPoint, radius = _a.radius, id = _a.id, startAngle = _a.startAngle, endAngle = _a.endAngle; var _b = __read([startPoint.x, startPoint.y], 2), centerX = _b[0], centerY = _b[1]; var start = polarToCartesian(centerX, centerY, radius, endAngle); var end = polarToCartesian(centerX, centerY, radius, startAngle); var largeArcFlag = getLargeArcFlag(startAngle, endAngle); var d = [ 'M', start.x, start.y, 'A', radius, radius, 0, largeArcFlag, 0, end.x, end.y ].join(' '); return createPath({ d: d, borderColor: '', id: id }); } function getTextForAngle(text, distance, fontSize) { var result = text; var perCharacter = 10.07; if (fontSize < 18) { perCharacter = 8.7; } var totalTextLength = Math.round(distance / perCharacter); if (text.length > 0 && text.length > totalTextLength) { result = text.substring(0, totalTextLength - 1) + '..'; } return result; } function writeTextOnArc(options) { var defaults = { text: '', label: '', pathId: '', 'font-size': '14px', }; options = __assign(__assign({}, defaults), (getOptionsOrEmpty(options))); var text = options.text, pathId = options.pathId, label = options.label; if (pathId !== '') { options['href'] = '#' + pathId; options['startOffset'] = '50%'; options['text-anchor'] = 'middle'; options['title'] = text; } var textOnArc = { name: 'text-on-arc', options: options, children: [] }; return textOnArc; } function createText(options) { var defaults = { content: '', x: 0, y: 0, stroke: 'white', 'stroke-width': '1px', 'font-size': '6px', 'text-anchor': 'middle' }; options = __assign(__assign({}, defaults), (getOptionsOrEmpty(options))); var textElement = { name: 'text', options: options, children: [] }; return textElement; } function convertToPercentage(input) { var plotMax = input.plotMax, actualScore = input.actualScore, maxScore = input.maxScore; if (actualScore > maxScore) { actualScore = maxScore; } var perValue = plotMax / maxScore; return actualScore * perValue; } function createOuterChartBarWithInArc(_a) { var item = _a.item, startAngle = _a.startAngle, endAngle = _a.endAngle, middleAngle = _a.middleAngle, color = _a.color, middleRadius = _a.middleRadius, maxScore = _a.maxScore, innerRadiusBorder = _a.innerRadiusBorder, center = _a.center; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var currentVal = item.value; var totalRadiusInside = middleRadius - innerRadiusBorder; var innerRadius = convertToPercentage({ plotMax: totalRadiusInside, actualScore: currentVal, maxScore: maxScore }); var radiusFromCenter = innerRadius + innerRadiusBorder; var firstPoint = polarToCartesian(centerX, centerY, radiusFromCenter, startAngle); var secondPoint = polarToCartesian(centerX, centerY, radiusFromCenter, endAngle); var startPoint = polarToCartesian(centerX, centerY, innerRadiusBorder, startAngle); var endPoint = polarToCartesian(centerX, centerY, innerRadiusBorder, endAngle); var startMiddlePoint = polarToCartesian(centerX, centerY, innerRadiusBorder, middleAngle); var distFromStartToFirst = Math.sqrt(Math.pow((startPoint.x - firstPoint.x), 2) + Math.pow((startPoint.y - firstPoint.y), 2)); var distFromStartToSecond = Math.sqrt(Math.pow((startPoint.x - secondPoint.x), 2) + Math.pow((startPoint.y - secondPoint.y), 2)); var _c = getUpdatedPoints(firstPoint, secondPoint, distFromStartToFirst, distFromStartToSecond), updatedFirstPoint = _c.updatedFirstPoint, updatedSecondPoint = _c.updatedSecondPoint; var d = getDrawPositions(updatedFirstPoint, middleRadius, updatedSecondPoint, endPoint, startMiddlePoint, startPoint); var title = getItemTitle(item); return createPathForBar({ d: d.join(' '), stroke: 'none', fill: color, "fill-opacity": '0.5', title: title }); } function getDrawPositions(firstPoint, middleRadius, secondPoint, endPoint, startMiddlePoint, startPoint) { var d = [ 'M', firstPoint.x, firstPoint.y, 'A', middleRadius, middleRadius, 0, 0, 1, secondPoint.x, secondPoint.y, 'L', endPoint.x, endPoint.y, 'C', endPoint.x, endPoint.y, startMiddlePoint.x, startMiddlePoint.y, startPoint.x, startPoint.y, 'L', firstPoint.x, firstPoint.y, 'Z' ]; return d; } function getUpdatedPoints(firstPoint, secondPoint, distFromStartToFirst, distFromStartToSecond) { var _a = __read([firstPoint, secondPoint], 2), updatedFirstPoint = _a[0], updatedSecondPoint = _a[1]; if (distFromStartToSecond < distFromStartToFirst) { updatedSecondPoint = firstPoint; updatedFirstPoint = secondPoint; } return { updatedSecondPoint: updatedSecondPoint, updatedFirstPoint: updatedFirstPoint }; } function createInnerChartBarWithInArc(_a) { var startPoint = _a.startPoint, item = _a.item, radius = _a.radius, startAngle = _a.startAngle, endAngle = _a.endAngle, maxScore = _a.maxScore; var _b = __read([startPoint.x, startPoint.y], 2), centerX = _b[0], centerY = _b[1]; var currentVal = item.value; var color = item.color; var arcRadius = convertToPercentage({ plotMax: radius, actualScore: currentVal, maxScore: maxScore }); var start = polarToCartesian(centerX, centerY, arcRadius, endAngle); var end = polarToCartesian(centerX, centerY, arcRadius, startAngle); var largeArcFlag = getLargeArcFlag(startAngle, endAngle); //const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'; var d = [ 'M', centerX, centerY, 'L', start.x, start.y, 'A', arcRadius, arcRadius, 0, largeArcFlag, 0, end.x, end.y ].join(' '); var title = getItemTitle(item); var arcForInnerChart = createPathForBar({ d: d, fill: color, title: title }); return arcForInnerChart; } function getRadiusForBorderAndText(radius, borderHeight) { var borderRadius = radius + borderHeight; var textRadius = radius + ((borderRadius - radius) / 2); return [borderRadius, textRadius]; } function getMaxDepth(items, currentLevel) { if (currentLevel === void 0) { currentLevel = 0; } var depths = []; if (items && items.length > 0) { var nextLevel_1 = currentLevel + 1; depths = items .filter(function (item) { return !!item.children; }) .filter(function (item) { return item.children.length > 0; }) .map(function (item) { return getMaxDepth(item.children, nextLevel_1); }); } return depths.length !== 0 ? Math.max.apply(Math, __spread(depths)) : currentLevel; } function getGlobalPositions(_a) { var size = _a.size, maxScore = _a.maxScore, items = _a.items; var center = { x: size / 2, y: size / 2 }; var maxDepth = getMaxDepth(items); var totalLevels = maxDepth + 1; var innerCircleRadius = Math.abs(size / 5.33); var totalRadiusToBeDrawn = 2 * Math.abs(size / 5.33); var borderHeight = 0.0375 * size; var everyLevelRadius = totalRadiusToBeDrawn / totalLevels; var levels = []; for (var i = 1; i <= totalLevels; i++) { var startRadius = i * everyLevelRadius; var _b = __read(getRadiusForBorderAndText(startRadius, borderHeight), 2), endRadius = _b[0], textRadius = _b[1]; levels.push({ startRadius: startRadius, endRadius: endRadius, textRadius: textRadius }); } var innerRadius = innerCircleRadius; var _c = __read(getRadiusForBorderAndText(innerRadius, borderHeight), 2), innerRadiusBorder = _c[0], innerTextRadius = _c[1]; var middleRadius = innerCircleRadius * 2; var _d = __read(getRadiusForBorderAndText(middleRadius, borderHeight), 2), middleRadiusBorder = _d[0], middleTextRadius = _d[1]; var outerRadius = middleRadius + borderHeight; var _e = __read(getRadiusForBorderAndText(outerRadius, borderHeight * 2), 2), outerRadiusBorder = _e[0], outerTextRadius = _e[1]; var textSize = 0.0175 * size; var outerTextSize = 0.0225 * size; var result = { textSize: textSize, outerTextSize: outerTextSize, levels: levels, innerRadius: innerRadius, innerRadiusBorder: innerRadiusBorder, innerTextRadius: innerTextRadius, middleRadius: middleRadius, middleTextRadius: middleTextRadius, middleRadiusBorder: middleRadiusBorder, outerRadius: outerRadius, outerRadiusBorder: outerRadiusBorder, outerTextRadius: outerTextRadius, center: center }; return result; } function calculatePointBetween(_a) { var centerX = _a.centerX, centerY = _a.centerY, startAngle = _a.startAngle, middleAngle = _a.middleAngle, endAngle = _a.endAngle, radius = _a.radius; var start = polarToCartesian(centerX, centerY, radius, startAngle); var middle = polarToCartesian(centerX, centerY, radius, middleAngle); var end = polarToCartesian(centerX, centerY, radius, endAngle); return { start: start, middle: middle, end: end }; } function createLegendWithOptions(_a) { var startPoint = _a.startPoint, center = _a.center, startRadius = _a.startRadius, endRadius = _a.endRadius, degreeToBeDrawn = _a.degreeToBeDrawn, maxScore = _a.maxScore; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var actRadius = endRadius - startRadius; var axisIncrement = maxScore / 4; var legendRadius = convertToPercentage({ plotMax: actRadius, actualScore: axisIncrement, maxScore: maxScore }); var smallCircleRadius = Math.round(0.083 * actRadius); var smallCircleFontSize = Math.round(0.067 * actRadius); var groups = [1, 2, 3] .map(function (val) { return { radius: val * legendRadius, content: Math.round(val * axisIncrement) }; }) .map(function (res) { var radius = res.radius, content = res.content; var _a = polarToCartesian(startPoint.x, startPoint.y, radius, degreeToBeDrawn), x = _a.x, y = _a.y; var circle = createCircle({ x: x, y: y, radius: smallCircleRadius, 'fillColor': '#000000' }); var legendCircle = createCircle({ x: centerX, y: centerY, radius: startRadius + radius, 'stroke-dasharray': 4, 'stroke-opacity': 0.3 }); var fontSize = smallCircleFontSize + "px"; //console.log("font-size",fontSize) var text = createText({ content: content, x: x, y: y, 'stroke': 'white', 'font-size': fontSize }); return [circle, legendCircle, text]; }); return [].concat.apply([], groups); } function createLegends(_a) { var startPoint = _a.startPoint, radius = _a.radius, degreeToBeDrawn = _a.degreeToBeDrawn, maxScore = _a.maxScore; return createLegendWithOptions({ startPoint: startPoint, center: startPoint, startRadius: 0, endRadius: radius, degreeToBeDrawn: degreeToBeDrawn, maxScore: maxScore }); } //Not Used now ,Might Use later // function anglesBasedOnPercentage(items) { // // const total = items.reduce((prevValue, curValue) => prevValue + //curValue, 0); // if (Math.round(total) != 100) { // console.error('Cannnot draw as the sum of values should be 100'); // throw new Error('Cannnot draw as the sum of values should be 100'); // } // let prevDegree = 0; // const results = []; // for (let i = 0; i < items.length; i++) { // // const item = items[i]; // const currentDegree = item * 3.6; // // const degreeToBeDrawn = currentDegree + prevDegree; // results.push(degreeToBeDrawn); // prevDegree = prevDegree + currentDegree; // } // // // return results; // } // function getInitialPosition(startLocation, totalDegrees, num) { var perLocation = totalDegrees / num; var middleLocation = perLocation / 2; var startMiddle = startLocation + middleLocation; return { startLocation: startLocation, perLocation: perLocation, middleLocation: middleLocation, startMiddle: startMiddle }; } function getDegreeForIndexBasedOnSplitAngle(index, data) { var perLocation = data.perLocation, middleLocation = data.middleLocation, startMiddle = data.startMiddle, startLocation = data.startLocation; var position = index; // + 1; var startDegree = startLocation + (position * perLocation); var middleDegree = startMiddle + (position * perLocation); var endDegree = startLocation + (position * perLocation) + perLocation; return { startDegree: startDegree, middleDegree: middleDegree, endDegree: endDegree }; } function getAllAnglesBasedOnChild(items) { var num = items.length; var results = []; var totalChildren = items.filter(function (item) { return item.children; }).map(function (item) { return item.children.length; }).reduce((function (a, b) { return a + b; }), 0); var childAngleDifference = 360 / totalChildren; var currentStartLocation = 0; for (var i = 0; i < items.length; i++) { var item = items[i]; var childCount = item.children ? item.children.length : 0; var totalDegrees = childCount * childAngleDifference; var endDegree = currentStartLocation + (childCount * childAngleDifference); var middleDegree = (endDegree - currentStartLocation) / 2; var currentItem = {}; currentItem['item'] = item; currentItem['startDegree'] = currentStartLocation; currentItem['middleDegree'] = middleDegree; currentItem['endDegree'] = endDegree; if (childCount > 0) { currentItem['children'] = iterateChildrenAndSetAngles({ children: item.children, currentItem: currentItem, angleDifference: totalDegrees }); } currentStartLocation = currentStartLocation + (childCount * childAngleDifference); results.push(currentItem); } return results; } function getAllAnglesBasedOnParent(items) { var num = items.length; var results = []; var angleDifference = 360 / num; var data = getInitialPosition(0, 360, num); for (var i = 0; i < items.length; i++) { var _a = getDegreeForIndexBasedOnSplitAngle(i, data), startDegree = _a.startDegree, middleDegree = _a.middleDegree, endDegree = _a.endDegree; var item = items[i]; var currentItem = {}; currentItem['item'] = item; currentItem['startDegree'] = startDegree; currentItem['middleDegree'] = middleDegree; currentItem['endDegree'] = endDegree; var hasChildren = items.filter(function (item) { return !!item.children; }).length > 0; if (hasChildren) { currentItem['children'] = iterateChildrenAndSetAngles({ children: item.children, currentItem: currentItem, angleDifference: angleDifference }); } results.push(currentItem); } return results; } function iterateChildrenAndSetAngles(_a) { var children = _a.children, currentItem = _a.currentItem, angleDifference = _a.angleDifference; var count = children.length; var childItems = []; var data = getInitialPosition(currentItem['startDegree'], angleDifference, count); for (var j = 0; j < count; j++) { var childItem = {}; childItem['item'] = children[j]; var _b = getDegreeForIndexBasedOnSplitAngle(j, data), startDegree = _b.startDegree, middleDegree = _b.middleDegree, endDegree = _b.endDegree; childItem['startDegree'] = startDegree; childItem['middleDegree'] = middleDegree; childItem['endDegree'] = endDegree; childItems.push(childItem); } return childItems; } function positionsOnAngles(centerX, centerY, radius, angels) { var results = []; for (var i = 0; i < angels.length; i++) { var degreeToBeDrawn = angels[i]; results.push(polarToCartesian(centerX, centerY, radius, degreeToBeDrawn)); } return results; } function getPointsOnCircleAtAngels(centerX, centerY, radius, angels) { var results = []; for (var i = 0; i < angels.length; i++) { var degreeToBeDrawn = angels[i]; results.push(polarToCartesian(centerX, centerY, radius, degreeToBeDrawn)); } return results; } function createSvgHandlerWithSelector(selectorName, center) { var svg = document.querySelector(selectorName); var pt = svg.createSVGPoint(); var maxRad = 6.283185307179586; var maxDeg = 360; return { initPoint: 0, cursorPoint: function (evt) { var _a = getCurrentPointFromEvent(evt), x = _a.x, y = _a.y; pt.x = x; pt.y = y; return pt.matrixTransform(svg.getScreenCTM().inverse()); }, startDrag: function (evt, initialPoint) { this.previousPoint = this.angleFromCenter(evt); this.initPoint = initialPoint; }, updateInitPointFromCurrentPoint: function (currentPoint) { var difference = Math.abs(this.previousPoint - currentPoint); if (currentPoint < this.previousPoint) { this.initPoint += difference; } else { this.initPoint -= difference; } }, getRotationAngle: function (evt) { var currentPoint = this.angleFromCenter(evt); this.updateInitPointFromCurrentPoint(currentPoint); this.previousPoint = currentPoint; return this.initPoint; }, angleFromCenter: function (evt) { var _a = __read([center.x, center.y], 2), centerX = _a[0], centerY = _a[1]; var _b = this.cursorPoint(evt), x = _b.x, y = _b.y; var angleInRadian = calculateAngleRadian({ x: x, y: y, centerX: centerX, centerY: centerY, maxRad: maxRad }); var currentDegree = maxDeg * angleInRadian / (2 * Math.PI); return currentDegree; } }; } var AngularSunburstRadarChartComponent = /** @class */ (function () { function AngularSunburstRadarChartComponent() { this.componentDisplayed = false; this.showToolTip = false; this.tooltipTopInPx = '0px'; this.tooltipLeftInPx = '0px'; this.tooltipText = ''; this.svgId = null; this.svgGroupId = null; this.svgHandler = null; this.currentRotationAngle = 10; this.svgCursor = 'default'; this.initialized = false; this.innerBorderHeight = 30; this.outerBorderHeight = 30; this.elements = []; this.hasChildren = false; this.outerBorderCircleRef = 'outerBorderCircle'; this.error = null; this.hasError = false; this.startRotation = false; } AngularSunburstRadarChartComponent.prototype.showError = function (msg) { this.error = msg; this.hasError = true; }; AngularSunburstRadarChartComponent.prototype.hideError = function () { this.error = null; this.hasError = false; }; AngularSunburstRadarChartComponent.prototype.appendToSvg = function (element) { this.elements.push(element); }; AngularSunburstRadarChartComponent.prototype.ngOnChanges = function (changes) { this.hideError(); var isFirstChange = Object.values(changes).some(function (c) { return c.isFirstChange(); }); this.modifyOnFirstChange(isFirstChange); }; AngularSunburstRadarChartComponent.prototype.modifyOnFirstChange = function (isFirstChange) { if (!isFirstChange) { this.initialize(); } }; AngularSunburstRadarChartComponent.prototype.ngOnInit = function () { this.hideError(); this.initialize(); }; AngularSunburstRadarChartComponent.prototype.initialize = function () { var _this = this; var defaults = { size: 300, maxScore: 100, animateChart: true, splitBasedOnChildren: true, legendAxisLinePosition: 1 }; var options = __assign(__assign({}, defaults), (getOptionsOrEmpty(this.options))); this.size = options.size; this.maxScore = options.maxScore; this.animateChart = options.animateChart; this.splitBasedOnChildren = options.splitBasedOnChildren; this.legendAxisLinePosition = options.legendAxisLinePosition; if (!this.hasValidParameters()) { this.showError('Input Values not set or Items was improper'); return; } this.initialized = false; this.svgId = 'svg' + hashCode(this.items); this.svgGroupId = 'svg-group' + hashCode(this.items); this.viewBox = '0 0 ' + this.size + ' ' + this.size; this.innerCircleRadius = Math.abs(this.size / 5.33); this.innerBorderHeight = this.innerCircleRadius / 5; this.outerBorderHeight = this.innerCircleRadius / 5; this.globalPosition = getGlobalPositions({ size: this.size, maxScore: this.maxScore, items: this.items }); this.hasChildren = this.items.filter(function (item) { return !!item.children; }).length > 0; this.drawLayout(); var _a = this.globalPosition, innerRadius = _a.innerRadius, innerTextRadius = _a.innerTextRadius, textSize = _a.textSize, outerTextSize = _a.outerTextSize, outerRadiusBorder = _a.outerRadiusBorder, outerTextRadius = _a.outerTextRadius, center = _a.center; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var items = this.items; var allAngels = []; var hasChildren = this.hasChildren; if (this.splitBasedOnChildren) { // Cannot have no children items = formatItems(items); allAngels = getAllAnglesBasedOnChild(items); } else { allAngels = getAllAnglesBasedOnParent(items); } var angleDifference = 360 / items.length; var angles = allAngels.map(function (value) { return value.startDegree; }); var middleAngles = allAngels.map(function (value) { return value.middleDegree; }); var points = positionsOnAngles(centerX, centerY, this.chartBorder, angles); var lines = []; var elements = []; var nextLevelElements = []; for (var i = 0; i < points.length; i++) { var _c = points[i], x = _c.x, y = _c.y; var endAngleIndex = i + 1; if (endAngleIndex >= points.length) { endAngleIndex = 0; } var endAngle = angles[endAngleIndex]; var startAngle = angles[i]; var middleAngle = middleAngles[i]; var item = items[i]; if (!!item.color === false) { var colorDefaults = { color: generateRandomColor() }; item = __assign(__assign({}, colorDefaults), item); } if (this.hasChildren && item.children && item.children.length > 0) { var childAngels = allAngels[i].children; nextLevelElements = nextLevelElements.concat(this.drawOnLevel({ items: item.children, totalDegrees: angleDifference, childAngels: childAngels, color: item.color })); } lines.push(createLine({ x1: centerX, y1: centerY, x2: x, y2: y, width: 2 })); // Create Arc for inner values var barWithinArc = createInnerChartBarWithInArc({ startPoint: center, item: item, radius: innerRadius, startAngle: startAngle, endAngle: endAngle, maxScore: this.maxScore }); elements.push(barWithinArc); var innerTextElements = this.addArcText({ arcForTextId: 'arc-text-inner' + this.getUniqueCode() + '-' + i, radius: innerTextRadius, fontSize: textSize, startAngle: startAngle, endAngle: endAngle, perAngle: angleDifference, item: item }); elements = elements.concat(innerTextElements); if (hasChildren) { elements.push(this.drawOuterBackgroundWithMiddle({ item: item, startAngle: startAngle, middleAngle: middleAngle, endAngle: endAngle })); var outerBackgroundTextElements = this.addArcText({ arcForTextId: 'arc-text-outer' + this.getUniqueCode() + '-' + i, radius: outerTextRadius, fontSize: outerTextSize, perAngle: angleDifference, startAngle: startAngle, endAngle: endAngle, item: item }); elements = elements.concat(outerBackgroundTextElements); } } nextLevelElements.forEach(function (line) { _this.appendToSvg(line); }); this.drawInnerBorders(); elements.forEach(function (line) { _this.appendToSvg(line); }); lines.forEach(function (line) { _this.appendToSvg(line); }); var legendAxisIndex = this.getLegendAxisIndex(angles); this.drawLegends(angles[legendAxisIndex]); this.addSmallCirclesAtCenter(centerX, centerY); this.initialized = true; this.currentRotationAngle = 10; this.rotationPoint = getFormattedAngle(this.currentRotationAngle, center); }; AngularSunburstRadarChartComponent.prototype.getLegendAxisIndex = function (angles) { var legendAxisIndex = this.legendAxisLinePosition - 1; if (legendAxisIndex < 0 || legendAxisIndex >= angles.length) { legendAxisIndex = 0; } return legendAxisIndex; }; AngularSunburstRadarChartComponent.prototype.hasValidParameters = function () { return this.items && this.items.length > 1; }; AngularSunburstRadarChartComponent.prototype.drawOuterBackgroundWithMiddle = function (_a) { var item = _a.item, startAngle = _a.startAngle, middleAngle = _a.middleAngle, endAngle = _a.endAngle; var color = item.color; var _b = this.globalPosition, outerTextRadius = _b.outerTextRadius, center = _b.center; var _c = __read([center.x, center.y], 2), centerX = _c[0], centerY = _c[1]; var middleCircle = calculatePointBetween({ centerX: centerX, centerY: centerY, startAngle: startAngle, middleAngle: middleAngle, endAngle: endAngle, radius: outerTextRadius }); var d = [ 'M', middleCircle.start.x, middleCircle.start.y, 'A', outerTextRadius, outerTextRadius, 0, 0, 1, middleCircle.end.x, middleCircle.end.y ]; var title = item.name + '-' + item.value; var strokeWidth = 0.0775 * this.size; return createPath({ d: d.join(' '), stroke: color, 'stroke-width': strokeWidth, title: title }); }; AngularSunburstRadarChartComponent.prototype.drawOnLevel = function (_a) { var items = _a.items, totalDegrees = _a.totalDegrees, childAngels = _a.childAngels, color = _a.color; var _b = this.globalPosition, innerRadiusBorder = _b.innerRadiusBorder, middleRadius = _b.middleRadius, textSize = _b.textSize, middleTextRadius = _b.middleTextRadius, center = _b.center; var _c = __read([center.x, center.y], 2), centerX = _c[0], centerY = _c[1]; var angles = childAngels.map(function (item) { return item.startDegree; }); var middleAngles = childAngels.map(function (item) { return item.middleDegree; }); var endAngles = childAngels.map(function (item) { return item.endDegree; }); var perAngle = totalDegrees / items.length; var pointsOnInnerRadiusBorder = getPointsOnCircleAtAngels(centerX, centerY, innerRadiusBorder, angles); var pointsOnMiddle = getPointsOnCircleAtAngels(centerX, centerY, middleRadius, angles); var elements = []; var lines = []; var currentDegree = angles[0]; for (var i = 0; i < pointsOnInnerRadiusBorder.length; i++) { var pointOnInnerRadiusBorder = pointsOnInnerRadiusBorder[i]; var pointOnMiddle = pointsOnMiddle[i]; lines.push(createLine({ x1: pointOnInnerRadiusBorder.x, y1: pointOnInnerRadiusBorder.y, x2: pointOnMiddle.x, y2: pointOnMiddle.y, width: 0.5 })); var startAngle = angles[i]; var middleAngle = middleAngles[i]; var endAngle = endAngles[i]; var item = items[i]; var params = { startPoint: pointOnInnerRadiusBorder, item: item, startAngle: startAngle, endAngle: endAngle, middleAngle: middleAngle, middleRadius: middleRadius, innerRadiusBorder: innerRadiusBorder, center: center, maxScore: this.maxScore, color: color, index: i }; var arcForChart = createOuterChartBarWithInArc(params); elements.push(arcForChart); var middleTextElements = this.addArcText({ arcForTextId: 'arc-text-middle' + this.getUniqueCode() + '-' + startAngle + i, radius: middleTextRadius, fontSize: textSize, perAngle: perAngle, startAngle: startAngle, endAngle: endAngle, item: item }); elements = elements.concat(middleTextElements); currentDegree = currentDegree + perAngle; } lines.forEach(function (line) { elements.push(line); }); return elements; }; AngularSunburstRadarChartComponent.prototype.getUniqueCode = function () { return hashCode(this.items) + '-' + this.size; }; AngularSunburstRadarChartComponent.prototype.drawInnerBorders = function () { var _a = this.globalPosition, innerRadius = _a.innerRadius, innerRadiusBorder = _a.innerRadiusBorder, center = _a.center; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var innerContainer = createCircle({ x: centerX, y: centerY, radius: innerRadius, fillColor: 'none' }); var innerBorderContainer = createCircle({ x: centerX, y: centerY, radius: innerRadiusBorder, fillColor: '#FFFFFF' }); this.appendToSvg(innerBorderContainer); this.appendToSvg(innerContainer); }; AngularSunburstRadarChartComponent.prototype.addSmallCirclesAtCenter = function (centerX, centerY) { var outerRadius = 0.0025 * 2 * this.size; var innerRadius = 0.0005 * 2 * this.size; this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: outerRadius, fillColor: '#FFFFFF' })); this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: innerRadius, fillColor: '#FFFFFF' })); }; AngularSunburstRadarChartComponent.prototype.drawLegends = function (degreeToBeDrawn) { var _this = this; var _a = this.globalPosition, innerRadius = _a.innerRadius, innerRadiusBorder = _a.innerRadiusBorder, middleRadius = _a.middleRadius, center = _a.center; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var maxScore = this.maxScore; var legends = createLegends({ startPoint: center, radius: innerRadius, degreeToBeDrawn: degreeToBeDrawn, maxScore: maxScore }); var startFrom = polarToCartesian(centerX, centerY, innerRadiusBorder, degreeToBeDrawn); if (this.hasChildren) { var nextLevelLegends = createLegendWithOptions({ startPoint: startFrom, center: center, startRadius: innerRadiusBorder, endRadius: middleRadius, maxScore: maxScore, degreeToBeDrawn: degreeToBeDrawn }); legends = legends.concat(nextLevelLegends); } legends.forEach(function (elem) { _this.appendToSvg(elem); }); }; AngularSunburstRadarChartComponent.prototype.addArcText = function (_a) { var arcForTextId = _a.arcForTextId, radius = _a.radius, startAngle = _a.startAngle, fontSize = _a.fontSize, endAngle = _a.endAngle, perAngle = _a.perAngle, item = _a.item; var elements = []; var center = this.globalPosition.center; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var arcForText = createArcToWriteText({ id: arcForTextId, startPoint: center, radius: radius, startAngle: startAngle, endAngle: endAngle }); elements.push(arcForText); var distance = distanceBetweenTwoPoints(centerX, centerY, radius, startAngle, endAngle); var label = getTextForAngle(item.name, distance, fontSize); elements.push(writeTextOnArc({ label: label, text: item.name, pathId: arcForTextId, 'font-size': fontSize + 'px' })); return elements; }; AngularSunburstRadarChartComponent.prototype.drawLayout = function () { var _a = this.globalPosition, innerRadius = _a.innerRadius, innerRadiusBorder = _a.innerRadiusBorder, middleRadius = _a.middleRadius, middleRadiusBorder = _a.middleRadiusBorder, outerRadius = _a.outerRadius, outerRadiusBorder = _a.outerRadiusBorder, center = _a.center; var _b = __read([center.x, center.y], 2), centerX = _b[0], centerY = _b[1]; var innerRadiusEnd = innerRadius; var innerRadiusBorderEnd = innerRadiusBorder; this.chartBorder = innerRadiusBorder; if (this.hasChildren) { var outerBorderCircle = createCircle({ x: centerX, y: centerY, radius: outerRadiusBorder, fillColor: 'none', 'stroke-width': '5', ref: this.outerBorderCircleRef }); this.appendToSvg(outerBorderCircle); var outerCircle = createCircle({ x: centerX, y: centerY, radius: outerRadius, fillColor: 'none' }); this.appendToSvg(outerCircle); innerRadiusEnd = middleRadius; innerRadiusBorderEnd = middleRadiusBorder; this.chartBorder = outerRadiusBorder; } this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: innerRadiusEnd })); this.appendToSvg(createCircle({ x: centerX, y: centerY, radius: innerRadiusBorderEnd })); }; AngularSunburstRadarChartComponent.prototype.hideTooltip = function () { this.showToolTip = false; }; AngularSunburstRadarChartComponent.prototype.showTooltipText = function ($event, text) { this.tooltipLeftInPx = $event.pageX + 10 + 'px'; this.tooltipTopInPx = $event.pageY + 10 + 'px'; this.tooltipText = text; this.showToolTip = true; }; AngularSunburstRadarChartComponent.prototype.onOutOfComponent = function () { this.hideTooltip(); this.stopRotate(); }; AngularSunburstRadarChartComponent.prototype.stopRotate = function () { this.svgCursor = 'default'; this.startRotation = false; }; AngularSunburstRadarChartComponent.prototype.startRotate = function ($event) { this.startRotation = true; this.svgCursor = 'grab'; var _a = this.globalPosition, outerRadiusBorder = _a.outerRadiusBorder, center = _a.center; this.svgHandler = createSvgHandlerWithSelector('#' + this.svgId, center); this.svgHandler.startDrag($event, this.currentRotationAngle); $event.preventDefault(); }; AngularSunburstRadarChartComponent.prototype.rotateChart = function ($event) { if (this.startRotation == false) { return; } this.svgCursor = 'grabbing'; var center = this.globalPosition.center; this.currentRotationAngle = this.svgHandler.getRotationAngle($event); this.rotationPoint = getFormattedAngle(Math.round(this.currentRotationAngle), center); }; __decorate([ Input() ], AngularSunburstRadarChartComponent.prototype, "items", void 0); __decorate([ Input() ], AngularSunburstRadarChartComponent.prototype, "options", void 0); AngularSunburstRadarChartComponent = __decorate([ Component({ selector: 'lib-sunburst-radar-chart', template: "<ng-container (mouseout)=\"onOutOfComponent();\">\n\n\n <div *ngIf=\"hasError\" style=\" color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n margin-top: 5px;\npadding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n\">\n <strong>Error!</strong> {{error}}\n </div>\n\n\n\n<div class=\"app-tooltip\" *ngIf=\"showToolTip\" style=\"position: absolute; display: block;background: cornsilk; border: 1px solid black; border-radius: 5px; padding: 5px; z-index: 1002;\"\n\n [style.left]=\"tooltipLeftInPx\" [style.top]=\"tooltipTopInPx\" >\n {{tooltipText}}\n</div>\n\n<svg [attr.id]=\"svgId\"\n [attr.height]=\"size\"\n [attr.width]=\"size\"\n [attr.viewBox]=\"viewBox\"\n [style.cursor]=\"svgCursor\"\n xmlns=\"http://www.w3.org/2000/svg\">\n\n\n\n\n <animateTransform\n *ngIf=\"animateChart\"\n attributeName=\"transform\"\n begin=\"4s\"\n dur=\"500ms\"\n type=\"rotate\"\n from=\"0\"\n to=\"10\"\n\n additive=\"sum\"\n fill=\"freeze\"\n repeatCount=\"1\"\n />\n\n\n<g\n (mousemove)=\"rotateChart($event);\"\n (mousedown)=\"startRotate($event)\"\n (mouseup)=\"stopRotate()\"\n (touchmove)=\"rotateChart($event);\"\n (touchstart)=\"startRotate($event)\"\n (touchend)=\"stopRotate()\"\n [attr.transform]=\"rotationPoint\"\n [attr.id]=\"svgGroupId\"\n\n\n >\n <ng-container *ngFor=\"let element of elements\" >\n\n\n\n <ng-container [ngSwitch]=\"element.name\" >\n\n\n <circle *ngSwitchCase=\"'circle'\" [attr.cx]=\"element.options.x\" [attr.cy]=[element.options.y]\n [attr.r]=\"element.options.radius\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.stroke]=\"element.options['stroke']\"\n [attr.stroke-dasharray]=\"element.options['stroke-dasharray']\"\n [attr.stroke-opacity]=\"element.options['stroke-opacity']\"\n [attr.fill]=\"element.options['fillColor']\"\n >\n\n\n\n\n </circle>\n\n <path *ngSwitchCase=\"'path'\" [attr.d]=\"element.options.d\" [attr.fill]=[element.options.fill]\n\n [attr.stroke]=\"element.options['stroke']\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.id]=\"element.options['id']\"\n (mousemove)=\"showTooltipText($event, element.options['title']);\"\n (mouseout)=\"hideTooltip()\" >\n\n\n\n\n\n </path>\n\n<g *ngSwitchCase=\"'path-bar'\" >\n\n\n\n <path [attr.d]=\"element.options.d\"\n [attr.fill]=[element.options.fill]\n\n [attr.stroke]=\"element.options['stroke']\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.stroke-opacity]=\"element.options['stroke-opacity']\"\n [attr.fill-opacity]=\"element.options['fill-opacity']\"\n [attr.id]=\"element.options['id']\"\n (mousemove)=\"showTooltipText($event, element.options['title']);\" (mouseout)=\"hideTooltip()\" >\n\n\n\n\n <ng-container\n\n *ngIf=\"animateChart\"\n >\n\n <animate\n attributeName=\"fill\"\n [attr.from]=\"element.options['fill']\"\n to=\"transparent\"\n dur=\"1ms\"\n fill=\"freeze\" />\n <animate\n attributeName=\"stroke\"\n [attr.from]=\"element.options['fill']\"\n [attr.to]=\"element.options['fill']\"\n dur=\"1ms\"\n fill=\"freeze\" />\n <animate\n attributeName=\"stroke-width\"\n from=\"8\"\n to=\"8\"\n dur=\"1ms\"\n fill=\"freeze\" />\n <animate\n attributeName=\"stroke-dasharray\"\n from=\"1000\"\n to=\"1000\"\n dur=\"1ms\"\n fill=\"freeze\" />\n\n\n <animate\n attributeName=\"fill\"\n from=\"#FFFFFF\"\n [attr.to]=\"element.options['fill']\"\n begin=\"2s\"\n dur=\"3s\"\n fill=\"freeze\" />\n\n <animate\n attributeName=\"stroke-dashoffset\"\n from=\"1000\"\n to=\"0\"\n begin=\"1ms\"\n dur=\"3s\"\n fill=\"freeze\" />\n\n <animate\n attributeName=\"stroke-width\"\n from=\"8\"\n [attr.to]=\"element.options['stroke']\"\n begin=\"3s\"\n dur=\"1s\"\n fill=\"freeze\" />\n </ng-container>\n </path>\n\n\n\n\n</g>\n\n <text *ngSwitchCase=\"'text-on-arc'\"\n [attr.font-size]=\"element.options['font-size']\"\n\n >\n <textPath\n [attr.href]=\"element.options.href\"\n [attr.startOffset]=\"element.options.startOffset\"\n [attr.text-anchor]=\"element.options['text-anchor']\"\n >{{element.options['label']}}</textPath>\n <title>{{element.options['title']}}</title>\n\n </text>\n\n\n <line *ngSwitchCase=\"'line'\"\n [attr.x1]=\"element.options.x1\"\n [attr.y1]=\"element.options.y1\"\n [attr.x2]=\"element.options.x2\"\n [attr.y2]=\"element.options.y2\"\n [attr.stroke-width]=\"element.options.width\"\n\n [attr.stroke]=\"element.options['color']\" >\n <title>{{element.options['title']}}</title>\n </line>\n\n\n <text *ngSwitchCase=\"'text'\"\n [attr.x]=\"element.options.x\"\n [attr.y]=\"element.options.y\"\n [attr.stroke]=\"element.options.stroke\"\n [attr.stroke-width]=\"element.options['stroke-width']\"\n [attr.font-size]=\"element.options['font-size']\"\n [attr.text-anchor]=\"element.options['text-anchor']\"\n >{{element.options.content}}\n <title>{{element.options['content']}}</title>\n </text>\n\n </ng-container>\n\n\n\n </ng-container>\n\n\n </g>\n</svg>\n</ng-container>\n", styles: [".app-tooltip{background:#fff8dc;border:1px solid #000;border-radius:5px;padding:5px;z-index:1002}.growAnimation{-moz-transition:transform 2s ease-in-out;-webkit-transition:transform 2s ease-in-out;-o-transition:transform 2s ease-in-out;transform:scale(1)}.growAnimation:active{transform:scale(.5)}"] }) ], AngularSunburstRadarChartComponent); return AngularSunburstRadarChartComponent; }()); var AngularSunburstRadarChartModule = /** @class */ (function () { function AngularSunburstRadarChartModule() { } AngularSunburstRadarChartModule = __decorate([ NgModule({ declarations: [AngularSunburstRadarChartComponent], imports: [ CommonModule ], exports: [AngularSunburstRadarChartComponent] }) ], AngularSunburstRadarChartModule); return AngularSunburstRadarChartModule; }()); /* * Public API Surface of angular-sunburst-radar-chart */ /** * Generated bundle index. Do not edit. */ export { AngularSunburstRadarChartComponent, AngularSunburstRadarChartModule }; //# sourceMappingURL=angular-sunburst-radar-chart.js.map