UNPKG

apexcharts

Version:

A JavaScript Chart Library

489 lines (488 loc) 16.3 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); /*! * ApexCharts v5.10.6 * (c) 2018-2026 ApexCharts */ import * as _core from "apexcharts/core"; import _core__default from "apexcharts/core"; import { default as default2 } from "apexcharts/core"; const Fill = _core.__apex_Fill; const Graphics = _core.__apex_Graphics; const Markers = _core.__apex_Markers; const DataLabels = _core.__apex_DataLabels; const Filters = _core.__apex_Filters; const Utils = _core.__apex_Utils; class CircularChartsHelpers { /** * @param {import('../../../types/internal').ChartStateW} w */ constructor(w) { this.w = w; } /** * @param {number} x * @param {number} y * @param {number} i * @param {string | number} text */ drawYAxisTexts(x, y, i, text) { const w = this.w; const yaxisConfig = w.config.yaxis[0]; const formatter = w.formatters.yLabelFormatters[0]; const graphics = new Graphics(this.w); const yaxisLabel = graphics.drawText({ x: x + yaxisConfig.labels.offsetX, y: y + yaxisConfig.labels.offsetY, text: formatter(text, i), textAnchor: "middle", fontSize: yaxisConfig.labels.style.fontSize, fontFamily: yaxisConfig.labels.style.fontFamily, foreColor: Array.isArray(yaxisConfig.labels.style.colors) ? yaxisConfig.labels.style.colors[i] : yaxisConfig.labels.style.colors }); return yaxisLabel; } } const CoreUtils = _core.__apex_CoreUtils; class Radar { /** * @param {import('../types/internal').ChartStateW} w * @param {import('../types/internal').ChartContext} ctx */ constructor(w, ctx) { this.ctx = ctx; this.w = w; this.chartType = this.w.config.chart.type; this.initialAnim = this.w.config.chart.animations.enabled; this.dynamicAnim = this.initialAnim && this.w.config.chart.animations.dynamicAnimation.enabled; this.animDur = 0; this.graphics = new Graphics(this.w); this.lineColorArr = w.globals.stroke.colors !== void 0 ? w.globals.stroke.colors : w.globals.colors; this.defaultSize = w.globals.svgHeight < w.globals.svgWidth ? w.layout.gridHeight : w.layout.gridWidth; this.isLog = w.config.yaxis[0].logarithmic; this.logBase = w.config.yaxis[0].logBase; this.coreUtils = new CoreUtils(this.w); this.maxValue = this.isLog ? this.coreUtils.getLogVal(this.logBase, w.globals.maxY, 0) : w.globals.maxY; this.minValue = this.isLog ? this.coreUtils.getLogVal(this.logBase, this.w.globals.minY, 0) : w.globals.minY; this.polygons = w.config.plotOptions.radar.polygons; this.strokeWidth = w.config.stroke.show ? w.config.stroke.width : 0; this.size = this.defaultSize / 2.1 - this.strokeWidth - w.config.chart.dropShadow.blur; if (w.config.xaxis.labels.show) { this.size = this.size - w.layout.xAxisLabelsWidth / 1.75; } if (w.config.plotOptions.radar.size !== void 0) { this.size = w.config.plotOptions.radar.size; } this.dataRadiusOfPercent = /** @type {any} */ []; this.dataRadius = /** @type {any} */ []; this.angleArr = /** @type {any} */ []; this.dataPointsLen = 0; this.disAngle = 0; this.yaxisLabelsTextsPos = []; } /** * @param {any[]} series */ draw(series) { const w = this.w; const fill = new Fill(this.w); const allSeries = []; const dataLabels = new DataLabels(this.w, this.ctx); if (series.length) { this.dataPointsLen = series[w.globals.maxValsInArrayIndex].length; } this.disAngle = Math.PI * 2 / this.dataPointsLen; const halfW = w.layout.gridWidth / 2; const halfH = w.layout.gridHeight / 2; const translateX = halfW + w.config.plotOptions.radar.offsetX; const translateY = halfH + w.config.plotOptions.radar.offsetY; const ret = this.graphics.group({ class: "apexcharts-radar-series apexcharts-plot-series", transform: `translate(${translateX || 0}, ${translateY || 0})` }); let dataPointsPos = []; let elPointsMain = null; let elDataPointsMain = null; this.yaxisLabels = this.graphics.group({ class: "apexcharts-yaxis" }); series.forEach((s, i) => { const longestSeries = s.length === w.globals.dataPoints; const elSeries = this.graphics.group().attr({ class: `apexcharts-series`, "data:longestSeries": longestSeries, seriesName: Utils.escapeString(w.seriesData.seriesNames[i]), rel: i + 1, "data:realIndex": i }); this.dataRadiusOfPercent[i] = []; this.dataRadius[i] = []; this.angleArr[i] = []; s.forEach((dv, j) => { const range = Math.abs(this.maxValue - this.minValue); dv = dv - this.minValue; if (this.isLog) { dv = this.coreUtils.getLogVal(this.logBase, dv, 0); } this.dataRadiusOfPercent[i][j] = dv / range; this.dataRadius[i][j] = this.dataRadiusOfPercent[i][j] * this.size; this.angleArr[i][j] = j * this.disAngle; }); dataPointsPos = this.getDataPointsPos( this.dataRadius[i], this.angleArr[i] ); const paths = this.createPaths(dataPointsPos, { x: 0, y: 0 }); elPointsMain = this.graphics.group({ class: "apexcharts-series-markers-wrap apexcharts-element-hidden" }); elDataPointsMain = this.graphics.group({ class: `apexcharts-datalabels`, "data:realIndex": i }); w.globals.delayedElements.push({ el: elPointsMain.node, index: i }); const defaultRenderedPathOptions = { i, realIndex: i, animationDelay: i, initialSpeed: w.config.chart.animations.speed, dataChangeSpeed: w.config.chart.animations.dynamicAnimation.speed, className: `apexcharts-radar`, shouldClipToGrid: false, bindEventsOnPaths: false, stroke: w.globals.stroke.colors[i], strokeLineCap: w.config.stroke.lineCap }; let pathFrom = null; if (w.globals.previousPaths.length > 0) { pathFrom = this.getPreviousPath(i); } for (let p = 0; p < paths.linePathsTo.length; p++) { const renderedLinePath = this.graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), { pathFrom: pathFrom === null ? paths.linePathsFrom[p] : pathFrom, pathTo: paths.linePathsTo[p], strokeWidth: Array.isArray(this.strokeWidth) ? this.strokeWidth[i] : this.strokeWidth, fill: "none", drawShadow: false })); elSeries.add(renderedLinePath); const pathFill = fill.fillPath({ seriesNumber: i }); const renderedAreaPath = this.graphics.renderPaths(__spreadProps(__spreadValues({}, defaultRenderedPathOptions), { pathFrom: pathFrom === null ? paths.areaPathsFrom[p] : pathFrom, pathTo: paths.areaPathsTo[p], strokeWidth: 0, fill: pathFill, drawShadow: false })); if (w.config.chart.dropShadow.enabled) { const filters = new Filters(this.w); const shadow = w.config.chart.dropShadow; filters.dropShadow( renderedAreaPath, Object.assign({}, shadow, { noUserSpaceOnUse: true }), i ); } elSeries.add(renderedAreaPath); } s.forEach((sj, j) => { const markers = new Markers(this.w, this.ctx); const opts = markers.getMarkerConfig({ cssClass: "apexcharts-marker", seriesIndex: i, dataPointIndex: j }); const point = this.graphics.drawMarker( dataPointsPos[j].x, dataPointsPos[j].y, opts ); point.attr("rel", j); point.attr("j", j); point.attr("index", i); point.node.setAttribute("default-marker-size", opts.pSize); const elPointsWrap = this.graphics.group({ class: "apexcharts-series-markers" }); if (elPointsWrap) { elPointsWrap.add(point); } elPointsMain.add(elPointsWrap); elSeries.add(elPointsMain); const dataLabelsConfig = w.config.dataLabels; if (dataLabelsConfig.enabled) { const text = dataLabelsConfig.formatter(w.seriesData.series[i][j], { seriesIndex: i, dataPointIndex: j, w }); dataLabels.plotDataLabelsText({ x: dataPointsPos[j].x, y: dataPointsPos[j].y, text, textAnchor: "middle", i, j: i, parent: elDataPointsMain, offsetCorrection: false, dataLabelsConfig: __spreadValues({}, dataLabelsConfig) }); } elSeries.add(elDataPointsMain); }); allSeries.push(elSeries); }); this.drawPolygons({ parent: ret }); if (w.config.xaxis.labels.show) { const xaxisTexts = this.drawXAxisTexts(); ret.add(xaxisTexts); } allSeries.forEach((elS) => { ret.add(elS); }); ret.add(this.yaxisLabels); return ret; } /** * @param {Record<string, any>} opts */ drawPolygons(opts) { const w = this.w; const { parent } = opts; const helpers = new CircularChartsHelpers(this.w); const yaxisTexts = w.globals.yAxisScale[0].result.reverse(); const layers = yaxisTexts.length; const radiusSizes = []; const layerDis = this.size / (layers - 1); for (let i = 0; i < layers; i++) { radiusSizes[i] = layerDis * i; } radiusSizes.reverse(); const polygonStrings = []; const lines = []; radiusSizes.forEach((radiusSize, r) => { const polygon = Utils.getPolygonPos(radiusSize, this.dataPointsLen); let string = ""; polygon.forEach((p, i) => { if (r === 0) { const line = this.graphics.drawLine( p.x, p.y, 0, 0, Array.isArray(this.polygons.connectorColors) ? this.polygons.connectorColors[i] : this.polygons.connectorColors ); lines.push(line); } if (i === 0) { this.yaxisLabelsTextsPos.push({ x: p.x, y: p.y }); } string += p.x + "," + p.y + " "; }); polygonStrings.push(string); }); polygonStrings.forEach((p, i) => { const strokeColors = this.polygons.strokeColors; const strokeWidth = this.polygons.strokeWidth; const polygon = this.graphics.drawPolygon( p, Array.isArray(strokeColors) ? strokeColors[i] : strokeColors, Array.isArray(strokeWidth) ? strokeWidth[i] : strokeWidth, w.globals.radarPolygons.fill.colors[i] ); parent.add(polygon); }); lines.forEach((l) => { parent.add(l); }); if (w.config.yaxis[0].show) { this.yaxisLabelsTextsPos.forEach( (p, i) => { const yText = helpers.drawYAxisTexts(p.x, p.y, i, yaxisTexts[i]); this.yaxisLabels.add(yText); } ); } } drawXAxisTexts() { const w = this.w; const xaxisLabelsConfig = w.config.xaxis.labels; const elXAxisWrap = this.graphics.group({ class: "apexcharts-xaxis" }); const polygonPos = Utils.getPolygonPos(this.size, this.dataPointsLen); w.labelData.labels.forEach((label, i) => { const formatter = w.config.xaxis.labels.formatter; const dataLabels = new DataLabels(this.w, this.ctx); if (polygonPos[i]) { const textPos = this.getTextPos(polygonPos[i], this.size); const text = formatter(label, { seriesIndex: -1, dataPointIndex: i, w }); const dataLabelText = dataLabels.plotDataLabelsText({ x: textPos.newX, y: textPos.newY, text, textAnchor: textPos.textAnchor, i, j: i, parent: elXAxisWrap, className: "apexcharts-xaxis-label", color: Array.isArray(xaxisLabelsConfig.style.colors) && xaxisLabelsConfig.style.colors[i] ? xaxisLabelsConfig.style.colors[i] : "#a8a8a8", dataLabelsConfig: __spreadValues({ textAnchor: textPos.textAnchor, dropShadow: { enabled: false } }, xaxisLabelsConfig), offsetCorrection: false }); dataLabelText.on("click", (e) => { if (typeof w.config.chart.events.xAxisLabelClick === "function") { const opts = Object.assign({}, w, { labelIndex: i }); w.config.chart.events.xAxisLabelClick(e, this.ctx, opts); } }); } }); return elXAxisWrap; } /** * @param {Array<Record<string, any>>} pos * @param {Record<string, any>} origin */ createPaths(pos, origin) { const linePathsTo = []; let linePathsFrom = []; const areaPathsTo = []; let areaPathsFrom = []; if (pos.length) { linePathsFrom = [this.graphics.move(origin.x, origin.y)]; areaPathsFrom = [this.graphics.move(origin.x, origin.y)]; let linePathTo = this.graphics.move(pos[0].x, pos[0].y); let areaPathTo = this.graphics.move(pos[0].x, pos[0].y); pos.forEach((p, i) => { linePathTo += this.graphics.line(p.x, p.y); areaPathTo += this.graphics.line(p.x, p.y); if (i === pos.length - 1) { linePathTo += "Z"; areaPathTo += "Z"; } }); linePathsTo.push(linePathTo); areaPathsTo.push(areaPathTo); } return { linePathsFrom, linePathsTo, areaPathsFrom, areaPathsTo }; } /** * @param {Record<string, any>} pos * @param {number} polygonSize */ getTextPos(pos, polygonSize) { const limit = 10; let textAnchor = "middle"; let newX = pos.x; let newY = pos.y; if (Math.abs(pos.x) >= limit) { if (pos.x > 0) { textAnchor = "start"; newX += 10; } else if (pos.x < 0) { textAnchor = "end"; newX -= 10; } } else { textAnchor = "middle"; } if (Math.abs(pos.y) >= polygonSize - limit) { if (pos.y < 0) { newY -= 10; } else if (pos.y > 0) { newY += 10; } } return { textAnchor, newX, newY }; } /** * @param {number} realIndex */ getPreviousPath(realIndex) { const w = this.w; let pathFrom = null; for (let pp = 0; pp < w.globals.previousPaths.length; pp++) { const gpp = w.globals.previousPaths[pp]; if (gpp.paths.length > 0 && parseInt(gpp.realIndex, 10) === parseInt(String(realIndex), 10)) { if (typeof w.globals.previousPaths[pp].paths[0] !== "undefined") { pathFrom = w.globals.previousPaths[pp].paths[0].d; } } } return pathFrom; } /** * @param {any[]} dataRadiusArr * @param {any[]} angleArr */ getDataPointsPos(dataRadiusArr, angleArr, dataPointsLen = this.dataPointsLen) { dataRadiusArr = dataRadiusArr || []; angleArr = angleArr || []; const dataPointsPosArray = []; for (let j = 0; j < dataPointsLen; j++) { const curPointPos = {}; curPointPos.x = dataRadiusArr[j] * Math.sin(angleArr[j]); curPointPos.y = -dataRadiusArr[j] * Math.cos(angleArr[j]); dataPointsPosArray.push(curPointPos); } return dataPointsPosArray; } } _core__default.use({ radar: Radar }); export { default2 as default };