/*!
 * ApexCharts v5.10.4
 * (c) 2018-2026 ApexCharts
 */
import * as _core from "apexcharts/core";
import _core__default from "apexcharts/core";
import { default as default2 } from "apexcharts/core";
const Animations = _core.__apex_Animations;
const Graphics = _core.__apex_Graphics;
const Fill = _core.__apex_Fill;
const Series = _core.__apex_Series;
const Utils = _core.__apex_Utils;
const DataLabels = _core.__apex_DataLabels;
class TreemapHelpers {
  /**
   * @param {import('../../../types/internal').ChartStateW} w
   * @param {import('../../../types/internal').ChartContext} ctx
   */
  constructor(w, ctx) {
    this.ctx = ctx;
    this.w = w;
  }
  checkColorRange() {
    const w = this.w;
    let negRange = false;
    const chartOpts = w.config.plotOptions[w.config.chart.type];
    if (chartOpts.colorScale.ranges.length > 0) {
      chartOpts.colorScale.ranges.map((range) => {
        if (range.from <= 0) {
          negRange = true;
        }
      });
    }
    return negRange;
  }
  /**
   * @param {string} chartType
   * @param {number} i
   * @param {number} j
   * @param {any} negRange
   */
  getShadeColor(chartType, i, j, negRange) {
    const w = this.w;
    let colorShadePercent = 1;
    const shadeIntensity = w.config.plotOptions[chartType].shadeIntensity;
    const colorProps = this.determineColor(chartType, i, j);
    if (
      /** @type {any} */
      w.globals.hasNegs || negRange
    ) {
      if (w.config.plotOptions[chartType].reverseNegativeShade) {
        if (colorProps.percent < 0) {
          colorShadePercent = colorProps.percent / 100 * (shadeIntensity * 1.25);
        } else {
          colorShadePercent = (1 - colorProps.percent / 100) * (shadeIntensity * 1.25);
        }
      } else {
        if (colorProps.percent <= 0) {
          colorShadePercent = 1 - (1 + colorProps.percent / 100) * shadeIntensity;
        } else {
          colorShadePercent = (1 - colorProps.percent / 100) * shadeIntensity;
        }
      }
    } else {
      colorShadePercent = 1 - colorProps.percent / 100;
      if (chartType === "treemap") {
        colorShadePercent = (1 - colorProps.percent / 100) * (shadeIntensity * 1.25);
      }
    }
    let color = colorProps.color;
    const utils = new Utils();
    if (w.config.plotOptions[chartType].enableShades) {
      if (this.w.config.theme.mode === "dark") {
        const shadeColor = utils.shadeColor(
          colorShadePercent * -1,
          colorProps.color
        );
        color = Utils.hexToRgba(
          Utils.isColorHex(shadeColor) ? shadeColor : Utils.rgb2hex(shadeColor),
          w.config.fill.opacity
        );
      } else {
        const shadeColor = utils.shadeColor(colorShadePercent, colorProps.color);
        color = Utils.hexToRgba(
          Utils.isColorHex(shadeColor) ? shadeColor : Utils.rgb2hex(shadeColor),
          w.config.fill.opacity
        );
      }
    }
    return { color, colorProps };
  }
  /**
   * @param {string} chartType
   * @param {number} i
   * @param {number} j
   */
  determineColor(chartType, i, j) {
    const w = this.w;
    const val = w.seriesData.series[i][j];
    const chartOpts = w.config.plotOptions[chartType];
    let seriesNumber = chartOpts.colorScale.inverse ? j : i;
    if (chartOpts.distributed && w.config.chart.type === "treemap") {
      seriesNumber = j;
    }
    let color = w.globals.colors[seriesNumber];
    let foreColor = null;
    let min = Math.min(...w.seriesData.series[i]);
    let max = Math.max(...w.seriesData.series[i]);
    if (!chartOpts.distributed && chartType === "heatmap") {
      min = w.globals.minY;
      max = w.globals.maxY;
    }
    if (typeof chartOpts.colorScale.min !== "undefined") {
      min = chartOpts.colorScale.min < w.globals.minY ? chartOpts.colorScale.min : w.globals.minY;
      max = chartOpts.colorScale.max > w.globals.maxY ? chartOpts.colorScale.max : w.globals.maxY;
    }
    const total = Math.abs(max) + Math.abs(min);
    let percent = 100 * val / (total === 0 ? total - 1e-6 : total);
    if (chartOpts.colorScale.ranges.length > 0) {
      const colorRange = chartOpts.colorScale.ranges;
      colorRange.map((range) => {
        if (val >= range.from && val <= range.to) {
          color = range.color;
          foreColor = range.foreColor ? range.foreColor : null;
          min = range.from;
          max = range.to;
          const rTotal = Math.abs(max) + Math.abs(min);
          percent = 100 * val / (rTotal === 0 ? rTotal - 1e-6 : rTotal);
        }
      });
    }
    return {
      color,
      foreColor,
      percent
    };
  }
  /** @param {{ text?: any, x?: any, y?: any, i?: any, j?: any, colorProps?: any, fontSize?: any, series?: any }} opts */
  calculateDataLabels({ text, x, y, i, j, colorProps, fontSize }) {
    const w = this.w;
    const dataLabelsConfig = w.config.dataLabels;
    const graphics = new Graphics(this.w);
    const dataLabels = new DataLabels(this.w, this.ctx);
    let elDataLabelsWrap = null;
    if (dataLabelsConfig.enabled) {
      elDataLabelsWrap = graphics.group({
        class: "apexcharts-data-labels"
      });
      const offX = dataLabelsConfig.offsetX;
      const offY = dataLabelsConfig.offsetY;
      const dataLabelsX = x + offX;
      const dataLabelsY = y + parseFloat(dataLabelsConfig.style.fontSize) / 3 + offY;
      dataLabels.plotDataLabelsText({
        x: dataLabelsX,
        y: dataLabelsY,
        text,
        i,
        j,
        color: colorProps.foreColor,
        parent: elDataLabelsWrap,
        fontSize,
        dataLabelsConfig
      });
    }
    return elDataLabelsWrap;
  }
}
const Filters = _core.__apex_Filters;
class HeatMap {
  /**
   * @param {import('../types/internal').ChartStateW} w
   * @param {import('../types/internal').ChartContext} ctx
   * @param {import('../types/internal').XYRatios} xyRatios
   */
  constructor(w, ctx, xyRatios) {
    this.ctx = ctx;
    this.w = w;
    this.xRatio = xyRatios.xRatio;
    this.yRatio = xyRatios.yRatio;
    this.dynamicAnim = this.w.config.chart.animations.dynamicAnimation;
    this.helpers = new TreemapHelpers(w, ctx);
    this.rectRadius = this.w.config.plotOptions.heatmap.radius;
    this.strokeWidth = this.w.config.stroke.show ? this.w.config.stroke.width : 0;
  }
  /**
   * @param {any[]} series
   */
  draw(series) {
    const w = this.w;
    const graphics = new Graphics(this.w, this.ctx);
    const ret = graphics.group({
      class: "apexcharts-heatmap"
    });
    ret.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
    const xDivision = w.layout.gridWidth / w.globals.dataPoints;
    const yDivision = w.layout.gridHeight / w.seriesData.series.length;
    let y1 = 0;
    let rev = false;
    this.negRange = this.helpers.checkColorRange();
    const heatSeries = series.slice();
    if (w.config.yaxis[0].reversed) {
      rev = true;
      heatSeries.reverse();
    }
    for (let i = rev ? 0 : heatSeries.length - 1; rev ? i < heatSeries.length : i >= 0; rev ? i++ : i--) {
      const elSeries = graphics.group({
        class: `apexcharts-series apexcharts-heatmap-series`,
        seriesName: Utils.escapeString(w.seriesData.seriesNames[i]),
        rel: i + 1,
        "data:realIndex": i
      });
      Series.addCollapsedClassToSeries(this.w, elSeries, i);
      graphics.setupEventDelegation(elSeries, ".apexcharts-heatmap-rect");
      if (w.config.chart.dropShadow.enabled) {
        const shadow = w.config.chart.dropShadow;
        const filters = new Filters(this.w);
        filters.dropShadow(elSeries, shadow, i);
      }
      let x1 = 0;
      const shadeIntensity = w.config.plotOptions.heatmap.shadeIntensity;
      let j = 0;
      for (let dIndex = 0; dIndex < w.globals.dataPoints; dIndex++) {
        if (w.seriesData.seriesX.length && !w.globals.allSeriesHasEqualX) {
          if (w.globals.minX + w.globals.minXDiff * dIndex < w.seriesData.seriesX[i][j]) {
            x1 = x1 + xDivision;
            continue;
          }
        }
        if (j >= heatSeries[i].length) break;
        const heatColor = this.helpers.getShadeColor(
          w.config.chart.type,
          i,
          j,
          this.negRange
        );
        let color = heatColor.color;
        const heatColorProps = heatColor.colorProps;
        if (w.config.fill.type === "image") {
          const fill = new Fill(this.w);
          color = fill.fillPath({
            seriesNumber: i,
            dataPointIndex: j,
            opacity: (
              /** @type {any} */
              w.globals.hasNegs ? heatColorProps.percent < 0 ? 1 - (1 + heatColorProps.percent / 100) : shadeIntensity + heatColorProps.percent / 100 : heatColorProps.percent / 100
            ),
            patternID: Utils.randomId(),
            width: w.config.fill.image.width ? w.config.fill.image.width : xDivision,
            height: w.config.fill.image.height ? w.config.fill.image.height : yDivision
          });
        }
        const radius = this.rectRadius;
        const rect = graphics.drawRect(x1, y1, xDivision, yDivision, radius);
        rect.attr({
          cx: x1,
          cy: y1
        });
        rect.node.classList.add("apexcharts-heatmap-rect");
        elSeries.add(rect);
        rect.attr({
          fill: color,
          i,
          index: i,
          j,
          val: series[i][j],
          "stroke-width": this.strokeWidth,
          stroke: w.config.plotOptions.heatmap.useFillColorAsStroke ? color : w.globals.stroke.colors[0],
          color
        });
        if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
          let speed = 1;
          if (!w.globals.resized) {
            speed = w.config.chart.animations.speed;
          }
          this.animateHeatMap(rect, x1, y1, xDivision, yDivision, speed);
        }
        if (w.globals.dataChanged) {
          let speed = 1;
          if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
            speed = this.dynamicAnim.speed;
            let colorFrom = w.globals.previousPaths[i] && w.globals.previousPaths[i][j] && w.globals.previousPaths[i][j].color;
            if (!colorFrom) colorFrom = "rgba(255, 255, 255, 0)";
            this.animateHeatColor(
              rect,
              Utils.isColorHex(colorFrom) ? colorFrom : Utils.rgb2hex(colorFrom),
              Utils.isColorHex(color) ? color : Utils.rgb2hex(color),
              speed
            );
          }
        }
        const formatter = w.config.dataLabels.formatter;
        const formattedText = formatter(w.seriesData.series[i][j], {
          value: w.seriesData.series[i][j],
          seriesIndex: i,
          dataPointIndex: j,
          w
        });
        const dataLabels = this.helpers.calculateDataLabels({
          text: formattedText,
          x: x1 + xDivision / 2,
          y: y1 + yDivision / 2,
          i,
          j,
          colorProps: heatColorProps,
          series: heatSeries
        });
        if (dataLabels !== null) {
          elSeries.add(dataLabels);
        }
        x1 = x1 + xDivision;
        j++;
      }
      y1 = y1 + yDivision;
      ret.add(elSeries);
    }
    const yAxisScale = (
      /** @type {any[]} */
      w.globals.yAxisScale[0].result.slice()
    );
    if (w.config.yaxis[0].reversed) {
      yAxisScale.unshift("");
    } else {
      yAxisScale.push("");
    }
    w.globals.yAxisScale[0].result = yAxisScale;
    return ret;
  }
  /**
   * @param {any} el
   * @param {number} x
   * @param {number} y
   * @param {number} width
   * @param {number} height
   * @param {number} speed
   */
  animateHeatMap(el, x, y, width, height, speed) {
    const animations = new Animations(this.w);
    animations.animateRect(
      el,
      {
        x: x + width / 2,
        y: y + height / 2,
        width: 0,
        height: 0
      },
      {
        x,
        y,
        width,
        height
      },
      speed,
      () => {
        animations.animationCompleted(el);
      }
    );
  }
  /**
   * @param {any} el
   * @param {string} colorFrom
   * @param {string} colorTo
   * @param {number} speed
   */
  animateHeatColor(el, colorFrom, colorTo, speed) {
    el.attr({
      fill: colorFrom
    }).animate(speed).attr({
      fill: colorTo
    });
  }
}
_core__default.use({
  heatmap: HeatMap
});
export {
  default2 as default
};
