UNPKG

@syncfusion/ej2-charts

Version:

Feature-rich chart control with built-in support for over 25 chart types, technical indictors, trendline, zooming, tooltip, selection, crosshair and trackball.

394 lines (393 loc) 21.1 kB
import { measureText, TextOption, renderTextElement, CircleOption, PathOption, RectOption } from '../../smithchart/utils/helper'; import { SmithchartRect } from '../../smithchart/utils/utils'; import { legendRender } from '../model/constant'; var SmithchartLegend = /** @class */ (function () { function SmithchartLegend() { this.legendSeries = []; } SmithchartLegend.prototype.renderLegend = function (smithchart) { this._drawLegend(smithchart); }; SmithchartLegend.prototype.calculateLegendBounds = function (smithchart) { this.legendSeries = []; var padding = 10; var legend = smithchart.legendSettings; var legendSizeHeight = legend.height; var legendSizeWidth = legend.width; var itemPadding = legend.itemPadding > 0 ? legend.itemPadding : 0; var position = legend.position.toLowerCase(); var font = legend.title.textStyle; var width = 0; var height = 0; var legendItemWidth = 0; var legendItemHeight = 0; var legendHeight = 0; var svgObjectWidth = smithchart.availableSize.width - ((smithchart.elementSpacing * 4) - (legend.border.width * 2) + (smithchart.border.width * 2)); var rowCount = legend.rowCount; var columnCount = legend.columnCount; var titleSize = measureText(smithchart.legendSettings['title']['text'], font, smithchart.themeStyle.legendTitleFont); var maxRowWidth = 0; var totalRowHeight = 0; var curRowWidth = 0; var curRowHeight = 0; var allowItems; var itemsCountRow = 0; var length = smithchart.series.length; var legendBounds; if (smithchart.legendSettings.visible && length !== 0) { if (position === 'bottom' || position === 'top' || position === 'custom') { if ((rowCount && columnCount) && (rowCount <= columnCount)) { rowCount = length / columnCount; } else if (rowCount == null && columnCount != null) { rowCount = length / columnCount; } else if (rowCount == null && columnCount == null) { rowCount = 1; } if (rowCount) { allowItems = Math.ceil(length / rowCount); } } else { if ((rowCount && columnCount) && (rowCount <= columnCount)) { columnCount = length / rowCount; } else if (rowCount != null && columnCount == null) { columnCount = length / rowCount; } else if (rowCount == null && columnCount == null) { columnCount = 1; } if (columnCount) { allowItems = columnCount; } } for (var i = 0; i < length; i++) { this.legendSeries.push({ text: smithchart.series[i]['name'] ? smithchart.series[i]['name'] : 'series' + i, seriesIndex: i, shape: smithchart.legendSettings.shape, fill: smithchart.series[i].fill || smithchart.seriesColors[i % smithchart.seriesColors.length], bounds: null }); var legendsize = this._getLegendSize(smithchart, this.legendSeries[i]); legendItemWidth = Math.max(legendsize['width'], legendItemWidth); legendItemHeight = Math.max(legendsize['height'], legendItemHeight); this.legendSeries[i]['bounds'] = { width: legendItemWidth, height: legendItemHeight }; itemsCountRow = itemsCountRow + 1; curRowWidth = curRowWidth + legendItemWidth + itemPadding; curRowHeight = Math.max(legendItemHeight, curRowHeight); if (position === 'top' || position === 'bottom' || position === 'custom') { if (curRowWidth > svgObjectWidth) { curRowWidth -= legendsize.width + itemPadding; maxRowWidth = Math.max(maxRowWidth, curRowWidth); curRowWidth = legendsize.width + itemPadding; totalRowHeight = totalRowHeight + curRowHeight + itemPadding; } } if (itemsCountRow === allowItems || i === length - 1) { maxRowWidth = Math.max(maxRowWidth, curRowWidth); totalRowHeight = totalRowHeight + curRowHeight + itemPadding; legendHeight = totalRowHeight; itemsCountRow = 0; curRowHeight = 0; curRowWidth = 0; } } width = (titleSize.width) > maxRowWidth - itemPadding ? (titleSize.width + padding * 2 + itemPadding) : maxRowWidth + padding * 2 - (smithchart.border.width * 2); height = legendHeight + smithchart.elementSpacing; legendBounds = { x: 0, y: 0, width: width, height: height }; } this.legendActualBounds = legendBounds; if (legendSizeWidth != null) { this.legendActualBounds.width = legendSizeWidth; } if (legendSizeHeight != null) { this.legendActualBounds.height = legendSizeHeight; } return this.legendActualBounds; }; SmithchartLegend.prototype._getLegendSize = function (smithchart, series) { var legend = smithchart.legendSettings; var symbolWidth = legend.itemStyle.width; var symbolHeight = legend.itemStyle.height; var textSize = measureText(series.text, legend.textStyle, smithchart.themeStyle.legendLabelFont); var width = symbolWidth + textSize.width + legend.shapePadding; var height = Math.max(symbolHeight, textSize.height); return { width: width, height: height }; }; SmithchartLegend.prototype._drawLegend = function (smithchart) { var legend = smithchart.legendSettings; var legendPosition = legend.position.toLowerCase(); var alignment = legend.alignment; var legendBounds = this.legendActualBounds; var maxWidth = 0; var startX; var startY; var titleFont = smithchart.title.font ? smithchart.title.font : smithchart.title.textStyle; var smithchartTitleHeight = measureText(smithchart.title.text, titleFont, smithchart.themeStyle.legendLabelFont).height; var smithchartSubtitleHeight = measureText(smithchart.title.subtitle.text, smithchart.title.subtitle.textStyle, smithchart.themeStyle.legendLabelFont).height; var elementSpacing = smithchart.elementSpacing; var offset = smithchartTitleHeight + smithchartSubtitleHeight + elementSpacing + smithchart.margin.top; var itemPadding = legend.itemPadding > 0 ? legend.itemPadding : 0; var svgObjectWidth = smithchart.availableSize.width; var svgObjectHeight = smithchart.availableSize.height; var legendBorder = legend.border.width; var legendWidth = 0; var titleSize = measureText(legend['title']['text'], legend.title.textStyle, smithchart.themeStyle.legendLabelFont); var legendTitleHeight = titleSize.height; var borderSize = smithchart.border.width; var svgWidth = svgObjectWidth - ((borderSize * 2)); var svgHeight = svgObjectHeight - ((borderSize * 2)); legendBounds.height += legendTitleHeight; if (legendPosition !== 'custom') { switch (legendPosition) { case 'bottom': legendBounds.y = svgHeight - (legendBounds.height + (legendBorder) + elementSpacing); break; case 'top': legendBounds.y = borderSize + offset; break; case 'right': legendBounds.x = svgWidth - legendBounds.width - (elementSpacing * 2); break; case 'left': legendBounds.x = borderSize + (elementSpacing * 2); break; } if (legendPosition === 'left' || legendPosition === 'right') { switch (alignment) { case 'Center': legendBounds.y = (svgHeight / 2) - ((legendBounds.height + legendBorder * 2) / 2) + (elementSpacing / 2); break; case 'Near': legendBounds.y = borderSize + (elementSpacing * 2) + offset; break; case 'Far': legendBounds.y = svgHeight - (legendBounds.height + (legendBorder)) - (elementSpacing * 2); break; } } else { switch (alignment) { case 'Center': legendBounds.x = (svgWidth / 2) - ((legendBounds.width + legendBorder * 2) / 2) + (elementSpacing / 2); break; case 'Near': legendBounds.x = borderSize + (elementSpacing * 2); break; case 'Far': legendBounds.x = svgWidth - (legendBounds.width + (legendBorder)) - (elementSpacing * 2); break; } } } else { legendBounds.y = (legend.location.y < svgHeight) ? legend.location.y : 0; legendBounds.x = (legend.location.x < svgWidth) ? legend.location.x : 0; } if (legendPosition === 'bottom' || legendPosition === 'top') { for (var i = 0; i < this.legendSeries.length; i++) { legendWidth += this.legendSeries[i].bounds.width + itemPadding; if (legendWidth > svgWidth) { legendBounds.x = (svgWidth / 2) - ((legendBounds.width + legendBorder * 2) / 2) + (elementSpacing / 2); break; } } } var gLegendEle = smithchart.renderer.createGroup({ 'id': smithchart.element.id + '_legend_group' }); smithchart.svgObject.appendChild(gLegendEle); this.legendItemGroup = smithchart.renderer.createGroup({ 'id': smithchart.element.id + 'legendItem_Group' }); var currentX = startX = elementSpacing; var currentY = startY = elementSpacing; if (legend.title.text !== '' && legend.title.visible) { gLegendEle.appendChild(this.drawLegendTitle(smithchart, legend, legendBounds, gLegendEle)); currentY = startY = elementSpacing + legendTitleHeight; } for (var k = 0; k < this.legendSeries.length; k++) { if ((legend.rowCount < legend.columnCount || legend.rowCount === legend.columnCount) && (legendPosition === 'top' || legendPosition === 'bottom' || legendPosition === 'custom')) { if ((currentX + this.legendSeries[k]['bounds'].width) > legendBounds.width + startX) { currentX = elementSpacing; currentY += this.legendSeries[k]['bounds'].height + itemPadding; } this.legendGroup = this.drawLegendItem(smithchart, legend, this.legendSeries[k], k, currentX, (currentY)); gLegendEle.appendChild(this.legendGroup); currentX += this.legendSeries[k]['bounds'].width + itemPadding; } else { if (((currentY + this.legendSeries[k]['bounds'].height + itemPadding) + legendTitleHeight + borderSize > legendBounds.height + startY)) { currentY = startY; currentX += maxWidth + (itemPadding); } this.legendGroup = this.drawLegendItem(smithchart, legend, this.legendSeries[k], k, (currentX), (currentY)); gLegendEle.appendChild(this.legendGroup); currentY += this.legendSeries[k]['bounds'].height + itemPadding; maxWidth = Math.max(maxWidth, this.legendSeries[k]['bounds'].width); } } gLegendEle.setAttribute('transform', 'translate(' + legendBounds.x.toString() + ',' + legendBounds.y.toString() + ')'); this.drawLegendBorder(gLegendEle, smithchart, legend, legendBounds); }; SmithchartLegend.prototype.drawLegendBorder = function (gLegendEle, smithchart, legend, legendBounds) { var borderRect = new RectOption(smithchart.element.id + '_svg' + '_legendRect', 'none', legend.border, 1, new SmithchartRect(0, 0, legendBounds.width, legendBounds.height)); gLegendEle.appendChild(smithchart.renderer.drawRectangle(borderRect)); }; SmithchartLegend.prototype.drawLegendTitle = function (smithchart, legend, legendBounds, gLegendEle) { var elementSpacing = smithchart.elementSpacing; var titleSize = measureText(legend.title.text, legend.title.textStyle, smithchart.themeStyle.legendLabelFont); var titleWidth = titleSize.width; var titleHeight = titleSize.height; var textAlignment = legend.title.textAlignment; var startX = 0; var legendBoundsWidth = legendBounds.width; var startY = elementSpacing + (titleHeight / 2); switch (textAlignment) { case 'Far': startX = legendBoundsWidth - titleWidth - startX; break; case 'Center': startX = legendBoundsWidth / 2 - (titleWidth) / 2; break; } if (startX < 0) { startX = 0; legendBoundsWidth = titleWidth; } if (legendBoundsWidth < titleWidth + startX) { legendBoundsWidth = titleWidth + startX; } var options = new TextOption(smithchart.element.id + '_LegendTitleText', startX, startY, 'start', legend.title.text); var element = renderTextElement(options, legend.title.textStyle, legend.title.textStyle.color || smithchart.themeStyle.legendTitleFont.color, gLegendEle, smithchart.themeStyle.legendTitleFont); element.setAttribute('aria-label', legend.title.description || legend.title.text); return element; }; SmithchartLegend.prototype.drawLegendItem = function (smithchart, legend, legendSeries, k, x, y) { var _this = this; var symbol = legend.itemStyle; var textHeight = measureText(legendSeries['text'], legend.textStyle, smithchart.themeStyle.legendLabelFont).height; var location = { x: x + symbol['width'] / 2, y: (y + (textHeight > symbol['height'] ? textHeight : symbol['height']) / 2) }; var legendGroup = smithchart.renderer.createGroup({ id: smithchart.element.id + '_svg' + '_Legend' + k.toString() }); legendGroup['style']['cursor'] = legend.toggleVisibility ? 'pointer' : 'default'; legendGroup.setAttribute('tabindex', k === 0 ? '0' : ''); var legendEventArgs = { text: legendSeries['text'], fill: legendSeries['fill'], shape: legendSeries['shape'], name: legendRender, cancel: false }; var legendRenderSuccess = function (args) { if (!args.cancel) { var shape = _this.drawLegendShape(smithchart, legendSeries, location.x, location.y, k, legend, args); legendGroup.appendChild(shape); var options = new TextOption(smithchart.element.id + '_LegendItemText' + k.toString(), location.x + symbol['width'] / 2 + legend.shapePadding, location.y + textHeight / 4, 'start', args.text); legend.textStyle.fontFamily = legend.textStyle.fontFamily || smithchart.themeStyle.legendLabelFont.fontFamily; legend.textStyle.size = legend.textStyle.size || smithchart.themeStyle.legendLabelFont.size; var element = renderTextElement(options, legend.textStyle, legend.textStyle.color || smithchart.themeStyle.legendLabelFont.color, legendGroup, smithchart.themeStyle.legendLabelFont); legendGroup.setAttribute('aria-label', legend.description || ('Show ' + options.text)); legendGroup.setAttribute('role', 'button'); legendGroup.appendChild(element); _this.legendItemGroup.appendChild(legendGroup); } }; legendRenderSuccess.bind(this); smithchart.trigger(legendRender, legendEventArgs, legendRenderSuccess); return this.legendItemGroup; }; SmithchartLegend.prototype.drawLegendShape = function (smithchart, legendSeries, locX, locY, index, legend, legendEventArgs) { var element; var circleOptions; var pathOptions; var path; var symbol = legend.itemStyle; var width = symbol['width']; var height = symbol['height']; var x = locX + (-width / 2); var border = { color: symbol.border.color, width: symbol.border.width }; var opacity = 1; var fill = (smithchart.series[index].visibility === 'visible') ? legendEventArgs.fill : 'grey'; var shape = legendEventArgs.shape.toLowerCase(); var radius = Math.sqrt(height * height + width * width) / 2; switch (shape) { case 'circle': circleOptions = new CircleOption(smithchart.element.id + '_svg' + '_LegendItemShape' + index.toString(), fill, border, opacity, locX, locY, radius, null); element = smithchart.renderer.drawCircle(circleOptions); break; case 'rectangle': path = 'M' + ' ' + x + ' ' + (locY + (-height / 2)) + ' ' + 'L' + ' ' + ((width / 2) + locX) + ' ' + (locY + (-height / 2)) + ' ' + 'L' + ' ' + (locX + (width / 2)) + ' ' + (locY + (height / 2)) + ' ' + 'L' + ' ' + x + ' ' + (locY + (height / 2)) + ' ' + 'L' + ' ' + x + ' ' + (locY + (-height / 2)) + ' z'; pathOptions = new PathOption(smithchart.element.id + '_svg' + '_LegendItemShape' + index.toString(), fill, border.width, border.color, 1, '', path); element = smithchart.renderer.drawPath(pathOptions); break; case 'diamond': path = 'M' + ' ' + x + ' ' + locY + ' ' + 'L' + ' ' + locX + ' ' + (locY + (-height / 2)) + ' ' + 'L' + ' ' + ((width / 2) + locX) + ' ' + locY + ' ' + 'L' + ' ' + locX + ' ' + (locY + (height / 2)) + ' ' + 'L' + ' ' + x + ' ' + locY + ' z'; pathOptions = new PathOption(smithchart.element.id + '_svg' + '_LegendItemShape' + index.toString(), fill, border.width, border.color, 1, '', path); element = smithchart.renderer.drawPath(pathOptions); break; case 'pentagon': { var eq = 72; for (var j = 0; j <= 5; j++) { var xValue = radius * Math.cos((Math.PI / 180) * (j * eq)); var yValue = radius * Math.sin((Math.PI / 180) * (j * eq)); if (j === 0) { path = 'M' + ' ' + (xValue + locX) + ' ' + (locY + yValue) + ' '; } else { path = path.concat('L' + ' ' + (locX + xValue) + ' ' + (locY + yValue) + ' '); } } path = path.concat('Z'); pathOptions = new PathOption(smithchart.element.id + '_svg' + '_LegendItemShape' + index.toString(), fill, border.width, border.color, 1, '', path); element = smithchart.renderer.drawPath(pathOptions); break; } case 'triangle': path = 'M' + ' ' + x + ' ' + ((height / 2) + locY) + ' ' + 'L' + ' ' + locX + ' ' + (locY + (-height / 2)) + ' ' + 'L' + ' ' + (locX + (width / 2)) + ' ' + (locY + (height / 2)) + ' ' + 'L' + ' ' + x + ' ' + (locY + (height / 2)) + ' Z'; pathOptions = new PathOption(smithchart.element.id + '_svg' + '_LegendItemShape' + index.toString(), fill, border.width, border.color, 1, '', path); element = smithchart.renderer.drawPath(pathOptions); break; } return element; }; /** * Get module name. * * @returns {string} - To get the module name. */ SmithchartLegend.prototype.getModuleName = function () { return 'SmithchartLegend'; }; /** * To destroy the legend. * * @returns {void} * @private */ SmithchartLegend.prototype.destroy = function () { /** * Destroy method performed here */ }; return SmithchartLegend; }()); export { SmithchartLegend };