/**
* Copyright (c) 2026, Yandex LLC
* All rights reserved. (MIT Licensed)
*
* Yagr@4.13.1
* High-performance HTML5 canvas chart renderer based on uPlot
* https://github.com/gravity-ui/yagr
*/
(function (g, f) {
  var hasExports = typeof exports === 'object';
  if (typeof define === "function" && define.amd) {
    define([], f);
  } else if (typeof module === "object" && module.exports) {
    module.exports = f();
  } else {
    var m = hasExports ? f() : f();
    var root = hasExports ? exports : g;
    for(var i in m) root[i] = m[i];
  }}(typeof self !== 'undefined' ? self : this, () => {
var exports = {};
var module = { exports };
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/plugins/labels/labels.ts
var labels_exports = {};
__export(labels_exports, {
  default: () => YagrLabelsPlugin
});
module.exports = __toCommonJS(labels_exports);

// src/YagrCore/utils/common.ts
var px = (x) => x + "px";
var html = (tag, attrs = {}, content) => {
  const el = document.createElement(tag);
  Object.keys(attrs).forEach((key) => {
    const attr = attrs[key];
    el.setAttribute(
      key,
      typeof attr === "object" ? Object.entries(attr).map(([a, b]) => `${a}:${b}`).join(";") : attr
    );
  });
  if (content) {
    if (typeof content === "string") {
      el.innerHTML = content;
    } else {
      el.appendChild(content);
    }
  }
  return el;
};
function isNil(v) {
  return v === null || v === void 0;
}

// src/plugins/labels/utils.ts
var defaultPositionTop = (u, x, y, scale) => {
  return [u.valToPos(x, "x"), u.valToPos(y, scale) - 15];
};
var getId = () => (x) => String(x);
function renderAxisLabel({
  yagr,
  scaleKey,
  x,
  y,
  className = "",
  render,
  onRender,
  onDestroy,
  label
}) {
  const over = yagr.root.querySelector(".u-over");
  if (render) {
    return render(yagr, x, y, label);
  }
  const labelValue = label.label ? typeof label.label === "function" ? label.label(label) : label.label : "";
  const div = html(
    "div",
    {
      class: `yagr-label ${className}`,
      style: {
        visibility: "hidden"
      }
    },
    labelValue ?? label.value.toString()
  );
  over.append(div);
  if (scaleKey === "x") {
    div.style.top = px(y - div.clientHeight / 2);
    div.style.left = px(x - div.clientWidth / 2);
  } else {
    if (yagr.config.axes[scaleKey]?.side === "right") {
      div.style.left = px(x - div.clientWidth / 2);
    } else {
      div.style.left = px(x);
    }
    div.style.top = px(y - div.clientHeight / 2);
  }
  div.style.visibility = "visible";
  onRender && onRender(div);
  return () => {
    onDestroy && onDestroy(div);
    div.remove();
  };
}
function renderPointLabel({
  yagr,
  label,
  x,
  y,
  className = "",
  shifts = {},
  onRender,
  onDestroy
}) {
  const over = yagr.root.querySelector(".u-over");
  const div = html(
    "div",
    {
      class: `yagr-label ${className}`,
      style: {
        top: px(y + (shifts.top || 0)),
        left: px(x + (shifts.left || 0))
      }
    },
    label
  );
  over.append(div);
  onRender && onRender(div);
  div.style.left = px(Number(div.style.left.replace("px", "")) - div.clientWidth / 2);
  return () => {
    div.remove();
    onDestroy && onDestroy(div);
  };
}
function drawLabelOnPoint(yagr, serieIdx, xIdx, scaleKey, labelOptions, xAxisFormatter, selfAxisFormatter, onDraw) {
  const x = yagr.uplot.data[0][xIdx];
  const y = yagr.uplot.data[serieIdx][xIdx];
  if (isNil(y) || !scaleKey || !labelOptions) {
    return;
  }
  const valX = xAxisFormatter(x);
  const valY = selfAxisFormatter(y);
  const label = typeof labelOptions.label === "function" ? labelOptions.label(x, y, xIdx) : labelOptions.label || `(${valX}, ${valY})`;
  if (labelOptions.render) {
    const clear2 = labelOptions.render(yagr, serieIdx, xIdx, scaleKey, labelOptions);
    clear2 && onDraw && onDraw(clear2, label ?? "", serieIdx);
    return;
  }
  if (!label || isNil(y)) {
    return;
  }
  const [xP, yP] = labelOptions.position ? labelOptions.position(x, y) : defaultPositionTop(yagr.uplot, x, y, scaleKey);
  const prev = yagr.uplot.data[serieIdx][xIdx - 1];
  const next = yagr.uplot.data[serieIdx][xIdx + 1];
  const className = prev !== null && prev !== void 0 && next !== null && next !== void 0 ? y < prev && y < next ? "_bottom" : "_top" : "_top";
  let clear = () => {
  };
  if (labelOptions.show !== false) {
    clear = renderPointLabel({
      yagr,
      label,
      x: xP,
      y: yP,
      className,
      onRender: labelOptions.onRender,
      onDestroy: labelOptions.onDestroy
    });
  }
  onDraw && onDraw(clear, label, serieIdx);
}

// src/plugins/labels/series.ts
function seriesDrawBasedLabels(yagr, hooks, options) {
  const clears = {};
  const cursorClears = [];
  const focusClears = [];
  const labels = {};
  hooks.drawClear = hooks.drawClear || [];
  hooks.draw = hooks.draw || [];
  hooks.setCursor = hooks.setCursor || [];
  hooks.setSeries = hooks.setSeries || [];
  function drawLabelsOnSeries(u, seriesIdxs) {
    const sIdxs = [];
    if (seriesIdxs) {
      sIdxs.push(...seriesIdxs);
    } else {
      for (let sIdx = 1; sIdx < u.series.length; sIdx++) {
        const series = u.series[sIdx];
        if (options.scales?.draw) {
          const scaleKey = series.scale;
          if (scaleKey && options.scales?.draw[scaleKey]) {
            sIdxs.push(sIdx);
          }
        }
        if (options.series?.draw) {
          if (options.series?.draw[series.id]) {
            sIdxs.push(sIdx);
          }
        }
      }
    }
    for (const sIdx of sIdxs) {
      const series = u.series[sIdx];
      if (!series.show || series._focus === false) {
        continue;
      }
      const { scale = "y", min, max } = series;
      const tSeries = u.series[0];
      const labelOptions = options.series?.draw?.[series.id] || options.scales?.draw?.[series.scale];
      const selfAxisFormatter = (u.axes.find((a) => a.scale === scale)?.getFormatter || getId)(max - min);
      const xAxisFormatter = (u.axes.find((a) => a.scale === "x")?.getFormatter || getId)(
        tSeries.max - tSeries.min
      );
      let idx = 0;
      while (idx < u.data[0].length) {
        drawLabelOnPoint(
          yagr,
          sIdx,
          idx,
          scale,
          labelOptions,
          xAxisFormatter,
          selfAxisFormatter,
          (clear, label) => {
            clears[sIdx] = clears[sIdx] || [];
            clears[sIdx].push(clear);
            labels[sIdx] = labels[sIdx] || [];
            labels[sIdx].push({ idx, label });
          }
        );
        idx++;
      }
    }
  }
  function drawLabelsOnCursor(u, idx) {
    const sIdxs = [];
    for (let sIdx = 1; sIdx < u.series.length; sIdx++) {
      const series = u.series[sIdx];
      if (options.scales?.cursor) {
        const scaleKey = series.scale;
        if (scaleKey && options.scales.cursor[scaleKey]) {
          sIdxs.push(sIdx);
        }
      }
      if (options.series?.cursor) {
        if (options.series.cursor[series.id]) {
          sIdxs.push(sIdx);
        }
      }
    }
    for (const sIdx of sIdxs) {
      const series = u.series[sIdx];
      if (!series.show || series._focus === false) {
        continue;
      }
      const { scale = "y", min, max } = series;
      const tSeries = u.series[0];
      const labelOptions = options.series?.cursor?.[series.id] || options.scales?.cursor?.[series.scale];
      const selfAxisFormatter = (u.axes.find((a) => a.scale === scale)?.getFormatter || getId)(max - min);
      const xAxisFormatter = (u.axes.find((a) => a.scale === "x")?.getFormatter || getId)(
        tSeries.max - tSeries.min
      );
      drawLabelOnPoint(yagr, sIdx, idx, scale, labelOptions, xAxisFormatter, selfAxisFormatter, (clear) => {
        cursorClears.push(clear);
      });
    }
  }
  if (options.series?.focus) {
    hooks.setSeries.push((u, sIdx, opts) => {
      if (sIdx === null) {
        focusClears?.forEach((fn) => fn());
        return;
      }
      const series = u.series[sIdx];
      const labelOptions = options.series?.focus?.[series.id];
      if (!labelOptions) {
        focusClears?.forEach((fn) => fn());
        return;
      }
      if (series.show && opts.focus === true) {
        const { scale = "y", min, max } = series;
        const tSeries = u.series[0];
        const selfAxisFormatter = (u.axes.find((a) => a.scale === scale)?.getFormatter || getId)(max - min);
        const xAxisFormatter = (u.axes.find((a) => a.scale === "x")?.getFormatter || getId)(
          tSeries.max - tSeries.min
        );
        let idx = 0;
        while (idx < u.data[0].length) {
          drawLabelOnPoint(
            yagr,
            sIdx,
            idx,
            scale,
            labelOptions,
            xAxisFormatter,
            selfAxisFormatter,
            (clear) => {
              focusClears.push(clear);
            }
          );
          idx++;
        }
      } else {
        focusClears?.forEach((fn) => fn());
      }
    });
  }
  if (options.scales?.draw || options.series?.draw) {
    hooks.draw.push((u) => {
      drawLabelsOnSeries(u);
    });
    hooks.drawClear.push(() => {
      Object.values(clears).forEach((fns) => fns.forEach((fn) => fn()));
      Object.keys(clears).forEach((k) => delete clears[Number(k)]);
    });
  }
  if (options.scales?.cursor || options.series?.cursor) {
    hooks.setCursor.push((u) => {
      cursorClears.forEach((fn) => fn());
      const { idx } = u.cursor;
      if (!isNil(idx)) {
        drawLabelsOnCursor(u, idx);
      }
    });
  }
  return {
    getSeriesLabels: () => labels,
    getCurrentSeriesLabels: () => {
      const cursor = yagr.uplot.cursor;
      if (cursor.idx === null) {
        return {};
      }
      return Object.entries(labels).reduce((acc, [sIdx, labels2]) => {
        acc[Number(sIdx)] = labels2.find((l) => l.idx === cursor.idx);
        return acc;
      }, {});
    }
  };
}

// src/plugins/labels/plotLines.ts
function plotLinesDrawBasedLabels(yagr, hooks, options) {
  let drawClears = [];
  let cursorClears = [];
  hooks.draw = hooks.draw || [];
  hooks.drawClear = hooks.drawClear || [];
  hooks.setCursor = hooks.setCursor || [];
  function renderLabelsOnPlotLines(psOptions, clears, predicate) {
    const bands = [];
    for (const [scaleName, labelOptions] of Object.entries(psOptions || {})) {
      const foundBands = (yagr.plugins.plotLines?.get() || []).filter((p) => {
        return p.scale === scaleName;
      });
      foundBands.length && bands.push({ bands: foundBands, labelOptions });
    }
    if (!bands.length) {
      return;
    }
    bands.forEach(({ bands: plotLines, labelOptions }) => {
      plotLines.forEach((band) => {
        if (predicate?.(band) === false) {
          return;
        }
        const [x, y] = band.scale === "x" ? [Array.isArray(band.value) ? band.value[0] : band.value, yagr.uplot.posToVal(0, "y")] : [yagr.uplot.posToVal(0, "x"), Array.isArray(band.value) ? band.value[0] : band.value];
        const [xP, yP] = labelOptions.position ? labelOptions.position(x, y) : defaultPositionTop(yagr.uplot, x, y, band.scale || "y");
        const label = typeof labelOptions.label === "function" ? labelOptions.label(band) : labelOptions.label || band.label;
        if (labelOptions.render) {
          const clear = labelOptions.render(yagr, band, xP, yP, labelOptions);
          clear && drawClears.push(clear);
          return;
        }
        if (label && labelOptions.show !== false) {
          clears.push(
            renderPointLabel({
              yagr,
              label,
              x: xP,
              y: yP
            })
          );
        }
      });
    });
  }
  if (options.plotLines?.cursor) {
    hooks.setCursor.push((u) => {
      cursorClears.forEach((fn) => fn());
      cursorClears = [];
      const { left, top } = u.cursor;
      if (!isNil(left) && !isNil(top) && left >= 0 && top >= 0) {
        renderLabelsOnPlotLines(options.plotLines?.cursor, cursorClears, (band) => {
          const x = yagr.uplot.posToVal(left, "x");
          const [x1, x2] = Array.isArray(band.value) ? band.value : [band.value, band.value];
          const [y1, y2] = Array.isArray(band.value) ? [band.value[0], band.value[1]] : [band.value, band.value];
          if (band.scale === "x") {
            if (x >= x1 && x <= x2) {
              return true;
            }
          } else {
            const y = yagr.uplot.posToVal(top, band.scale);
            if (y >= y1 && y <= y2) {
              return true;
            }
          }
          return false;
        });
      }
    });
  }
  if (options.plotLines?.draw) {
    hooks.draw.push(() => {
      renderLabelsOnPlotLines(options.plotLines?.draw, drawClears);
    });
    hooks.drawClear.push(() => {
      drawClears.forEach((fn) => fn());
      drawClears = [];
    });
  }
  return {
    getPlotLinesLabels: () => {
      const bands = yagr.plugins.plotLines?.get() || [];
      return bands.filter((band) => {
        return options.plotLines?.draw?.[band.scale || "y"];
      }).map((band) => {
        return { band, label: options.plotLines?.draw?.[band.scale || "y"]?.label || band.label };
      });
    },
    getCurrentPlotLinesLabels: () => {
      const cursor = yagr.uplot.cursor;
      if (!cursor.left || !cursor.top || cursor.left < 0 || cursor.top < 0) {
        return [];
      }
      const labels = [];
      const { left, top } = cursor;
      const x = yagr.uplot.posToVal(left, "x");
      yagr.plugins.plotLines?.get().forEach((band) => {
        const [x1, x2] = Array.isArray(band.value) ? band.value : [band.value, band.value];
        const [y1, y2] = Array.isArray(band.value) ? [band.value[0], band.value[1]] : [band.value, band.value];
        if (band.scale === "x") {
          if (x >= x1 && x <= x2) {
            labels.push({ band, label: band.label });
          }
        } else {
          const y = yagr.uplot.posToVal(top, band.scale);
          if (y >= y1 && y <= y2) {
            labels.push({ band, label: band.label });
          }
        }
      });
      return labels;
    }
  };
}

// src/plugins/labels/axes.ts
function axisDrawBasedLabels(yagr, hooks, options) {
  let pointsClears = [];
  function onDrawAxes(u) {
    pointsClears.forEach((fn) => fn());
    pointsClears = [];
    Object.entries(options.axes || {}).forEach(([scaleKey, opts]) => {
      const axis = u.axes.find((a) => a.scale === scaleKey);
      if (!axis) {
        return;
      }
      opts.forEach((opt) => {
        let x, y;
        if (scaleKey === "x") {
          x = u.valToPos(opt.value, "x");
          y = u.valToPos(0, "y");
        } else {
          if (yagr.config.axes[scaleKey]?.side === "right") {
            x = u.valToPos(u.data[0][u.data[0].length - 1], "x");
          } else {
            x = u.valToPos(u.data[0][0], "x");
          }
          y = u.valToPos(opt.value, "y");
        }
        pointsClears.push(
          renderAxisLabel({
            yagr,
            scaleKey,
            x,
            y,
            render: opt.render,
            label: opt,
            className: opt.className,
            onRender: opt.onRender,
            onDestroy: opt.onDestroy
          })
        );
      });
    });
  }
  hooks.drawAxes = hooks.drawAxes || [];
  if (options.axes) {
    hooks.drawAxes.push(onDrawAxes);
  }
  return {
    getAxisLabels() {
      return options.axes || {};
    },
    getCurrentAxisLabels(proximity) {
      const cursor = yagr.uplot.cursor;
      if (!cursor) {
        return {};
      }
      const { left, top } = cursor;
      if (isNil(left) || isNil(top) || left < 0 || top < 0) {
        return {};
      }
      const labels = {};
      Object.entries(options.axes || {}).forEach(([scaleKey, opts]) => {
        const axis = yagr.uplot.axes.find((a) => a.scale === scaleKey);
        if (!axis) {
          return;
        }
        opts.forEach((opt) => {
          let x, y;
          if (scaleKey === "x") {
            x = yagr.uplot.posToVal(left, "x");
            if (Math.abs(x - opt.value) < proximity.x) {
              labels[scaleKey] = labels[scaleKey] || [];
              labels[scaleKey].push(opt);
            }
          } else {
            y = yagr.uplot.posToVal(top, "y");
            if (Math.abs(y - opt.value) < proximity.y) {
              labels[scaleKey] = labels[scaleKey] || [];
              labels[scaleKey].push(opt);
            }
          }
        });
      });
      return labels;
    }
  };
}

// src/plugins/labels/labels.ts
function YagrLabelsPlugin(options) {
  return (yagr) => {
    const hooks = {};
    return {
      ...seriesDrawBasedLabels(yagr, hooks, options),
      ...plotLinesDrawBasedLabels(yagr, hooks, options),
      ...axisDrawBasedLabels(yagr, hooks, options),
      uplot: {
        hooks
      }
    };
  };
}
if (typeof window !== "undefined") {
  Object.assign(window, { YagrLabelsPlugin });
}
if (typeof module.exports == "object" && typeof exports == "object") {
  var __cp = (to, from, except, desc) => {
    if ((from && typeof from === "object") || typeof from === "function") {
      for (let key of Object.getOwnPropertyNames(from)) {
        if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except)
        Object.defineProperty(to, key, {
          get: () => from[key],
          enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable,
        });
      }
    }
    return to;
  };
  module.exports = __cp(module.exports, exports);
}
return module.exports;
}))
//# sourceMappingURL=labels.umd.js.map
