import { BaseChart as e } from "../base.js";
import { ChartTooltip as t } from "../tooltip.js";
import { defaultColors as n, formatNumber as r, hexToRgba as i } from "../utils.js";
//#region src/charts/funnel/index.ts
var a = "600 12px ui-sans-serif, system-ui, -apple-system, sans-serif", o = "500 11px ui-sans-serif, system-ui, -apple-system, sans-serif", s = .12, c = new Map([
	["black", [
		0,
		0,
		0
	]],
	["white", [
		255,
		255,
		255
	]],
	["navy", [
		0,
		0,
		128
	]],
	["rebeccapurple", [
		102,
		51,
		153
	]],
	["transparent", [
		0,
		0,
		0
	]]
]);
function l(e) {
	let t = u(e);
	if (t === null) return {
		text: "#0f172a",
		shadow: "rgba(255, 255, 255, 0.45)"
	};
	let [n, r, i] = t;
	return (.299 * n + .587 * r + .114 * i) / 255 > .6 ? {
		text: "#0f172a",
		shadow: "rgba(255, 255, 255, 0.45)"
	} : {
		text: "#ffffff",
		shadow: "rgba(0, 0, 0, 0.45)"
	};
}
function u(e) {
	let t = e.trim(), n = d(t);
	if (n !== null) return n;
	let r = c.get(t.toLowerCase());
	if (r !== void 0) return r;
	let i = m(t);
	return i === null ? null : d(i);
}
function d(e) {
	if (e.startsWith("#")) {
		let t = e.slice(1);
		return t.length === 3 ? [
			parseInt(t[0] + t[0], 16),
			parseInt(t[1] + t[1], 16),
			parseInt(t[2] + t[2], 16)
		] : t.length === 6 ? [
			parseInt(t.slice(0, 2), 16),
			parseInt(t.slice(2, 4), 16),
			parseInt(t.slice(4, 6), 16)
		] : null;
	}
	let t = e.match(/^rgba?\(([^)]+)\)$/i);
	if (t) {
		let e = h(t[1]), n = g(e[0]), r = g(e[1]), i = g(e[2]);
		if (Number.isFinite(n) && Number.isFinite(r) && Number.isFinite(i)) return [
			n,
			r,
			i
		];
	}
	let n = e.match(/^hsla?\(([^)]+)\)$/i);
	if (n) {
		let e = h(n[1]), t = _(e[0]), r = v(e[1]), i = v(e[2]);
		if (Number.isFinite(t) && Number.isFinite(r) && Number.isFinite(i)) return y(t, r, i);
	}
	return null;
}
var f;
function p() {
	if (f !== void 0) return f;
	if (typeof document > "u") return f = null, null;
	let e = document.createElement("canvas");
	return e.width = 1, e.height = 1, f = e.getContext("2d"), f;
}
function m(e) {
	let t = p();
	if (t === null) return null;
	t.fillStyle = "#010203";
	let n = t.fillStyle;
	t.fillStyle = e;
	let r = t.fillStyle;
	return r === n && e.trim().toLowerCase() !== "#010203" ? null : typeof r == "string" ? r : null;
}
function h(e) {
	let t = e.split("/")[0].trim();
	return t.includes(",") ? t.split(",").map((e) => e.trim()) : t.split(/\s+/).map((e) => e.trim());
}
function g(e) {
	if (e === void 0) return NaN;
	if (e.endsWith("%")) {
		let t = Number(e.slice(0, -1));
		return Number.isFinite(t) ? Math.round(t / 100 * 255) : NaN;
	}
	return Number(e);
}
function _(e) {
	if (e === void 0) return NaN;
	if (e.endsWith("turn")) {
		let t = Number(e.slice(0, -4));
		return Number.isFinite(t) ? t % 1 : NaN;
	}
	if (e.endsWith("rad")) {
		let t = Number(e.slice(0, -3));
		return Number.isFinite(t) ? t / (Math.PI * 2) % 1 : NaN;
	}
	let t = e.endsWith("deg") ? e.slice(0, -3) : e, n = Number(t);
	return Number.isFinite(n) ? (n % 360 + 360) % 360 / 360 : NaN;
}
function v(e) {
	if (e === void 0 || !e.endsWith("%")) return NaN;
	let t = Number(e.slice(0, -1));
	return Number.isFinite(t) ? t / 100 : NaN;
}
function y(e, t, n) {
	if (t === 0) {
		let e = Math.round(n * 255);
		return [
			e,
			e,
			e
		];
	}
	let r = (e, t, n) => {
		let r = n;
		return r < 0 && (r += 1), r > 1 && --r, r < 1 / 6 ? e + (t - e) * 6 * r : r < 1 / 2 ? t : r < 2 / 3 ? e + (t - e) * (2 / 3 - r) * 6 : e;
	}, i = n < .5 ? n * (1 + t) : n + t - n * t, a = 2 * n - i;
	return [
		Math.round(r(a, i, e + 1 / 3) * 255),
		Math.round(r(a, i, e) * 255),
		Math.round(r(a, i, e - 1 / 3) * 255)
	];
}
var b = class extends e {
	segments;
	resolved = [];
	colors;
	showLabels;
	showValues;
	direction;
	curved;
	gap;
	tooltip = null;
	hoveredIndex = -1;
	boundMouseMove;
	boundMouseLeave;
	constructor(e) {
		super(e), this.segments = e.segments, this.colors = n(), this.showLabels = e.showLabels ?? !0, this.showValues = e.showValues ?? !0, this.direction = e.direction ?? "vertical", this.curved = e.curved ?? !1, this.gap = e.gap ?? 2, e.tooltip?.enabled !== !1 && (this.tooltip = new t(this.container)), this.boundMouseMove = (e) => {
			this.handleMouseMove(e);
		}, this.boundMouseLeave = () => {
			this.handleMouseLeave();
		}, this.canvas.addEventListener("mousemove", this.boundMouseMove), this.canvas.addEventListener("mouseleave", this.boundMouseLeave), this.resolveSegments(), this.render();
	}
	update(e) {
		this.segments = e, this.resolveSegments(), this.render();
	}
	render() {
		this.clear(), this.resolved.length !== 0 && (this.direction === "horizontal" ? this.renderHorizontal() : this.renderVertical());
	}
	destroy() {
		this.canvas.removeEventListener("mousemove", this.boundMouseMove), this.canvas.removeEventListener("mouseleave", this.boundMouseLeave), this.tooltip !== null && this.tooltip.destroy(), super.destroy();
	}
	resolveSegments() {
		let e = this.findMaxValue(), t = this.segments[0]?.value ?? 1;
		this.resolved = [];
		for (let n = 0; n < this.segments.length; n++) {
			let r = this.segments[n];
			if (r === void 0) continue;
			let i = r.color ?? this.colors[n % this.colors.length] ?? "#3b82f6", a = e > 0 ? r.value / e : 0, o = t > 0 ? r.value / t * 100 : 0;
			this.resolved.push({
				label: r.label,
				value: r.value,
				color: i,
				widthRatio: a,
				percentage: o
			});
		}
	}
	findMaxValue() {
		let e = 0;
		for (let t of this.segments) t.value > e && (e = t.value);
		return e;
	}
	renderVertical() {
		let e = this.plotArea, t = this.resolved.length;
		if (t === 0) return;
		let n = this.gap * Math.max(0, t - 1), r = (e.height - n) / t;
		for (let n = 0; n < t; n++) {
			let t = this.resolved[n];
			if (t === void 0) continue;
			let a = this.resolved[n + 1], o = t.widthRatio * e.width, c = a === void 0 ? o * .7 : a.widthRatio * e.width, l = e.y + n * (r + this.gap), u = e.x + e.width / 2, d = u - o / 2, f = u + o / 2, p = u - c / 2, m = u + c / 2, h = n === this.hoveredIndex ? i(t.color, 1 - s) : t.color;
			if (this.ctx.save(), this.ctx.beginPath(), this.curved) {
				let e = l + r * .6;
				this.ctx.moveTo(d, l), this.ctx.lineTo(f, l), this.ctx.quadraticCurveTo(f, e, m, l + r), this.ctx.lineTo(p, l + r), this.ctx.quadraticCurveTo(d, e, d, l);
			} else this.ctx.moveTo(d, l), this.ctx.lineTo(f, l), this.ctx.lineTo(m, l + r), this.ctx.lineTo(p, l + r);
			this.ctx.closePath(), this.ctx.fillStyle = h, this.ctx.fill(), this.ctx.restore(), this.drawSegmentText(u, l + r / 2, t);
		}
	}
	renderHorizontal() {
		let e = this.plotArea, t = this.resolved.length;
		if (t === 0) return;
		let n = this.gap * Math.max(0, t - 1), r = (e.width - n) / t;
		for (let n = 0; n < t; n++) {
			let t = this.resolved[n];
			if (t === void 0) continue;
			let a = this.resolved[n + 1], o = t.widthRatio * e.height, c = a === void 0 ? o * .7 : a.widthRatio * e.height, l = e.x + n * (r + this.gap), u = e.y + e.height / 2, d = u - o / 2, f = u + o / 2, p = u - c / 2, m = u + c / 2, h = n === this.hoveredIndex ? i(t.color, 1 - s) : t.color;
			if (this.ctx.save(), this.ctx.beginPath(), this.curved) {
				let e = l + r * .6;
				this.ctx.moveTo(l, d), this.ctx.lineTo(l, f), this.ctx.quadraticCurveTo(e, f, l + r, m), this.ctx.lineTo(l + r, p), this.ctx.quadraticCurveTo(e, d, l, d);
			} else this.ctx.moveTo(l, d), this.ctx.lineTo(l, f), this.ctx.lineTo(l + r, m), this.ctx.lineTo(l + r, p);
			this.ctx.closePath(), this.ctx.fillStyle = h, this.ctx.fill(), this.ctx.restore(), this.drawSegmentText(l + r / 2, u, t);
		}
	}
	drawSegmentText(e, t, n) {
		let { text: i, shadow: s } = l(n.color);
		this.ctx.save(), this.ctx.textAlign = "center", this.ctx.textBaseline = "middle", this.ctx.shadowColor = s, this.ctx.shadowBlur = 4, this.ctx.shadowOffsetY = 1, this.ctx.fillStyle = i, this.showLabels && this.showValues ? (this.ctx.font = a, this.ctx.fillText(n.label, e, t - 8), this.ctx.font = o, this.ctx.globalAlpha = .9, this.ctx.fillText(`${r(n.value)} (${n.percentage.toFixed(1)}%)`, e, t + 8)) : this.showLabels ? (this.ctx.font = a, this.ctx.fillText(n.label, e, t)) : this.showValues && (this.ctx.font = o, this.ctx.fillText(r(n.value), e, t)), this.ctx.restore();
	}
	handleMouseMove(e) {
		let t = this.canvas.getBoundingClientRect(), n = e.clientX - t.left, i = e.clientY - t.top, a = this.plotArea, o = this.resolved.length;
		if (o === 0) return;
		let s = -1;
		if (this.direction === "horizontal") {
			let e = this.gap * Math.max(0, o - 1), t = (a.width - e) / o, r = n - a.x;
			if (r >= 0 && r <= a.width && i >= a.y && i <= a.y + a.height) for (let e = 0; e < o; e++) {
				let n = e * (t + this.gap), i = n + t;
				if (r >= n && r < i) {
					s = e;
					break;
				}
			}
		} else {
			let e = this.gap * Math.max(0, o - 1), t = (a.height - e) / o, r = i - a.y;
			if (r >= 0 && r <= a.height && n >= a.x && n <= a.x + a.width) for (let e = 0; e < o; e++) {
				let n = e * (t + this.gap), i = n + t;
				if (r >= n && r < i) {
					s = e;
					break;
				}
			}
		}
		if (s !== this.hoveredIndex && (this.hoveredIndex = s, this.render()), s !== -1 && this.tooltip !== null) {
			let e = this.resolved[s];
			if (e !== void 0) {
				let t = `<strong>${e.label}</strong><br/>${r(e.value)} (${e.percentage.toFixed(1)}%)`;
				this.tooltip.show(n, i, t);
			}
		} else this.tooltip !== null && this.tooltip.hide();
	}
	handleMouseLeave() {
		this.hoveredIndex !== -1 && (this.hoveredIndex = -1, this.tooltip !== null && this.tooltip.hide(), this.render());
	}
};
//#endregion
export { b as FunnelChart };

//# sourceMappingURL=index.js.map