import { BaseChart as e } from "../base.js";
import { ChartTooltip as t } from "../tooltip.js";
import { clamp as n, formatNumber as r, lerpColor as i, roundRect as a } from "../utils.js";
//#region src/charts/heatmap/index.ts
var o = "#f0f9ff", s = "#1e40af", c = 1, l = "11px system-ui, sans-serif", u = "10px system-ui, sans-serif", d = "#64748b", f = class extends e {
	data;
	rowLabels;
	colLabels;
	colorLow;
	colorHigh;
	showValues;
	cellRadius;
	cellGap;
	tooltipEnabled;
	tooltipFormat;
	tooltip;
	handleMouseMove;
	handleMouseLeave;
	valueMin;
	valueMax;
	constructor(e) {
		super(e), this.data = e.data, this.rowLabels = e.rowLabels, this.colLabels = e.colLabels, this.colorLow = e.colorRange === void 0 ? o : e.colorRange[0], this.colorHigh = e.colorRange === void 0 ? s : e.colorRange[1], this.showValues = e.showValues === !0, this.cellRadius = e.cellRadius ?? 0, this.cellGap = e.cellGap ?? c, this.tooltipEnabled = e.tooltip?.enabled !== !1, this.tooltipFormat = e.tooltip?.format ?? null, this.tooltip = null, this.handleMouseMove = null, this.handleMouseLeave = null, this.valueMin = 0, this.valueMax = 0, this.computeValueRange(), this.tooltipEnabled && this.setupTooltip(), this.render();
	}
	computeValueRange() {
		if (this.data.length === 0) {
			this.valueMin = 0, this.valueMax = 1;
			return;
		}
		let e = Infinity, t = -Infinity;
		for (let n of this.data) n.value < e && (e = n.value), n.value > t && (t = n.value);
		this.valueMin = e, this.valueMax = t === e ? e + 1 : t;
	}
	getCellColor(e) {
		let t = n((e - this.valueMin) / (this.valueMax - this.valueMin), 0, 1);
		return i(this.colorLow, this.colorHigh, t);
	}
	getCellBounds() {
		let e = this.plotArea, t = this.colLabels.length, n = this.rowLabels.length;
		return t === 0 || n === 0 ? {
			cellWidth: 0,
			cellHeight: 0,
			offsetX: e.x,
			offsetY: e.y
		} : {
			cellWidth: (e.width - this.cellGap * (t - 1)) / t,
			cellHeight: (e.height - this.cellGap * (n - 1)) / n,
			offsetX: e.x,
			offsetY: e.y
		};
	}
	setupTooltip() {
		this.tooltip = new t(this.container), this.handleMouseMove = (e) => {
			let t = this.canvas.getBoundingClientRect(), n = e.clientX - t.left, i = e.clientY - t.top, { cellWidth: a, cellHeight: o, offsetX: s, offsetY: c } = this.getCellBounds();
			if (a <= 0 || o <= 0) return;
			let l = Math.floor((n - s) / (a + this.cellGap)), u = Math.floor((i - c) / (o + this.cellGap));
			if (l < 0 || l >= this.colLabels.length || u < 0 || u >= this.rowLabels.length) {
				this.tooltip?.hide();
				return;
			}
			let d = s + l * (a + this.cellGap), f = c + u * (o + this.cellGap);
			if (n < d || n > d + a || i < f || i > f + o) {
				this.tooltip?.hide();
				return;
			}
			let p = this.data.find((e) => e.row === u && e.col === l), m = p === void 0 ? 0 : p.value, h = this.rowLabels[u] ?? String(u), g = this.colLabels[l] ?? String(l), _;
			_ = this.tooltipFormat === null ? `<strong>${h} / ${g}</strong><br/>Value: ${r(m)}` : this.tooltipFormat(m, h, g), this.tooltip?.show(n, i, _);
		}, this.handleMouseLeave = () => {
			this.tooltip?.hide();
		}, this.canvas.addEventListener("mousemove", this.handleMouseMove), this.canvas.addEventListener("mouseleave", this.handleMouseLeave);
	}
	render() {
		this.clear();
		let { ctx: e } = this, t = this.plotArea, n = this.colLabels.length, i = this.rowLabels.length;
		if (n === 0 || i === 0) return;
		let { cellWidth: o, cellHeight: s, offsetX: c, offsetY: f } = this.getCellBounds();
		e.save(), e.fillStyle = d, e.font = l, e.textAlign = "center", e.textBaseline = "bottom";
		for (let r = 0; r < n; r++) {
			let n = this.colLabels[r];
			if (n === void 0) continue;
			let i = c + r * (o + this.cellGap) + o / 2;
			e.fillText(n, i, t.y - 4, o);
		}
		e.restore(), e.save(), e.fillStyle = d, e.font = l, e.textAlign = "right", e.textBaseline = "middle";
		for (let n = 0; n < i; n++) {
			let r = this.rowLabels[n];
			if (r === void 0) continue;
			let i = f + n * (s + this.cellGap) + s / 2;
			e.fillText(r, t.x - 6, i);
		}
		e.restore();
		let p = /* @__PURE__ */ new Map();
		for (let e of this.data) p.set(`${String(e.row)},${String(e.col)}`, e.value);
		e.save();
		for (let t = 0; t < i; t++) for (let i = 0; i < n; i++) {
			let n = c + i * (o + this.cellGap), l = f + t * (s + this.cellGap), d = p.get(`${String(t)},${String(i)}`) ?? 0;
			e.fillStyle = this.getCellColor(d), this.cellRadius > 0 ? (a(e, n, l, o, s, this.cellRadius), e.fill()) : e.fillRect(n, l, o, s), this.showValues && (e.fillStyle = this.getContrastTextColor(d), e.font = u, e.textAlign = "center", e.textBaseline = "middle", e.fillText(r(d), n + o / 2, l + s / 2, o - 4));
		}
		e.restore();
	}
	getContrastTextColor(e) {
		return n((e - this.valueMin) / (this.valueMax - this.valueMin), 0, 1) > .5 ? "#ffffff" : "#1e293b";
	}
	update(e) {
		this.data = e, this.computeValueRange(), this.render();
	}
	destroy() {
		this.handleMouseMove !== null && this.canvas.removeEventListener("mousemove", this.handleMouseMove), this.handleMouseLeave !== null && this.canvas.removeEventListener("mouseleave", this.handleMouseLeave), this.tooltip?.destroy(), super.destroy();
	}
};
//#endregion
export { f as HeatmapChart };

//# sourceMappingURL=index.js.map