UNPKG

apexcharts

Version:

A JavaScript Chart Library

1,209 lines (1,208 loc) 149 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"; const apexchartsLegendCSS = ".apexcharts-flip-y {\n transform: scaleY(-1) translateY(-100%);\n transform-origin: top;\n transform-box: fill-box;\n}\n.apexcharts-flip-x {\n transform: scaleX(-1);\n transform-origin: center;\n transform-box: fill-box;\n}\n.apexcharts-legend {\n display: flex;\n overflow: auto;\n padding: 0 10px;\n}\n.apexcharts-legend.apexcharts-legend-group-horizontal {\n flex-direction: column;\n}\n.apexcharts-legend-group {\n display: flex;\n}\n.apexcharts-legend-group-vertical {\n flex-direction: column-reverse;\n}\n.apexcharts-legend.apx-legend-position-bottom, .apexcharts-legend.apx-legend-position-top {\n flex-wrap: wrap\n}\n.apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n flex-direction: column;\n bottom: 0;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-left, .apexcharts-legend.apx-legend-position-top.apexcharts-align-left, .apexcharts-legend.apx-legend-position-right, .apexcharts-legend.apx-legend-position-left {\n justify-content: flex-start;\n align-items: flex-start;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-center, .apexcharts-legend.apx-legend-position-top.apexcharts-align-center {\n justify-content: center;\n align-items: center;\n}\n.apexcharts-legend.apx-legend-position-bottom.apexcharts-align-right, .apexcharts-legend.apx-legend-position-top.apexcharts-align-right {\n justify-content: flex-end;\n align-items: flex-end;\n}\n.apexcharts-legend-series {\n cursor: pointer;\n line-height: normal;\n display: flex;\n align-items: center;\n}\n.apexcharts-legend-text {\n position: relative;\n font-size: 14px;\n}\n.apexcharts-legend-text *, .apexcharts-legend-marker * {\n pointer-events: none;\n}\n.apexcharts-legend-marker {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n margin-right: 1px;\n}\n\n.apexcharts-legend-series.apexcharts-no-click {\n cursor: auto;\n}\n.apexcharts-legend .apexcharts-hidden-zero-series, .apexcharts-legend .apexcharts-hidden-null-series {\n display: none !important;\n}\n.apexcharts-inactive-legend {\n opacity: 0.45;\n} "; const AxesUtils = _core.__apex_axes_AxesUtils; const Data = _core.__apex_Data; const Series = _core.__apex_Series; const Utils = _core.__apex_Utils; const Environment = _core.__apex_Environment_Environment; class Exports { /** * @param {import('../types/internal').ChartStateW} w * @param {import('../types/internal').ChartContext} ctx */ constructor(w, ctx) { this.w = w; this.ctx = ctx; } /** * @param {string} svgString */ svgStringToNode(svgString) { const parser = new DOMParser(); const svgDoc = parser.parseFromString(svgString, "image/svg+xml"); return svgDoc.documentElement; } /** * @param {any} svg * @param {number} scale */ scaleSvgNode(svg, scale) { const svgWidth = parseFloat(svg.getAttributeNS(null, "width")); const svgHeight = parseFloat(svg.getAttributeNS(null, "height")); svg.setAttributeNS(null, "width", svgWidth * scale); svg.setAttributeNS(null, "height", svgHeight * scale); svg.setAttributeNS(null, "viewBox", "0 0 " + svgWidth + " " + svgHeight); } /** * @param {number} [_scale] */ getSvgString(_scale) { return new Promise((resolve) => { const w = this.w; let scale = _scale || w.config.chart.toolbar.export.scale || w.config.chart.toolbar.export.width / w.globals.svgWidth; if (!scale) { scale = 1; } const width = w.globals.svgWidth * scale; const height = w.globals.svgHeight * scale; const clonedNode = ( /** @type {HTMLElement} */ w.dom.elWrap.cloneNode(true) ); clonedNode.style.width = width + "px"; clonedNode.style.height = height + "px"; const serializedNode = new XMLSerializer().serializeToString(clonedNode); const shouldIncludeLegendStyles = w.config.legend.show && w.dom.elLegendWrap && w.dom.elLegendWrap.children.length > 0; let exportStyles = ` .apexcharts-tooltip, .apexcharts-toolbar, .apexcharts-xaxistooltip, .apexcharts-yaxistooltip, .apexcharts-xcrosshairs, .apexcharts-ycrosshairs, .apexcharts-zoom-rect, .apexcharts-selection-rect { display: none; } `; if (shouldIncludeLegendStyles) { exportStyles += apexchartsLegendCSS; } let svgString = ` <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" class="apexcharts-svg" xmlns:data="ApexChartsNS" transform="translate(0, 0)" width="${w.globals.svgWidth}px" height="${w.globals.svgHeight}px"> <foreignObject width="100%" height="100%"> <div xmlns="http://www.w3.org/1999/xhtml" style="width:${width}px; height:${height}px;"> <style type="text/css"> ${exportStyles} </style> ${serializedNode} </div> </foreignObject> </svg> `; const svgNode = this.svgStringToNode(svgString); if (scale !== 1) { this.scaleSvgNode(svgNode, scale); } this.convertImagesToBase64(svgNode).then(() => { svgString = new XMLSerializer().serializeToString(svgNode); resolve(svgString.replace(/&nbsp;/g, "&#160;")); }); }); } /** * @param {any} svgNode */ convertImagesToBase64(svgNode) { const images = svgNode.getElementsByTagName("image"); const promises = Array.from(images).map((img) => { const href = img.getAttributeNS("http://www.w3.org/1999/xlink", "href"); if (href && !href.startsWith("data:")) { return this.getBase64FromUrl(href).then((base64) => { img.setAttributeNS("http://www.w3.org/1999/xlink", "href", base64); }).catch((error) => { console.error("Error converting image to base64:", error); }); } return Promise.resolve(); }); return Promise.all(promises); } /** * @param {string} url */ getBase64FromUrl(url) { if (Environment.isSSR()) return Promise.resolve(url); return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = () => { const canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext("2d"); if (ctx) ctx.drawImage(img, 0, 0); resolve(canvas.toDataURL()); }; img.onerror = reject; img.src = url; }); } svgUrl() { return new Promise((resolve) => { this.getSvgString().then((svgData) => { const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" }); resolve(URL.createObjectURL(svgBlob)); }); }); } /** * @param {Record<string, any> | undefined} options */ dataURI(options) { if (Environment.isSSR()) return Promise.resolve({ imgURI: "" }); return new Promise((resolve) => { const w = this.w; const scale = options ? options.scale || options.width / w.globals.svgWidth : 1; const canvas = document.createElement("canvas"); canvas.width = w.globals.svgWidth * scale; canvas.height = parseInt(w.dom.elWrap.style.height, 10) * scale; const canvasBg = w.config.chart.background === "transparent" || !w.config.chart.background ? "#fff" : w.config.chart.background; const ctx = canvas.getContext("2d"); if (!ctx) return; ctx.fillStyle = canvasBg; ctx.fillRect(0, 0, canvas.width * scale, canvas.height * scale); this.getSvgString(scale).then((svgData) => { const svgUrl = "data:image/svg+xml," + encodeURIComponent(svgData); const img = new Image(); img.crossOrigin = "anonymous"; img.onload = () => { ctx.drawImage(img, 0, 0); const edgeCanvas = canvas; if (edgeCanvas.msToBlob) { const blob = edgeCanvas.msToBlob(); resolve({ blob }); } else { const imgURI = canvas.toDataURL("image/png"); resolve({ imgURI }); } }; img.src = svgUrl; }); }); } exportToSVG() { this.svgUrl().then((url) => { this.triggerDownload( url, this.w.config.chart.toolbar.export.svg.filename, ".svg" ); }); } exportToPng() { const scale = this.w.config.chart.toolbar.export.scale; const width = this.w.config.chart.toolbar.export.width; const option = scale ? { scale } : width ? { width } : void 0; this.dataURI(option).then(({ imgURI, blob }) => { if (blob) { navigator.msSaveOrOpenBlob(blob, this.w.globals.chartID + ".png"); } else { this.triggerDownload( imgURI, this.w.config.chart.toolbar.export.png.filename, ".png" ); } }); } /** @param {{ series?: any, fileName?: any, columnDelimiter?: string, lineDelimiter?: string }} opts */ exportToCSV({ series, fileName, columnDelimiter = ",", lineDelimiter = "\n" }) { const w = this.w; if (!series) series = w.config.series; let columns = []; const rows = []; let result = ""; const universalBOM = "\uFEFF"; const gSeries = w.seriesData.series.map((s, i) => { return w.globals.collapsedSeriesIndices.indexOf(i) === -1 ? s : []; }); const getFormattedCategory = (cat) => { if (typeof w.config.chart.toolbar.export.csv.categoryFormatter === "function") { return w.config.chart.toolbar.export.csv.categoryFormatter(cat); } if (w.config.xaxis.type === "datetime" && String(cat).length >= 10) { return new Date(cat).toDateString(); } return Utils.isNumber(cat) ? cat : cat.split(columnDelimiter).join(""); }; const getFormattedValue = (value) => { return typeof w.config.chart.toolbar.export.csv.valueFormatter === "function" ? w.config.chart.toolbar.export.csv.valueFormatter(value) : value; }; const seriesMaxDataLength = Math.max( ...series.map((s) => { return s.data ? s.data.length : 0; }) ); const dataFormat = new Data(this.w); const axesUtils = new AxesUtils(this.w, { theme: this.ctx.theme, timeScale: this.ctx.timeScale }); const getCat = (i) => { let cat = ""; if (!w.globals.axisCharts) { cat = w.config.labels[i]; } else { if (w.config.xaxis.type === "category" || w.config.xaxis.convertedCatToNumeric) { if (w.globals.isBarHorizontal) { const lbFormatter = w.formatters.yLabelFormatters[0]; const sr = new Series(this.ctx.w); const activeSeries = sr.getActiveConfigSeriesIndex(); cat = lbFormatter(w.labelData.labels[i], { seriesIndex: activeSeries, dataPointIndex: i, w }); } else { cat = axesUtils.getLabel( w.labelData.labels, w.labelData.timescaleLabels, 0, i ).text; } } if (w.config.xaxis.type === "datetime") { if (w.config.xaxis.categories.length) { cat = w.config.xaxis.categories[i]; } else if (w.config.labels.length) { cat = w.config.labels[i]; } } } if (cat === null) return "nullvalue"; if (Array.isArray(cat)) { cat = cat.join(" "); } return Utils.isNumber(cat) ? cat : cat.split(columnDelimiter).join(""); }; const getEmptyDataForCsvColumn = () => { return [...Array(seriesMaxDataLength)].map(() => ""); }; const handleAxisRowsColumns = (s, sI) => { var _a; if (columns.length && sI === 0) { rows.push(columns.join(columnDelimiter)); } if (s.data) { s.data = s.data.length && s.data || getEmptyDataForCsvColumn(); for (let i = 0; i < s.data.length; i++) { columns = []; let cat = getCat(i); if (cat === "nullvalue") continue; if (!cat) { if (dataFormat.isFormatXY()) { cat = series[sI].data[i].x; } else if (dataFormat.isFormat2DArray()) { cat = series[sI].data[i] ? series[sI].data[i][0] : ""; } } if (sI === 0) { columns.push(getFormattedCategory(cat)); for (let ci = 0; ci < w.seriesData.series.length; ci++) { const value = dataFormat.isFormatXY() ? (_a = series[ci].data[i]) == null ? void 0 : _a.y : gSeries[ci][i]; columns.push(getFormattedValue(value)); } } if (w.config.chart.type === "candlestick" || s.type && s.type === "candlestick") { columns.pop(); columns.push(w.candleData.seriesCandleO[sI][i]); columns.push(w.candleData.seriesCandleH[sI][i]); columns.push(w.candleData.seriesCandleL[sI][i]); columns.push(w.candleData.seriesCandleC[sI][i]); } if (w.config.chart.type === "boxPlot" || s.type && s.type === "boxPlot") { columns.pop(); columns.push(w.candleData.seriesCandleO[sI][i]); columns.push(w.candleData.seriesCandleH[sI][i]); columns.push(w.candleData.seriesCandleM[sI][i]); columns.push(w.candleData.seriesCandleL[sI][i]); columns.push(w.candleData.seriesCandleC[sI][i]); } if (w.config.chart.type === "rangeBar") { columns.pop(); columns.push(w.rangeData.seriesRangeStart[sI][i]); columns.push(w.rangeData.seriesRangeEnd[sI][i]); } if (columns.length) { rows.push(columns.join(columnDelimiter)); } } } }; const handleUnequalXValues = () => { const categories = /* @__PURE__ */ new Set(); const data = {}; series.forEach((s, sI) => { s == null ? void 0 : s.data.forEach((dataItem) => { let cat, value; if (dataFormat.isFormatXY()) { cat = dataItem.x; value = dataItem.y; } else if (dataFormat.isFormat2DArray()) { cat = dataItem[0]; value = dataItem[1]; } else { return; } if (!/** @type {Record<string,any>} */ data[cat]) { data[cat] = Array( series.length ).fill(""); } data[cat][sI] = getFormattedValue(value); categories.add(cat); }); }); if (columns.length) { rows.push(columns.join(columnDelimiter)); } Array.from(categories).sort().forEach((cat) => { rows.push([ getFormattedCategory(cat), /** @type {Record<string,any>} */ data[cat].join(columnDelimiter) ]); }); }; columns.push(w.config.chart.toolbar.export.csv.headerCategory); if (w.config.chart.type === "boxPlot") { columns.push("minimum"); columns.push("q1"); columns.push("median"); columns.push("q3"); columns.push("maximum"); } else if (w.config.chart.type === "candlestick") { columns.push("open"); columns.push("high"); columns.push("low"); columns.push("close"); } else if (w.config.chart.type === "rangeBar") { columns.push("minimum"); columns.push("maximum"); } else { series.map((s, sI) => { const sname = (s.name ? s.name : `series-${sI}`) + ""; if (w.globals.axisCharts) { columns.push( sname.split(columnDelimiter).join("") ? sname.split(columnDelimiter).join("") : `series-${sI}` ); } }); } if (!w.globals.axisCharts) { columns.push(w.config.chart.toolbar.export.csv.headerValue); rows.push(columns.join(columnDelimiter)); } if (!w.globals.allSeriesHasEqualX && w.globals.axisCharts && !w.config.xaxis.categories.length && !w.config.labels.length) { handleUnequalXValues(); } else { series.map((s, sI) => { if (w.globals.axisCharts) { handleAxisRowsColumns(s, sI); } else { columns = []; columns.push(getFormattedCategory(w.labelData.labels[sI])); columns.push(getFormattedValue(gSeries[sI])); rows.push(columns.join(columnDelimiter)); } }); } result += rows.join(lineDelimiter); this.triggerDownload( "data:text/csv; charset=utf-8," + encodeURIComponent(universalBOM + result), fileName ? fileName : w.config.chart.toolbar.export.csv.filename, ".csv" ); } /** * @param {string} href * @param {string} filename * @param {string} ext */ triggerDownload(href, filename, ext) { if (Environment.isSSR()) return; const downloadLink = document.createElement("a"); downloadLink.href = href; downloadLink.download = (filename ? filename : this.w.globals.chartID) + ext; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); } } _core__default.registerFeatures({ exports: Exports }); const CoreUtils = _core.__apex_CoreUtils; const Dimensions = _core.__apex_dimensions_Dimensions; const Graphics = _core.__apex_Graphics; let Helpers$1 = class Helpers { /** * @param {import('./Legend').default} lgCtx */ constructor(lgCtx) { this.w = lgCtx.w; this.lgCtx = lgCtx; } getLegendStyles() { if (Environment.isSSR()) return null; const stylesheet = document.createElement("style"); stylesheet.setAttribute("type", "text/css"); const nonce = this.w.config.chart.nonce; if (nonce) { stylesheet.setAttribute("nonce", nonce); } const rule = document.createTextNode(apexchartsLegendCSS); stylesheet.appendChild(rule); return stylesheet; } getLegendDimensions() { const w = this.w; const currLegendsWrap = w.dom.baseEl.querySelector(".apexcharts-legend"); if (!currLegendsWrap) { return { clwh: 0, clww: 0 }; } const { width: currLegendsWrapWidth, height: currLegendsWrapHeight } = currLegendsWrap.getBoundingClientRect(); return { clwh: currLegendsWrapHeight, clww: currLegendsWrapWidth }; } appendToForeignObject() { var _a; const legendStyles = this.getLegendStyles(); if (this.w.config.chart.injectStyleSheet !== false && legendStyles) { (_a = this.w.dom.elLegendForeign) == null ? void 0 : _a.appendChild(legendStyles); } } /** * @param {number} seriesCnt * @param {boolean} isHidden */ toggleDataSeries(seriesCnt, isHidden) { var _a, _b; const w = this.w; if (w.globals.axisCharts || w.config.chart.type === "radialBar") { w.globals.resized = true; let seriesEl = null; let realIndex = null; w.globals.risingSeries = []; if (w.globals.axisCharts) { seriesEl = w.dom.baseEl.querySelector( `.apexcharts-series[data\\:realIndex='${seriesCnt}']` ); if (!seriesEl) return; realIndex = parseInt((_a = seriesEl.getAttribute("data:realIndex")) != null ? _a : "", 10); } else { seriesEl = w.dom.baseEl.querySelector( `.apexcharts-series[rel='${seriesCnt + 1}']` ); if (!seriesEl) return; realIndex = parseInt((_b = seriesEl.getAttribute("rel")) != null ? _b : "", 10) - 1; } if (isHidden) { const seriesToMakeVisible = [ { cs: w.globals.collapsedSeries, csi: w.globals.collapsedSeriesIndices }, { cs: w.globals.ancillaryCollapsedSeries, csi: w.globals.ancillaryCollapsedSeriesIndices } ]; seriesToMakeVisible.forEach((r) => { const cs = ( /** @type {any} */ r.cs ); const csi = ( /** @type {any} */ r.csi ); this.riseCollapsedSeries( cs, csi, /** @type {number} */ realIndex ); }); } else { this.hideSeries({ seriesEl, realIndex }); } if (w.config.chart.accessibility.enabled) { const legendItem = w.dom.baseEl.querySelector( `.apexcharts-legend-series[rel="${seriesCnt + 1}"]` ); if (legendItem) { const isCollapsed = w.globals.collapsedSeriesIndices.includes(realIndex) || w.globals.ancillaryCollapsedSeriesIndices.includes(realIndex); legendItem.setAttribute( "aria-pressed", isCollapsed ? "true" : "false" ); const legendTextEl = legendItem.querySelector( ".apexcharts-legend-text" ); const seriesName = legendTextEl ? legendTextEl.textContent : w.seriesData.seriesNames[seriesCnt]; const statusText = isCollapsed ? "hidden" : "visible"; legendItem.setAttribute( "aria-label", `${seriesName}, ${statusText}. Press Enter or Space to toggle.` ); } } } else { const seriesEl = w.dom.Paper.findOne( ` .apexcharts-series[rel='${seriesCnt + 1}'] path` ); const type = w.config.chart.type; if (type === "pie" || type === "polarArea" || type === "donut") { const dataLabels = w.config.plotOptions.pie.donut.labels; const graphics = new Graphics(this.w); graphics.pathMouseDown(seriesEl, null); this.lgCtx.printDataLabelsInner(seriesEl.node, dataLabels); } if (w.config.chart.accessibility.enabled) { const legendItem = w.dom.baseEl.querySelector( `.apexcharts-legend-series[rel="${seriesCnt + 1}"]` ); if (legendItem) { const isCollapsed = w.globals.collapsedSeriesIndices.includes(seriesCnt); legendItem.setAttribute( "aria-pressed", isCollapsed ? "true" : "false" ); const legendTextEl = legendItem.querySelector( ".apexcharts-legend-text" ); const seriesName = legendTextEl ? legendTextEl.textContent : w.seriesData.seriesNames[seriesCnt]; const statusText = isCollapsed ? "hidden" : "visible"; legendItem.setAttribute( "aria-label", `${seriesName}, ${statusText}. Press Enter or Space to toggle.` ); } } } } /** @param {{realIndex: any}} opts */ getSeriesAfterCollapsing({ realIndex }) { var _a; const w = this.w; const gl = w.globals; const series = Utils.clone(w.config.series); if (gl.axisCharts) { const yaxis = w.config.yaxis[gl.seriesYAxisReverseMap[realIndex]]; const collapseData = { index: realIndex, data: series[realIndex].data.slice(), type: series[realIndex].type || w.config.chart.type }; if (yaxis && yaxis.show && yaxis.showAlways) { if (gl.ancillaryCollapsedSeriesIndices.indexOf(realIndex) < 0) { gl.ancillaryCollapsedSeries.push(collapseData); gl.ancillaryCollapsedSeriesIndices.push(realIndex); } } else { if (gl.collapsedSeriesIndices.indexOf(realIndex) < 0) { gl.collapsedSeries.push(collapseData); gl.collapsedSeriesIndices.push(realIndex); const removeIndexOfRising = gl.risingSeries.indexOf(realIndex); gl.risingSeries.splice(removeIndexOfRising, 1); } } } else { gl.collapsedSeries.push({ index: realIndex, data: series[realIndex], type: ( /** @type {any} */ (_a = w.config.series[realIndex].type) != null ? _a : "line" ) }); gl.collapsedSeriesIndices.push(realIndex); } gl.allSeriesCollapsed = gl.collapsedSeries.length + gl.ancillaryCollapsedSeries.length === w.config.series.length; return this._getSeriesBasedOnCollapsedState(series); } /** @param {{seriesEl: any, realIndex: any}} opts */ hideSeries({ seriesEl, realIndex }) { const w = this.w; const series = this.getSeriesAfterCollapsing({ realIndex }); const seriesChildren = seriesEl.childNodes; for (let sc = 0; sc < seriesChildren.length; sc++) { if (seriesChildren[sc].classList.contains("apexcharts-series-markers-wrap")) { if (seriesChildren[sc].classList.contains("apexcharts-hide")) { seriesChildren[sc].classList.remove("apexcharts-hide"); } else { seriesChildren[sc].classList.add("apexcharts-hide"); } } } this.lgCtx.updateSeries( series, w.config.chart.animations.dynamicAnimation.enabled ); } /** * @param {any[]} collapsedSeries * @param {number[]} seriesIndices * @param {number} realIndex */ riseCollapsedSeries(collapsedSeries, seriesIndices, realIndex) { const w = this.w; let series = Utils.clone(w.config.series); if (collapsedSeries.length > 0) { for (let c = 0; c < collapsedSeries.length; c++) { if (collapsedSeries[c].index === realIndex) { if (w.globals.axisCharts) { series[realIndex].data = collapsedSeries[c].data.slice(); } else { series[realIndex] = collapsedSeries[c].data; } if (typeof series[realIndex] !== "number") { series[realIndex].hidden = false; } collapsedSeries.splice(c, 1); seriesIndices.splice(c, 1); w.globals.risingSeries.push(realIndex); c--; } } series = this._getSeriesBasedOnCollapsedState(series); this.lgCtx.updateSeries( series, w.config.chart.animations.dynamicAnimation.enabled ); } } /** * @param {any[]} series */ _getSeriesBasedOnCollapsedState(series) { const w = this.w; let collapsed = 0; if (w.globals.axisCharts) { series.forEach((s, sI) => { if (!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(sI) < 0)) { series[sI].data = []; collapsed++; } }); } else { series.forEach((s, sI) => { if (!(w.globals.collapsedSeriesIndices.indexOf(sI) < 0)) { series[sI] = 0; collapsed++; } }); } w.globals.allSeriesCollapsed = collapsed === series.length; return series; } }; const Markers = _core.__apex_Markers; const BrowserAPIs = _core.__apex_BrowserAPIs_BrowserAPIs; class Legend { /** * @param {import('../../types/internal').ChartStateW} w * @param {import('../../types/internal').ChartContext} ctx */ constructor(w, ctx) { this.w = w; this.ctx = ctx; this.printDataLabelsInner = (...a) => { var _a; return (_a = ctx.pie) == null ? void 0 : _a.printDataLabelsInner(...a); }; this.updateSeries = (...a) => ctx.updateHelpers._updateSeries(...a); this.onLegendClick = this.onLegendClick.bind(this); this.onLegendHovered = this.onLegendHovered.bind(this); this.isBarsDistributed = this.w.config.chart.type === "bar" && this.w.config.plotOptions.bar.distributed && this.w.config.series.length === 1; this.legendHelpers = new Helpers$1(this); } init() { const w = this.w; const gl = w.globals; const cnf = w.config; const showLegendAlways = cnf.legend.showForSingleSeries && this.w.seriesData.series.length === 1 || this.isBarsDistributed || this.w.seriesData.series.length > 1; this.legendHelpers.appendToForeignObject(); if ((showLegendAlways || !gl.axisCharts) && cnf.legend.show) { const elLegendWrap = ( /** @type {HTMLElement} */ w.dom.elLegendWrap ); while (elLegendWrap.firstChild) { elLegendWrap.removeChild(elLegendWrap.firstChild); } this.drawLegends(); if (cnf.legend.position === "bottom" || cnf.legend.position === "top") { this.legendAlignHorizontal(); } else if (cnf.legend.position === "right" || cnf.legend.position === "left") { this.legendAlignVertical(); } } } createLegendMarker({ i, fillcolor }) { const w = this.w; const elMarker = BrowserAPIs.createElement("span"); elMarker.classList.add("apexcharts-legend-marker"); const mShape = w.config.legend.markers.shape || w.config.markers.shape; let shape = mShape; if (Array.isArray(mShape)) { shape = mShape[i]; } const mSize = Array.isArray(w.config.legend.markers.size) ? parseFloat(w.config.legend.markers.size[i]) : parseFloat(w.config.legend.markers.size); const mOffsetX = Array.isArray(w.config.legend.markers.offsetX) ? parseFloat(w.config.legend.markers.offsetX[i]) : parseFloat(w.config.legend.markers.offsetX); const mOffsetY = Array.isArray(w.config.legend.markers.offsetY) ? parseFloat(w.config.legend.markers.offsetY[i]) : parseFloat(w.config.legend.markers.offsetY); const mBorderWidth = Array.isArray(w.config.legend.markers.strokeWidth) ? parseFloat(w.config.legend.markers.strokeWidth[i]) : parseFloat(w.config.legend.markers.strokeWidth); const mStyle = elMarker.style; mStyle.height = (mSize + mBorderWidth) * 2 + "px"; mStyle.width = (mSize + mBorderWidth) * 2 + "px"; mStyle.left = mOffsetX + "px"; mStyle.top = mOffsetY + "px"; if (w.config.legend.markers.customHTML) { mStyle.background = "transparent"; mStyle.color = fillcolor[i]; if (Array.isArray(w.config.legend.markers.customHTML)) { if (w.config.legend.markers.customHTML[i]) { elMarker.innerHTML = w.config.legend.markers.customHTML[i](); } } else { elMarker.innerHTML = w.config.legend.markers.customHTML(); } } else { const markers = new Markers(this.ctx.w, this.ctx); const markerConfig = markers.getMarkerConfig({ cssClass: `apexcharts-legend-marker apexcharts-marker apexcharts-marker-${shape}`, seriesIndex: i, strokeWidth: mBorderWidth, size: mSize }); const SVGLib = Environment.isBrowser() ? ( /** @type {any} */ window.SVG ) : ( /** @type {any} */ global.SVG ); const SVGMarker = SVGLib().addTo(elMarker).size("100%", "100%"); const marker = new Graphics(this.w).drawMarker(0, 0, __spreadProps(__spreadValues({}, markerConfig), { pointFillColor: Array.isArray(fillcolor) ? fillcolor[i] : markerConfig.pointFillColor, shape })); const shapesEls = w.dom.Paper.find( ".apexcharts-legend-marker.apexcharts-marker" ); shapesEls.forEach((shapeEl) => { if (shapeEl.node.classList.contains("apexcharts-marker-triangle")) { shapeEl.node.style.transform = "translate(50%, 45%)"; } else { shapeEl.node.style.transform = "translate(50%, 50%)"; } }); SVGMarker.add(marker); } return elMarker; } drawLegends() { var _a; const me = this; const w = this.w; const elLegendWrap = ( /** @type {HTMLElement} */ w.dom.elLegendWrap ); const fontFamily = w.config.legend.fontFamily; let legendNames = w.seriesData.seriesNames; let fillcolor = w.config.legend.markers.fillColors ? w.config.legend.markers.fillColors.slice() : w.globals.colors.slice(); if (w.config.chart.type === "heatmap") { const ranges = w.config.plotOptions.heatmap.colorScale.ranges; legendNames = ranges.map((colorScale) => { return colorScale.name ? colorScale.name : colorScale.from + " - " + colorScale.to; }); fillcolor = ranges.map((color) => color.color); } else if (this.isBarsDistributed) { legendNames = w.labelData.labels.slice(); } if (w.config.legend.customLegendItems.length) { legendNames = w.config.legend.customLegendItems; } const legendFormatter = w.formatters.legendFormatter; const isLegendInversed = w.config.legend.inverseOrder; const legendGroups = []; if (w.labelData.seriesGroups.length > 1 && w.config.legend.clusterGroupedSeries) { w.labelData.seriesGroups.forEach((_, gi) => { legendGroups[gi] = BrowserAPIs.createElement("div"); legendGroups[gi].classList.add( "apexcharts-legend-group", `apexcharts-legend-group-${gi}` ); if (w.config.legend.clusterGroupedSeriesOrientation === "horizontal") { elLegendWrap.classList.add("apexcharts-legend-group-horizontal"); } else { legendGroups[gi].classList.add("apexcharts-legend-group-vertical"); } }); } for (let i = isLegendInversed ? legendNames.length - 1 : 0; isLegendInversed ? i >= 0 : i <= legendNames.length - 1; isLegendInversed ? i-- : i++) { const text = legendFormatter(legendNames[i], { seriesIndex: i, w }); let collapsedSeries = false; let ancillaryCollapsedSeries = false; if (w.globals.collapsedSeries.length > 0) { for (let c = 0; c < w.globals.collapsedSeries.length; c++) { if (w.globals.collapsedSeries[c].index === i) { collapsedSeries = true; } } } if (w.globals.ancillaryCollapsedSeriesIndices.length > 0) { for (let c = 0; c < w.globals.ancillaryCollapsedSeriesIndices.length; c++) { if (w.globals.ancillaryCollapsedSeriesIndices[c] === i) { ancillaryCollapsedSeries = true; } } } const elMarker = this.createLegendMarker({ i, fillcolor }); Graphics.setAttrs(elMarker, { rel: i + 1, "data:collapsed": collapsedSeries || ancillaryCollapsedSeries }); if (collapsedSeries || ancillaryCollapsedSeries) { elMarker.classList.add("apexcharts-inactive-legend"); } const elLegend = BrowserAPIs.createElement("div"); if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) { elLegend.setAttribute("role", "button"); elLegend.setAttribute("tabindex", "0"); const seriesName = Array.isArray(text) ? text.join(" ") : text; const isCollapsed = collapsedSeries || ancillaryCollapsedSeries; const statusText = isCollapsed ? "hidden" : "visible"; elLegend.setAttribute( "aria-label", `${seriesName}, ${statusText}. Press Enter or Space to toggle.` ); elLegend.setAttribute("aria-pressed", isCollapsed ? "true" : "false"); } const elLegendText = BrowserAPIs.createElement("span"); elLegendText.classList.add("apexcharts-legend-text"); elLegendText.innerHTML = Array.isArray(text) ? text.join(" ") : text; let textColor = w.config.legend.labels.useSeriesColors ? w.globals.colors[i] : Array.isArray(w.config.legend.labels.colors) ? (_a = w.config.legend.labels.colors) == null ? void 0 : _a[i] : w.config.legend.labels.colors; if (!textColor) { textColor = w.config.chart.foreColor; } elLegendText.style.color = textColor; elLegendText.style.fontSize = w.config.legend.fontSize; elLegendText.style.fontWeight = w.config.legend.fontWeight; elLegendText.style.fontFamily = fontFamily || w.config.chart.fontFamily; Graphics.setAttrs(elLegendText, { rel: i + 1, i, "data:default-text": encodeURIComponent(text), "data:collapsed": collapsedSeries || ancillaryCollapsedSeries }); elLegend.appendChild(elMarker); elLegend.appendChild(elLegendText); const coreUtils = new CoreUtils(this.w); if (!w.config.legend.showForZeroSeries) { const total = coreUtils.getSeriesTotalByIndex(i); if (total === 0 && coreUtils.seriesHaveSameValues(i) && !coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) { elLegend.classList.add("apexcharts-hidden-zero-series"); } } if (!w.config.legend.showForNullSeries) { if (coreUtils.isSeriesNull(i) && w.globals.collapsedSeriesIndices.indexOf(i) === -1 && w.globals.ancillaryCollapsedSeriesIndices.indexOf(i) === -1) { elLegend.classList.add("apexcharts-hidden-null-series"); } } if (legendGroups.length) { w.labelData.seriesGroups.forEach((group, gi) => { var _a2, _b; if (group.includes( /** @type {Record<string,any>} */ (_b = (_a2 = w.config.series[i]) == null ? void 0 : _a2.name) != null ? _b : "" )) { elLegendWrap.appendChild(legendGroups[gi]); legendGroups[gi].appendChild(elLegend); } }); } else { elLegendWrap.appendChild(elLegend); } elLegendWrap.classList.add( `apexcharts-align-${w.config.legend.horizontalAlign}` ); elLegendWrap.classList.add( "apx-legend-position-" + w.config.legend.position ); elLegend.classList.add("apexcharts-legend-series"); elLegend.style.margin = `${w.config.legend.itemMargin.vertical}px ${w.config.legend.itemMargin.horizontal}px`; elLegendWrap.style.width = w.config.legend.width ? w.config.legend.width + "px" : ""; elLegendWrap.style.height = w.config.legend.height ? w.config.legend.height + "px" : ""; Graphics.setAttrs(elLegend, { rel: i + 1, seriesName: Utils.escapeString(legendNames[i]), "data:collapsed": collapsedSeries || ancillaryCollapsedSeries }); if (collapsedSeries || ancillaryCollapsedSeries) { elLegend.classList.add("apexcharts-inactive-legend"); } if (!w.config.legend.onItemClick.toggleDataSeries) { elLegend.classList.add("apexcharts-no-click"); } } w.dom.elWrap.addEventListener("click", me.onLegendClick, true); if (w.config.legend.onItemHover.highlightDataSeries && w.config.legend.customLegendItems.length === 0) { w.dom.elWrap.addEventListener("mousemove", me.onLegendHovered, true); w.dom.elWrap.addEventListener("mouseout", me.onLegendHovered, true); } if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.keyboard.enabled) { w.dom.elWrap.addEventListener( "keydown", me.onLegendKeyDown.bind(me), true ); } } /** * @param {number} offsetX * @param {number} offsetY */ setLegendWrapXY(offsetX, offsetY) { const w = this.w; const elLegendWrap = ( /** @type {HTMLElement} */ w.dom.elLegendWrap ); const legendHeight = elLegendWrap.clientHeight; let x = 0; let y = 0; if (w.config.legend.position === "bottom") { y = w.globals.svgHeight - Math.min(legendHeight, w.globals.svgHeight / 2) - 5; } else if (w.config.legend.position === "top") { const dim = new Dimensions(this.w, this.ctx); const titleH = dim.dimHelpers.getTitleSubtitleCoords("title").height; const subtitleH = dim.dimHelpers.getTitleSubtitleCoords("subtitle").height; y = (titleH > 0 ? titleH - 10 : 0) + (subtitleH > 0 ? subtitleH - 10 : 0); } elLegendWrap.style.position = "absolute"; x = x + offsetX + w.config.legend.offsetX; y = y + offsetY + w.config.legend.offsetY; elLegendWrap.style.left = x + "px"; elLegendWrap.style.top = y + "px"; if (w.config.legend.position === "right") { elLegendWrap.style.left = "auto"; elLegendWrap.style.right = 25 + w.config.legend.offsetX + "px"; } const fixedHeigthWidth = ( /** @type {const} */ ["width", "height"] ); fixedHeigthWidth.forEach((hw) => { if (elLegendWrap && elLegendWrap.style[hw]) { elLegendWrap.style[hw] = parseInt(String(w.config.legend[hw]), 10) + "px"; } }); } legendAlignHorizontal() { const w = this.w; const elLegendWrap = ( /** @type {HTMLElement} */ w.dom.elLegendWrap ); elLegendWrap.style.right = "0"; const dimensions = new Dimensions(this.w, this.ctx); const titleRect = dimensions.dimHelpers.getTitleSubtitleCoords("title"); const subtitleRect = dimensions.dimHelpers.getTitleSubtitleCoords("subtitle"); const offsetX = 20; let offsetY = 0; if (w.config.legend.position === "top") { offsetY = titleRect.height + subtitleRect.height + w.config.title.margin + w.config.subtitle.margin - 10; } this.setLegendWrapXY(offsetX, offsetY); } legendAlignVertical() { const w = this.w; const lRect = this.legendHelpers.getLegendDimensions(); const offsetY = 20; let offsetX = 0; if (w.config.legend.position === "left") { offsetX = 20; } if (w.config.legend.position === "right") { offsetX = w.globals.svgWidth - lRect.clww - 10; } this.setLegendWrapXY(offsetX, offsetY); } /** * @param {MouseEvent} e */ onLegendHovered(e) { var _a; const w = this.w; const target = ( /** @type {Element} */ e.target ); const hoverOverLegend = target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker"); if (w.config.chart.type !== "heatmap" && !this.isBarsDistributed) { if (!target.classList.contains("apexcharts-inactive-legend") && hoverOverLegend) { const series = new Series(this.ctx.w); series.toggleSeriesOnHover(e, target); } } else { if (hoverOverLegend) { const seriesCnt = parseInt((_a = target.getAttribute("rel")) != null ? _a : "0", 10) - 1; this.ctx.events.fireEvent("legendHover", [this.ctx, seriesCnt, this.w]); const series = new Series(this.ctx.w); series.highlightRangeInSeries(e, target); } } } /** * @param {KeyboardEvent} e */ onLegendKeyDown(e) { const me = this; const w = this.w; const target = ( /** @type {Element} */ e.target ); const isLegendItem = target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker"); if (!isLegendItem) return; if (e.key === "Enter" || e.key === " ") { e.preventDefault(); const rel = target.getAttribute("rel"); me.onLegendClick(e); if (rel !== null && w.config.legend.onItemClick.toggleDataSeries) { requestAnimationFrame(() => { const restored = w.dom.baseEl.querySelector( `.apexcharts-legend-series[rel="${rel}"]` ); if (restored) restored.focus(); }); } } } /** * @param {Event} e */ onLegendClick(e) { var _a; const w = this.w; const target = ( /** @type {Element} */ e.target ); if (w.config.legend.customLegendItems.length) return; if (target.classList.contains("apexcharts-legend-series") || target.classList.contains("apexcharts-legend-text") || target.classList.contains("apexcharts-legend-marker")) { const seriesCnt = parseInt((_a = target.getAttribute("rel")) != null ? _a : "0", 10) - 1; const isHidden = target.getAttribute("data:collapsed") === "true"; const legendClick = this.w.config.chart.events.legendClick; if (typeof legendClick === "function") { legendClick(this.ctx, seriesCnt, this.w); } this.ctx.events.fireEvent("legendClick", [this.ctx, seriesCnt, this.w]); const markerClick = this.w.config.legend.markers.onClick; if (typeof markerClick === "function" && target.classList.contains("apexcharts-legend-marker")) { markerClick(this.ctx, seriesCnt, this.w); this.ctx.events.fireEvent("legendMarkerClick", [ this.ctx, seriesCnt, this.w ]); } const clickAllowed = w.config.chart.type !== "treemap" && w.config.chart.type !== "heatmap" && !this.isBarsDistributed; if (clickAllowed && w.config.legend.onItemClick.toggleDataSeries) { this.legendHelpers.toggleDataSeries(seriesCnt, isHidden); } } } } _core__default.registerFeatures({ legend: Legend }); const icoPan = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n <defs>\n <path d="M0 0h24v24H0z" id="a"/>\n </defs>\n <clipPath id="b">\n <use overflow="visible" xlink:href="#a"/>\n </clipPath>\n <path clip-path="url(#b)" d="M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/>\n</svg>'; const icoZoom = '<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">\n <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>\n <path d="M0 0h24v24H0V0z" fill="none"/>\n <path d="M12 10h-2v2H9v-2H7V9h2V7h1v2h2v1z"/>\n</svg>'; const icoReset = '<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>\n <path d="M0 0h24v24H0z" fill="none"/>\n</svg>'; const icoZoomIn = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path d="M13 7h-2v4H7v2h4v4h2v-4h4v-2h-4V7zm-1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n'; const icoZoomOut = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path d="M7 11v2h10v-2H7zm5-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\n</svg>\n'; const icoSelect = '<svg fill="#6E8192" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path d="M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2z"/>\n</svg>'; const icoMenu = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>'; class Toolbar { /** * @param {import('../types/internal').ChartStateW} w * @param {import('../types/internal').ChartContext} ctx */ constructor(w, ctx) { this.w = w; this.ctx = ctx; this.ev = this.w.config.chart.events; this.selectedClass = "apexcharts-selected"; this.localeValues = this.w.globals.locale.toolbar; this.minX = w.globals.minX; this.maxX = w.globals.maxX; this.elZoom = null; this.elZoomIn = null; this.elZoomOut = null; this.elPan = null; this.elSelection = null; this.elZoomReset = null; this.elMenuIcon = null; this.elMenu = null; this.elMenuItems = []; this.t = null; } createToolbar() { const w = this.w; const createDiv = () => { return BrowserAPIs.createElementNS("http://www.w3.org/1999/xhtml", "div"); }; const elToolbarWrap = createDiv(); elToolbarWrap.setAttribute("class", "apexcharts-toolbar"); elToolbarWrap.style.top = w.config.chart.toolbar.offsetY + "px"; elToolbarWrap.style.right = -w.config.chart.toolbar.offsetX + 3 + "px"; w.dom.elWrap.appendChild(elToolbarWrap); this.elZoom = createDiv(); this.elZoomIn = createDiv(); this.elZoomOut = createDiv(); this.elPan = createDiv(); this.elSelection = createDiv(); this.elZoomReset = createDiv(); this.elMenuIcon = createDiv(); this.elMenu = createDiv(); this.elCustomIcons = []; this.t = w.config.chart.toolbar.tools; if (Array.isArray(this.t.customIcons)) { for (let i = 0; i < this.t.customIcons.length; i++) { this.elCustomIcons.push(createDiv()); } } const toolbarControls = []; const appendZoomControl = (type, el, ico) => { const tool = type.toLowerCase(); if (this.t[tool] && w.config.chart.zoom.enabled) { toolbarControls.push({ el, icon: typeof this.t[tool] === "string" ? this.t[tool] : ico,