@validationcloud/fractal-ui 1.52.0 → 1.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/dist/assets/vc-logo.svg.js +4 -0
  2. package/dist/components/echarts-renderer/calculate-title-layout.d.ts +8 -0
  3. package/dist/components/echarts-renderer/calculate-title-layout.js +72 -0
  4. package/dist/components/echarts-renderer/calculate-title-layout.test.d.ts +1 -0
  5. package/dist/components/echarts-renderer/detect-horizontal-bars.d.ts +13 -0
  6. package/dist/components/echarts-renderer/detect-horizontal-bars.js +13 -0
  7. package/dist/components/echarts-renderer/mavrik-chart.d.ts +19 -0
  8. package/dist/components/echarts-renderer/mavrik-chart.js +12 -0
  9. package/dist/components/echarts-renderer/mavrik-theme-horizontal.json.d.ts +277 -0
  10. package/dist/components/echarts-renderer/mavrik-theme-horizontal.json.js +33 -0
  11. package/dist/components/echarts-renderer/mavrik-theme.d.ts +242 -0
  12. package/dist/components/echarts-renderer/mavrik-theme.js +18 -6
  13. package/dist/components/echarts-renderer/mavrik-theme.json.d.ts +6 -2
  14. package/dist/components/echarts-renderer/sanitize-chart-options.d.ts +6 -0
  15. package/dist/components/echarts-renderer/sanitize-chart-options.js +9 -0
  16. package/dist/components/echarts-renderer/use-chart-instance.d.ts +0 -1
  17. package/dist/components/echarts-renderer/use-chart-instance.js +54 -37
  18. package/dist/components/echarts-renderer/watermark-graphic.d.ts +12 -0
  19. package/dist/components/echarts-renderer/watermark-graphic.js +25 -0
  20. package/dist/index.d.ts +2 -1
  21. package/dist/index.js +57 -54
  22. package/dist/lib/render-chart-to-image.js +36 -19
  23. package/dist/lib/render-mavrik-chart-to-image.d.ts +33 -0
  24. package/package.json +19 -15
@@ -0,0 +1,4 @@
1
+ const a = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='210'%20height='24'%20fill='none'%20viewBox='0%200%20210%2024'%3e%3cg%20fill='%23a7a9ad'%20fill-opacity='0.3'%3e%3cpath%20fill-rule='evenodd'%20d='M33.733%201.868h-21.67C6.438%201.868%201.878%206.404%201.878%2012s4.56%2010.132%2010.185%2010.132h21.67c5.625%200%2010.185-4.536%2010.185-10.132S39.358%201.868%2033.733%201.868M0%2012c0%206.627%205.4%2012%2012.063%2012h21.67c6.662%200%2012.063-5.373%2012.063-12s-5.4-12-12.063-12h-21.67C5.401%200%200%205.373%200%2012'%20clip-rule='evenodd'/%3e%3cpath%20fill-rule='evenodd'%20d='M33.734%205.174h-21.67C8.273%205.174%205.2%208.23%205.2%2012s3.073%206.826%206.863%206.826h21.67c3.79%200%206.862-3.056%206.862-6.826s-3.072-6.826-6.862-6.826M3.323%2012c0%204.802%203.912%208.695%208.74%208.695h21.67c4.827%200%208.74-3.893%208.74-8.695s-3.913-8.695-8.74-8.695h-21.67c-4.828%200-8.74%203.893-8.74%208.695'%20clip-rule='evenodd'/%3e%3cpath%20fill-rule='evenodd'%20d='M33.733%208.48h-21.67A3.53%203.53%200%200%200%208.523%2012a3.53%203.53%200%200%200%203.54%203.521h21.67a3.53%203.53%200%200%200%203.54-3.52%203.53%203.53%200%200%200-3.54-3.522M6.646%2012c0%202.976%202.425%205.39%205.417%205.39h21.67c2.992%200%205.418-2.414%205.418-5.39s-2.426-5.39-5.418-5.39h-21.67c-2.992%200-5.417%202.414-5.417%205.39'%20clip-rule='evenodd'/%3e%3cpath%20d='M58.45%2020.695h-2.77L48.592%203.327h2.7l5.773%2014.542%205.773-14.542h2.7zM73.986%2020.695h-2.06l-.14-1.482q-.64.81-1.617%201.262-.978.45-2.165.451-1.246%200-2.223-.486a3.86%203.86%200%200%201-1.537-1.332%203.4%203.4%200%200%201-.559-1.922q0-1.134.606-1.991.605-.868%201.653-1.355%201.047-.498%202.386-.498.838%200%201.699.197a6.6%206.6%200%200%201%201.571.556v-.429q0-.844-.442-1.447a2.7%202.7%200%200%200-1.187-.938%204.1%204.1%200%200%200-1.653-.324q-.802%200-1.641.278-.826.277-1.56.857l-.721-1.934a9.3%209.3%200%200%201%202.2-.95%208.3%208.3%200%200%201%202.257-.323q1.583%200%202.724.625a4.35%204.35%200%200%201%201.78%201.783q.63%201.146.63%202.71zm-5.517-1.783q.827%200%201.525-.336a2.93%202.93%200%200%200%201.129-.973q.442-.636.477-1.482v-.162a4.7%204.7%200%200%200-1.338-.683%204.6%204.6%200%200%200-1.502-.255q-1.176%200-1.955.556-.78.555-.78%201.424%200%20.544.314.984.326.43.873.683.56.244%201.257.244M77.988%2020.695h-2.54V2.864h2.54zM80.666%205.758q-.548%200-.92-.382a1.28%201.28%200%200%201-.373-.926q0-.545.373-.915.372-.382.92-.382.56%200%20.932.382.385.37.385.915t-.385.926q-.373.382-.932.382m1.188%2014.937h-2.388V9.116h2.388zM95.628%2020.695H93.52l-.128-1.656a5.7%205.7%200%200%201-1.909%201.39q-1.106.497-2.432.497-1.677%200-3.003-.787a5.7%205.7%200%200%201-2.095-2.154q-.757-1.365-.757-3.08%200-1.724.757-3.08a5.7%205.7%200%200%201%202.095-2.153q1.326-.787%203.003-.787%201.257%200%202.328.451a5.5%205.5%200%200%201%201.862%201.262V3.327h2.386zm-6.18-1.9q1.059%200%201.908-.486a3.75%203.75%200%200%200%201.374-1.32q.512-.833.512-1.898v-.394q0-1.065-.512-1.899a3.66%203.66%200%200%200-1.374-1.308q-.85-.475-1.908-.475-1.083%200-1.944.51a3.7%203.7%200%200%200-1.362%201.389q-.5.869-.5%201.98t.5%201.991a3.8%203.8%200%200%200%201.362%201.401q.861.51%201.944.51M107.269%2020.695h-2.061l-.139-1.482q-.64.81-1.618%201.262-.978.45-2.165.451-1.245%200-2.223-.486a3.86%203.86%200%200%201-1.536-1.332%203.4%203.4%200%200%201-.56-1.922q0-1.134.606-1.991.605-.868%201.653-1.355%201.047-.498%202.386-.498a7.6%207.6%200%200%201%201.699.197%206.6%206.6%200%200%201%201.571.556v-.429q0-.844-.442-1.447a2.7%202.7%200%200%200-1.187-.938%204.1%204.1%200%200%200-1.653-.324%205.166%205.166%200%200%200-3.2%201.135l-.722-1.934a9.3%209.3%200%200%201%202.2-.95%208.3%208.3%200%200%201%202.258-.323q1.583%200%202.723.625a4.35%204.35%200%200%201%201.781%201.783q.629%201.146.629%202.71zm-5.517-1.783q.826%200%201.524-.336a2.9%202.9%200%200%200%201.129-.973q.442-.636.477-1.482v-.162a4.6%204.6%200%200%200-1.338-.683%204.6%204.6%200%200%200-1.502-.255q-1.175%200-1.955.556-.78.555-.78%201.424%200%20.544.314.984.327.43.873.683.56.244%201.258.244M116.424%2020.405q-1.221.521-2.362.521t-2.002-.486a3.5%203.5%200%200%201-1.339-1.366q-.477-.892-.477-2.05v-5.789h-2.037V9.116h2.153V6.222h2.27v2.894h3.399v2.119h-3.399v5.35q0%201.018.547%201.62.558.59%201.432.59.734%200%201.455-.44zM118.58%205.758q-.548%200-.92-.382a1.28%201.28%200%200%201-.373-.926q0-.545.373-.915.372-.382.92-.382.56%200%20.932.382.385.37.385.915t-.385.926a1.25%201.25%200%200%201-.932.382m1.188%2014.937h-2.388V9.116h2.388zM127.257%2020.926q-1.746%200-3.143-.787a5.85%205.85%200%200%201-2.2-2.142q-.803-1.366-.803-3.092%200-1.713.803-3.068a5.8%205.8%200%200%201%202.2-2.153q1.397-.8%203.143-.8%201.757%200%203.142.8a5.76%205.76%200%200%201%202.177%202.153q.803%201.355.803%203.068%200%201.725-.803%203.092a5.8%205.8%200%200%201-2.177%202.142q-1.385.787-3.142.787m-.012-2.13q1.06%200%201.886-.51a3.7%203.7%200%200%200%201.315-1.39q.489-.88.489-2.002%200-1.1-.489-1.969a3.6%203.6%200%200%200-1.315-1.389q-.827-.52-1.886-.52-1.047%200-1.885.52a3.7%203.7%200%200%200-1.327%201.39q-.477.868-.477%201.968%200%201.123.477%202.003a3.8%203.8%200%200%200%201.327%201.39q.837.509%201.885.509M145.816%2020.695h-2.386v-6.287q0-1.54-.849-2.455-.839-.915-2.258-.915-1.466%200-2.363.973-.896.972-.896%202.582v6.102h-2.386V9.116h2.013l.082%201.864a4.25%204.25%200%200%201%201.676-1.551q1.035-.544%202.432-.544%202.294%200%203.609%201.377%201.326%201.379%201.326%203.798zM166.178%2018.483a8.7%208.7%200%200%201-2.888%201.887q-1.664.672-3.631.672t-3.632-.672a8.7%208.7%200%200%201-2.898-1.887%208.9%208.9%200%200%201-1.908-2.871q-.676-1.656-.676-3.601%200-1.957.676-3.601a8.7%208.7%200%200%201%201.908-2.872%208.7%208.7%200%200%201%202.898-1.887q1.665-.671%203.632-.671%201.955%200%203.619.683%201.677.671%202.875%201.864l-1.78%201.806a6.2%206.2%200%200%200-2.094-1.54q-1.212-.567-2.654-.567-1.397%200-2.573.51a6%206%200%200%200-2.049%201.423%206.6%206.6%200%200%200-1.361%202.154q-.478%201.239-.478%202.698t.478%202.698a6.7%206.7%200%200%200%201.361%202.165%206.2%206.2%200%200%200%202.049%201.424q1.175.498%202.573.498%201.442%200%202.654-.556a6.2%206.2%200%200%200%202.083-1.552zM170.092%2020.695h-2.54V2.864h2.54zM177.534%2020.926q-1.745%200-3.143-.787a5.84%205.84%200%200%201-2.199-2.142q-.803-1.366-.803-3.092%200-1.713.803-3.068a5.8%205.8%200%200%201%202.199-2.153q1.398-.8%203.143-.8%201.758%200%203.142.8a5.75%205.75%200%200%201%202.176%202.153q.804%201.355.803%203.068%200%201.725-.803%203.092a5.8%205.8%200%200%201-2.176%202.142q-1.384.787-3.142.787m-.013-2.13q1.06%200%201.887-.51a3.7%203.7%200%200%200%201.315-1.39q.488-.88.488-2.002%200-1.1-.488-1.969a3.6%203.6%200%200%200-1.315-1.389q-.827-.52-1.887-.52a3.5%203.5%200%200%200-1.885.52%203.7%203.7%200%200%200-1.326%201.39q-.477.868-.477%201.968%200%201.123.477%202.003a3.8%203.8%200%200%200%201.326%201.39%203.56%203.56%200%200%200%201.885.509M196.1%2020.695h-2.026l-.082-1.864q-.64%201.018-1.676%201.563-1.025.532-2.433.532-2.28%200-3.607-1.378-1.316-1.39-1.316-3.797V9.116h2.387v6.287q0%201.54.837%202.455.84.915%202.258.915%201.468%200%202.364-.973.907-.984.907-2.582V9.116h2.387zM209.84%2020.695h-2.106l-.129-1.656a5.7%205.7%200%200%201-1.908%201.39q-1.105.497-2.433.497-1.676%200-3.002-.787a5.7%205.7%200%200%201-2.096-2.154q-.756-1.365-.756-3.08%200-1.724.756-3.08a5.7%205.7%200%200%201%202.096-2.153q1.326-.787%203.002-.787%201.257%200%202.329.451a5.5%205.5%200%200%201%201.862%201.262V3.327h2.385zm-6.18-1.9q1.059%200%201.908-.486a3.74%203.74%200%200%200%201.374-1.32q.512-.833.513-1.898v-.394q0-1.065-.513-1.899a3.65%203.65%200%200%200-1.374-1.308q-.849-.475-1.908-.475-1.082%200-1.943.51a3.7%203.7%200%200%200-1.363%201.389q-.5.869-.499%201.98%200%201.111.499%201.991a3.8%203.8%200%200%200%201.363%201.401q.86.51%201.943.51'/%3e%3c/g%3e%3c/svg%3e";
2
+ export {
3
+ a as default
4
+ };
@@ -0,0 +1,8 @@
1
+ import { EChartsOption } from 'echarts';
2
+ import { EChartsThemeOption } from './echarts-theme-option';
3
+ /**
4
+ * Calculates adjusted ECharts options with proper title layout.
5
+ * Sets title width based on grid/title margins and truncates with ellipsis if too long.
6
+ * Merges options with theme settings (options take precedence).
7
+ */
8
+ export declare function calculateTitleLayout(options: EChartsOption, containerWidth: number, theme?: EChartsThemeOption): EChartsOption;
@@ -0,0 +1,72 @@
1
+ function s(r, n) {
2
+ if (typeof r == "number")
3
+ return r;
4
+ if (typeof r == "string") {
5
+ if (r.endsWith("%")) {
6
+ const t = parseFloat(r);
7
+ if (!Number.isNaN(t))
8
+ return t / 100 * n;
9
+ }
10
+ if (r.endsWith("px")) {
11
+ const t = parseFloat(r);
12
+ if (!Number.isNaN(t))
13
+ return t;
14
+ }
15
+ }
16
+ }
17
+ function d(r, n) {
18
+ const t = r.grid, i = n?.grid, e = r.title, l = n?.title;
19
+ let f;
20
+ (t && !Array.isArray(t) || i) && (f = {
21
+ left: (t && !Array.isArray(t) ? t.left : void 0) ?? i?.left,
22
+ right: (t && !Array.isArray(t) ? t.right : void 0) ?? i?.right
23
+ });
24
+ let T;
25
+ return (e && !Array.isArray(e) || l) && (T = {
26
+ left: (e && !Array.isArray(e) ? e.left : void 0) ?? l?.left,
27
+ padding: (e && !Array.isArray(e) ? e.padding : void 0) ?? l?.padding
28
+ }), { grid: f, title: T };
29
+ }
30
+ function A(r, n, t) {
31
+ const { grid: i, title: e } = d(r, n);
32
+ let l;
33
+ if (e?.left !== void 0) {
34
+ const T = s(e.left, t);
35
+ T !== void 0 ? l = T : typeof e.left == "string" && ["center", "left", "right"].includes(e.left) ? l = typeof e.padding == "number" ? e.padding : 5 : l = 5;
36
+ } else
37
+ i?.left !== void 0 ? l = s(i.left, t) ?? s("15%", t) ?? 0 : l = s("15%", t) ?? 0;
38
+ let f;
39
+ if (i?.right !== void 0)
40
+ f = s(i.right, t) ?? s("10%", t) ?? 0;
41
+ else if (i?.left !== void 0 && e?.left === void 0)
42
+ f = s("10%", t) ?? 0;
43
+ else if (e?.left !== void 0) {
44
+ const T = s(e.left, t);
45
+ T !== void 0 ? f = T : typeof e.left == "string" && ["center", "left", "right"].includes(e.left) ? f = typeof e.padding == "number" ? e.padding : 5 : f = s("10%", t) ?? 0;
46
+ } else
47
+ f = s("10%", t) ?? 0;
48
+ return t - l - f;
49
+ }
50
+ function o(r, n, t) {
51
+ const i = r.title;
52
+ if (!i || Array.isArray(i))
53
+ return r;
54
+ const e = i.text;
55
+ if (!e || typeof e != "string")
56
+ return r;
57
+ const l = A(r, t, n);
58
+ return l <= 0 ? r : {
59
+ ...r,
60
+ title: {
61
+ ...i,
62
+ textStyle: {
63
+ ...i.textStyle,
64
+ width: l,
65
+ overflow: "truncate"
66
+ }
67
+ }
68
+ };
69
+ }
70
+ export {
71
+ o as calculateTitleLayout
72
+ };
@@ -0,0 +1,13 @@
1
+ import { EChartsOption } from 'echarts';
2
+ /**
3
+ * Detects if a chart configuration represents a horizontal bar chart.
4
+ *
5
+ * A horizontal bar chart has bars extending horizontally (left to right),
6
+ * which means the category axis is on the Y-axis instead of the X-axis.
7
+ *
8
+ * Detection logic:
9
+ * 1. Chart must have at least one bar series
10
+ * 2. The Y-axis must be of type 'category' (or have data which implies category)
11
+ * 3. The X-axis must NOT be of type 'category'
12
+ */
13
+ export declare function hasHorizontalBars(option: EChartsOption): boolean;
@@ -0,0 +1,13 @@
1
+ function x(e) {
2
+ const s = e.series;
3
+ if (!s || !(Array.isArray(s) ? s : [s]).some((r) => typeof r != "object" ? !1 : "type" in r && r.type === "bar")) return !1;
4
+ const t = e.xAxis, i = e.yAxis, o = Array.isArray(t) ? t[0] : t, y = Array.isArray(i) ? i[0] : i, n = (r) => {
5
+ if (!r || typeof r != "object") return !1;
6
+ const a = r;
7
+ return a.type === "category" || a.data !== void 0 && a.type === void 0;
8
+ }, A = n(y), f = n(o);
9
+ return A && !f;
10
+ }
11
+ export {
12
+ x as hasHorizontalBars
13
+ };
@@ -0,0 +1,19 @@
1
+ import { EChartsOption } from 'echarts';
2
+ import { EChartsRendererRef } from './echarts-renderer';
3
+ export type MavrikChartProps = {
4
+ readonly option: EChartsOption;
5
+ readonly className?: string;
6
+ } & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;
7
+ /**
8
+ * ECharts renderer with Mavrik theme applied.
9
+ *
10
+ * Automatically selects the correct theme variant based on chart type:
11
+ * - Vertical bars: gradient flows top-to-bottom
12
+ * - Horizontal bars: gradient flows left-to-right
13
+ *
14
+ * For custom themes, use EChartsRenderer directly.
15
+ */
16
+ export declare const MavrikChart: import('react').ForwardRefExoticComponent<{
17
+ readonly option: EChartsOption;
18
+ readonly className?: string;
19
+ } & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children"> & import('react').RefAttributes<EChartsRendererRef>>;
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ import { jsx as a } from "react/jsx-runtime";
3
+ import { forwardRef as f, useMemo as i } from "react";
4
+ import { EChartsRenderer as s } from "./echarts-renderer.js";
5
+ import { selectMavrikTheme as c } from "./mavrik-theme.js";
6
+ const p = f(function({ option: r, className: e, ...t }, m) {
7
+ const o = i(() => c(r), [r]);
8
+ return /* @__PURE__ */ a(s, { ref: m, option: r, theme: o, className: e, ...t });
9
+ });
10
+ export {
11
+ p as MavrikChart
12
+ };
@@ -0,0 +1,277 @@
1
+ declare const _default: {
2
+ "color": [
3
+ {
4
+ "type": "linear",
5
+ "x": 0,
6
+ "y": 0,
7
+ "x2": 1,
8
+ "y2": 0,
9
+ "colorStops": [
10
+ {
11
+ "offset": 0,
12
+ "color": "#C14E64"
13
+ },
14
+ {
15
+ "offset": 1,
16
+ "color": "#DF687D"
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "type": "linear",
22
+ "x": 0,
23
+ "y": 0,
24
+ "x2": 1,
25
+ "y2": 0,
26
+ "colorStops": [
27
+ {
28
+ "offset": 0,
29
+ "color": "#FFFFFF"
30
+ },
31
+ {
32
+ "offset": 1,
33
+ "color": "#FFFFFF"
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "type": "linear",
39
+ "x": 0,
40
+ "y": 0,
41
+ "x2": 1,
42
+ "y2": 0,
43
+ "colorStops": [
44
+ {
45
+ "offset": 0,
46
+ "color": "#1E6FDA"
47
+ },
48
+ {
49
+ "offset": 1,
50
+ "color": "#3F8CFF"
51
+ }
52
+ ]
53
+ }
54
+ ],
55
+ "backgroundColor": "#242731",
56
+ "textStyle": {
57
+ "fontFamily": "Poppins, sans-serif",
58
+ "fontWeight": 500
59
+ },
60
+ "title": {
61
+ "top": 32,
62
+ "left": 32,
63
+ "textStyle": {
64
+ "color": "#FFFFFF",
65
+ "fontSize": 16,
66
+ "fontWeight": 600
67
+ },
68
+ "subtextStyle": {
69
+ "color": "#A7A9AD"
70
+ }
71
+ },
72
+ "line": {
73
+ "itemStyle": {
74
+ "borderWidth": 1
75
+ },
76
+ "lineStyle": {
77
+ "width": 2
78
+ },
79
+ "areaStyle": {
80
+ "opacity": 0.15
81
+ },
82
+ "showSymbol": false,
83
+ "symbolSize": 5,
84
+ "symbol": "circle",
85
+ "smooth": false,
86
+ "sampling": "lttb"
87
+ },
88
+ "bar": {
89
+ "barGap": "25%",
90
+ "barCategoryGap": "25%"
91
+ },
92
+ "categoryAxis": {
93
+ "axisLine": {
94
+ "show": true,
95
+ "lineStyle": {
96
+ "color": "#3A3D46",
97
+ "type": "dashed"
98
+ }
99
+ },
100
+ "axisTick": {
101
+ "show": false
102
+ },
103
+ "axisLabel": {
104
+ "show": true,
105
+ "color": "#A7A9AD",
106
+ "hideOverlap": true
107
+ },
108
+ "nameLocation": "middle",
109
+ "nameTextStyle": {
110
+ "color": "#A7A9AD",
111
+ "fontSize": 11,
112
+ "fontWeight": 400
113
+ },
114
+ "splitLine": {
115
+ "show": false
116
+ }
117
+ },
118
+ "valueAxis": {
119
+ "axisLine": {
120
+ "show": false
121
+ },
122
+ "axisTick": {
123
+ "show": false
124
+ },
125
+ "axisLabel": {
126
+ "show": true,
127
+ "color": "#A7A9AD",
128
+ "hideOverlap": true
129
+ },
130
+ "nameLocation": "middle",
131
+ "nameTextStyle": {
132
+ "color": "#A7A9AD",
133
+ "fontSize": 11,
134
+ "fontWeight": 400
135
+ },
136
+ "splitLine": {
137
+ "show": true,
138
+ "lineStyle": {
139
+ "color": [
140
+ "#3A3D46"
141
+ ],
142
+ "type": "dashed"
143
+ }
144
+ }
145
+ },
146
+ "logAxis": {
147
+ "axisLine": {
148
+ "show": false
149
+ },
150
+ "axisTick": {
151
+ "show": false
152
+ },
153
+ "axisLabel": {
154
+ "show": true,
155
+ "color": "#A7A9AD",
156
+ "hideOverlap": true
157
+ },
158
+ "nameLocation": "middle",
159
+ "nameTextStyle": {
160
+ "color": "#A7A9AD",
161
+ "fontSize": 11,
162
+ "fontWeight": 400
163
+ },
164
+ "splitLine": {
165
+ "show": true,
166
+ "lineStyle": {
167
+ "color": [
168
+ "#3A3D46"
169
+ ],
170
+ "type": "dashed"
171
+ }
172
+ }
173
+ },
174
+ "timeAxis": {
175
+ "axisLine": {
176
+ "show": true,
177
+ "lineStyle": {
178
+ "color": "#3A3D46"
179
+ }
180
+ },
181
+ "axisTick": {
182
+ "show": false
183
+ },
184
+ "axisLabel": {
185
+ "show": true,
186
+ "color": "#A7A9AD",
187
+ "hideOverlap": true
188
+ },
189
+ "nameLocation": "middle",
190
+ "nameTextStyle": {
191
+ "color": "#A7A9AD",
192
+ "fontSize": 11,
193
+ "fontWeight": 400
194
+ },
195
+ "splitLine": {
196
+ "show": false
197
+ }
198
+ },
199
+ "legend": {
200
+ "top": 82,
201
+ "left": "auto",
202
+ "right": 32,
203
+ "icon": "circle",
204
+ "itemGap": 22,
205
+ "itemWidth": 12,
206
+ "itemHeight": 12,
207
+ "textStyle": {
208
+ "color": "#A7A9AD",
209
+ "fontSize": 11
210
+ }
211
+ },
212
+ "grid": {
213
+ "top": 132,
214
+ "left": 32,
215
+ "right": 32,
216
+ "bottom": 32,
217
+ "outerBoundsMode": "same",
218
+ "outerBoundsContain": "axisLabel"
219
+ },
220
+ "dataZoom": {
221
+ "backgroundColor": "rgba(36, 39, 49, 0)",
222
+ "borderColor": "#3A3D46",
223
+ "borderRadius": 4,
224
+ "dataBackground": {
225
+ "lineStyle": {
226
+ "color": "#606060",
227
+ "width": 1
228
+ },
229
+ "areaStyle": {
230
+ "color": "rgba(96, 96, 96, 0.3)"
231
+ }
232
+ },
233
+ "selectedDataBackground": {
234
+ "lineStyle": {
235
+ "color": "#b36674",
236
+ "width": 1
237
+ },
238
+ "areaStyle": {
239
+ "color": "rgba(164, 91, 105, 0.5)"
240
+ }
241
+ },
242
+ "fillerColor": "rgba(82, 45, 52, 0.35)",
243
+ "handleStyle": {
244
+ "color": "#C14E64",
245
+ "borderColor": "#C14E64"
246
+ },
247
+ "moveHandleStyle": {
248
+ "color": "#b36674"
249
+ },
250
+ "brushStyle": {
251
+ "color": "rgba(95, 58, 65, 0.2)"
252
+ },
253
+ "emphasis": {
254
+ "handleStyle": {
255
+ "color": "rgb(209, 123, 140)",
256
+ "borderColor": "rgb(209, 123, 140)"
257
+ }
258
+ },
259
+ "handleSize": "100%",
260
+ "textStyle": {
261
+ "color": "#A7A9AD"
262
+ }
263
+ },
264
+ "markPoint": {
265
+ "label": {
266
+ "color": "#A7A9AD"
267
+ },
268
+ "emphasis": {
269
+ "label": {
270
+ "color": "#FFFFFF"
271
+ }
272
+ }
273
+ }
274
+ }
275
+ ;
276
+
277
+ export default _default;
@@ -0,0 +1,33 @@
1
+ const o = [{ type: "linear", x: 0, y: 0, x2: 1, y2: 0, colorStops: [{ offset: 0, color: "#C14E64" }, { offset: 1, color: "#DF687D" }] }, { type: "linear", x: 0, y: 0, x2: 1, y2: 0, colorStops: [{ offset: 0, color: "#FFFFFF" }, { offset: 1, color: "#FFFFFF" }] }, { type: "linear", x: 0, y: 0, x2: 1, y2: 0, colorStops: [{ offset: 0, color: "#1E6FDA" }, { offset: 1, color: "#3F8CFF" }] }], e = "#242731", t = { fontFamily: "Poppins, sans-serif", fontWeight: 500 }, l = { top: 32, left: 32, textStyle: { color: "#FFFFFF", fontSize: 16, fontWeight: 600 }, subtextStyle: { color: "#A7A9AD" } }, r = { itemStyle: { borderWidth: 1 }, lineStyle: { width: 2 }, areaStyle: { opacity: 0.15 }, showSymbol: !1, symbolSize: 5, symbol: "circle", smooth: !1, sampling: "lttb" }, i = { barGap: "25%", barCategoryGap: "25%" }, a = { axisLine: { show: !0, lineStyle: { color: "#3A3D46", type: "dashed" } }, axisTick: { show: !1 }, axisLabel: { show: !0, color: "#A7A9AD", hideOverlap: !0 }, nameLocation: "middle", nameTextStyle: { color: "#A7A9AD", fontSize: 11, fontWeight: 400 }, splitLine: { show: !1 } }, s = { axisLine: { show: !1 }, axisTick: { show: !1 }, axisLabel: { show: !0, color: "#A7A9AD", hideOverlap: !0 }, nameLocation: "middle", nameTextStyle: { color: "#A7A9AD", fontSize: 11, fontWeight: 400 }, splitLine: { show: !0, lineStyle: { color: ["#3A3D46"], type: "dashed" } } }, n = { axisLine: { show: !1 }, axisTick: { show: !1 }, axisLabel: { show: !0, color: "#A7A9AD", hideOverlap: !0 }, nameLocation: "middle", nameTextStyle: { color: "#A7A9AD", fontSize: 11, fontWeight: 400 }, splitLine: { show: !0, lineStyle: { color: ["#3A3D46"], type: "dashed" } } }, c = { axisLine: { show: !0, lineStyle: { color: "#3A3D46" } }, axisTick: { show: !1 }, axisLabel: { show: !0, color: "#A7A9AD", hideOverlap: !0 }, nameLocation: "middle", nameTextStyle: { color: "#A7A9AD", fontSize: 11, fontWeight: 400 }, splitLine: { show: !1 } }, d = { top: 82, left: "auto", right: 32, icon: "circle", itemGap: 22, itemWidth: 12, itemHeight: 12, textStyle: { color: "#A7A9AD", fontSize: 11 } }, h = { top: 132, left: 32, right: 32, bottom: 32, outerBoundsMode: "same", outerBoundsContain: "axisLabel" }, A = { backgroundColor: "rgba(36, 39, 49, 0)", borderColor: "#3A3D46", borderRadius: 4, dataBackground: { lineStyle: { color: "#606060", width: 1 }, areaStyle: { color: "rgba(96, 96, 96, 0.3)" } }, selectedDataBackground: { lineStyle: { color: "#b36674", width: 1 }, areaStyle: { color: "rgba(164, 91, 105, 0.5)" } }, fillerColor: "rgba(82, 45, 52, 0.35)", handleStyle: { color: "#C14E64", borderColor: "#C14E64" }, moveHandleStyle: { color: "#b36674" }, brushStyle: { color: "rgba(95, 58, 65, 0.2)" }, emphasis: { handleStyle: { color: "rgb(209, 123, 140)", borderColor: "rgb(209, 123, 140)" } }, handleSize: "100%", textStyle: { color: "#A7A9AD" } }, y = { label: { color: "#A7A9AD" }, emphasis: { label: { color: "#FFFFFF" } } }, f = {
2
+ color: o,
3
+ backgroundColor: e,
4
+ textStyle: t,
5
+ title: l,
6
+ line: r,
7
+ bar: i,
8
+ categoryAxis: a,
9
+ valueAxis: s,
10
+ logAxis: n,
11
+ timeAxis: c,
12
+ legend: d,
13
+ grid: h,
14
+ dataZoom: A,
15
+ markPoint: y
16
+ };
17
+ export {
18
+ e as backgroundColor,
19
+ i as bar,
20
+ a as categoryAxis,
21
+ o as color,
22
+ A as dataZoom,
23
+ f as default,
24
+ h as grid,
25
+ d as legend,
26
+ r as line,
27
+ n as logAxis,
28
+ y as markPoint,
29
+ t as textStyle,
30
+ c as timeAxis,
31
+ l as title,
32
+ s as valueAxis
33
+ };
@@ -1,3 +1,5 @@
1
+ import { EChartsOption } from 'echarts';
2
+ /** Default Mavrik theme with vertical gradients (for vertical bars and other charts) */
1
3
  export declare const MAVRIK_THEME: {
2
4
  readonly name: "mavrik";
3
5
  readonly config: {
@@ -229,3 +231,243 @@ export declare const MAVRIK_THEME: {
229
231
  };
230
232
  };
231
233
  };
234
+ /** Mavrik theme variant with horizontal gradients (for horizontal bar charts) */
235
+ export declare const MAVRIK_THEME_HORIZONTAL: {
236
+ readonly name: "mavrik-horizontal";
237
+ readonly config: {
238
+ color: {
239
+ type: string;
240
+ x: number;
241
+ y: number;
242
+ x2: number;
243
+ y2: number;
244
+ colorStops: {
245
+ offset: number;
246
+ color: string;
247
+ }[];
248
+ }[];
249
+ backgroundColor: string;
250
+ textStyle: {
251
+ fontFamily: string;
252
+ fontWeight: number;
253
+ };
254
+ title: {
255
+ top: number;
256
+ left: number;
257
+ textStyle: {
258
+ color: string;
259
+ fontSize: number;
260
+ fontWeight: number;
261
+ };
262
+ subtextStyle: {
263
+ color: string;
264
+ };
265
+ };
266
+ line: {
267
+ itemStyle: {
268
+ borderWidth: number;
269
+ };
270
+ lineStyle: {
271
+ width: number;
272
+ };
273
+ areaStyle: {
274
+ opacity: number;
275
+ };
276
+ showSymbol: boolean;
277
+ symbolSize: number;
278
+ symbol: string;
279
+ smooth: boolean;
280
+ sampling: string;
281
+ };
282
+ bar: {
283
+ barGap: string;
284
+ barCategoryGap: string;
285
+ };
286
+ categoryAxis: {
287
+ axisLine: {
288
+ show: boolean;
289
+ lineStyle: {
290
+ color: string;
291
+ type: string;
292
+ };
293
+ };
294
+ axisTick: {
295
+ show: boolean;
296
+ };
297
+ axisLabel: {
298
+ show: boolean;
299
+ color: string;
300
+ hideOverlap: boolean;
301
+ };
302
+ nameLocation: string;
303
+ nameTextStyle: {
304
+ color: string;
305
+ fontSize: number;
306
+ fontWeight: number;
307
+ };
308
+ splitLine: {
309
+ show: boolean;
310
+ };
311
+ };
312
+ valueAxis: {
313
+ axisLine: {
314
+ show: boolean;
315
+ };
316
+ axisTick: {
317
+ show: boolean;
318
+ };
319
+ axisLabel: {
320
+ show: boolean;
321
+ color: string;
322
+ hideOverlap: boolean;
323
+ };
324
+ nameLocation: string;
325
+ nameTextStyle: {
326
+ color: string;
327
+ fontSize: number;
328
+ fontWeight: number;
329
+ };
330
+ splitLine: {
331
+ show: boolean;
332
+ lineStyle: {
333
+ color: string[];
334
+ type: string;
335
+ };
336
+ };
337
+ };
338
+ logAxis: {
339
+ axisLine: {
340
+ show: boolean;
341
+ };
342
+ axisTick: {
343
+ show: boolean;
344
+ };
345
+ axisLabel: {
346
+ show: boolean;
347
+ color: string;
348
+ hideOverlap: boolean;
349
+ };
350
+ nameLocation: string;
351
+ nameTextStyle: {
352
+ color: string;
353
+ fontSize: number;
354
+ fontWeight: number;
355
+ };
356
+ splitLine: {
357
+ show: boolean;
358
+ lineStyle: {
359
+ color: string[];
360
+ type: string;
361
+ };
362
+ };
363
+ };
364
+ timeAxis: {
365
+ axisLine: {
366
+ show: boolean;
367
+ lineStyle: {
368
+ color: string;
369
+ };
370
+ };
371
+ axisTick: {
372
+ show: boolean;
373
+ };
374
+ axisLabel: {
375
+ show: boolean;
376
+ color: string;
377
+ hideOverlap: boolean;
378
+ };
379
+ nameLocation: string;
380
+ nameTextStyle: {
381
+ color: string;
382
+ fontSize: number;
383
+ fontWeight: number;
384
+ };
385
+ splitLine: {
386
+ show: boolean;
387
+ };
388
+ };
389
+ legend: {
390
+ top: number;
391
+ left: string;
392
+ right: number;
393
+ icon: string;
394
+ itemGap: number;
395
+ itemWidth: number;
396
+ itemHeight: number;
397
+ textStyle: {
398
+ color: string;
399
+ fontSize: number;
400
+ };
401
+ };
402
+ grid: {
403
+ top: number;
404
+ left: number;
405
+ right: number;
406
+ bottom: number;
407
+ outerBoundsMode: string;
408
+ outerBoundsContain: string;
409
+ };
410
+ dataZoom: {
411
+ backgroundColor: string;
412
+ borderColor: string;
413
+ borderRadius: number;
414
+ dataBackground: {
415
+ lineStyle: {
416
+ color: string;
417
+ width: number;
418
+ };
419
+ areaStyle: {
420
+ color: string;
421
+ };
422
+ };
423
+ selectedDataBackground: {
424
+ lineStyle: {
425
+ color: string;
426
+ width: number;
427
+ };
428
+ areaStyle: {
429
+ color: string;
430
+ };
431
+ };
432
+ fillerColor: string;
433
+ handleStyle: {
434
+ color: string;
435
+ borderColor: string;
436
+ };
437
+ moveHandleStyle: {
438
+ color: string;
439
+ };
440
+ brushStyle: {
441
+ color: string;
442
+ };
443
+ emphasis: {
444
+ handleStyle: {
445
+ color: string;
446
+ borderColor: string;
447
+ };
448
+ };
449
+ handleSize: string;
450
+ textStyle: {
451
+ color: string;
452
+ };
453
+ };
454
+ markPoint: {
455
+ label: {
456
+ color: string;
457
+ };
458
+ emphasis: {
459
+ label: {
460
+ color: string;
461
+ };
462
+ };
463
+ };
464
+ };
465
+ };
466
+ export type MavrikTheme = typeof MAVRIK_THEME | typeof MAVRIK_THEME_HORIZONTAL;
467
+ /**
468
+ * Selects the appropriate Mavrik theme variant based on chart options.
469
+ *
470
+ * - Returns horizontal gradient theme for horizontal bar charts
471
+ * - Returns vertical gradient theme for all other chart types
472
+ */
473
+ export declare function selectMavrikTheme(option: EChartsOption): MavrikTheme;
@@ -1,11 +1,23 @@
1
- import { isEChartsThemeOption as r } from "./echarts-theme-option.js";
2
- import o from "./mavrik-theme.json.js";
3
- if (!r(o))
1
+ import { hasHorizontalBars as t } from "./detect-horizontal-bars.js";
2
+ import { isEChartsThemeOption as o } from "./echarts-theme-option.js";
3
+ import r from "./mavrik-theme-horizontal.json.js";
4
+ import i from "./mavrik-theme.json.js";
5
+ if (!o(i))
4
6
  throw new Error("Invalid mavrik theme configuration");
5
- const t = {
7
+ if (!o(r))
8
+ throw new Error("Invalid mavrik horizontal theme configuration");
9
+ const e = {
6
10
  name: "mavrik",
7
- config: o
11
+ config: i
12
+ }, m = {
13
+ name: "mavrik-horizontal",
14
+ config: r
8
15
  };
16
+ function l(n) {
17
+ return t(n) ? m : e;
18
+ }
9
19
  export {
10
- t as MAVRIK_THEME
20
+ e as MAVRIK_THEME,
21
+ m as MAVRIK_THEME_HORIZONTAL,
22
+ l as selectMavrikTheme
11
23
  };
@@ -136,7 +136,9 @@ declare const _default: {
136
136
  "splitLine": {
137
137
  "show": true,
138
138
  "lineStyle": {
139
- "color": ["#3A3D46"],
139
+ "color": [
140
+ "#3A3D46"
141
+ ],
140
142
  "type": "dashed"
141
143
  }
142
144
  }
@@ -162,7 +164,9 @@ declare const _default: {
162
164
  "splitLine": {
163
165
  "show": true,
164
166
  "lineStyle": {
165
- "color": ["#3A3D46"],
167
+ "color": [
168
+ "#3A3D46"
169
+ ],
166
170
  "type": "dashed"
167
171
  }
168
172
  }
@@ -0,0 +1,6 @@
1
+ import { EChartsOption } from 'echarts';
2
+ /**
3
+ * Removes problematic interactive components from chart options.
4
+ * These components have known issues with ECharts' cleanup lifecycle.
5
+ */
6
+ export declare function sanitizeChartOptions(option: EChartsOption): EChartsOption;
@@ -0,0 +1,9 @@
1
+ const n = /* @__PURE__ */ new Set(["axisPointer"]);
2
+ function i(t) {
3
+ return Object.fromEntries(
4
+ Object.entries(t).filter(([e]) => !n.has(e))
5
+ );
6
+ }
7
+ export {
8
+ i as sanitizeChartOptions
9
+ };
@@ -9,7 +9,6 @@ export type UseChartInstanceProps = {
9
9
  };
10
10
  export type UseChartInstanceReturn = {
11
11
  containerRef: React.RefObject<HTMLDivElement | null>;
12
- isReady: boolean;
13
12
  downloadChart: () => Promise<void>;
14
13
  };
15
14
  /**
@@ -1,46 +1,63 @@
1
1
  "use client";
2
- import { init as f, registerTheme as h } from "echarts";
3
- import { useRef as i, useState as w, useEffect as d, useCallback as g } from "react";
4
- const u = /* @__PURE__ */ new Set();
5
- function R(e, n) {
6
- u.has(e) || (h(e, n), u.add(e));
7
- }
8
- function b({ options: e, theme: n }) {
9
- const o = i(null), c = i(null), [s, a] = w(!1);
10
- d(() => {
11
- if (!o.current) return;
12
- n && R(n.name, n.config);
13
- const r = f(o.current, n?.name, {
14
- renderer: "svg"
15
- });
16
- c.current = r, r.setOption(e), a(!0);
17
- const t = new ResizeObserver(() => {
18
- r.resize();
2
+ import { useRef as d, useState as I, useEffect as w, useCallback as W } from "react";
3
+ import { calculateTitleLayout as p } from "./calculate-title-layout.js";
4
+ import { sanitizeChartOptions as g } from "./sanitize-chart-options.js";
5
+ import { addWatermarkToOptions as h } from "./watermark-graphic.js";
6
+ const z = /* @__PURE__ */ new Set();
7
+ function D({ options: i, theme: t }) {
8
+ const e = d(null), c = d(null), O = d(i), m = d(t?.config), [y, R] = I(!1);
9
+ O.current = i, m.current = t?.config, w(() => {
10
+ const s = e.current;
11
+ if (!s) return;
12
+ let n = !0, r;
13
+ const C = new ResizeObserver((o) => {
14
+ const a = o[0], u = c.current;
15
+ if (!a || !u) return;
16
+ const f = a.contentRect.width, l = g(O.current), v = h(
17
+ p(l, f, m.current)
18
+ );
19
+ u.setOption(v), u.resize();
19
20
  });
20
- return t.observe(o.current), () => {
21
- t.disconnect(), r.dispose(), c.current = null, a(!1);
21
+ return C.observe(s), (async () => {
22
+ try {
23
+ const o = await import("echarts");
24
+ if (!n || !e.current) return;
25
+ t && !z.has(t.name) && (o.registerTheme(t.name, t.config), z.add(t.name));
26
+ const a = o.getInstanceByDom(e.current);
27
+ a && a.dispose(), r = o.init(e.current, t?.name, {
28
+ renderer: "svg"
29
+ }), c.current = r;
30
+ const u = e.current.clientWidth, f = g(i), l = h(
31
+ p(f, u, t?.config)
32
+ );
33
+ r.setOption(l), r.resize(), R(!0);
34
+ } catch (o) {
35
+ console.error("Failed to load echarts", o);
36
+ }
37
+ })(), () => {
38
+ n = !1, C.disconnect(), r && r.dispose(), c.current = null, R(!1);
22
39
  };
23
- }, [e, n]), d(() => {
24
- !c.current || !s || c.current.setOption(e);
25
- }, [e, s]);
26
- const l = g(async () => {
27
- if (!c.current)
28
- throw new Error("Chart is not initialized");
29
- try {
30
- const r = c.current.getDataURL({
31
- type: "svg"
32
- }), t = document.createElement("a");
33
- t.download = `chart-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.svg`, t.href = r, document.body.appendChild(t), t.click(), document.body.removeChild(t);
34
- } catch (r) {
35
- throw console.error("Failed to download chart:", r), new Error("Failed to download chart");
36
- }
40
+ }, [t, i]), w(() => {
41
+ if (!y || !c.current || !e.current) return;
42
+ const s = e.current.clientWidth, n = g(i), r = h(
43
+ p(n, s, t?.config)
44
+ );
45
+ c.current.setOption(r);
46
+ }, [y, i, t?.config]);
47
+ const b = W(async () => {
48
+ if (!c.current) return;
49
+ const s = c.current.getDataURL({
50
+ type: "png",
51
+ pixelRatio: 2,
52
+ backgroundColor: "#fff"
53
+ }), n = document.createElement("a");
54
+ n.download = `chart-${(/* @__PURE__ */ new Date()).toISOString()}.png`, n.href = s, document.body.appendChild(n), n.click(), document.body.removeChild(n);
37
55
  }, []);
38
56
  return {
39
- containerRef: o,
40
- isReady: s,
41
- downloadChart: l
57
+ containerRef: e,
58
+ downloadChart: b
42
59
  };
43
60
  }
44
61
  export {
45
- b as useChartInstance
62
+ D as useChartInstance
46
63
  };
@@ -0,0 +1,12 @@
1
+ import { GraphicComponentOption } from 'echarts';
2
+ /**
3
+ * Watermark graphic element for ECharts charts.
4
+ * This is applied via setOption(), not via theme (themes don't properly merge graphic components).
5
+ */
6
+ export declare const WATERMARK_GRAPHIC: GraphicComponentOption;
7
+ /**
8
+ * Merges watermark graphic into existing ECharts options.
9
+ */
10
+ export declare function addWatermarkToOptions<T extends {
11
+ graphic?: GraphicComponentOption | GraphicComponentOption[];
12
+ }>(options: T): T;
@@ -0,0 +1,25 @@
1
+ import o from "../../assets/vc-logo.svg.js";
2
+ const a = 210, c = 24, i = {
3
+ type: "image",
4
+ left: "center",
5
+ top: "middle",
6
+ style: {
7
+ image: o,
8
+ width: a,
9
+ height: c
10
+ },
11
+ z: 100,
12
+ silent: !0
13
+ };
14
+ function s(r) {
15
+ const e = r.graphic;
16
+ let t;
17
+ return e === void 0 ? t = i : Array.isArray(e) ? t = [...e, i] : t = [e, i], {
18
+ ...r,
19
+ graphic: t
20
+ };
21
+ }
22
+ export {
23
+ i as WATERMARK_GRAPHIC,
24
+ s as addWatermarkToOptions
25
+ };
package/dist/index.d.ts CHANGED
@@ -6,7 +6,8 @@ export { EChartsRenderer, type EChartsRendererProps, type EChartsRendererRef, ty
6
6
  export { EChartsThemeOption, isEChartsThemeOption } from './components/echarts-renderer/echarts-theme-option';
7
7
  export { EChartsChartOption, isEChartsChartOption } from './components/echarts-renderer/echarts-chart-option';
8
8
  export { useChartInstance, type UseChartInstanceProps, type UseChartInstanceReturn, } from './components/echarts-renderer/use-chart-instance';
9
- export { MAVRIK_THEME } from './components/echarts-renderer/mavrik-theme';
9
+ export { MavrikChart, type MavrikChartProps } from './components/echarts-renderer/mavrik-chart';
10
+ export { MAVRIK_THEME, MAVRIK_THEME_HORIZONTAL } from './components/echarts-renderer/mavrik-theme';
10
11
  export { ClientModal } from './components/client-modal/client-modal';
11
12
  export { CopyButton } from './components/copy-button/copy-button';
12
13
  export { DecoratedIcon } from './components/decorated-icon/decorated-icon';
package/dist/index.js CHANGED
@@ -2,68 +2,71 @@ import { AnimatedLoader as t } from "./components/animated-loader/animated-loade
2
2
  import { Badge as p } from "./components/badge/badge.js";
3
3
  import { Box as x } from "./components/box/box.js";
4
4
  import { Button as n } from "./components/button/button.js";
5
- import { EChartsRenderer as d } from "./components/echarts-renderer/echarts-renderer.js";
5
+ import { EChartsRenderer as i } from "./components/echarts-renderer/echarts-renderer.js";
6
6
  import { EChartsThemeOption as u, isEChartsThemeOption as h } from "./components/echarts-renderer/echarts-theme-option.js";
7
- import { EChartsChartOption as l, isEChartsChartOption as C } from "./components/echarts-renderer/echarts-chart-option.js";
7
+ import { EChartsChartOption as C, isEChartsChartOption as l } from "./components/echarts-renderer/echarts-chart-option.js";
8
8
  import { useChartInstance as T } from "./components/echarts-renderer/use-chart-instance.js";
9
- import { MAVRIK_THEME as E } from "./components/echarts-renderer/mavrik-theme.js";
10
- import { ClientModal as M } from "./components/client-modal/client-modal.js";
11
- import { CopyButton as w } from "./components/copy-button/copy-button.js";
12
- import { DecoratedIcon as D } from "./components/decorated-icon/decorated-icon.js";
13
- import { DropdownMenu as P, DropdownMenuItem as A } from "./components/dropdown-menu/dropdown-menu.js";
14
- import { ErrorBoundary as y } from "./components/error-boundary/error-boundary.js";
15
- import { ScrollArea as R } from "./components/scroll-area/index.js";
16
- import { Icon as b } from "./components/icon/icon.js";
17
- import { IconButton as F } from "./components/icon-button/icon-button.js";
18
- import { InputButton as K } from "./components/input-button/input-button.js";
19
- import { MountSvgSprite as V } from "./components/mount-svg-sprite/mount-svg-sprite.js";
20
- import { NotFoundComponent as j } from "./components/not-found-component/not-found-component.js";
21
- import { PagePadding as z } from "./components/page-padding/page-padding.js";
22
- import { ProtocolLogo as J } from "./components/protocol-logo/protocol-logo.js";
23
- import { Skeleton as W } from "./components/skeleton/skeleton.js";
24
- import { Switch as Y } from "./components/switch/switch.js";
25
- import { TextInput as $ } from "./components/text-input/text-input.js";
26
- import { Tooltip as ro } from "./components/tooltip/tooltip.js";
27
- import { TooltipProvider as eo } from "./components/tooltip-provider/tooltip-provider.js";
28
- import { TouchTarget as mo } from "./components/touch-target/touch-target.js";
29
- import { twMerge as fo } from "./lib/tailwind-merge.js";
30
- import { UserDropdown as ao } from "./components/user-dropdown/user-dropdown.js";
31
- import { UserDropdownMobile as uo } from "./components/user-dropdown-mobile/user-dropdown-mobile.js";
32
- import { useScrollToBottom as so } from "./hooks/use-scroll-to-bottom.js";
9
+ import { MavrikChart as E } from "./components/echarts-renderer/mavrik-chart.js";
10
+ import { MAVRIK_THEME as B, MAVRIK_THEME_HORIZONTAL as g } from "./components/echarts-renderer/mavrik-theme.js";
11
+ import { ClientModal as O } from "./components/client-modal/client-modal.js";
12
+ import { CopyButton as A } from "./components/copy-button/copy-button.js";
13
+ import { DecoratedIcon as P } from "./components/decorated-icon/decorated-icon.js";
14
+ import { DropdownMenu as v, DropdownMenuItem as H } from "./components/dropdown-menu/dropdown-menu.js";
15
+ import { ErrorBoundary as _ } from "./components/error-boundary/error-boundary.js";
16
+ import { ScrollArea as y } from "./components/scroll-area/index.js";
17
+ import { Icon as N } from "./components/icon/icon.js";
18
+ import { IconButton as V } from "./components/icon-button/icon-button.js";
19
+ import { InputButton as F } from "./components/input-button/input-button.js";
20
+ import { MountSvgSprite as j } from "./components/mount-svg-sprite/mount-svg-sprite.js";
21
+ import { NotFoundComponent as z } from "./components/not-found-component/not-found-component.js";
22
+ import { PagePadding as J } from "./components/page-padding/page-padding.js";
23
+ import { ProtocolLogo as W } from "./components/protocol-logo/protocol-logo.js";
24
+ import { Skeleton as Y } from "./components/skeleton/skeleton.js";
25
+ import { Switch as oo } from "./components/switch/switch.js";
26
+ import { TextInput as to } from "./components/text-input/text-input.js";
27
+ import { Tooltip as po } from "./components/tooltip/tooltip.js";
28
+ import { TooltipProvider as xo } from "./components/tooltip-provider/tooltip-provider.js";
29
+ import { TouchTarget as no } from "./components/touch-target/touch-target.js";
30
+ import { twMerge as io } from "./lib/tailwind-merge.js";
31
+ import { UserDropdown as ho } from "./components/user-dropdown/user-dropdown.js";
32
+ import { UserDropdownMobile as Co } from "./components/user-dropdown-mobile/user-dropdown-mobile.js";
33
+ import { useScrollToBottom as Mo } from "./hooks/use-scroll-to-bottom.js";
33
34
  export {
34
35
  t as AnimatedLoader,
35
36
  p as Badge,
36
37
  x as Box,
37
38
  n as Button,
38
- M as ClientModal,
39
- w as CopyButton,
40
- D as DecoratedIcon,
41
- P as DropdownMenu,
42
- A as DropdownMenuItem,
43
- l as EChartsChartOption,
44
- d as EChartsRenderer,
39
+ O as ClientModal,
40
+ A as CopyButton,
41
+ P as DecoratedIcon,
42
+ v as DropdownMenu,
43
+ H as DropdownMenuItem,
44
+ C as EChartsChartOption,
45
+ i as EChartsRenderer,
45
46
  u as EChartsThemeOption,
46
- y as ErrorBoundary,
47
- b as Icon,
48
- F as IconButton,
49
- K as InputButton,
50
- E as MAVRIK_THEME,
51
- V as MountSvgSprite,
52
- j as NotFoundComponent,
53
- z as PagePadding,
54
- J as ProtocolLogo,
55
- R as ScrollArea,
56
- W as Skeleton,
57
- Y as Switch,
58
- $ as TextInput,
59
- ro as Tooltip,
60
- eo as TooltipProvider,
61
- mo as TouchTarget,
62
- ao as UserDropdown,
63
- uo as UserDropdownMobile,
64
- C as isEChartsChartOption,
47
+ _ as ErrorBoundary,
48
+ N as Icon,
49
+ V as IconButton,
50
+ F as InputButton,
51
+ B as MAVRIK_THEME,
52
+ g as MAVRIK_THEME_HORIZONTAL,
53
+ E as MavrikChart,
54
+ j as MountSvgSprite,
55
+ z as NotFoundComponent,
56
+ J as PagePadding,
57
+ W as ProtocolLogo,
58
+ y as ScrollArea,
59
+ Y as Skeleton,
60
+ oo as Switch,
61
+ to as TextInput,
62
+ po as Tooltip,
63
+ xo as TooltipProvider,
64
+ no as TouchTarget,
65
+ ho as UserDropdown,
66
+ Co as UserDropdownMobile,
67
+ l as isEChartsChartOption,
65
68
  h as isEChartsThemeOption,
66
- fo as twMerge,
69
+ io as twMerge,
67
70
  T as useChartInstance,
68
- so as useScrollToBottom
71
+ Mo as useScrollToBottom
69
72
  };
@@ -1,34 +1,51 @@
1
- import { createCanvas as f } from "canvas";
2
- import { randomUUID as m } from "node:crypto";
3
- import { createRequire as u } from "node:module";
4
- const p = u(import.meta.url), s = p("echarts");
5
- function l(r) {
1
+ import { createCanvas as u } from "canvas";
2
+ import { randomUUID as l } from "node:crypto";
3
+ import { createRequire as d } from "node:module";
4
+ import { calculateTitleLayout as O } from "../components/echarts-renderer/calculate-title-layout.js";
5
+ import { addWatermarkToOptions as y } from "../components/echarts-renderer/watermark-graphic.js";
6
+ const T = d(import.meta.url), b = /* @__PURE__ */ new Set([
7
+ "aria",
8
+ // Tries to set DOM attributes which node-canvas doesn't implement
9
+ "toolbox",
10
+ // Export/zoom/reset buttons - not useful in static image
11
+ "dataZoom",
12
+ // Interactive range slider
13
+ "brush",
14
+ // Selection tool
15
+ "axisPointer"
16
+ // Crosshair on hover
17
+ ]);
18
+ function j(r) {
6
19
  if (!r || typeof r != "object" || Array.isArray(r))
7
20
  return { animation: !1 };
8
- const e = { ...r };
9
- return "aria" in e && delete e.aria, e.animation = !1, e;
21
+ const t = Object.fromEntries(
22
+ Object.entries(r).filter(([e]) => !b.has(e))
23
+ );
24
+ return t.animation = !1, t;
10
25
  }
11
- function h({
26
+ function g({
12
27
  option: r,
13
- theme: e,
14
- width: a = 800,
15
- height: n = 600,
28
+ theme: t,
29
+ width: e = 800,
30
+ height: o = 600,
16
31
  devicePixelRatio: c = 2
17
32
  }) {
18
- let t;
19
- e && typeof e == "object" && (t = `theme-${m()}`, s.registerTheme(t, e));
20
- const i = f(a, n), o = s.init(i, t, {
33
+ const n = T("echarts");
34
+ let a;
35
+ t && typeof t == "object" && (a = `theme-${l()}`, n.registerTheme(a, t));
36
+ const i = u(e, o), s = n.init(i, a, {
21
37
  renderer: "canvas",
22
38
  devicePixelRatio: c,
23
- width: a,
24
- height: n
39
+ width: e,
40
+ height: o
25
41
  });
26
42
  try {
27
- return o.setOption(l(r)), i.toBuffer("image/png");
43
+ const m = j(r), f = O(m, e, t), p = y(f);
44
+ return s.setOption(p), i.toBuffer("image/png");
28
45
  } finally {
29
- o.dispose();
46
+ s.dispose();
30
47
  }
31
48
  }
32
49
  export {
33
- h as renderChartToImage
50
+ g as renderChartToImage
34
51
  };
@@ -0,0 +1,33 @@
1
+ import { EChartsOption } from 'echarts';
2
+ export interface RenderMavrikChartToImageOptions {
3
+ option: EChartsOption;
4
+ width?: number;
5
+ height?: number;
6
+ devicePixelRatio?: number;
7
+ }
8
+ /**
9
+ * Renders an ECharts chart to a PNG image buffer using the Mavrik theme.
10
+ *
11
+ * Automatically selects the correct theme variant based on chart type:
12
+ * - Vertical bars: gradient flows top-to-bottom
13
+ * - Horizontal bars: gradient flows left-to-right
14
+ *
15
+ * For custom themes, use renderChartToImage directly.
16
+ *
17
+ * @param options - Chart configuration and rendering options
18
+ * @returns PNG image buffer
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const buffer = renderMavrikChartToImage({
23
+ * option: {
24
+ * xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] },
25
+ * yAxis: { type: 'value' },
26
+ * series: [{ data: [120, 200, 150], type: 'bar' }]
27
+ * },
28
+ * width: 800,
29
+ * height: 600
30
+ * });
31
+ * ```
32
+ */
33
+ export declare function renderMavrikChartToImage({ option, width, height, devicePixelRatio, }: RenderMavrikChartToImageOptions): Buffer;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@validationcloud/fractal-ui",
3
3
  "private": false,
4
- "version": "1.52.0",
4
+ "version": "1.53.0",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
7
7
  "files": [
@@ -17,6 +17,7 @@
17
17
  "url": "https://github.com/validationcloud/fractal-ui/issues"
18
18
  },
19
19
  "scripts": {
20
+ "prebuild": "pnpm run generate:theme",
20
21
  "build": "vite build",
21
22
  "lint": "eslint",
22
23
  "storybook": "storybook dev -p 6006",
@@ -25,7 +26,8 @@
25
26
  "format:check": "prettier --check .",
26
27
  "typecheck": "tsc -b --noEmit",
27
28
  "test": "vitest run",
28
- "prepublishOnly": "pnpm build"
29
+ "prepublishOnly": "pnpm build",
30
+ "generate:theme": "node --experimental-transform-types scripts/generate-mavrik-theme.ts"
29
31
  },
30
32
  "exports": {
31
33
  ".": {
@@ -38,7 +40,7 @@
38
40
  },
39
41
  "./tailwind.css": "./dist/styles/tailwind.css"
40
42
  },
41
- "packageManager": "pnpm@10.24.0",
43
+ "packageManager": "pnpm@10.25.0",
42
44
  "engines": {
43
45
  "node": ">=22.14.0"
44
46
  },
@@ -51,37 +53,39 @@
51
53
  "zod": "^4"
52
54
  },
53
55
  "devDependencies": {
54
- "@eslint/compat": "^1.4.1",
56
+ "@eslint/compat": "^2.0.0",
55
57
  "@eslint/js": "^9.39.1",
56
- "@storybook/addon-docs": "^10.0.4",
57
- "@storybook/addon-onboarding": "^10.0.4",
58
- "@storybook/react-vite": "^10.0.4",
58
+ "@storybook/addon-docs": "^10.1.5",
59
+ "@storybook/addon-onboarding": "^10.1.5",
60
+ "@storybook/react-vite": "^10.1.5",
59
61
  "@tailwindcss/postcss": "^4",
60
62
  "@trivago/prettier-plugin-sort-imports": "^6.0.0",
63
+ "@types/culori": "^4.0.1",
61
64
  "@types/node": "^24",
62
65
  "@types/react": "^19",
63
66
  "@types/react-dom": "^19",
64
- "@vitejs/plugin-react": "^5.1.0",
67
+ "@vitejs/plugin-react": "^5.1.2",
65
68
  "canvas": "^3.2.0",
69
+ "culori": "^4.0.2",
66
70
  "echarts": "^6.0.0",
67
71
  "eslint": "^9.39.1",
68
72
  "eslint-config-prettier": "^10.1.8",
69
73
  "eslint-plugin-react-hooks": "^7.0.1",
70
74
  "eslint-plugin-react-refresh": "^0.4.24",
71
- "eslint-plugin-storybook": "^10.0.4",
75
+ "eslint-plugin-storybook": "^10.1.5",
72
76
  "globals": "^16.5.0",
73
77
  "postcss": "^8.5.6",
74
- "prettier": "3.6.2",
75
- "prettier-plugin-tailwindcss": "^0.7.1",
78
+ "prettier": "3.7.4",
79
+ "prettier-plugin-tailwindcss": "^0.7.2",
76
80
  "rollup-plugin-analyzer": "^4.0.0",
77
81
  "rollup-plugin-copy": "^3.5.0",
78
82
  "rollup-preserve-directives": "^1.1.3",
79
83
  "semantic-release": "^25.0.2",
80
- "storybook": "^10.0.4",
81
- "tailwindcss": "^4.1.16",
84
+ "storybook": "^10.1.5",
85
+ "tailwindcss": "^4.1.17",
82
86
  "typescript": "^5",
83
- "typescript-eslint": "^8.46.3",
84
- "vite": "^7.1.12",
87
+ "typescript-eslint": "^8.49.0",
88
+ "vite": "^7.2.7",
85
89
  "vite-plugin-dts": "^4.5.4",
86
90
  "vitest": "^4.0.15"
87
91
  },