elseware-ui 2.32.0 → 2.34.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.
- package/dist/index.css +422 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +913 -158
- package/dist/index.d.ts +913 -158
- package/dist/index.js +2938 -385
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2751 -244
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { twMerge } from 'tailwind-merge';
|
|
2
|
-
import
|
|
2
|
+
import React3, { createContext, forwardRef, useState, useImperativeHandle, useEffect, useMemo, useContext, Fragment as Fragment$1, useCallback, useRef } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { BsStarFill, BsStarHalf, BsStar, BsChevronDown, BsFillDiamondFill } from 'react-icons/bs';
|
|
5
5
|
import { FaSun, FaMoon, FaGripVertical, FaTrash, FaPlus, FaTimes, FaBars, FaCircle, FaEyeSlash, FaEye } from 'react-icons/fa';
|
|
@@ -10,7 +10,7 @@ import classNames16 from 'classnames';
|
|
|
10
10
|
import { FaCircleChevronDown } from 'react-icons/fa6';
|
|
11
11
|
import ReactWorldFlags from 'react-world-flags';
|
|
12
12
|
import emojiFlags from 'emoji-flags';
|
|
13
|
-
import
|
|
13
|
+
import { ResponsiveContainer, LineChart as LineChart$1, CartesianGrid, XAxis, YAxis, Tooltip as Tooltip$1, Line as Line$1, AreaChart, Area, BarChart as BarChart$1, Bar as Bar$1, PieChart as PieChart$1, Pie as Pie$1, Cell, ScatterChart, Scatter } from 'recharts';
|
|
14
14
|
import { Image, CloudinaryContext as CloudinaryContext$1 } from 'cloudinary-react';
|
|
15
15
|
import { useField, ErrorMessage, Formik, Form as Form$1, Field, useFormikContext, FieldArray } from 'formik';
|
|
16
16
|
import { toast, ToastContainer } from 'react-toastify';
|
|
@@ -179,6 +179,326 @@ function resolveAppearanceStyles({
|
|
|
179
179
|
return solid[variant];
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
|
|
183
|
+
// src/utils/configurator/errors.ts
|
|
184
|
+
var ConfiguratorError = class extends Error {
|
|
185
|
+
constructor(message, cause) {
|
|
186
|
+
super(message);
|
|
187
|
+
this.name = "ConfiguratorError";
|
|
188
|
+
this.cause = cause;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
function formatIssue(issue) {
|
|
192
|
+
const path = issue.path?.join(".") || "config";
|
|
193
|
+
return `${path} : ${issue.message ?? "Invalid value"}`;
|
|
194
|
+
}
|
|
195
|
+
function formatConfigError(error) {
|
|
196
|
+
const maybeZodError = error;
|
|
197
|
+
if (Array.isArray(maybeZodError.issues)) {
|
|
198
|
+
return maybeZodError.issues.map(formatIssue).join("\n");
|
|
199
|
+
}
|
|
200
|
+
if (maybeZodError?.message) {
|
|
201
|
+
return maybeZodError.message;
|
|
202
|
+
}
|
|
203
|
+
return "Invalid configuration";
|
|
204
|
+
}
|
|
205
|
+
function toConfiguratorError(error, fallbackMessage) {
|
|
206
|
+
if (error instanceof ConfiguratorError) {
|
|
207
|
+
return error;
|
|
208
|
+
}
|
|
209
|
+
if (error instanceof Error) {
|
|
210
|
+
return new ConfiguratorError(error.message || fallbackMessage, error);
|
|
211
|
+
}
|
|
212
|
+
return new ConfiguratorError(fallbackMessage, error);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/utils/configurator/Configurator.ts
|
|
216
|
+
var Configurator = class {
|
|
217
|
+
constructor(options) {
|
|
218
|
+
this.initialized = false;
|
|
219
|
+
this.config = null;
|
|
220
|
+
this.configError = null;
|
|
221
|
+
this.name = options.name ?? "config";
|
|
222
|
+
this.source = options.env;
|
|
223
|
+
this.schema = options.schema;
|
|
224
|
+
this.transform = options.transform;
|
|
225
|
+
if (options.validateOnCreate !== false) {
|
|
226
|
+
this.reload();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
get isValid() {
|
|
230
|
+
this.ensureInitialized();
|
|
231
|
+
return !this.configError;
|
|
232
|
+
}
|
|
233
|
+
get error() {
|
|
234
|
+
this.ensureInitialized();
|
|
235
|
+
return this.configError;
|
|
236
|
+
}
|
|
237
|
+
get value() {
|
|
238
|
+
this.ensureInitialized();
|
|
239
|
+
if (this.configError) {
|
|
240
|
+
throw this.configError;
|
|
241
|
+
}
|
|
242
|
+
return this.config;
|
|
243
|
+
}
|
|
244
|
+
get optionalValue() {
|
|
245
|
+
this.ensureInitialized();
|
|
246
|
+
return this.config;
|
|
247
|
+
}
|
|
248
|
+
reload(env = this.source) {
|
|
249
|
+
this.source = env;
|
|
250
|
+
this.initialized = true;
|
|
251
|
+
const result = this.schema.safeParse(env);
|
|
252
|
+
if (!result.success) {
|
|
253
|
+
this.config = null;
|
|
254
|
+
this.configError = toConfiguratorError(
|
|
255
|
+
result.error,
|
|
256
|
+
formatConfigError(result.error)
|
|
257
|
+
);
|
|
258
|
+
return {
|
|
259
|
+
success: false,
|
|
260
|
+
config: null,
|
|
261
|
+
error: this.configError
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
this.config = this.transform ? this.transform(result.data, { name: this.name }) : result.data;
|
|
266
|
+
this.configError = null;
|
|
267
|
+
return {
|
|
268
|
+
success: true,
|
|
269
|
+
config: this.config,
|
|
270
|
+
error: null
|
|
271
|
+
};
|
|
272
|
+
} catch (error) {
|
|
273
|
+
this.config = null;
|
|
274
|
+
this.configError = toConfiguratorError(
|
|
275
|
+
error,
|
|
276
|
+
`Failed to transform ${this.name}`
|
|
277
|
+
);
|
|
278
|
+
return {
|
|
279
|
+
success: false,
|
|
280
|
+
config: null,
|
|
281
|
+
error: this.configError
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
get(key) {
|
|
286
|
+
this.ensureInitialized();
|
|
287
|
+
if (!this.config) {
|
|
288
|
+
return void 0;
|
|
289
|
+
}
|
|
290
|
+
return this.config[key];
|
|
291
|
+
}
|
|
292
|
+
getRequired(key) {
|
|
293
|
+
const value = this.get(key);
|
|
294
|
+
if (value === void 0 || value === null) {
|
|
295
|
+
throw new Error(`Missing required config value: ${String(key)}`);
|
|
296
|
+
}
|
|
297
|
+
return value;
|
|
298
|
+
}
|
|
299
|
+
getPath(path, fallback) {
|
|
300
|
+
this.ensureInitialized();
|
|
301
|
+
if (!this.config) {
|
|
302
|
+
return fallback;
|
|
303
|
+
}
|
|
304
|
+
const value = path.split(".").reduce((current, key) => {
|
|
305
|
+
if (!current || typeof current !== "object") {
|
|
306
|
+
return void 0;
|
|
307
|
+
}
|
|
308
|
+
return current[key];
|
|
309
|
+
}, this.config);
|
|
310
|
+
return value === void 0 ? fallback : value;
|
|
311
|
+
}
|
|
312
|
+
getPathRequired(path) {
|
|
313
|
+
const value = this.getPath(path);
|
|
314
|
+
if (value === void 0 || value === null) {
|
|
315
|
+
throw new Error(`Missing required config value: ${path}`);
|
|
316
|
+
}
|
|
317
|
+
return value;
|
|
318
|
+
}
|
|
319
|
+
ensureInitialized() {
|
|
320
|
+
if (!this.initialized) {
|
|
321
|
+
this.reload();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/utils/configurator/createConfigurator.ts
|
|
327
|
+
function createConfigurator(options) {
|
|
328
|
+
return new Configurator(options);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// src/utils/configurator/helpers/browser.ts
|
|
332
|
+
function getBrowserOrigin() {
|
|
333
|
+
if (typeof window === "undefined") {
|
|
334
|
+
return "";
|
|
335
|
+
}
|
|
336
|
+
return window.location.origin;
|
|
337
|
+
}
|
|
338
|
+
function getBrowserHref() {
|
|
339
|
+
if (typeof window === "undefined") {
|
|
340
|
+
return "";
|
|
341
|
+
}
|
|
342
|
+
return window.location.href;
|
|
343
|
+
}
|
|
344
|
+
function getBrowserRedirectURL(options = {}) {
|
|
345
|
+
const {
|
|
346
|
+
queryParam = "redirect_uri",
|
|
347
|
+
fallbackPath = "/",
|
|
348
|
+
currentHref = getBrowserHref(),
|
|
349
|
+
referrerMode = "path"
|
|
350
|
+
} = options;
|
|
351
|
+
try {
|
|
352
|
+
if (currentHref) {
|
|
353
|
+
const currentURL = new URL(currentHref);
|
|
354
|
+
const redirectUri = currentURL.searchParams.get(queryParam);
|
|
355
|
+
if (redirectUri) {
|
|
356
|
+
return redirectUri;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (typeof document !== "undefined" && document.referrer) {
|
|
360
|
+
const referrerURL = new URL(document.referrer);
|
|
361
|
+
if (referrerMode === "full") {
|
|
362
|
+
return referrerURL.toString();
|
|
363
|
+
}
|
|
364
|
+
return `${referrerURL.pathname}${referrerURL.search}${referrerURL.hash}`;
|
|
365
|
+
}
|
|
366
|
+
return fallbackPath;
|
|
367
|
+
} catch {
|
|
368
|
+
return fallbackPath;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// src/utils/configurator/helpers/json.ts
|
|
373
|
+
function isRecord(value) {
|
|
374
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
375
|
+
}
|
|
376
|
+
function parseJson(value, key = "JSON value") {
|
|
377
|
+
if (isRecord(value) || Array.isArray(value)) {
|
|
378
|
+
return value;
|
|
379
|
+
}
|
|
380
|
+
if (typeof value !== "string") {
|
|
381
|
+
throw new ConfiguratorError(`${key} must be a JSON string`);
|
|
382
|
+
}
|
|
383
|
+
try {
|
|
384
|
+
return JSON.parse(value);
|
|
385
|
+
} catch {
|
|
386
|
+
throw new ConfiguratorError(`Invalid ${key} JSON`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function parseJsonRecord(value, key = "JSON record", validateValue) {
|
|
390
|
+
const parsed = parseJson(value, key);
|
|
391
|
+
if (!isRecord(parsed)) {
|
|
392
|
+
throw new ConfiguratorError(`${key} must be a JSON object`);
|
|
393
|
+
}
|
|
394
|
+
return Object.entries(parsed).reduce(
|
|
395
|
+
(acc, [name, item]) => {
|
|
396
|
+
acc[name] = validateValue ? validateValue(name, item) : item;
|
|
397
|
+
return acc;
|
|
398
|
+
},
|
|
399
|
+
{}
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// src/utils/configurator/helpers/url.ts
|
|
404
|
+
function assertAbsoluteURL(value, key = "URL") {
|
|
405
|
+
if (typeof value !== "string") {
|
|
406
|
+
throw new ConfiguratorError(`${key} must be a string URL`);
|
|
407
|
+
}
|
|
408
|
+
try {
|
|
409
|
+
const url = new URL(value);
|
|
410
|
+
if (!["http:", "https:"].includes(url.protocol)) {
|
|
411
|
+
throw new Error();
|
|
412
|
+
}
|
|
413
|
+
return url.toString();
|
|
414
|
+
} catch {
|
|
415
|
+
throw new ConfiguratorError(`${key} must be a valid http/https URL`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
function parseUrlMap(value, key = "URL map") {
|
|
419
|
+
return parseJsonRecord(
|
|
420
|
+
value,
|
|
421
|
+
key,
|
|
422
|
+
(name, item) => assertAbsoluteURL(item, `${key}.${name}`)
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
function buildURL(base, path = "", params = {}) {
|
|
426
|
+
const url = new URL(assertAbsoluteURL(base, "base URL"));
|
|
427
|
+
if (path) {
|
|
428
|
+
const currentPath = url.pathname.replace(/\/$/, "");
|
|
429
|
+
const nextPath = path.replace(/^\/+/, "");
|
|
430
|
+
url.pathname = `${currentPath}/${nextPath}`;
|
|
431
|
+
}
|
|
432
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
433
|
+
if (value !== void 0 && value !== null) {
|
|
434
|
+
url.searchParams.set(key, String(value));
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
return url.toString();
|
|
438
|
+
}
|
|
439
|
+
function resolveURLMap(source) {
|
|
440
|
+
return typeof source === "function" ? source() : source;
|
|
441
|
+
}
|
|
442
|
+
function createURLResolver(source, options = {}) {
|
|
443
|
+
const { label = "URL" } = options;
|
|
444
|
+
return (tag, path = "", params = {}) => {
|
|
445
|
+
const map = resolveURLMap(source) ?? {};
|
|
446
|
+
const base = map[tag];
|
|
447
|
+
if (!base) {
|
|
448
|
+
throw new ConfiguratorError(`${label} not configured for tag: ${tag}`);
|
|
449
|
+
}
|
|
450
|
+
return buildURL(base, path, params);
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function getAllowedOrigins(options = {}) {
|
|
454
|
+
const {
|
|
455
|
+
urls = [],
|
|
456
|
+
maps = [],
|
|
457
|
+
includeCurrentOrigin = true,
|
|
458
|
+
currentOrigin = getBrowserOrigin()
|
|
459
|
+
} = options;
|
|
460
|
+
const origins = /* @__PURE__ */ new Set();
|
|
461
|
+
if (includeCurrentOrigin && currentOrigin) {
|
|
462
|
+
origins.add(currentOrigin);
|
|
463
|
+
}
|
|
464
|
+
urls.forEach((url) => {
|
|
465
|
+
origins.add(new URL(assertAbsoluteURL(url)).origin);
|
|
466
|
+
});
|
|
467
|
+
maps.forEach((map) => {
|
|
468
|
+
Object.values(map ?? {}).forEach((url) => {
|
|
469
|
+
origins.add(new URL(assertAbsoluteURL(url)).origin);
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
return Array.from(origins);
|
|
473
|
+
}
|
|
474
|
+
function getSafeRedirect(options = {}) {
|
|
475
|
+
const {
|
|
476
|
+
redirectUri,
|
|
477
|
+
fallback = "/",
|
|
478
|
+
allowedOrigins = [],
|
|
479
|
+
currentOrigin = getBrowserOrigin(),
|
|
480
|
+
allowedProtocols = ["http:", "https:"]
|
|
481
|
+
} = options;
|
|
482
|
+
try {
|
|
483
|
+
if (!redirectUri) {
|
|
484
|
+
return fallback;
|
|
485
|
+
}
|
|
486
|
+
const url = new URL(redirectUri, currentOrigin || fallback);
|
|
487
|
+
if (!allowedProtocols.includes(url.protocol)) {
|
|
488
|
+
return fallback;
|
|
489
|
+
}
|
|
490
|
+
const allowed = new Set(allowedOrigins);
|
|
491
|
+
if (currentOrigin) {
|
|
492
|
+
allowed.add(currentOrigin);
|
|
493
|
+
}
|
|
494
|
+
if (!allowed.has(url.origin)) {
|
|
495
|
+
return fallback;
|
|
496
|
+
}
|
|
497
|
+
return url.toString();
|
|
498
|
+
} catch {
|
|
499
|
+
return fallback;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
182
502
|
var EUIContext = createContext(null);
|
|
183
503
|
var EUIProvider = ({
|
|
184
504
|
config,
|
|
@@ -1320,257 +1640,2444 @@ var Flag = ({
|
|
|
1320
1640
|
);
|
|
1321
1641
|
};
|
|
1322
1642
|
|
|
1323
|
-
// src/components/data-display/graphs/
|
|
1324
|
-
var
|
|
1325
|
-
var
|
|
1326
|
-
|
|
1643
|
+
// src/components/data-display/graphs-v2/constants/graph.constants.ts
|
|
1644
|
+
var GRAPH_DEFAULT_HEIGHT = 320;
|
|
1645
|
+
var GRAPH_DEFAULT_MAX_REALTIME_POINTS = 100;
|
|
1646
|
+
var GRAPH_DEFAULT_POLLING_INTERVAL = 5e3;
|
|
1647
|
+
var GRAPH_DEFAULT_ANIMATION_DURATION = 350;
|
|
1648
|
+
var GRAPH_DEFAULT_MARGIN = {
|
|
1649
|
+
top: 16,
|
|
1650
|
+
right: 24,
|
|
1651
|
+
bottom: 16,
|
|
1652
|
+
left: 8
|
|
1327
1653
|
};
|
|
1328
|
-
var
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1654
|
+
var GRAPH_DEFAULT_STROKE_WIDTH = 2;
|
|
1655
|
+
var GRAPH_DEFAULT_DOT_RADIUS = 3;
|
|
1656
|
+
var GRAPH_DEFAULT_ACTIVE_DOT_RADIUS = 5;
|
|
1657
|
+
var GRAPH_DEFAULT_BAR_RADIUS = [
|
|
1658
|
+
6,
|
|
1659
|
+
6,
|
|
1660
|
+
0,
|
|
1661
|
+
0
|
|
1662
|
+
];
|
|
1663
|
+
var GRAPH_STATUSES = {
|
|
1664
|
+
IDLE: "idle",
|
|
1665
|
+
LOADING: "loading",
|
|
1666
|
+
SUCCESS: "success",
|
|
1667
|
+
ERROR: "error",
|
|
1668
|
+
STREAMING: "streaming"
|
|
1334
1669
|
};
|
|
1335
|
-
var
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
}));
|
|
1350
|
-
return d3.forceSimulation(nodes).force(
|
|
1351
|
-
"link",
|
|
1352
|
-
d3.forceLink(d3Links).id((d) => d.id).distance(120).strength(0.7)
|
|
1353
|
-
).force("charge", d3.forceManyBody().strength(-280)).force("center", d3.forceCenter(width / 2, height / 2)).force("collision", d3.forceCollide().radius(35));
|
|
1670
|
+
var GRAPH_DATA_MODES = {
|
|
1671
|
+
STATIC: "static",
|
|
1672
|
+
POLLING: "polling",
|
|
1673
|
+
REALTIME: "realtime"
|
|
1674
|
+
};
|
|
1675
|
+
var GRAPH_VALUE_FORMATS = {
|
|
1676
|
+
RAW: "raw",
|
|
1677
|
+
NUMBER: "number",
|
|
1678
|
+
INTEGER: "integer",
|
|
1679
|
+
COMPACT: "compact",
|
|
1680
|
+
PERCENT: "percent",
|
|
1681
|
+
CURRENCY: "currency",
|
|
1682
|
+
BYTES: "bytes",
|
|
1683
|
+
DURATION: "duration"
|
|
1354
1684
|
};
|
|
1685
|
+
var GRAPH_EMPTY_MESSAGE = "No graph data available";
|
|
1686
|
+
var GRAPH_ERROR_MESSAGE = "Unable to load graph data";
|
|
1687
|
+
var GRAPH_LOADING_MESSAGE = "Loading graph data...";
|
|
1355
1688
|
|
|
1356
|
-
// src/components/data-display/graphs/
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1689
|
+
// src/components/data-display/graphs-v2/constants/graph-theme.constants.ts
|
|
1690
|
+
var GRAPH_COLOR_PALETTE = [
|
|
1691
|
+
"#7dd3fc",
|
|
1692
|
+
"#a78bfa",
|
|
1693
|
+
"#34d399",
|
|
1694
|
+
"#fbbf24",
|
|
1695
|
+
"#fb7185",
|
|
1696
|
+
"#60a5fa",
|
|
1697
|
+
"#f472b6",
|
|
1698
|
+
"#22d3ee",
|
|
1699
|
+
"#c084fc",
|
|
1700
|
+
"#a3e635"
|
|
1701
|
+
];
|
|
1702
|
+
var GRAPH_STATUS_COLORS = {
|
|
1703
|
+
primary: "#7dd3fc",
|
|
1704
|
+
secondary: "#a78bfa",
|
|
1705
|
+
success: "#34d399",
|
|
1706
|
+
warning: "#fbbf24",
|
|
1707
|
+
danger: "#fb7185",
|
|
1708
|
+
info: "#60a5fa",
|
|
1709
|
+
muted: "#6b7280"
|
|
1710
|
+
};
|
|
1711
|
+
var GRAPH_DARK_THEME = {
|
|
1712
|
+
panel: {
|
|
1713
|
+
background: "bg-[#111217]",
|
|
1714
|
+
border: "border border-[#2a2d35]",
|
|
1715
|
+
radius: "rounded-xl",
|
|
1716
|
+
shadow: "shadow-sm"
|
|
1717
|
+
},
|
|
1718
|
+
text: {
|
|
1719
|
+
title: "text-gray-100",
|
|
1720
|
+
description: "text-gray-400",
|
|
1721
|
+
muted: "text-gray-500"
|
|
1722
|
+
},
|
|
1723
|
+
chart: {
|
|
1724
|
+
grid: "#2a2d35",
|
|
1725
|
+
axis: "#8b949e",
|
|
1726
|
+
cursor: "rgba(255, 255, 255, 0.06)"
|
|
1727
|
+
},
|
|
1728
|
+
tooltip: {
|
|
1729
|
+
background: "#181b21",
|
|
1730
|
+
border: "#2a2d35",
|
|
1731
|
+
text: "#f3f4f6",
|
|
1732
|
+
muted: "#9ca3af"
|
|
1733
|
+
},
|
|
1734
|
+
colors: GRAPH_COLOR_PALETTE
|
|
1735
|
+
};
|
|
1736
|
+
var GRAPH_LIGHT_THEME = {
|
|
1737
|
+
panel: {
|
|
1738
|
+
background: "bg-white",
|
|
1739
|
+
border: "border border-gray-200",
|
|
1740
|
+
radius: "rounded-xl",
|
|
1741
|
+
shadow: "shadow-sm"
|
|
1742
|
+
},
|
|
1743
|
+
text: {
|
|
1744
|
+
title: "text-gray-900",
|
|
1745
|
+
description: "text-gray-500",
|
|
1746
|
+
muted: "text-gray-400"
|
|
1747
|
+
},
|
|
1748
|
+
chart: {
|
|
1749
|
+
grid: "#e5e7eb",
|
|
1750
|
+
axis: "#6b7280",
|
|
1751
|
+
cursor: "rgba(0, 0, 0, 0.04)"
|
|
1752
|
+
},
|
|
1753
|
+
tooltip: {
|
|
1754
|
+
background: "#ffffff",
|
|
1755
|
+
border: "#e5e7eb",
|
|
1756
|
+
text: "#111827",
|
|
1757
|
+
muted: "#6b7280"
|
|
1758
|
+
},
|
|
1759
|
+
colors: GRAPH_COLOR_PALETTE
|
|
1760
|
+
};
|
|
1761
|
+
var DEFAULT_GRAPH_THEME = GRAPH_DARK_THEME;
|
|
1367
1762
|
|
|
1368
|
-
// src/components/data-display/graphs/
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
const levelGroups = {};
|
|
1381
|
-
nodes.forEach((node) => {
|
|
1382
|
-
const level = levelMap[node.id] ?? 0;
|
|
1383
|
-
if (!levelGroups[level]) levelGroups[level] = [];
|
|
1384
|
-
levelGroups[level].push(node);
|
|
1385
|
-
});
|
|
1386
|
-
return nodes.map((node) => {
|
|
1387
|
-
const level = levelMap[node.id] ?? 0;
|
|
1388
|
-
const siblings = levelGroups[level];
|
|
1389
|
-
const index = siblings.indexOf(node);
|
|
1390
|
-
return {
|
|
1391
|
-
...node,
|
|
1392
|
-
x: (index + 1) * width / (siblings.length + 1),
|
|
1393
|
-
y: (level + 1) * height / (maxLevel + 2)
|
|
1394
|
-
};
|
|
1395
|
-
});
|
|
1763
|
+
// src/components/data-display/graphs-v2/utils/normalizeGraphData.ts
|
|
1764
|
+
var DEFAULT_NORMALIZE_OPTIONS = {
|
|
1765
|
+
serializeDates: true,
|
|
1766
|
+
parseNumericStrings: true,
|
|
1767
|
+
sanitizeInvalidNumbers: true,
|
|
1768
|
+
removeUndefined: true
|
|
1769
|
+
};
|
|
1770
|
+
function isNumericString(value) {
|
|
1771
|
+
if (!value.trim()) {
|
|
1772
|
+
return false;
|
|
1773
|
+
}
|
|
1774
|
+
return !Number.isNaN(Number(value));
|
|
1396
1775
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
const x = node.x;
|
|
1401
|
-
const y = node.y;
|
|
1402
|
-
if (renderCustom) {
|
|
1403
|
-
return /* @__PURE__ */ jsx(
|
|
1404
|
-
"foreignObject",
|
|
1405
|
-
{
|
|
1406
|
-
x: x - NODE_SIZE / 2,
|
|
1407
|
-
y: y - NODE_SIZE / 2,
|
|
1408
|
-
width: NODE_SIZE,
|
|
1409
|
-
height: NODE_SIZE,
|
|
1410
|
-
style: { overflow: "visible" },
|
|
1411
|
-
children: /* @__PURE__ */ jsx(
|
|
1412
|
-
"div",
|
|
1413
|
-
{
|
|
1414
|
-
style: {
|
|
1415
|
-
width: NODE_SIZE,
|
|
1416
|
-
height: NODE_SIZE,
|
|
1417
|
-
display: "flex",
|
|
1418
|
-
alignItems: "center",
|
|
1419
|
-
justifyContent: "center"
|
|
1420
|
-
},
|
|
1421
|
-
children: renderCustom(node)
|
|
1422
|
-
}
|
|
1423
|
-
)
|
|
1424
|
-
}
|
|
1425
|
-
);
|
|
1776
|
+
function normalizeValue(value, options) {
|
|
1777
|
+
if (value instanceof Date) {
|
|
1778
|
+
return options.serializeDates ? value.toISOString() : value;
|
|
1426
1779
|
}
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1780
|
+
if (typeof value === "number") {
|
|
1781
|
+
if (options.sanitizeInvalidNumbers && (Number.isNaN(value) || !Number.isFinite(value))) {
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
return value;
|
|
1785
|
+
}
|
|
1786
|
+
if (typeof value === "string") {
|
|
1787
|
+
if (options.parseNumericStrings && isNumericString(value)) {
|
|
1788
|
+
return Number(value);
|
|
1789
|
+
}
|
|
1790
|
+
return value;
|
|
1791
|
+
}
|
|
1792
|
+
if (typeof value === "boolean" || value === null || value === void 0) {
|
|
1793
|
+
return value;
|
|
1794
|
+
}
|
|
1795
|
+
return String(value);
|
|
1796
|
+
}
|
|
1797
|
+
function normalizeGraphData(data, options = {}) {
|
|
1798
|
+
if (!Array.isArray(data)) {
|
|
1799
|
+
return [];
|
|
1800
|
+
}
|
|
1801
|
+
const resolvedOptions = {
|
|
1802
|
+
...DEFAULT_NORMALIZE_OPTIONS,
|
|
1803
|
+
...options
|
|
1804
|
+
};
|
|
1805
|
+
return data.map((item) => {
|
|
1806
|
+
const normalizedPoint = {};
|
|
1807
|
+
const keys = options.keys ?? Object.keys(item);
|
|
1808
|
+
keys.forEach((key) => {
|
|
1809
|
+
const value = normalizeValue(item[key], resolvedOptions);
|
|
1810
|
+
if (resolvedOptions.removeUndefined && value === void 0) {
|
|
1811
|
+
return;
|
|
1438
1812
|
}
|
|
1439
|
-
|
|
1440
|
-
|
|
1813
|
+
normalizedPoint[key] = value;
|
|
1814
|
+
});
|
|
1815
|
+
return normalizedPoint;
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
function normalizeGraphDataPoint(dataPoint, options = {}) {
|
|
1819
|
+
return normalizeGraphData([dataPoint], options)[0] ?? {};
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
// src/components/data-display/graphs-v2/utils/formatGraphValue.ts
|
|
1823
|
+
var DEFAULT_FORMAT_OPTIONS = {
|
|
1824
|
+
format: "number",
|
|
1825
|
+
locale: "en-US",
|
|
1826
|
+
fallback: "-"
|
|
1441
1827
|
};
|
|
1442
|
-
function
|
|
1443
|
-
return typeof
|
|
1828
|
+
function isValidNumber(value) {
|
|
1829
|
+
return typeof value === "number" && Number.isFinite(value) && !Number.isNaN(value);
|
|
1444
1830
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1831
|
+
function formatBytes(value, locale) {
|
|
1832
|
+
if (value === 0) {
|
|
1833
|
+
return "0 B";
|
|
1834
|
+
}
|
|
1835
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB"];
|
|
1836
|
+
const unitIndex = Math.min(
|
|
1837
|
+
Math.floor(Math.log(Math.abs(value)) / Math.log(1024)),
|
|
1838
|
+
units.length - 1
|
|
1839
|
+
);
|
|
1840
|
+
const formattedValue = value / 1024 ** unitIndex;
|
|
1841
|
+
return `${new Intl.NumberFormat(locale, {
|
|
1842
|
+
maximumFractionDigits: formattedValue >= 10 ? 1 : 2
|
|
1843
|
+
}).format(formattedValue)} ${units[unitIndex]}`;
|
|
1844
|
+
}
|
|
1845
|
+
function formatDuration(value, locale) {
|
|
1846
|
+
if (value < 1e3) {
|
|
1847
|
+
return `${Math.round(value)} ms`;
|
|
1848
|
+
}
|
|
1849
|
+
const seconds = value / 1e3;
|
|
1850
|
+
if (seconds < 60) {
|
|
1851
|
+
return `${new Intl.NumberFormat(locale, {
|
|
1852
|
+
maximumFractionDigits: 2
|
|
1853
|
+
}).format(seconds)} s`;
|
|
1854
|
+
}
|
|
1855
|
+
const minutes = seconds / 60;
|
|
1856
|
+
if (minutes < 60) {
|
|
1857
|
+
return `${new Intl.NumberFormat(locale, {
|
|
1858
|
+
maximumFractionDigits: 2
|
|
1859
|
+
}).format(minutes)} min`;
|
|
1860
|
+
}
|
|
1861
|
+
const hours = minutes / 60;
|
|
1862
|
+
return `${new Intl.NumberFormat(locale, {
|
|
1863
|
+
maximumFractionDigits: 2
|
|
1864
|
+
}).format(hours)} h`;
|
|
1865
|
+
}
|
|
1866
|
+
function formatGraphValue(value, options = {}) {
|
|
1867
|
+
const {
|
|
1868
|
+
format,
|
|
1869
|
+
locale,
|
|
1870
|
+
fallback,
|
|
1871
|
+
prefix = "",
|
|
1872
|
+
suffix = "",
|
|
1873
|
+
currency = "USD",
|
|
1874
|
+
minimumFractionDigits,
|
|
1875
|
+
maximumFractionDigits
|
|
1876
|
+
} = {
|
|
1877
|
+
...DEFAULT_FORMAT_OPTIONS,
|
|
1878
|
+
...options
|
|
1879
|
+
};
|
|
1880
|
+
if (value === null || value === void 0 || value === "") {
|
|
1881
|
+
return fallback;
|
|
1882
|
+
}
|
|
1883
|
+
if (format === "raw") {
|
|
1884
|
+
return `${prefix}${String(value)}${suffix}`;
|
|
1885
|
+
}
|
|
1886
|
+
const numericValue = typeof value === "string" && value.trim() !== "" ? Number(value) : value;
|
|
1887
|
+
if (!isValidNumber(numericValue)) {
|
|
1888
|
+
return `${prefix}${String(value)}${suffix}`;
|
|
1889
|
+
}
|
|
1890
|
+
let formattedValue;
|
|
1891
|
+
switch (format) {
|
|
1892
|
+
case "integer":
|
|
1893
|
+
formattedValue = new Intl.NumberFormat(locale, {
|
|
1894
|
+
maximumFractionDigits: 0
|
|
1895
|
+
}).format(numericValue);
|
|
1896
|
+
break;
|
|
1897
|
+
case "compact":
|
|
1898
|
+
formattedValue = new Intl.NumberFormat(locale, {
|
|
1899
|
+
notation: "compact",
|
|
1900
|
+
maximumFractionDigits: maximumFractionDigits ?? 2
|
|
1901
|
+
}).format(numericValue);
|
|
1902
|
+
break;
|
|
1903
|
+
case "percent":
|
|
1904
|
+
formattedValue = new Intl.NumberFormat(locale, {
|
|
1905
|
+
style: "percent",
|
|
1906
|
+
minimumFractionDigits: minimumFractionDigits ?? 0,
|
|
1907
|
+
maximumFractionDigits: maximumFractionDigits ?? 2
|
|
1908
|
+
}).format(numericValue / 100);
|
|
1909
|
+
break;
|
|
1910
|
+
case "currency":
|
|
1911
|
+
formattedValue = new Intl.NumberFormat(locale, {
|
|
1912
|
+
style: "currency",
|
|
1913
|
+
currency,
|
|
1914
|
+
minimumFractionDigits,
|
|
1915
|
+
maximumFractionDigits
|
|
1916
|
+
}).format(numericValue);
|
|
1917
|
+
break;
|
|
1918
|
+
case "bytes":
|
|
1919
|
+
formattedValue = formatBytes(numericValue, locale);
|
|
1920
|
+
break;
|
|
1921
|
+
case "duration":
|
|
1922
|
+
formattedValue = formatDuration(numericValue, locale);
|
|
1923
|
+
break;
|
|
1924
|
+
case "number":
|
|
1925
|
+
default:
|
|
1926
|
+
formattedValue = new Intl.NumberFormat(locale, {
|
|
1927
|
+
minimumFractionDigits,
|
|
1928
|
+
maximumFractionDigits: maximumFractionDigits ?? 2
|
|
1929
|
+
}).format(numericValue);
|
|
1930
|
+
break;
|
|
1931
|
+
}
|
|
1932
|
+
return `${prefix}${formattedValue}${suffix}`;
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
// src/components/data-display/graphs-v2/utils/resolveGraphColor.ts
|
|
1936
|
+
var NAMED_COLORS = {
|
|
1937
|
+
primary: GRAPH_STATUS_COLORS.primary,
|
|
1938
|
+
secondary: GRAPH_STATUS_COLORS.secondary,
|
|
1939
|
+
success: GRAPH_STATUS_COLORS.success,
|
|
1940
|
+
warning: GRAPH_STATUS_COLORS.warning,
|
|
1941
|
+
danger: GRAPH_STATUS_COLORS.danger,
|
|
1942
|
+
info: GRAPH_STATUS_COLORS.info,
|
|
1943
|
+
muted: GRAPH_STATUS_COLORS.muted
|
|
1477
1944
|
};
|
|
1478
|
-
|
|
1945
|
+
function isCssColor(value) {
|
|
1946
|
+
return value.startsWith("#") || value.startsWith("rgb(") || value.startsWith("rgba(") || value.startsWith("hsl(") || value.startsWith("hsla(") || value.startsWith("var(");
|
|
1947
|
+
}
|
|
1948
|
+
function resolveGraphColor(color, options = {}) {
|
|
1949
|
+
const {
|
|
1950
|
+
index = 0,
|
|
1951
|
+
fallback = GRAPH_COLOR_PALETTE[0],
|
|
1952
|
+
palette = GRAPH_COLOR_PALETTE
|
|
1953
|
+
} = options;
|
|
1954
|
+
if (color) {
|
|
1955
|
+
if (isCssColor(color)) {
|
|
1956
|
+
return color;
|
|
1957
|
+
}
|
|
1958
|
+
if (color in NAMED_COLORS) {
|
|
1959
|
+
return NAMED_COLORS[color];
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
if (palette.length > 0) {
|
|
1963
|
+
return palette[index % palette.length];
|
|
1964
|
+
}
|
|
1965
|
+
return fallback;
|
|
1966
|
+
}
|
|
1967
|
+
function resolveGraphColors(count, options = {}) {
|
|
1968
|
+
return Array.from(
|
|
1969
|
+
{ length: count },
|
|
1970
|
+
(_, index) => resolveGraphColor(void 0, {
|
|
1971
|
+
...options,
|
|
1972
|
+
index
|
|
1973
|
+
})
|
|
1974
|
+
);
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// src/components/data-display/graphs-v2/utils/limitRealtimePoints.ts
|
|
1978
|
+
var DEFAULT_MAX_POINTS = 100;
|
|
1979
|
+
function limitRealtimePoints(currentData = [], nextData, options = {}) {
|
|
1980
|
+
const { maxPoints = DEFAULT_MAX_POINTS, appendDirection = "end" } = options;
|
|
1981
|
+
const incomingData = Array.isArray(nextData) ? nextData : [nextData];
|
|
1982
|
+
const mergedData = appendDirection === "start" ? [...incomingData, ...currentData] : [...currentData, ...incomingData];
|
|
1983
|
+
if (maxPoints <= 0) {
|
|
1984
|
+
return mergedData;
|
|
1985
|
+
}
|
|
1986
|
+
if (mergedData.length <= maxPoints) {
|
|
1987
|
+
return mergedData;
|
|
1988
|
+
}
|
|
1989
|
+
return appendDirection === "start" ? mergedData.slice(0, maxPoints) : mergedData.slice(-maxPoints);
|
|
1990
|
+
}
|
|
1991
|
+
function replaceRealtimePoints(nextData = [], options = {}) {
|
|
1992
|
+
const { maxPoints = DEFAULT_MAX_POINTS } = options;
|
|
1993
|
+
if (maxPoints <= 0) {
|
|
1994
|
+
return nextData;
|
|
1995
|
+
}
|
|
1996
|
+
return nextData.slice(-maxPoints);
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
// src/components/data-display/graphs-v2/hooks/useGraphData.ts
|
|
2000
|
+
function useGraphData({
|
|
1479
2001
|
data,
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
const
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
2002
|
+
dataSource,
|
|
2003
|
+
autoLoad = true,
|
|
2004
|
+
maxDataPoints = GRAPH_DEFAULT_MAX_REALTIME_POINTS,
|
|
2005
|
+
normalize: normalize2 = true,
|
|
2006
|
+
onDataChange,
|
|
2007
|
+
onError
|
|
2008
|
+
} = {}) {
|
|
2009
|
+
const [state, setState] = useState({
|
|
2010
|
+
data: data ?? [],
|
|
2011
|
+
loading: false,
|
|
2012
|
+
error: null,
|
|
2013
|
+
status: data?.length ? "success" : "idle",
|
|
2014
|
+
lastUpdatedAt: data?.length ? /* @__PURE__ */ new Date() : void 0
|
|
2015
|
+
});
|
|
2016
|
+
const prepareData = useCallback(
|
|
2017
|
+
(nextData) => {
|
|
2018
|
+
if (!normalize2) {
|
|
2019
|
+
return nextData;
|
|
2020
|
+
}
|
|
2021
|
+
return normalizeGraphData(nextData);
|
|
2022
|
+
},
|
|
2023
|
+
[normalize2]
|
|
2024
|
+
);
|
|
2025
|
+
const replaceData = useCallback(
|
|
2026
|
+
(nextData) => {
|
|
2027
|
+
const normalizedData = prepareData(nextData);
|
|
2028
|
+
setState({
|
|
2029
|
+
data: normalizedData,
|
|
2030
|
+
loading: false,
|
|
2031
|
+
error: null,
|
|
2032
|
+
status: "success",
|
|
2033
|
+
lastUpdatedAt: /* @__PURE__ */ new Date()
|
|
2034
|
+
});
|
|
2035
|
+
onDataChange?.(normalizedData);
|
|
2036
|
+
},
|
|
2037
|
+
[onDataChange, prepareData]
|
|
2038
|
+
);
|
|
2039
|
+
const appendData = useCallback(
|
|
2040
|
+
(nextData) => {
|
|
2041
|
+
setState((currentState) => {
|
|
2042
|
+
const incomingData = Array.isArray(nextData) ? nextData : [nextData];
|
|
2043
|
+
const normalizedIncomingData = prepareData(incomingData);
|
|
2044
|
+
const limitedData = limitRealtimePoints(
|
|
2045
|
+
currentState.data,
|
|
2046
|
+
normalizedIncomingData,
|
|
2047
|
+
{
|
|
2048
|
+
maxPoints: maxDataPoints
|
|
2049
|
+
}
|
|
2050
|
+
);
|
|
2051
|
+
onDataChange?.(limitedData);
|
|
2052
|
+
return {
|
|
2053
|
+
data: limitedData,
|
|
2054
|
+
loading: false,
|
|
2055
|
+
error: null,
|
|
2056
|
+
status: "streaming",
|
|
2057
|
+
lastUpdatedAt: /* @__PURE__ */ new Date()
|
|
2058
|
+
};
|
|
2059
|
+
});
|
|
2060
|
+
},
|
|
2061
|
+
[maxDataPoints, onDataChange, prepareData]
|
|
2062
|
+
);
|
|
2063
|
+
const clearData = useCallback(() => {
|
|
2064
|
+
setState({
|
|
2065
|
+
data: [],
|
|
2066
|
+
loading: false,
|
|
2067
|
+
error: null,
|
|
2068
|
+
status: "idle",
|
|
2069
|
+
lastUpdatedAt: void 0
|
|
1508
2070
|
});
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
return /* @__PURE__ */ jsx("div", { className: "relative overflow-hidden border border-gray-800 rounded-lg", children: /* @__PURE__ */ jsx(
|
|
1528
|
-
"svg",
|
|
1529
|
-
{
|
|
1530
|
-
width: "100%",
|
|
1531
|
-
height,
|
|
1532
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
1533
|
-
onMouseDown,
|
|
1534
|
-
onMouseMove,
|
|
1535
|
-
onMouseUp: stopDrag,
|
|
1536
|
-
onMouseLeave: stopDrag,
|
|
1537
|
-
style: {
|
|
1538
|
-
cursor: isDragging.current ? "grabbing" : "grab"
|
|
1539
|
-
},
|
|
1540
|
-
children: /* @__PURE__ */ jsxs("g", { transform: `translate(${offset.x}, ${offset.y})`, children: [
|
|
1541
|
-
edges.map((edge, i) => /* @__PURE__ */ jsx(GraphEdge, { edge, nodeMap }, edge.id || i)),
|
|
1542
|
-
nodes.map((node) => /* @__PURE__ */ jsx(GraphNode, { node, renderCustom: nodeRenderer }, node.id))
|
|
1543
|
-
] })
|
|
2071
|
+
onDataChange?.([]);
|
|
2072
|
+
}, [onDataChange]);
|
|
2073
|
+
const handleError = useCallback(
|
|
2074
|
+
(error) => {
|
|
2075
|
+
setState((currentState) => ({
|
|
2076
|
+
...currentState,
|
|
2077
|
+
loading: false,
|
|
2078
|
+
error,
|
|
2079
|
+
status: "error"
|
|
2080
|
+
}));
|
|
2081
|
+
onError?.(error);
|
|
2082
|
+
},
|
|
2083
|
+
[onError]
|
|
2084
|
+
);
|
|
2085
|
+
const refresh = useCallback(async () => {
|
|
2086
|
+
const resolvedDataSource = dataSource;
|
|
2087
|
+
if (!resolvedDataSource?.refresh && !resolvedDataSource?.getInitialData) {
|
|
2088
|
+
return;
|
|
1544
2089
|
}
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
})
|
|
1556
|
-
|
|
1557
|
-
"div",
|
|
1558
|
-
{
|
|
1559
|
-
...rest,
|
|
1560
|
-
style: { width, height },
|
|
1561
|
-
className: cn("relative bg-gray-900 rounded-lg", className),
|
|
1562
|
-
children: /* @__PURE__ */ jsx(
|
|
1563
|
-
GraphRenderer,
|
|
1564
|
-
{
|
|
1565
|
-
data,
|
|
1566
|
-
layout,
|
|
1567
|
-
nodeRenderer,
|
|
1568
|
-
width,
|
|
1569
|
-
height
|
|
1570
|
-
}
|
|
1571
|
-
)
|
|
2090
|
+
try {
|
|
2091
|
+
setState((currentState) => ({
|
|
2092
|
+
...currentState,
|
|
2093
|
+
loading: true,
|
|
2094
|
+
error: null,
|
|
2095
|
+
status: "loading"
|
|
2096
|
+
}));
|
|
2097
|
+
const loader = resolvedDataSource.refresh ?? resolvedDataSource.getInitialData;
|
|
2098
|
+
const result = await loader?.();
|
|
2099
|
+
replaceData(result ?? []);
|
|
2100
|
+
} catch (error) {
|
|
2101
|
+
handleError(error instanceof Error ? error : new Error(String(error)));
|
|
1572
2102
|
}
|
|
1573
|
-
);
|
|
2103
|
+
}, [dataSource, handleError, replaceData]);
|
|
2104
|
+
useEffect(() => {
|
|
2105
|
+
if (!data) {
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
replaceData(data);
|
|
2109
|
+
}, [data, replaceData]);
|
|
2110
|
+
useEffect(() => {
|
|
2111
|
+
if (!dataSource || !autoLoad) {
|
|
2112
|
+
return;
|
|
2113
|
+
}
|
|
2114
|
+
const resolvedDataSource = dataSource;
|
|
2115
|
+
let unsubscribe;
|
|
2116
|
+
let isMounted = true;
|
|
2117
|
+
async function loadInitialData() {
|
|
2118
|
+
if (!resolvedDataSource.getInitialData) {
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
try {
|
|
2122
|
+
setState((currentState) => ({
|
|
2123
|
+
...currentState,
|
|
2124
|
+
loading: true,
|
|
2125
|
+
error: null,
|
|
2126
|
+
status: "loading"
|
|
2127
|
+
}));
|
|
2128
|
+
const result = await resolvedDataSource.getInitialData();
|
|
2129
|
+
if (isMounted) {
|
|
2130
|
+
replaceData(result ?? []);
|
|
2131
|
+
}
|
|
2132
|
+
} catch (error) {
|
|
2133
|
+
if (isMounted) {
|
|
2134
|
+
handleError(
|
|
2135
|
+
error instanceof Error ? error : new Error(String(error))
|
|
2136
|
+
);
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
void loadInitialData();
|
|
2141
|
+
if (resolvedDataSource.subscribe) {
|
|
2142
|
+
unsubscribe = resolvedDataSource.subscribe(appendData, handleError);
|
|
2143
|
+
}
|
|
2144
|
+
return () => {
|
|
2145
|
+
isMounted = false;
|
|
2146
|
+
unsubscribe?.();
|
|
2147
|
+
};
|
|
2148
|
+
}, [appendData, autoLoad, dataSource, handleError, replaceData]);
|
|
2149
|
+
return useMemo(
|
|
2150
|
+
() => ({
|
|
2151
|
+
...state,
|
|
2152
|
+
refresh,
|
|
2153
|
+
replaceData,
|
|
2154
|
+
appendData,
|
|
2155
|
+
clearData
|
|
2156
|
+
}),
|
|
2157
|
+
[appendData, clearData, refresh, replaceData, state]
|
|
2158
|
+
);
|
|
2159
|
+
}
|
|
2160
|
+
function useGraphRealtime({
|
|
2161
|
+
enabled = true,
|
|
2162
|
+
maxDataPoints = GRAPH_DEFAULT_MAX_REALTIME_POINTS,
|
|
2163
|
+
normalize: normalize2 = true,
|
|
2164
|
+
connect,
|
|
2165
|
+
onData,
|
|
2166
|
+
onError
|
|
2167
|
+
}) {
|
|
2168
|
+
const [data, setData] = useState([]);
|
|
2169
|
+
const [error, setError] = useState(null);
|
|
2170
|
+
const [connected, setConnected] = useState(false);
|
|
2171
|
+
const [lastUpdatedAt, setLastUpdatedAt] = useState();
|
|
2172
|
+
useEffect(() => {
|
|
2173
|
+
if (!enabled) {
|
|
2174
|
+
setConnected(false);
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
const handleData = (incomingData) => {
|
|
2178
|
+
const incomingArray = Array.isArray(incomingData) ? incomingData : [incomingData];
|
|
2179
|
+
const normalizedIncomingData = normalize2 ? normalizeGraphData(incomingArray) : incomingArray;
|
|
2180
|
+
setData((currentData) => {
|
|
2181
|
+
const nextData = limitRealtimePoints(
|
|
2182
|
+
currentData,
|
|
2183
|
+
normalizedIncomingData,
|
|
2184
|
+
{
|
|
2185
|
+
maxPoints: maxDataPoints
|
|
2186
|
+
}
|
|
2187
|
+
);
|
|
2188
|
+
onData?.(nextData);
|
|
2189
|
+
return nextData;
|
|
2190
|
+
});
|
|
2191
|
+
setError(null);
|
|
2192
|
+
setConnected(true);
|
|
2193
|
+
setLastUpdatedAt(/* @__PURE__ */ new Date());
|
|
2194
|
+
};
|
|
2195
|
+
const handleError = (nextError) => {
|
|
2196
|
+
setError(nextError);
|
|
2197
|
+
onError?.(nextError);
|
|
2198
|
+
};
|
|
2199
|
+
const unsubscribe = connect(handleData, handleError);
|
|
2200
|
+
setConnected(true);
|
|
2201
|
+
return () => {
|
|
2202
|
+
unsubscribe?.();
|
|
2203
|
+
setConnected(false);
|
|
2204
|
+
};
|
|
2205
|
+
}, [connect, enabled, maxDataPoints, normalize2, onData, onError]);
|
|
2206
|
+
return useMemo(
|
|
2207
|
+
() => ({
|
|
2208
|
+
data,
|
|
2209
|
+
error,
|
|
2210
|
+
connected,
|
|
2211
|
+
loading: enabled && !connected && !error,
|
|
2212
|
+
status: error ? "error" : connected ? "streaming" : "idle",
|
|
2213
|
+
lastUpdatedAt,
|
|
2214
|
+
clearData: () => setData([])
|
|
2215
|
+
}),
|
|
2216
|
+
[connected, data, enabled, error, lastUpdatedAt]
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2219
|
+
function useGraphPolling({
|
|
2220
|
+
enabled = true,
|
|
2221
|
+
interval = GRAPH_DEFAULT_POLLING_INTERVAL,
|
|
2222
|
+
immediate = true,
|
|
2223
|
+
normalize: normalize2 = true,
|
|
2224
|
+
fetcher,
|
|
2225
|
+
onData,
|
|
2226
|
+
onError
|
|
2227
|
+
}) {
|
|
2228
|
+
const isMountedRef = useRef(false);
|
|
2229
|
+
const isFetchingRef = useRef(false);
|
|
2230
|
+
const [data, setData] = useState([]);
|
|
2231
|
+
const [error, setError] = useState(null);
|
|
2232
|
+
const [loading, setLoading] = useState(immediate);
|
|
2233
|
+
const [lastUpdatedAt, setLastUpdatedAt] = useState();
|
|
2234
|
+
const refresh = useCallback(async () => {
|
|
2235
|
+
if (isFetchingRef.current) {
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
try {
|
|
2239
|
+
isFetchingRef.current = true;
|
|
2240
|
+
setLoading(true);
|
|
2241
|
+
setError(null);
|
|
2242
|
+
const result = await fetcher();
|
|
2243
|
+
const nextData = normalize2 ? normalizeGraphData(result ?? []) : result ?? [];
|
|
2244
|
+
if (!isMountedRef.current) {
|
|
2245
|
+
return;
|
|
2246
|
+
}
|
|
2247
|
+
setData(nextData);
|
|
2248
|
+
setLastUpdatedAt(/* @__PURE__ */ new Date());
|
|
2249
|
+
onData?.(nextData);
|
|
2250
|
+
} catch (error2) {
|
|
2251
|
+
const nextError = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
2252
|
+
if (isMountedRef.current) {
|
|
2253
|
+
setError(nextError);
|
|
2254
|
+
onError?.(nextError);
|
|
2255
|
+
}
|
|
2256
|
+
} finally {
|
|
2257
|
+
if (isMountedRef.current) {
|
|
2258
|
+
setLoading(false);
|
|
2259
|
+
}
|
|
2260
|
+
isFetchingRef.current = false;
|
|
2261
|
+
}
|
|
2262
|
+
}, [fetcher, normalize2, onData, onError]);
|
|
2263
|
+
useEffect(() => {
|
|
2264
|
+
isMountedRef.current = true;
|
|
2265
|
+
return () => {
|
|
2266
|
+
isMountedRef.current = false;
|
|
2267
|
+
};
|
|
2268
|
+
}, []);
|
|
2269
|
+
useEffect(() => {
|
|
2270
|
+
if (!enabled) {
|
|
2271
|
+
setLoading(false);
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
if (immediate) {
|
|
2275
|
+
void refresh();
|
|
2276
|
+
}
|
|
2277
|
+
const timer = window.setInterval(() => {
|
|
2278
|
+
void refresh();
|
|
2279
|
+
}, interval);
|
|
2280
|
+
return () => {
|
|
2281
|
+
window.clearInterval(timer);
|
|
2282
|
+
};
|
|
2283
|
+
}, [enabled, immediate, interval, refresh]);
|
|
2284
|
+
return useMemo(
|
|
2285
|
+
() => ({
|
|
2286
|
+
data,
|
|
2287
|
+
error,
|
|
2288
|
+
loading,
|
|
2289
|
+
status: error ? "error" : loading ? "loading" : "success",
|
|
2290
|
+
lastUpdatedAt,
|
|
2291
|
+
refresh
|
|
2292
|
+
}),
|
|
2293
|
+
[data, error, lastUpdatedAt, loading, refresh]
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
function createLabelFromKey(key) {
|
|
2297
|
+
return key.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (character) => character.toUpperCase());
|
|
2298
|
+
}
|
|
2299
|
+
function inferSeriesKeys(data, xKey, excludeKeys = []) {
|
|
2300
|
+
const firstPoint = data[0];
|
|
2301
|
+
if (!firstPoint) {
|
|
2302
|
+
return [];
|
|
2303
|
+
}
|
|
2304
|
+
return Object.keys(firstPoint).filter((key) => {
|
|
2305
|
+
if (key === xKey) {
|
|
2306
|
+
return false;
|
|
2307
|
+
}
|
|
2308
|
+
if (excludeKeys.includes(key)) {
|
|
2309
|
+
return false;
|
|
2310
|
+
}
|
|
2311
|
+
const value = firstPoint[key];
|
|
2312
|
+
return typeof value === "number";
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
function useGraphSeries({
|
|
2316
|
+
data = [],
|
|
2317
|
+
series,
|
|
2318
|
+
xKey,
|
|
2319
|
+
excludeKeys = []
|
|
2320
|
+
}) {
|
|
2321
|
+
return useMemo(() => {
|
|
2322
|
+
const normalizedSeries = series && series.length > 0 ? series : inferSeriesKeys(data, xKey, excludeKeys).map((key) => ({
|
|
2323
|
+
key
|
|
2324
|
+
}));
|
|
2325
|
+
return normalizedSeries.map((item, index) => ({
|
|
2326
|
+
key: item.key,
|
|
2327
|
+
label: item.label ?? createLabelFromKey(item.key),
|
|
2328
|
+
type: item.type ?? "line",
|
|
2329
|
+
color: resolveGraphColor(item.color, { index }),
|
|
2330
|
+
unit: item.unit,
|
|
2331
|
+
visible: item.visible ?? true,
|
|
2332
|
+
strokeWidth: item.strokeWidth ?? GRAPH_DEFAULT_STROKE_WIDTH,
|
|
2333
|
+
radius: item.radius ?? GRAPH_DEFAULT_ACTIVE_DOT_RADIUS,
|
|
2334
|
+
format: item.format,
|
|
2335
|
+
prefix: item.prefix,
|
|
2336
|
+
suffix: item.suffix,
|
|
2337
|
+
yAxisId: item.yAxisId
|
|
2338
|
+
}));
|
|
2339
|
+
}, [data, excludeKeys, series, xKey]);
|
|
2340
|
+
}
|
|
2341
|
+
function mergeGraphTheme(baseTheme, customTheme) {
|
|
2342
|
+
if (!customTheme) {
|
|
2343
|
+
return baseTheme;
|
|
2344
|
+
}
|
|
2345
|
+
return {
|
|
2346
|
+
panel: {
|
|
2347
|
+
...baseTheme.panel,
|
|
2348
|
+
...customTheme.panel
|
|
2349
|
+
},
|
|
2350
|
+
text: {
|
|
2351
|
+
...baseTheme.text,
|
|
2352
|
+
...customTheme.text
|
|
2353
|
+
},
|
|
2354
|
+
chart: {
|
|
2355
|
+
...baseTheme.chart,
|
|
2356
|
+
...customTheme.chart
|
|
2357
|
+
},
|
|
2358
|
+
tooltip: {
|
|
2359
|
+
...baseTheme.tooltip,
|
|
2360
|
+
...customTheme.tooltip
|
|
2361
|
+
},
|
|
2362
|
+
colors: customTheme.colors ?? baseTheme.colors
|
|
2363
|
+
};
|
|
2364
|
+
}
|
|
2365
|
+
function useGraphTheme({
|
|
2366
|
+
mode = "dark",
|
|
2367
|
+
theme
|
|
2368
|
+
} = {}) {
|
|
2369
|
+
return useMemo(() => {
|
|
2370
|
+
const baseTheme = mode === "light" ? GRAPH_LIGHT_THEME : mode === "dark" ? GRAPH_DARK_THEME : DEFAULT_GRAPH_THEME;
|
|
2371
|
+
return mergeGraphTheme(baseTheme, theme);
|
|
2372
|
+
}, [mode, theme]);
|
|
2373
|
+
}
|
|
2374
|
+
var GraphContext = createContext({
|
|
2375
|
+
data: [],
|
|
2376
|
+
loading: false,
|
|
2377
|
+
error: null,
|
|
2378
|
+
status: "idle",
|
|
2379
|
+
maxDataPoints: GRAPH_DEFAULT_MAX_REALTIME_POINTS,
|
|
2380
|
+
refresh: async () => {
|
|
2381
|
+
},
|
|
2382
|
+
replaceData: () => {
|
|
2383
|
+
},
|
|
2384
|
+
appendData: () => {
|
|
2385
|
+
},
|
|
2386
|
+
clearData: () => {
|
|
2387
|
+
}
|
|
2388
|
+
});
|
|
2389
|
+
function GraphProvider({
|
|
2390
|
+
children,
|
|
2391
|
+
data,
|
|
2392
|
+
dataSource,
|
|
2393
|
+
maxDataPoints = GRAPH_DEFAULT_MAX_REALTIME_POINTS,
|
|
2394
|
+
autoLoad = true,
|
|
2395
|
+
onDataChange,
|
|
2396
|
+
onError
|
|
2397
|
+
}) {
|
|
2398
|
+
const graphData = useGraphData({
|
|
2399
|
+
data,
|
|
2400
|
+
dataSource,
|
|
2401
|
+
autoLoad,
|
|
2402
|
+
maxDataPoints,
|
|
2403
|
+
onDataChange,
|
|
2404
|
+
onError
|
|
2405
|
+
});
|
|
2406
|
+
const value = useMemo(
|
|
2407
|
+
() => ({
|
|
2408
|
+
...graphData,
|
|
2409
|
+
mode: dataSource?.mode,
|
|
2410
|
+
maxDataPoints
|
|
2411
|
+
}),
|
|
2412
|
+
[dataSource?.mode, graphData, maxDataPoints]
|
|
2413
|
+
);
|
|
2414
|
+
return /* @__PURE__ */ jsx(
|
|
2415
|
+
GraphContext.Provider,
|
|
2416
|
+
{
|
|
2417
|
+
value,
|
|
2418
|
+
children
|
|
2419
|
+
}
|
|
2420
|
+
);
|
|
2421
|
+
}
|
|
2422
|
+
function useGraphContext() {
|
|
2423
|
+
return useContext(GraphContext);
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
// src/components/data-display/graphs-v2/context/graphReducer.ts
|
|
2427
|
+
function createInitialGraphState(data = []) {
|
|
2428
|
+
return {
|
|
2429
|
+
data,
|
|
2430
|
+
loading: false,
|
|
2431
|
+
error: null,
|
|
2432
|
+
status: data.length > 0 ? "success" : "idle",
|
|
2433
|
+
lastUpdatedAt: data.length > 0 ? /* @__PURE__ */ new Date() : void 0
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
function graphReducer(state, action) {
|
|
2437
|
+
switch (action.type) {
|
|
2438
|
+
case "SET_LOADING": {
|
|
2439
|
+
const loading = action.payload ?? true;
|
|
2440
|
+
return {
|
|
2441
|
+
...state,
|
|
2442
|
+
loading,
|
|
2443
|
+
error: loading ? null : state.error,
|
|
2444
|
+
status: loading ? "loading" : state.status
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
case "SET_ERROR": {
|
|
2448
|
+
return {
|
|
2449
|
+
...state,
|
|
2450
|
+
loading: false,
|
|
2451
|
+
error: action.payload,
|
|
2452
|
+
status: action.payload ? "error" : state.data.length > 0 ? "success" : "idle"
|
|
2453
|
+
};
|
|
2454
|
+
}
|
|
2455
|
+
case "SET_DATA": {
|
|
2456
|
+
return {
|
|
2457
|
+
data: action.payload,
|
|
2458
|
+
loading: false,
|
|
2459
|
+
error: null,
|
|
2460
|
+
status: "success",
|
|
2461
|
+
lastUpdatedAt: /* @__PURE__ */ new Date()
|
|
2462
|
+
};
|
|
2463
|
+
}
|
|
2464
|
+
case "APPEND_DATA": {
|
|
2465
|
+
const nextData = limitRealtimePoints(state.data, action.payload.data, {
|
|
2466
|
+
maxPoints: action.payload.maxDataPoints ?? GRAPH_DEFAULT_MAX_REALTIME_POINTS
|
|
2467
|
+
});
|
|
2468
|
+
return {
|
|
2469
|
+
data: nextData,
|
|
2470
|
+
loading: false,
|
|
2471
|
+
error: null,
|
|
2472
|
+
status: "streaming",
|
|
2473
|
+
lastUpdatedAt: /* @__PURE__ */ new Date()
|
|
2474
|
+
};
|
|
2475
|
+
}
|
|
2476
|
+
case "CLEAR_DATA": {
|
|
2477
|
+
return {
|
|
2478
|
+
data: [],
|
|
2479
|
+
loading: false,
|
|
2480
|
+
error: null,
|
|
2481
|
+
status: "idle",
|
|
2482
|
+
lastUpdatedAt: void 0
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
case "SET_STREAMING": {
|
|
2486
|
+
const streaming = action.payload ?? true;
|
|
2487
|
+
return {
|
|
2488
|
+
...state,
|
|
2489
|
+
loading: false,
|
|
2490
|
+
error: null,
|
|
2491
|
+
status: streaming ? "streaming" : state.data.length > 0 ? "success" : "idle",
|
|
2492
|
+
lastUpdatedAt: streaming ? /* @__PURE__ */ new Date() : state.lastUpdatedAt
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
default:
|
|
2496
|
+
return state;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
function GraphEmptyState({
|
|
2500
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2501
|
+
message = GRAPH_EMPTY_MESSAGE,
|
|
2502
|
+
description,
|
|
2503
|
+
className = ""
|
|
2504
|
+
}) {
|
|
2505
|
+
return /* @__PURE__ */ jsxs(
|
|
2506
|
+
"div",
|
|
2507
|
+
{
|
|
2508
|
+
className: `eui-graph flex flex-col items-center justify-center rounded-xl border border-dashed border-gray-700/80 bg-[#111217]/40 px-6 text-center ${className}`,
|
|
2509
|
+
style: { height },
|
|
2510
|
+
children: [
|
|
2511
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-gray-700 bg-white/5 text-gray-500", children: "\u2205" }),
|
|
2512
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 text-sm font-medium text-gray-300", children: message }),
|
|
2513
|
+
description && /* @__PURE__ */ jsx("div", { className: "mt-1 max-w-sm text-xs text-gray-500", children: description })
|
|
2514
|
+
]
|
|
2515
|
+
}
|
|
2516
|
+
);
|
|
2517
|
+
}
|
|
2518
|
+
function GraphErrorState({
|
|
2519
|
+
error,
|
|
2520
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2521
|
+
title = GRAPH_ERROR_MESSAGE,
|
|
2522
|
+
message,
|
|
2523
|
+
className = "",
|
|
2524
|
+
onRetry,
|
|
2525
|
+
retryLabel = "Retry"
|
|
2526
|
+
}) {
|
|
2527
|
+
const resolvedMessage = message ?? error?.message;
|
|
2528
|
+
return /* @__PURE__ */ jsxs(
|
|
2529
|
+
"div",
|
|
2530
|
+
{
|
|
2531
|
+
className: `eui-graph flex flex-col items-center justify-center rounded-xl border border-red-500/30 bg-red-500/5 px-6 text-center ${className}`,
|
|
2532
|
+
style: { height },
|
|
2533
|
+
role: "alert",
|
|
2534
|
+
children: [
|
|
2535
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full border border-red-500/30 bg-red-500/10 text-red-400", children: "!" }),
|
|
2536
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 text-sm font-medium text-red-300", children: title }),
|
|
2537
|
+
resolvedMessage && /* @__PURE__ */ jsx("div", { className: "mt-1 max-w-md text-xs text-red-200/70", children: resolvedMessage }),
|
|
2538
|
+
onRetry && /* @__PURE__ */ jsx(
|
|
2539
|
+
"button",
|
|
2540
|
+
{
|
|
2541
|
+
type: "button",
|
|
2542
|
+
onClick: () => void onRetry(),
|
|
2543
|
+
className: "mt-4 rounded-md border border-red-500/30 px-3 py-1.5 text-xs font-medium text-red-200 transition-colors hover:bg-red-500/10",
|
|
2544
|
+
children: retryLabel
|
|
2545
|
+
}
|
|
2546
|
+
)
|
|
2547
|
+
]
|
|
2548
|
+
}
|
|
2549
|
+
);
|
|
2550
|
+
}
|
|
2551
|
+
function GraphHeader({
|
|
2552
|
+
title,
|
|
2553
|
+
description,
|
|
2554
|
+
actions,
|
|
2555
|
+
className = ""
|
|
2556
|
+
}) {
|
|
2557
|
+
if (!title && !description && !actions) {
|
|
2558
|
+
return null;
|
|
2559
|
+
}
|
|
2560
|
+
return /* @__PURE__ */ jsxs(
|
|
2561
|
+
"div",
|
|
2562
|
+
{
|
|
2563
|
+
className: `flex items-start justify-between gap-4 border-b border-[#2a2d35] px-4 py-3 ${className}`,
|
|
2564
|
+
children: [
|
|
2565
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
2566
|
+
title && /* @__PURE__ */ jsx("div", { className: "eui-graph-title truncate text-sm font-semibold text-gray-100", children: title }),
|
|
2567
|
+
description && /* @__PURE__ */ jsx("div", { className: "eui-graph-description mt-1 text-xs text-gray-400", children: description })
|
|
2568
|
+
] }),
|
|
2569
|
+
actions && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: actions })
|
|
2570
|
+
]
|
|
2571
|
+
}
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
function GraphLoadingState({
|
|
2575
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2576
|
+
message = GRAPH_LOADING_MESSAGE,
|
|
2577
|
+
className = "",
|
|
2578
|
+
showMessage = true
|
|
2579
|
+
}) {
|
|
2580
|
+
return /* @__PURE__ */ jsxs(
|
|
2581
|
+
"div",
|
|
2582
|
+
{
|
|
2583
|
+
className: `eui-graph eui-graph-loading flex flex-col items-center justify-center rounded-xl border border-[#2a2d35] bg-[#111217]/60 px-6 text-center ${className}`,
|
|
2584
|
+
style: { height },
|
|
2585
|
+
role: "status",
|
|
2586
|
+
"aria-live": "polite",
|
|
2587
|
+
"aria-busy": "true",
|
|
2588
|
+
children: [
|
|
2589
|
+
/* @__PURE__ */ jsx("div", { className: "h-7 w-7 animate-spin rounded-full border-2 border-gray-700 border-t-gray-200" }),
|
|
2590
|
+
showMessage && /* @__PURE__ */ jsx("span", { className: "mt-3 text-sm font-medium text-gray-300", children: message })
|
|
2591
|
+
]
|
|
2592
|
+
}
|
|
2593
|
+
);
|
|
2594
|
+
}
|
|
2595
|
+
function formatLastUpdatedAt(value) {
|
|
2596
|
+
if (!value) {
|
|
2597
|
+
return "Never updated";
|
|
2598
|
+
}
|
|
2599
|
+
return `Updated ${value.toLocaleTimeString([], {
|
|
2600
|
+
hour: "2-digit",
|
|
2601
|
+
minute: "2-digit",
|
|
2602
|
+
second: "2-digit"
|
|
2603
|
+
})}`;
|
|
2604
|
+
}
|
|
2605
|
+
function GraphToolbar({
|
|
2606
|
+
children,
|
|
2607
|
+
className = "",
|
|
2608
|
+
showRefresh = true,
|
|
2609
|
+
showLastUpdated = true,
|
|
2610
|
+
refreshLabel = "Refresh",
|
|
2611
|
+
onRefresh
|
|
2612
|
+
}) {
|
|
2613
|
+
const graph = useGraphContext();
|
|
2614
|
+
async function handleRefresh() {
|
|
2615
|
+
if (onRefresh) {
|
|
2616
|
+
await onRefresh();
|
|
2617
|
+
return;
|
|
2618
|
+
}
|
|
2619
|
+
await graph.refresh();
|
|
2620
|
+
}
|
|
2621
|
+
if (!children && !showRefresh && !showLastUpdated) {
|
|
2622
|
+
return null;
|
|
2623
|
+
}
|
|
2624
|
+
return /* @__PURE__ */ jsxs(
|
|
2625
|
+
"div",
|
|
2626
|
+
{
|
|
2627
|
+
className: `flex flex-wrap items-center justify-between gap-3 border-b border-[#2a2d35] px-4 py-2 ${className}`,
|
|
2628
|
+
children: [
|
|
2629
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-2", children }),
|
|
2630
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-3", children: [
|
|
2631
|
+
showLastUpdated && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: formatLastUpdatedAt(graph.lastUpdatedAt) }),
|
|
2632
|
+
showRefresh && /* @__PURE__ */ jsx(
|
|
2633
|
+
"button",
|
|
2634
|
+
{
|
|
2635
|
+
type: "button",
|
|
2636
|
+
onClick: () => void handleRefresh(),
|
|
2637
|
+
disabled: graph.loading,
|
|
2638
|
+
className: "rounded-md border border-[#2a2d35] px-2.5 py-1.5 text-xs font-medium text-gray-300 transition-colors hover:bg-white/5 disabled:cursor-not-allowed disabled:opacity-60",
|
|
2639
|
+
children: graph.loading ? "Refreshing..." : refreshLabel
|
|
2640
|
+
}
|
|
2641
|
+
)
|
|
2642
|
+
] })
|
|
2643
|
+
]
|
|
2644
|
+
}
|
|
2645
|
+
);
|
|
2646
|
+
}
|
|
2647
|
+
function GraphPanel({
|
|
2648
|
+
title,
|
|
2649
|
+
description,
|
|
2650
|
+
actions,
|
|
2651
|
+
toolbar,
|
|
2652
|
+
children,
|
|
2653
|
+
className = "",
|
|
2654
|
+
contentClassName = "",
|
|
2655
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2656
|
+
loading,
|
|
2657
|
+
error,
|
|
2658
|
+
empty,
|
|
2659
|
+
emptyMessage,
|
|
2660
|
+
emptyDescription,
|
|
2661
|
+
showToolbar = false,
|
|
2662
|
+
showRefresh = true,
|
|
2663
|
+
showLastUpdated = true,
|
|
2664
|
+
onRetry
|
|
2665
|
+
}) {
|
|
2666
|
+
const graph = useGraphContext();
|
|
2667
|
+
const resolvedLoading = loading ?? graph.loading;
|
|
2668
|
+
const resolvedError = error ?? graph.error;
|
|
2669
|
+
const resolvedEmpty = empty ?? graph.data.length === 0;
|
|
2670
|
+
function renderContent() {
|
|
2671
|
+
if (resolvedLoading) {
|
|
2672
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height });
|
|
2673
|
+
}
|
|
2674
|
+
if (resolvedError) {
|
|
2675
|
+
return /* @__PURE__ */ jsx(
|
|
2676
|
+
GraphErrorState,
|
|
2677
|
+
{
|
|
2678
|
+
height,
|
|
2679
|
+
error: resolvedError,
|
|
2680
|
+
onRetry: onRetry ?? graph.refresh
|
|
2681
|
+
}
|
|
2682
|
+
);
|
|
2683
|
+
}
|
|
2684
|
+
if (resolvedEmpty) {
|
|
2685
|
+
return /* @__PURE__ */ jsx(
|
|
2686
|
+
GraphEmptyState,
|
|
2687
|
+
{
|
|
2688
|
+
height,
|
|
2689
|
+
message: emptyMessage,
|
|
2690
|
+
description: emptyDescription
|
|
2691
|
+
}
|
|
2692
|
+
);
|
|
2693
|
+
}
|
|
2694
|
+
return children;
|
|
2695
|
+
}
|
|
2696
|
+
return /* @__PURE__ */ jsxs(
|
|
2697
|
+
"section",
|
|
2698
|
+
{
|
|
2699
|
+
className: `eui-graph eui-graph-panel overflow-hidden rounded-xl border border-[#2a2d35] bg-[#111217] ${className}`,
|
|
2700
|
+
children: [
|
|
2701
|
+
/* @__PURE__ */ jsx(GraphHeader, { title, description, actions }),
|
|
2702
|
+
showToolbar && /* @__PURE__ */ jsx(
|
|
2703
|
+
GraphToolbar,
|
|
2704
|
+
{
|
|
2705
|
+
showRefresh,
|
|
2706
|
+
showLastUpdated,
|
|
2707
|
+
children: toolbar
|
|
2708
|
+
}
|
|
2709
|
+
),
|
|
2710
|
+
/* @__PURE__ */ jsx("div", { className: `p-4 ${contentClassName}`, children: renderContent() })
|
|
2711
|
+
]
|
|
2712
|
+
}
|
|
2713
|
+
);
|
|
2714
|
+
}
|
|
2715
|
+
function createLabelFromKey2(key) {
|
|
2716
|
+
return key.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\b\w/g, (character) => character.toUpperCase());
|
|
2717
|
+
}
|
|
2718
|
+
function GraphLegend({
|
|
2719
|
+
items,
|
|
2720
|
+
series,
|
|
2721
|
+
data = [],
|
|
2722
|
+
className = "",
|
|
2723
|
+
showValues = true,
|
|
2724
|
+
valueSource = "latest",
|
|
2725
|
+
onItemClick
|
|
2726
|
+
}) {
|
|
2727
|
+
const legendItems = useMemo(() => {
|
|
2728
|
+
if (items?.length) {
|
|
2729
|
+
return items;
|
|
2730
|
+
}
|
|
2731
|
+
if (!series?.length) {
|
|
2732
|
+
return [];
|
|
2733
|
+
}
|
|
2734
|
+
const latestPoint = data[data.length - 1];
|
|
2735
|
+
return series.map((item, index) => ({
|
|
2736
|
+
key: item.key,
|
|
2737
|
+
label: item.label ?? createLabelFromKey2(item.key),
|
|
2738
|
+
color: resolveGraphColor(item.color, { index }),
|
|
2739
|
+
value: valueSource === "latest" ? latestPoint?.[item.key] : void 0,
|
|
2740
|
+
unit: item.unit,
|
|
2741
|
+
format: item.format,
|
|
2742
|
+
prefix: item.prefix,
|
|
2743
|
+
suffix: item.suffix,
|
|
2744
|
+
active: item.visible ?? true
|
|
2745
|
+
}));
|
|
2746
|
+
}, [data, items, series, valueSource]);
|
|
2747
|
+
if (!legendItems.length) {
|
|
2748
|
+
return null;
|
|
2749
|
+
}
|
|
2750
|
+
return /* @__PURE__ */ jsx(
|
|
2751
|
+
"div",
|
|
2752
|
+
{
|
|
2753
|
+
className: `eui-graph flex flex-wrap items-center gap-x-4 gap-y-2 text-xs ${className}`,
|
|
2754
|
+
children: legendItems.map((item, index) => {
|
|
2755
|
+
const color = resolveGraphColor(item.color, { index });
|
|
2756
|
+
const active = item.active ?? true;
|
|
2757
|
+
return /* @__PURE__ */ jsxs(
|
|
2758
|
+
"button",
|
|
2759
|
+
{
|
|
2760
|
+
type: "button",
|
|
2761
|
+
onClick: () => onItemClick?.(item),
|
|
2762
|
+
disabled: !onItemClick,
|
|
2763
|
+
className: `inline-flex items-center gap-2 rounded-md transition-opacity ${active ? "opacity-100" : "opacity-40"} ${onItemClick ? "cursor-pointer hover:opacity-80" : "cursor-default"}`,
|
|
2764
|
+
children: [
|
|
2765
|
+
/* @__PURE__ */ jsx(
|
|
2766
|
+
"span",
|
|
2767
|
+
{
|
|
2768
|
+
className: "h-2.5 w-2.5 rounded-full",
|
|
2769
|
+
style: { backgroundColor: color }
|
|
2770
|
+
}
|
|
2771
|
+
),
|
|
2772
|
+
/* @__PURE__ */ jsx("span", { className: "text-gray-400", children: item.label ?? createLabelFromKey2(item.key) }),
|
|
2773
|
+
showValues && item.value !== void 0 && /* @__PURE__ */ jsx("span", { className: "font-medium text-gray-200", children: formatGraphValue(item.value, {
|
|
2774
|
+
format: item.format ?? "number",
|
|
2775
|
+
prefix: item.prefix,
|
|
2776
|
+
suffix: item.suffix ?? item.unit
|
|
2777
|
+
}) })
|
|
2778
|
+
]
|
|
2779
|
+
},
|
|
2780
|
+
item.key
|
|
2781
|
+
);
|
|
2782
|
+
})
|
|
2783
|
+
}
|
|
2784
|
+
);
|
|
2785
|
+
}
|
|
2786
|
+
function GraphTooltip({
|
|
2787
|
+
active,
|
|
2788
|
+
label,
|
|
2789
|
+
payload,
|
|
2790
|
+
className = "",
|
|
2791
|
+
labelFormatter,
|
|
2792
|
+
valueFormatter,
|
|
2793
|
+
seriesFormatters = {}
|
|
2794
|
+
}) {
|
|
2795
|
+
if (!active || !payload?.length) {
|
|
2796
|
+
return null;
|
|
2797
|
+
}
|
|
2798
|
+
return /* @__PURE__ */ jsxs(
|
|
2799
|
+
"div",
|
|
2800
|
+
{
|
|
2801
|
+
className: `eui-graph rounded-xl border border-[#2a2d35] bg-[#181b21] px-3 py-2 shadow-xl ${className}`,
|
|
2802
|
+
children: [
|
|
2803
|
+
label !== void 0 && /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-semibold text-gray-100", children: labelFormatter ? labelFormatter(label) : label }),
|
|
2804
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: payload.map((item, index) => {
|
|
2805
|
+
const dataKey = item.dataKey ?? item.name ?? String(index);
|
|
2806
|
+
const formatterOptions = seriesFormatters[dataKey];
|
|
2807
|
+
const formattedValue = valueFormatter ? valueFormatter(item.value, item.name, item) : formatGraphValue(item.value, {
|
|
2808
|
+
format: formatterOptions?.format ?? "number",
|
|
2809
|
+
prefix: formatterOptions?.prefix,
|
|
2810
|
+
suffix: formatterOptions?.suffix ?? formatterOptions?.unit
|
|
2811
|
+
});
|
|
2812
|
+
return /* @__PURE__ */ jsxs(
|
|
2813
|
+
"div",
|
|
2814
|
+
{
|
|
2815
|
+
className: "flex min-w-[140px] items-center justify-between gap-4 text-xs",
|
|
2816
|
+
children: [
|
|
2817
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2818
|
+
/* @__PURE__ */ jsx(
|
|
2819
|
+
"span",
|
|
2820
|
+
{
|
|
2821
|
+
className: "h-2 w-2 rounded-full",
|
|
2822
|
+
style: { backgroundColor: item.color }
|
|
2823
|
+
}
|
|
2824
|
+
),
|
|
2825
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-gray-400", children: item.name ?? dataKey })
|
|
2826
|
+
] }),
|
|
2827
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-100", children: formattedValue })
|
|
2828
|
+
]
|
|
2829
|
+
},
|
|
2830
|
+
`${dataKey}-${index}`
|
|
2831
|
+
);
|
|
2832
|
+
}) })
|
|
2833
|
+
]
|
|
2834
|
+
}
|
|
2835
|
+
);
|
|
2836
|
+
}
|
|
2837
|
+
function GraphContainer({
|
|
2838
|
+
children,
|
|
2839
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2840
|
+
className = "",
|
|
2841
|
+
contentClassName = ""
|
|
2842
|
+
}) {
|
|
2843
|
+
return /* @__PURE__ */ jsx(
|
|
2844
|
+
"div",
|
|
2845
|
+
{
|
|
2846
|
+
className: `eui-graph relative w-full min-w-0 overflow-hidden ${className}`,
|
|
2847
|
+
style: { height },
|
|
2848
|
+
children: /* @__PURE__ */ jsx("div", { className: `h-full w-full ${contentClassName}`, children })
|
|
2849
|
+
}
|
|
2850
|
+
);
|
|
2851
|
+
}
|
|
2852
|
+
function LineGraph({
|
|
2853
|
+
data,
|
|
2854
|
+
xKey = "time",
|
|
2855
|
+
series,
|
|
2856
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2857
|
+
loading,
|
|
2858
|
+
error,
|
|
2859
|
+
className = "",
|
|
2860
|
+
showGrid = true,
|
|
2861
|
+
showTooltip = true,
|
|
2862
|
+
showLegend = true,
|
|
2863
|
+
animated = true
|
|
2864
|
+
}) {
|
|
2865
|
+
const context = useGraphContext();
|
|
2866
|
+
const theme = useGraphTheme();
|
|
2867
|
+
const graphData = data ?? context.data;
|
|
2868
|
+
const graphLoading = loading ?? context.loading;
|
|
2869
|
+
const graphError = error ?? context.error;
|
|
2870
|
+
const resolvedSeries = useGraphSeries({
|
|
2871
|
+
data: graphData,
|
|
2872
|
+
series,
|
|
2873
|
+
xKey: String(xKey)
|
|
2874
|
+
}).filter((item) => item.visible);
|
|
2875
|
+
if (graphLoading) {
|
|
2876
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height, className });
|
|
2877
|
+
}
|
|
2878
|
+
if (graphError) {
|
|
2879
|
+
return /* @__PURE__ */ jsx(
|
|
2880
|
+
GraphErrorState,
|
|
2881
|
+
{
|
|
2882
|
+
error: graphError,
|
|
2883
|
+
height,
|
|
2884
|
+
className
|
|
2885
|
+
}
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
if (!graphData.length || !resolvedSeries.length) {
|
|
2889
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height, className });
|
|
2890
|
+
}
|
|
2891
|
+
return /* @__PURE__ */ jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
|
|
2892
|
+
/* @__PURE__ */ jsx(GraphContainer, { height, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(LineChart$1, { data: graphData, margin: GRAPH_DEFAULT_MARGIN, children: [
|
|
2893
|
+
showGrid && /* @__PURE__ */ jsx(
|
|
2894
|
+
CartesianGrid,
|
|
2895
|
+
{
|
|
2896
|
+
stroke: theme.chart.grid,
|
|
2897
|
+
strokeDasharray: "3 3",
|
|
2898
|
+
vertical: false
|
|
2899
|
+
}
|
|
2900
|
+
),
|
|
2901
|
+
/* @__PURE__ */ jsx(
|
|
2902
|
+
XAxis,
|
|
2903
|
+
{
|
|
2904
|
+
dataKey: String(xKey),
|
|
2905
|
+
stroke: theme.chart.axis,
|
|
2906
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
2907
|
+
tickLine: false,
|
|
2908
|
+
axisLine: false
|
|
2909
|
+
}
|
|
2910
|
+
),
|
|
2911
|
+
/* @__PURE__ */ jsx(
|
|
2912
|
+
YAxis,
|
|
2913
|
+
{
|
|
2914
|
+
stroke: theme.chart.axis,
|
|
2915
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
2916
|
+
tickLine: false,
|
|
2917
|
+
axisLine: false,
|
|
2918
|
+
tickFormatter: (value) => formatGraphValue(value, {
|
|
2919
|
+
format: "compact"
|
|
2920
|
+
})
|
|
2921
|
+
}
|
|
2922
|
+
),
|
|
2923
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
2924
|
+
Tooltip$1,
|
|
2925
|
+
{
|
|
2926
|
+
content: /* @__PURE__ */ jsx(
|
|
2927
|
+
GraphTooltip,
|
|
2928
|
+
{
|
|
2929
|
+
seriesFormatters: Object.fromEntries(
|
|
2930
|
+
resolvedSeries.map((item) => [
|
|
2931
|
+
item.key,
|
|
2932
|
+
{
|
|
2933
|
+
format: item.format,
|
|
2934
|
+
prefix: item.prefix,
|
|
2935
|
+
suffix: item.suffix,
|
|
2936
|
+
unit: item.unit
|
|
2937
|
+
}
|
|
2938
|
+
])
|
|
2939
|
+
)
|
|
2940
|
+
}
|
|
2941
|
+
),
|
|
2942
|
+
cursor: { stroke: theme.chart.cursor }
|
|
2943
|
+
}
|
|
2944
|
+
),
|
|
2945
|
+
resolvedSeries.map((item) => /* @__PURE__ */ jsx(
|
|
2946
|
+
Line$1,
|
|
2947
|
+
{
|
|
2948
|
+
type: "monotone",
|
|
2949
|
+
dataKey: item.key,
|
|
2950
|
+
name: item.label,
|
|
2951
|
+
stroke: item.color,
|
|
2952
|
+
strokeWidth: item.strokeWidth,
|
|
2953
|
+
dot: false,
|
|
2954
|
+
activeDot: { r: item.radius },
|
|
2955
|
+
isAnimationActive: animated,
|
|
2956
|
+
animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
|
|
2957
|
+
yAxisId: item.yAxisId
|
|
2958
|
+
},
|
|
2959
|
+
item.key
|
|
2960
|
+
))
|
|
2961
|
+
] }) }) }),
|
|
2962
|
+
showLegend && /* @__PURE__ */ jsx(
|
|
2963
|
+
GraphLegend,
|
|
2964
|
+
{
|
|
2965
|
+
series: resolvedSeries,
|
|
2966
|
+
data: graphData,
|
|
2967
|
+
showValues: true,
|
|
2968
|
+
valueSource: "latest"
|
|
2969
|
+
}
|
|
2970
|
+
)
|
|
2971
|
+
] });
|
|
2972
|
+
}
|
|
2973
|
+
function AreaGraph({
|
|
2974
|
+
data,
|
|
2975
|
+
xKey = "time",
|
|
2976
|
+
series,
|
|
2977
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
2978
|
+
loading,
|
|
2979
|
+
error,
|
|
2980
|
+
className = "",
|
|
2981
|
+
showGrid = true,
|
|
2982
|
+
showTooltip = true,
|
|
2983
|
+
showLegend = true,
|
|
2984
|
+
animated = true
|
|
2985
|
+
}) {
|
|
2986
|
+
const context = useGraphContext();
|
|
2987
|
+
const theme = useGraphTheme();
|
|
2988
|
+
const graphData = data ?? context.data;
|
|
2989
|
+
const graphLoading = loading ?? context.loading;
|
|
2990
|
+
const graphError = error ?? context.error;
|
|
2991
|
+
const resolvedSeries = useGraphSeries({
|
|
2992
|
+
data: graphData,
|
|
2993
|
+
series,
|
|
2994
|
+
xKey: String(xKey)
|
|
2995
|
+
}).filter((item) => item.visible);
|
|
2996
|
+
if (graphLoading) {
|
|
2997
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height, className });
|
|
2998
|
+
}
|
|
2999
|
+
if (graphError) {
|
|
3000
|
+
return /* @__PURE__ */ jsx(
|
|
3001
|
+
GraphErrorState,
|
|
3002
|
+
{
|
|
3003
|
+
error: graphError,
|
|
3004
|
+
height,
|
|
3005
|
+
className
|
|
3006
|
+
}
|
|
3007
|
+
);
|
|
3008
|
+
}
|
|
3009
|
+
if (!graphData.length || !resolvedSeries.length) {
|
|
3010
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height, className });
|
|
3011
|
+
}
|
|
3012
|
+
return /* @__PURE__ */ jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
|
|
3013
|
+
/* @__PURE__ */ jsx(GraphContainer, { height, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart, { data: graphData, margin: GRAPH_DEFAULT_MARGIN, children: [
|
|
3014
|
+
/* @__PURE__ */ jsx("defs", { children: resolvedSeries.map((item) => /* @__PURE__ */ jsxs(
|
|
3015
|
+
"linearGradient",
|
|
3016
|
+
{
|
|
3017
|
+
id: `eui-area-gradient-${item.key}`,
|
|
3018
|
+
x1: "0",
|
|
3019
|
+
y1: "0",
|
|
3020
|
+
x2: "0",
|
|
3021
|
+
y2: "1",
|
|
3022
|
+
children: [
|
|
3023
|
+
/* @__PURE__ */ jsx("stop", { offset: "5%", stopColor: item.color, stopOpacity: 0.35 }),
|
|
3024
|
+
/* @__PURE__ */ jsx(
|
|
3025
|
+
"stop",
|
|
3026
|
+
{
|
|
3027
|
+
offset: "95%",
|
|
3028
|
+
stopColor: item.color,
|
|
3029
|
+
stopOpacity: 0.02
|
|
3030
|
+
}
|
|
3031
|
+
)
|
|
3032
|
+
]
|
|
3033
|
+
},
|
|
3034
|
+
item.key
|
|
3035
|
+
)) }),
|
|
3036
|
+
showGrid && /* @__PURE__ */ jsx(
|
|
3037
|
+
CartesianGrid,
|
|
3038
|
+
{
|
|
3039
|
+
stroke: theme.chart.grid,
|
|
3040
|
+
strokeDasharray: "3 3",
|
|
3041
|
+
vertical: false
|
|
3042
|
+
}
|
|
3043
|
+
),
|
|
3044
|
+
/* @__PURE__ */ jsx(
|
|
3045
|
+
XAxis,
|
|
3046
|
+
{
|
|
3047
|
+
dataKey: String(xKey),
|
|
3048
|
+
stroke: theme.chart.axis,
|
|
3049
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3050
|
+
tickLine: false,
|
|
3051
|
+
axisLine: false
|
|
3052
|
+
}
|
|
3053
|
+
),
|
|
3054
|
+
/* @__PURE__ */ jsx(
|
|
3055
|
+
YAxis,
|
|
3056
|
+
{
|
|
3057
|
+
stroke: theme.chart.axis,
|
|
3058
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3059
|
+
tickLine: false,
|
|
3060
|
+
axisLine: false,
|
|
3061
|
+
tickFormatter: (value) => formatGraphValue(value, {
|
|
3062
|
+
format: "compact"
|
|
3063
|
+
})
|
|
3064
|
+
}
|
|
3065
|
+
),
|
|
3066
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
3067
|
+
Tooltip$1,
|
|
3068
|
+
{
|
|
3069
|
+
content: /* @__PURE__ */ jsx(
|
|
3070
|
+
GraphTooltip,
|
|
3071
|
+
{
|
|
3072
|
+
seriesFormatters: Object.fromEntries(
|
|
3073
|
+
resolvedSeries.map((item) => [
|
|
3074
|
+
item.key,
|
|
3075
|
+
{
|
|
3076
|
+
format: item.format,
|
|
3077
|
+
prefix: item.prefix,
|
|
3078
|
+
suffix: item.suffix,
|
|
3079
|
+
unit: item.unit
|
|
3080
|
+
}
|
|
3081
|
+
])
|
|
3082
|
+
)
|
|
3083
|
+
}
|
|
3084
|
+
),
|
|
3085
|
+
cursor: { stroke: theme.chart.cursor }
|
|
3086
|
+
}
|
|
3087
|
+
),
|
|
3088
|
+
resolvedSeries.map((item) => /* @__PURE__ */ jsx(
|
|
3089
|
+
Area,
|
|
3090
|
+
{
|
|
3091
|
+
type: "monotone",
|
|
3092
|
+
dataKey: item.key,
|
|
3093
|
+
name: item.label,
|
|
3094
|
+
stroke: item.color,
|
|
3095
|
+
strokeWidth: item.strokeWidth,
|
|
3096
|
+
fill: `url(#eui-area-gradient-${item.key})`,
|
|
3097
|
+
isAnimationActive: animated,
|
|
3098
|
+
animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
|
|
3099
|
+
yAxisId: item.yAxisId
|
|
3100
|
+
},
|
|
3101
|
+
item.key
|
|
3102
|
+
))
|
|
3103
|
+
] }) }) }),
|
|
3104
|
+
showLegend && /* @__PURE__ */ jsx(
|
|
3105
|
+
GraphLegend,
|
|
3106
|
+
{
|
|
3107
|
+
series: resolvedSeries,
|
|
3108
|
+
data: graphData,
|
|
3109
|
+
showValues: true,
|
|
3110
|
+
valueSource: "latest"
|
|
3111
|
+
}
|
|
3112
|
+
)
|
|
3113
|
+
] });
|
|
3114
|
+
}
|
|
3115
|
+
function BarGraph({
|
|
3116
|
+
data,
|
|
3117
|
+
xKey = "name",
|
|
3118
|
+
series,
|
|
3119
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
3120
|
+
loading,
|
|
3121
|
+
error,
|
|
3122
|
+
className = "",
|
|
3123
|
+
showGrid = true,
|
|
3124
|
+
showTooltip = true,
|
|
3125
|
+
showLegend = true,
|
|
3126
|
+
animated = true,
|
|
3127
|
+
layout = "horizontal"
|
|
3128
|
+
}) {
|
|
3129
|
+
const context = useGraphContext();
|
|
3130
|
+
const theme = useGraphTheme();
|
|
3131
|
+
const graphData = data ?? context.data;
|
|
3132
|
+
const graphLoading = loading ?? context.loading;
|
|
3133
|
+
const graphError = error ?? context.error;
|
|
3134
|
+
const resolvedSeries = useGraphSeries({
|
|
3135
|
+
data: graphData,
|
|
3136
|
+
series,
|
|
3137
|
+
xKey: String(xKey)
|
|
3138
|
+
}).filter((item) => item.visible);
|
|
3139
|
+
if (graphLoading) {
|
|
3140
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height, className });
|
|
3141
|
+
}
|
|
3142
|
+
if (graphError) {
|
|
3143
|
+
return /* @__PURE__ */ jsx(
|
|
3144
|
+
GraphErrorState,
|
|
3145
|
+
{
|
|
3146
|
+
error: graphError,
|
|
3147
|
+
height,
|
|
3148
|
+
className
|
|
3149
|
+
}
|
|
3150
|
+
);
|
|
3151
|
+
}
|
|
3152
|
+
if (!graphData.length || !resolvedSeries.length) {
|
|
3153
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height, className });
|
|
3154
|
+
}
|
|
3155
|
+
const isVertical = layout === "vertical";
|
|
3156
|
+
return /* @__PURE__ */ jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
|
|
3157
|
+
/* @__PURE__ */ jsx(GraphContainer, { height, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
|
|
3158
|
+
BarChart$1,
|
|
3159
|
+
{
|
|
3160
|
+
data: graphData,
|
|
3161
|
+
margin: GRAPH_DEFAULT_MARGIN,
|
|
3162
|
+
layout: isVertical ? "vertical" : "horizontal",
|
|
3163
|
+
children: [
|
|
3164
|
+
showGrid && /* @__PURE__ */ jsx(
|
|
3165
|
+
CartesianGrid,
|
|
3166
|
+
{
|
|
3167
|
+
stroke: theme.chart.grid,
|
|
3168
|
+
strokeDasharray: "3 3",
|
|
3169
|
+
horizontal: !isVertical,
|
|
3170
|
+
vertical: isVertical
|
|
3171
|
+
}
|
|
3172
|
+
),
|
|
3173
|
+
isVertical ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3174
|
+
/* @__PURE__ */ jsx(
|
|
3175
|
+
XAxis,
|
|
3176
|
+
{
|
|
3177
|
+
type: "number",
|
|
3178
|
+
stroke: theme.chart.axis,
|
|
3179
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3180
|
+
tickLine: false,
|
|
3181
|
+
axisLine: false,
|
|
3182
|
+
tickFormatter: (value) => formatGraphValue(value, {
|
|
3183
|
+
format: "compact"
|
|
3184
|
+
})
|
|
3185
|
+
}
|
|
3186
|
+
),
|
|
3187
|
+
/* @__PURE__ */ jsx(
|
|
3188
|
+
YAxis,
|
|
3189
|
+
{
|
|
3190
|
+
type: "category",
|
|
3191
|
+
dataKey: String(xKey),
|
|
3192
|
+
stroke: theme.chart.axis,
|
|
3193
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3194
|
+
tickLine: false,
|
|
3195
|
+
axisLine: false,
|
|
3196
|
+
width: 110
|
|
3197
|
+
}
|
|
3198
|
+
)
|
|
3199
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3200
|
+
/* @__PURE__ */ jsx(
|
|
3201
|
+
XAxis,
|
|
3202
|
+
{
|
|
3203
|
+
dataKey: String(xKey),
|
|
3204
|
+
stroke: theme.chart.axis,
|
|
3205
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3206
|
+
tickLine: false,
|
|
3207
|
+
axisLine: false
|
|
3208
|
+
}
|
|
3209
|
+
),
|
|
3210
|
+
/* @__PURE__ */ jsx(
|
|
3211
|
+
YAxis,
|
|
3212
|
+
{
|
|
3213
|
+
stroke: theme.chart.axis,
|
|
3214
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3215
|
+
tickLine: false,
|
|
3216
|
+
axisLine: false,
|
|
3217
|
+
tickFormatter: (value) => formatGraphValue(value, {
|
|
3218
|
+
format: "compact"
|
|
3219
|
+
})
|
|
3220
|
+
}
|
|
3221
|
+
)
|
|
3222
|
+
] }),
|
|
3223
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
3224
|
+
Tooltip$1,
|
|
3225
|
+
{
|
|
3226
|
+
content: /* @__PURE__ */ jsx(
|
|
3227
|
+
GraphTooltip,
|
|
3228
|
+
{
|
|
3229
|
+
seriesFormatters: Object.fromEntries(
|
|
3230
|
+
resolvedSeries.map((item) => [
|
|
3231
|
+
item.key,
|
|
3232
|
+
{
|
|
3233
|
+
format: item.format,
|
|
3234
|
+
prefix: item.prefix,
|
|
3235
|
+
suffix: item.suffix,
|
|
3236
|
+
unit: item.unit
|
|
3237
|
+
}
|
|
3238
|
+
])
|
|
3239
|
+
)
|
|
3240
|
+
}
|
|
3241
|
+
),
|
|
3242
|
+
cursor: { fill: theme.chart.cursor }
|
|
3243
|
+
}
|
|
3244
|
+
),
|
|
3245
|
+
resolvedSeries.map((item) => /* @__PURE__ */ jsx(
|
|
3246
|
+
Bar$1,
|
|
3247
|
+
{
|
|
3248
|
+
dataKey: item.key,
|
|
3249
|
+
name: item.label,
|
|
3250
|
+
fill: item.color,
|
|
3251
|
+
radius: GRAPH_DEFAULT_BAR_RADIUS,
|
|
3252
|
+
isAnimationActive: animated,
|
|
3253
|
+
animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
|
|
3254
|
+
yAxisId: isVertical ? void 0 : item.yAxisId
|
|
3255
|
+
},
|
|
3256
|
+
item.key
|
|
3257
|
+
))
|
|
3258
|
+
]
|
|
3259
|
+
}
|
|
3260
|
+
) }) }),
|
|
3261
|
+
showLegend && /* @__PURE__ */ jsx(
|
|
3262
|
+
GraphLegend,
|
|
3263
|
+
{
|
|
3264
|
+
series: resolvedSeries,
|
|
3265
|
+
data: graphData,
|
|
3266
|
+
showValues: true,
|
|
3267
|
+
valueSource: "latest"
|
|
3268
|
+
}
|
|
3269
|
+
)
|
|
3270
|
+
] });
|
|
3271
|
+
}
|
|
3272
|
+
function PieGraph({
|
|
3273
|
+
data,
|
|
3274
|
+
nameKey = "name",
|
|
3275
|
+
valueKey = "value",
|
|
3276
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
3277
|
+
loading,
|
|
3278
|
+
error,
|
|
3279
|
+
className = "",
|
|
3280
|
+
showTooltip = true,
|
|
3281
|
+
showLegend = true,
|
|
3282
|
+
animated = true,
|
|
3283
|
+
innerRadius = "45%",
|
|
3284
|
+
outerRadius = "75%",
|
|
3285
|
+
valueFormat = "number",
|
|
3286
|
+
unit
|
|
3287
|
+
}) {
|
|
3288
|
+
const context = useGraphContext();
|
|
3289
|
+
const theme = useGraphTheme();
|
|
3290
|
+
const graphData = data ?? context.data;
|
|
3291
|
+
const graphLoading = loading ?? context.loading;
|
|
3292
|
+
const graphError = error ?? context.error;
|
|
3293
|
+
if (graphLoading) {
|
|
3294
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height, className });
|
|
3295
|
+
}
|
|
3296
|
+
if (graphError) {
|
|
3297
|
+
return /* @__PURE__ */ jsx(
|
|
3298
|
+
GraphErrorState,
|
|
3299
|
+
{
|
|
3300
|
+
error: graphError,
|
|
3301
|
+
height,
|
|
3302
|
+
className
|
|
3303
|
+
}
|
|
3304
|
+
);
|
|
3305
|
+
}
|
|
3306
|
+
if (!graphData.length) {
|
|
3307
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height, className });
|
|
3308
|
+
}
|
|
3309
|
+
const legendItems = graphData.map((item, index) => {
|
|
3310
|
+
const key = String(item[String(nameKey)] ?? index);
|
|
3311
|
+
return {
|
|
3312
|
+
key,
|
|
3313
|
+
label: key,
|
|
3314
|
+
value: item[String(valueKey)],
|
|
3315
|
+
color: resolveGraphColor(void 0, {
|
|
3316
|
+
index,
|
|
3317
|
+
palette: theme.colors
|
|
3318
|
+
}),
|
|
3319
|
+
format: valueFormat,
|
|
3320
|
+
unit,
|
|
3321
|
+
active: true
|
|
3322
|
+
};
|
|
3323
|
+
});
|
|
3324
|
+
return /* @__PURE__ */ jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
|
|
3325
|
+
/* @__PURE__ */ jsx(GraphContainer, { height, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart$1, { children: [
|
|
3326
|
+
/* @__PURE__ */ jsx(
|
|
3327
|
+
Pie$1,
|
|
3328
|
+
{
|
|
3329
|
+
data: graphData,
|
|
3330
|
+
dataKey: String(valueKey),
|
|
3331
|
+
nameKey: String(nameKey),
|
|
3332
|
+
innerRadius,
|
|
3333
|
+
outerRadius,
|
|
3334
|
+
paddingAngle: 2,
|
|
3335
|
+
isAnimationActive: animated,
|
|
3336
|
+
animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION,
|
|
3337
|
+
children: graphData.map((_item, index) => /* @__PURE__ */ jsx(
|
|
3338
|
+
Cell,
|
|
3339
|
+
{
|
|
3340
|
+
fill: resolveGraphColor(void 0, {
|
|
3341
|
+
index,
|
|
3342
|
+
palette: theme.colors
|
|
3343
|
+
})
|
|
3344
|
+
},
|
|
3345
|
+
`cell-${index}`
|
|
3346
|
+
))
|
|
3347
|
+
}
|
|
3348
|
+
),
|
|
3349
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
3350
|
+
Tooltip$1,
|
|
3351
|
+
{
|
|
3352
|
+
content: /* @__PURE__ */ jsx(
|
|
3353
|
+
GraphTooltip,
|
|
3354
|
+
{
|
|
3355
|
+
seriesFormatters: {
|
|
3356
|
+
[String(valueKey)]: {
|
|
3357
|
+
format: valueFormat,
|
|
3358
|
+
suffix: unit
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
)
|
|
3363
|
+
}
|
|
3364
|
+
)
|
|
3365
|
+
] }) }) }),
|
|
3366
|
+
showLegend && /* @__PURE__ */ jsx(GraphLegend, { items: legendItems, showValues: true, valueSource: "latest" })
|
|
3367
|
+
] });
|
|
3368
|
+
}
|
|
3369
|
+
function ScatterGraph({
|
|
3370
|
+
data,
|
|
3371
|
+
xKey = "x",
|
|
3372
|
+
series,
|
|
3373
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
3374
|
+
loading,
|
|
3375
|
+
error,
|
|
3376
|
+
className = "",
|
|
3377
|
+
showGrid = true,
|
|
3378
|
+
showTooltip = true,
|
|
3379
|
+
showLegend = true,
|
|
3380
|
+
animated = true
|
|
3381
|
+
}) {
|
|
3382
|
+
const context = useGraphContext();
|
|
3383
|
+
const theme = useGraphTheme();
|
|
3384
|
+
const graphData = data ?? context.data;
|
|
3385
|
+
const graphLoading = loading ?? context.loading;
|
|
3386
|
+
const graphError = error ?? context.error;
|
|
3387
|
+
const resolvedSeries = useGraphSeries({
|
|
3388
|
+
data: graphData,
|
|
3389
|
+
series,
|
|
3390
|
+
xKey: String(xKey)
|
|
3391
|
+
}).filter((item) => item.visible);
|
|
3392
|
+
if (graphLoading) {
|
|
3393
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height, className });
|
|
3394
|
+
}
|
|
3395
|
+
if (graphError) {
|
|
3396
|
+
return /* @__PURE__ */ jsx(
|
|
3397
|
+
GraphErrorState,
|
|
3398
|
+
{
|
|
3399
|
+
error: graphError,
|
|
3400
|
+
height,
|
|
3401
|
+
className
|
|
3402
|
+
}
|
|
3403
|
+
);
|
|
3404
|
+
}
|
|
3405
|
+
if (!graphData.length || !resolvedSeries.length) {
|
|
3406
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height, className });
|
|
3407
|
+
}
|
|
3408
|
+
return /* @__PURE__ */ jsxs("div", { className: `eui-graph flex w-full flex-col gap-3 ${className}`, children: [
|
|
3409
|
+
/* @__PURE__ */ jsx(GraphContainer, { height, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(ScatterChart, { margin: GRAPH_DEFAULT_MARGIN, children: [
|
|
3410
|
+
showGrid && /* @__PURE__ */ jsx(CartesianGrid, { stroke: theme.chart.grid, strokeDasharray: "3 3" }),
|
|
3411
|
+
/* @__PURE__ */ jsx(
|
|
3412
|
+
XAxis,
|
|
3413
|
+
{
|
|
3414
|
+
type: "number",
|
|
3415
|
+
dataKey: String(xKey),
|
|
3416
|
+
name: String(xKey),
|
|
3417
|
+
stroke: theme.chart.axis,
|
|
3418
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3419
|
+
tickLine: false,
|
|
3420
|
+
axisLine: false,
|
|
3421
|
+
tickFormatter: (value) => formatGraphValue(value, {
|
|
3422
|
+
format: "compact"
|
|
3423
|
+
})
|
|
3424
|
+
}
|
|
3425
|
+
),
|
|
3426
|
+
/* @__PURE__ */ jsx(
|
|
3427
|
+
YAxis,
|
|
3428
|
+
{
|
|
3429
|
+
type: "number",
|
|
3430
|
+
stroke: theme.chart.axis,
|
|
3431
|
+
tick: { fill: theme.chart.axis, fontSize: 12 },
|
|
3432
|
+
tickLine: false,
|
|
3433
|
+
axisLine: false,
|
|
3434
|
+
tickFormatter: (value) => formatGraphValue(value, {
|
|
3435
|
+
format: "compact"
|
|
3436
|
+
})
|
|
3437
|
+
}
|
|
3438
|
+
),
|
|
3439
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
3440
|
+
Tooltip$1,
|
|
3441
|
+
{
|
|
3442
|
+
content: /* @__PURE__ */ jsx(
|
|
3443
|
+
GraphTooltip,
|
|
3444
|
+
{
|
|
3445
|
+
seriesFormatters: Object.fromEntries(
|
|
3446
|
+
resolvedSeries.map((item) => [
|
|
3447
|
+
item.key,
|
|
3448
|
+
{
|
|
3449
|
+
format: item.format,
|
|
3450
|
+
prefix: item.prefix,
|
|
3451
|
+
suffix: item.suffix,
|
|
3452
|
+
unit: item.unit
|
|
3453
|
+
}
|
|
3454
|
+
])
|
|
3455
|
+
)
|
|
3456
|
+
}
|
|
3457
|
+
),
|
|
3458
|
+
cursor: { stroke: theme.chart.cursor, strokeDasharray: "3 3" }
|
|
3459
|
+
}
|
|
3460
|
+
),
|
|
3461
|
+
resolvedSeries.map((item) => /* @__PURE__ */ jsx(
|
|
3462
|
+
Scatter,
|
|
3463
|
+
{
|
|
3464
|
+
data: graphData,
|
|
3465
|
+
dataKey: item.key,
|
|
3466
|
+
name: item.label,
|
|
3467
|
+
fill: item.color,
|
|
3468
|
+
isAnimationActive: animated,
|
|
3469
|
+
animationDuration: GRAPH_DEFAULT_ANIMATION_DURATION
|
|
3470
|
+
},
|
|
3471
|
+
item.key
|
|
3472
|
+
))
|
|
3473
|
+
] }) }) }),
|
|
3474
|
+
showLegend && /* @__PURE__ */ jsx(
|
|
3475
|
+
GraphLegend,
|
|
3476
|
+
{
|
|
3477
|
+
series: resolvedSeries,
|
|
3478
|
+
data: graphData,
|
|
3479
|
+
showValues: true,
|
|
3480
|
+
valueSource: "latest"
|
|
3481
|
+
}
|
|
3482
|
+
)
|
|
3483
|
+
] });
|
|
3484
|
+
}
|
|
3485
|
+
function GaugeGraph({
|
|
3486
|
+
data,
|
|
3487
|
+
valueKey = "value",
|
|
3488
|
+
label,
|
|
3489
|
+
value,
|
|
3490
|
+
min = 0,
|
|
3491
|
+
max = 100,
|
|
3492
|
+
height = GRAPH_DEFAULT_HEIGHT,
|
|
3493
|
+
color,
|
|
3494
|
+
unit,
|
|
3495
|
+
format = "number",
|
|
3496
|
+
loading,
|
|
3497
|
+
error,
|
|
3498
|
+
className = ""
|
|
3499
|
+
}) {
|
|
3500
|
+
const context = useGraphContext();
|
|
3501
|
+
const theme = useGraphTheme();
|
|
3502
|
+
const graphData = data ?? context.data;
|
|
3503
|
+
const graphLoading = loading ?? context.loading;
|
|
3504
|
+
const graphError = error ?? context.error;
|
|
3505
|
+
const resolvedValue = useMemo(() => {
|
|
3506
|
+
if (typeof value === "number") {
|
|
3507
|
+
return value;
|
|
3508
|
+
}
|
|
3509
|
+
const latestPoint = graphData[graphData.length - 1];
|
|
3510
|
+
const latestValue = latestPoint?.[String(valueKey)];
|
|
3511
|
+
return typeof latestValue === "number" ? latestValue : void 0;
|
|
3512
|
+
}, [graphData, value, valueKey]);
|
|
3513
|
+
if (graphLoading) {
|
|
3514
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height, className });
|
|
3515
|
+
}
|
|
3516
|
+
if (graphError) {
|
|
3517
|
+
return /* @__PURE__ */ jsx(
|
|
3518
|
+
GraphErrorState,
|
|
3519
|
+
{
|
|
3520
|
+
error: graphError,
|
|
3521
|
+
height,
|
|
3522
|
+
className
|
|
3523
|
+
}
|
|
3524
|
+
);
|
|
3525
|
+
}
|
|
3526
|
+
if (resolvedValue === void 0) {
|
|
3527
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height, className });
|
|
3528
|
+
}
|
|
3529
|
+
const range = max - min;
|
|
3530
|
+
const percentage = range === 0 ? 0 : Math.min(100, Math.max(0, (resolvedValue - min) / range * 100));
|
|
3531
|
+
const radius = 72;
|
|
3532
|
+
const strokeWidth = 14;
|
|
3533
|
+
const circumference = Math.PI * radius;
|
|
3534
|
+
const offset = circumference - percentage / 100 * circumference;
|
|
3535
|
+
const resolvedColor = resolveGraphColor(color, {
|
|
3536
|
+
index: 0,
|
|
3537
|
+
palette: theme.colors
|
|
3538
|
+
});
|
|
3539
|
+
return /* @__PURE__ */ jsx(
|
|
3540
|
+
"div",
|
|
3541
|
+
{
|
|
3542
|
+
className: `eui-graph flex items-center justify-center ${className}`,
|
|
3543
|
+
style: { height },
|
|
3544
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3", children: [
|
|
3545
|
+
/* @__PURE__ */ jsxs("svg", { width: "220", height: "130", viewBox: "0 0 220 130", children: [
|
|
3546
|
+
/* @__PURE__ */ jsx(
|
|
3547
|
+
"path",
|
|
3548
|
+
{
|
|
3549
|
+
d: "M 38 104 A 72 72 0 0 1 182 104",
|
|
3550
|
+
fill: "none",
|
|
3551
|
+
stroke: theme.chart.grid,
|
|
3552
|
+
strokeWidth,
|
|
3553
|
+
strokeLinecap: "round"
|
|
3554
|
+
}
|
|
3555
|
+
),
|
|
3556
|
+
/* @__PURE__ */ jsx(
|
|
3557
|
+
"path",
|
|
3558
|
+
{
|
|
3559
|
+
d: "M 38 104 A 72 72 0 0 1 182 104",
|
|
3560
|
+
fill: "none",
|
|
3561
|
+
stroke: resolvedColor,
|
|
3562
|
+
strokeWidth,
|
|
3563
|
+
strokeLinecap: "round",
|
|
3564
|
+
strokeDasharray: circumference,
|
|
3565
|
+
strokeDashoffset: offset
|
|
3566
|
+
}
|
|
3567
|
+
),
|
|
3568
|
+
/* @__PURE__ */ jsx(
|
|
3569
|
+
"text",
|
|
3570
|
+
{
|
|
3571
|
+
x: "110",
|
|
3572
|
+
y: "92",
|
|
3573
|
+
textAnchor: "middle",
|
|
3574
|
+
fill: theme.tooltip.text,
|
|
3575
|
+
fontSize: "28",
|
|
3576
|
+
fontWeight: "700",
|
|
3577
|
+
children: formatGraphValue(resolvedValue, {
|
|
3578
|
+
format,
|
|
3579
|
+
suffix: unit,
|
|
3580
|
+
maximumFractionDigits: 2
|
|
3581
|
+
})
|
|
3582
|
+
}
|
|
3583
|
+
),
|
|
3584
|
+
label && /* @__PURE__ */ jsx(
|
|
3585
|
+
"text",
|
|
3586
|
+
{
|
|
3587
|
+
x: "110",
|
|
3588
|
+
y: "118",
|
|
3589
|
+
textAnchor: "middle",
|
|
3590
|
+
fill: theme.tooltip.muted,
|
|
3591
|
+
fontSize: "12",
|
|
3592
|
+
children: label
|
|
3593
|
+
}
|
|
3594
|
+
)
|
|
3595
|
+
] }),
|
|
3596
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full max-w-[180px] justify-between text-xs text-gray-500", children: [
|
|
3597
|
+
/* @__PURE__ */ jsx("span", { children: formatGraphValue(min, {
|
|
3598
|
+
format,
|
|
3599
|
+
suffix: unit
|
|
3600
|
+
}) }),
|
|
3601
|
+
/* @__PURE__ */ jsx("span", { children: formatGraphValue(max, {
|
|
3602
|
+
format,
|
|
3603
|
+
suffix: unit
|
|
3604
|
+
}) })
|
|
3605
|
+
] })
|
|
3606
|
+
] })
|
|
3607
|
+
}
|
|
3608
|
+
);
|
|
3609
|
+
}
|
|
3610
|
+
function StatGraph({
|
|
3611
|
+
data,
|
|
3612
|
+
valueKey = "value",
|
|
3613
|
+
label,
|
|
3614
|
+
value,
|
|
3615
|
+
previousValue,
|
|
3616
|
+
format = "number",
|
|
3617
|
+
prefix,
|
|
3618
|
+
suffix,
|
|
3619
|
+
unit,
|
|
3620
|
+
loading,
|
|
3621
|
+
error,
|
|
3622
|
+
className = "",
|
|
3623
|
+
showTrend = true
|
|
3624
|
+
}) {
|
|
3625
|
+
const context = useGraphContext();
|
|
3626
|
+
const graphData = data ?? context.data;
|
|
3627
|
+
const graphLoading = loading ?? context.loading;
|
|
3628
|
+
const graphError = error ?? context.error;
|
|
3629
|
+
const resolvedValue = useMemo(() => {
|
|
3630
|
+
if (value !== void 0) {
|
|
3631
|
+
return value;
|
|
3632
|
+
}
|
|
3633
|
+
const latestPoint = graphData[graphData.length - 1];
|
|
3634
|
+
return latestPoint?.[String(valueKey)] ?? null;
|
|
3635
|
+
}, [graphData, value, valueKey]);
|
|
3636
|
+
const resolvedPreviousValue = useMemo(() => {
|
|
3637
|
+
if (previousValue !== void 0) {
|
|
3638
|
+
return previousValue;
|
|
3639
|
+
}
|
|
3640
|
+
const previousPoint = graphData[graphData.length - 2];
|
|
3641
|
+
const previous = previousPoint?.[String(valueKey)];
|
|
3642
|
+
return typeof previous === "number" ? previous : void 0;
|
|
3643
|
+
}, [graphData, previousValue, valueKey]);
|
|
3644
|
+
const trend = useMemo(() => {
|
|
3645
|
+
if (typeof resolvedValue !== "number" || typeof resolvedPreviousValue !== "number") {
|
|
3646
|
+
return null;
|
|
3647
|
+
}
|
|
3648
|
+
const difference = resolvedValue - resolvedPreviousValue;
|
|
3649
|
+
const percentage = resolvedPreviousValue === 0 ? 0 : difference / Math.abs(resolvedPreviousValue) * 100;
|
|
3650
|
+
return {
|
|
3651
|
+
difference,
|
|
3652
|
+
percentage,
|
|
3653
|
+
direction: difference > 0 ? "up" : difference < 0 ? "down" : "neutral"
|
|
3654
|
+
};
|
|
3655
|
+
}, [resolvedPreviousValue, resolvedValue]);
|
|
3656
|
+
if (graphLoading) {
|
|
3657
|
+
return /* @__PURE__ */ jsx(GraphLoadingState, { height: 120, className });
|
|
3658
|
+
}
|
|
3659
|
+
if (graphError) {
|
|
3660
|
+
return /* @__PURE__ */ jsx(GraphErrorState, { error: graphError, height: 120, className });
|
|
3661
|
+
}
|
|
3662
|
+
if (resolvedValue === null || resolvedValue === void 0) {
|
|
3663
|
+
return /* @__PURE__ */ jsx(GraphEmptyState, { height: 120, className });
|
|
3664
|
+
}
|
|
3665
|
+
return /* @__PURE__ */ jsxs(
|
|
3666
|
+
"div",
|
|
3667
|
+
{
|
|
3668
|
+
className: `eui-graph rounded-xl border border-[#2a2d35] bg-[#111217] p-5 ${className}`,
|
|
3669
|
+
children: [
|
|
3670
|
+
label && /* @__PURE__ */ jsx("div", { className: "text-sm text-gray-400", children: label }),
|
|
3671
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 text-3xl font-semibold tracking-tight text-gray-100", children: formatGraphValue(resolvedValue, {
|
|
3672
|
+
format,
|
|
3673
|
+
prefix,
|
|
3674
|
+
suffix: suffix ?? unit
|
|
3675
|
+
}) }),
|
|
3676
|
+
showTrend && trend && /* @__PURE__ */ jsxs(
|
|
3677
|
+
"div",
|
|
3678
|
+
{
|
|
3679
|
+
className: `mt-3 text-sm ${trend.direction === "up" ? "text-emerald-400" : trend.direction === "down" ? "text-red-400" : "text-gray-500"}`,
|
|
3680
|
+
children: [
|
|
3681
|
+
trend.direction === "up" ? "\u2191" : trend.direction === "down" ? "\u2193" : "\u2192",
|
|
3682
|
+
" ",
|
|
3683
|
+
formatGraphValue(Math.abs(trend.percentage), {
|
|
3684
|
+
format: "number",
|
|
3685
|
+
suffix: "%",
|
|
3686
|
+
maximumFractionDigits: 2
|
|
3687
|
+
})
|
|
3688
|
+
]
|
|
3689
|
+
}
|
|
3690
|
+
)
|
|
3691
|
+
]
|
|
3692
|
+
}
|
|
3693
|
+
);
|
|
3694
|
+
}
|
|
3695
|
+
function renderGraphChart(props) {
|
|
3696
|
+
const {
|
|
3697
|
+
type = "line",
|
|
3698
|
+
data,
|
|
3699
|
+
xKey,
|
|
3700
|
+
series,
|
|
3701
|
+
height,
|
|
3702
|
+
loading,
|
|
3703
|
+
error,
|
|
3704
|
+
chartClassName = "",
|
|
3705
|
+
showGrid = true,
|
|
3706
|
+
showTooltip = true,
|
|
3707
|
+
showLegend = true,
|
|
3708
|
+
animated = true,
|
|
3709
|
+
layout,
|
|
3710
|
+
nameKey,
|
|
3711
|
+
valueKey,
|
|
3712
|
+
innerRadius,
|
|
3713
|
+
outerRadius,
|
|
3714
|
+
valueFormat,
|
|
3715
|
+
value,
|
|
3716
|
+
previousValue,
|
|
3717
|
+
label,
|
|
3718
|
+
min,
|
|
3719
|
+
max,
|
|
3720
|
+
color,
|
|
3721
|
+
unit,
|
|
3722
|
+
format,
|
|
3723
|
+
prefix,
|
|
3724
|
+
suffix,
|
|
3725
|
+
showTrend
|
|
3726
|
+
} = props;
|
|
3727
|
+
switch (type) {
|
|
3728
|
+
case "area":
|
|
3729
|
+
return /* @__PURE__ */ jsx(
|
|
3730
|
+
AreaGraph,
|
|
3731
|
+
{
|
|
3732
|
+
data,
|
|
3733
|
+
xKey,
|
|
3734
|
+
series,
|
|
3735
|
+
height,
|
|
3736
|
+
loading,
|
|
3737
|
+
error,
|
|
3738
|
+
className: chartClassName,
|
|
3739
|
+
showGrid,
|
|
3740
|
+
showTooltip,
|
|
3741
|
+
showLegend,
|
|
3742
|
+
animated
|
|
3743
|
+
}
|
|
3744
|
+
);
|
|
3745
|
+
case "bar":
|
|
3746
|
+
return /* @__PURE__ */ jsx(
|
|
3747
|
+
BarGraph,
|
|
3748
|
+
{
|
|
3749
|
+
data,
|
|
3750
|
+
xKey,
|
|
3751
|
+
series,
|
|
3752
|
+
height,
|
|
3753
|
+
loading,
|
|
3754
|
+
error,
|
|
3755
|
+
className: chartClassName,
|
|
3756
|
+
showGrid,
|
|
3757
|
+
showTooltip,
|
|
3758
|
+
showLegend,
|
|
3759
|
+
animated,
|
|
3760
|
+
layout
|
|
3761
|
+
}
|
|
3762
|
+
);
|
|
3763
|
+
case "pie":
|
|
3764
|
+
return /* @__PURE__ */ jsx(
|
|
3765
|
+
PieGraph,
|
|
3766
|
+
{
|
|
3767
|
+
data,
|
|
3768
|
+
nameKey,
|
|
3769
|
+
valueKey,
|
|
3770
|
+
height,
|
|
3771
|
+
loading,
|
|
3772
|
+
error,
|
|
3773
|
+
className: chartClassName,
|
|
3774
|
+
showTooltip,
|
|
3775
|
+
showLegend,
|
|
3776
|
+
animated,
|
|
3777
|
+
innerRadius,
|
|
3778
|
+
outerRadius,
|
|
3779
|
+
valueFormat,
|
|
3780
|
+
unit
|
|
3781
|
+
}
|
|
3782
|
+
);
|
|
3783
|
+
case "scatter":
|
|
3784
|
+
return /* @__PURE__ */ jsx(
|
|
3785
|
+
ScatterGraph,
|
|
3786
|
+
{
|
|
3787
|
+
data,
|
|
3788
|
+
xKey,
|
|
3789
|
+
series,
|
|
3790
|
+
height,
|
|
3791
|
+
loading,
|
|
3792
|
+
error,
|
|
3793
|
+
className: chartClassName,
|
|
3794
|
+
showGrid,
|
|
3795
|
+
showTooltip,
|
|
3796
|
+
showLegend,
|
|
3797
|
+
animated
|
|
3798
|
+
}
|
|
3799
|
+
);
|
|
3800
|
+
case "gauge":
|
|
3801
|
+
return /* @__PURE__ */ jsx(
|
|
3802
|
+
GaugeGraph,
|
|
3803
|
+
{
|
|
3804
|
+
data,
|
|
3805
|
+
valueKey,
|
|
3806
|
+
value: typeof value === "number" ? value : void 0,
|
|
3807
|
+
label,
|
|
3808
|
+
min,
|
|
3809
|
+
max,
|
|
3810
|
+
height,
|
|
3811
|
+
color,
|
|
3812
|
+
unit,
|
|
3813
|
+
format,
|
|
3814
|
+
loading,
|
|
3815
|
+
error,
|
|
3816
|
+
className: chartClassName
|
|
3817
|
+
}
|
|
3818
|
+
);
|
|
3819
|
+
case "stat":
|
|
3820
|
+
return /* @__PURE__ */ jsx(
|
|
3821
|
+
StatGraph,
|
|
3822
|
+
{
|
|
3823
|
+
data,
|
|
3824
|
+
valueKey,
|
|
3825
|
+
value,
|
|
3826
|
+
previousValue,
|
|
3827
|
+
label,
|
|
3828
|
+
format,
|
|
3829
|
+
prefix,
|
|
3830
|
+
suffix,
|
|
3831
|
+
unit,
|
|
3832
|
+
loading,
|
|
3833
|
+
error,
|
|
3834
|
+
className: chartClassName,
|
|
3835
|
+
showTrend
|
|
3836
|
+
}
|
|
3837
|
+
);
|
|
3838
|
+
case "line":
|
|
3839
|
+
default:
|
|
3840
|
+
return /* @__PURE__ */ jsx(
|
|
3841
|
+
LineGraph,
|
|
3842
|
+
{
|
|
3843
|
+
data,
|
|
3844
|
+
xKey,
|
|
3845
|
+
series,
|
|
3846
|
+
height,
|
|
3847
|
+
loading,
|
|
3848
|
+
error,
|
|
3849
|
+
className: chartClassName,
|
|
3850
|
+
showGrid,
|
|
3851
|
+
showTooltip,
|
|
3852
|
+
showLegend,
|
|
3853
|
+
animated
|
|
3854
|
+
}
|
|
3855
|
+
);
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
function GraphContent(props) {
|
|
3859
|
+
const {
|
|
3860
|
+
children,
|
|
3861
|
+
withPanel = true,
|
|
3862
|
+
title,
|
|
3863
|
+
description,
|
|
3864
|
+
actions,
|
|
3865
|
+
toolbar,
|
|
3866
|
+
className = "",
|
|
3867
|
+
contentClassName = "",
|
|
3868
|
+
height,
|
|
3869
|
+
loading,
|
|
3870
|
+
error,
|
|
3871
|
+
showToolbar = false,
|
|
3872
|
+
showRefresh = true,
|
|
3873
|
+
showLastUpdated = true,
|
|
3874
|
+
emptyMessage,
|
|
3875
|
+
emptyDescription,
|
|
3876
|
+
onRetry
|
|
3877
|
+
} = props;
|
|
3878
|
+
const chart = children ?? renderGraphChart(props);
|
|
3879
|
+
if (!withPanel) {
|
|
3880
|
+
return /* @__PURE__ */ jsx(Fragment, { children: chart });
|
|
3881
|
+
}
|
|
3882
|
+
return /* @__PURE__ */ jsx(
|
|
3883
|
+
GraphPanel,
|
|
3884
|
+
{
|
|
3885
|
+
title,
|
|
3886
|
+
description,
|
|
3887
|
+
actions,
|
|
3888
|
+
toolbar,
|
|
3889
|
+
className,
|
|
3890
|
+
contentClassName,
|
|
3891
|
+
height,
|
|
3892
|
+
loading,
|
|
3893
|
+
error,
|
|
3894
|
+
empty: children ? false : void 0,
|
|
3895
|
+
showToolbar,
|
|
3896
|
+
showRefresh,
|
|
3897
|
+
showLastUpdated,
|
|
3898
|
+
emptyMessage,
|
|
3899
|
+
emptyDescription,
|
|
3900
|
+
onRetry,
|
|
3901
|
+
children: chart
|
|
3902
|
+
}
|
|
3903
|
+
);
|
|
3904
|
+
}
|
|
3905
|
+
function Graph(props) {
|
|
3906
|
+
const {
|
|
3907
|
+
data,
|
|
3908
|
+
dataSource,
|
|
3909
|
+
autoLoad = true,
|
|
3910
|
+
maxDataPoints,
|
|
3911
|
+
theme,
|
|
3912
|
+
onDataChange,
|
|
3913
|
+
onError
|
|
3914
|
+
} = props;
|
|
3915
|
+
const shouldUseProvider = Boolean(data || dataSource);
|
|
3916
|
+
const content = /* @__PURE__ */ jsx(GraphContent, { ...props });
|
|
3917
|
+
if (!shouldUseProvider) {
|
|
3918
|
+
return content;
|
|
3919
|
+
}
|
|
3920
|
+
return /* @__PURE__ */ jsx(
|
|
3921
|
+
GraphProvider,
|
|
3922
|
+
{
|
|
3923
|
+
data,
|
|
3924
|
+
dataSource,
|
|
3925
|
+
autoLoad,
|
|
3926
|
+
maxDataPoints,
|
|
3927
|
+
theme,
|
|
3928
|
+
onDataChange,
|
|
3929
|
+
onError,
|
|
3930
|
+
children: content
|
|
3931
|
+
}
|
|
3932
|
+
);
|
|
3933
|
+
}
|
|
3934
|
+
|
|
3935
|
+
// src/components/data-display/graphs-v2/datasource/GraphDataSource.ts
|
|
3936
|
+
var BaseGraphDataSource = class {
|
|
3937
|
+
normalizeError(error) {
|
|
3938
|
+
if (error instanceof Error) {
|
|
3939
|
+
return error;
|
|
3940
|
+
}
|
|
3941
|
+
return new Error(String(error));
|
|
3942
|
+
}
|
|
3943
|
+
ensureArray(data) {
|
|
3944
|
+
if (!data) {
|
|
3945
|
+
return [];
|
|
3946
|
+
}
|
|
3947
|
+
return Array.isArray(data) ? data : [data];
|
|
3948
|
+
}
|
|
3949
|
+
safeExecute(executor) {
|
|
3950
|
+
try {
|
|
3951
|
+
return Promise.resolve(executor());
|
|
3952
|
+
} catch (error) {
|
|
3953
|
+
return Promise.reject(this.normalizeError(error));
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
};
|
|
3957
|
+
|
|
3958
|
+
// src/components/data-display/graphs-v2/datasource/StaticGraphDataSource.ts
|
|
3959
|
+
var StaticGraphDataSource = class extends BaseGraphDataSource {
|
|
3960
|
+
constructor(config = {}) {
|
|
3961
|
+
super();
|
|
3962
|
+
this.mode = GRAPH_DATA_MODES.STATIC;
|
|
3963
|
+
this.data = Array.isArray(config) ? config : config.data ?? [];
|
|
3964
|
+
}
|
|
3965
|
+
getInitialData() {
|
|
3966
|
+
return this.data;
|
|
3967
|
+
}
|
|
3968
|
+
refresh() {
|
|
3969
|
+
return this.data;
|
|
3970
|
+
}
|
|
3971
|
+
setData(data) {
|
|
3972
|
+
this.data = data;
|
|
3973
|
+
}
|
|
3974
|
+
appendData(data) {
|
|
3975
|
+
const nextData = this.ensureArray(data);
|
|
3976
|
+
this.data = [...this.data, ...nextData];
|
|
3977
|
+
}
|
|
3978
|
+
clearData() {
|
|
3979
|
+
this.data = [];
|
|
3980
|
+
}
|
|
3981
|
+
};
|
|
3982
|
+
|
|
3983
|
+
// src/components/data-display/graphs-v2/datasource/PollingGraphDataSource.ts
|
|
3984
|
+
var PollingGraphDataSource = class extends BaseGraphDataSource {
|
|
3985
|
+
constructor(config) {
|
|
3986
|
+
super();
|
|
3987
|
+
this.mode = GRAPH_DATA_MODES.POLLING;
|
|
3988
|
+
this.fetcher = config.fetcher;
|
|
3989
|
+
this.interval = config.interval ?? GRAPH_DEFAULT_POLLING_INTERVAL;
|
|
3990
|
+
this.immediate = config.immediate ?? true;
|
|
3991
|
+
}
|
|
3992
|
+
getInitialData() {
|
|
3993
|
+
return this.refresh();
|
|
3994
|
+
}
|
|
3995
|
+
refresh() {
|
|
3996
|
+
return this.safeExecute(async () => {
|
|
3997
|
+
const data = await this.fetcher();
|
|
3998
|
+
return this.ensureArray(data);
|
|
3999
|
+
});
|
|
4000
|
+
}
|
|
4001
|
+
subscribe(onData, onError) {
|
|
4002
|
+
let disposed = false;
|
|
4003
|
+
let fetching = false;
|
|
4004
|
+
let timer;
|
|
4005
|
+
const execute = async () => {
|
|
4006
|
+
if (disposed || fetching) {
|
|
4007
|
+
return;
|
|
4008
|
+
}
|
|
4009
|
+
try {
|
|
4010
|
+
fetching = true;
|
|
4011
|
+
const data = await this.refresh();
|
|
4012
|
+
if (!disposed) {
|
|
4013
|
+
onData(data);
|
|
4014
|
+
}
|
|
4015
|
+
} catch (error) {
|
|
4016
|
+
if (!disposed) {
|
|
4017
|
+
onError?.(this.normalizeError(error));
|
|
4018
|
+
}
|
|
4019
|
+
} finally {
|
|
4020
|
+
fetching = false;
|
|
4021
|
+
}
|
|
4022
|
+
};
|
|
4023
|
+
if (this.immediate) {
|
|
4024
|
+
void execute();
|
|
4025
|
+
}
|
|
4026
|
+
timer = globalThis.setInterval(() => {
|
|
4027
|
+
void execute();
|
|
4028
|
+
}, this.interval);
|
|
4029
|
+
return () => {
|
|
4030
|
+
disposed = true;
|
|
4031
|
+
if (timer) {
|
|
4032
|
+
globalThis.clearInterval(timer);
|
|
4033
|
+
}
|
|
4034
|
+
};
|
|
4035
|
+
}
|
|
4036
|
+
};
|
|
4037
|
+
|
|
4038
|
+
// src/components/data-display/graphs-v2/datasource/RealtimeGraphDataSource.ts
|
|
4039
|
+
var RealtimeGraphDataSource = class extends BaseGraphDataSource {
|
|
4040
|
+
constructor(config) {
|
|
4041
|
+
super();
|
|
4042
|
+
this.mode = GRAPH_DATA_MODES.REALTIME;
|
|
4043
|
+
this.connect = config.connect;
|
|
4044
|
+
this.initialDataLoader = config.getInitialData;
|
|
4045
|
+
this.refreshHandler = config.refresh;
|
|
4046
|
+
}
|
|
4047
|
+
getInitialData() {
|
|
4048
|
+
if (!this.initialDataLoader) {
|
|
4049
|
+
return [];
|
|
4050
|
+
}
|
|
4051
|
+
return this.safeExecute(async () => {
|
|
4052
|
+
const data = await this.initialDataLoader?.();
|
|
4053
|
+
return this.ensureArray(data);
|
|
4054
|
+
});
|
|
4055
|
+
}
|
|
4056
|
+
refresh() {
|
|
4057
|
+
if (!this.refreshHandler) {
|
|
4058
|
+
return this.getInitialData();
|
|
4059
|
+
}
|
|
4060
|
+
return this.safeExecute(async () => {
|
|
4061
|
+
const data = await this.refreshHandler?.();
|
|
4062
|
+
return this.ensureArray(data);
|
|
4063
|
+
});
|
|
4064
|
+
}
|
|
4065
|
+
subscribe(onData, onError) {
|
|
4066
|
+
try {
|
|
4067
|
+
return this.connect(
|
|
4068
|
+
(data) => {
|
|
4069
|
+
onData(this.ensureArray(data));
|
|
4070
|
+
},
|
|
4071
|
+
(error) => {
|
|
4072
|
+
onError?.(this.normalizeError(error));
|
|
4073
|
+
}
|
|
4074
|
+
);
|
|
4075
|
+
} catch (error) {
|
|
4076
|
+
onError?.(this.normalizeError(error));
|
|
4077
|
+
return () => {
|
|
4078
|
+
};
|
|
4079
|
+
}
|
|
4080
|
+
}
|
|
1574
4081
|
};
|
|
1575
4082
|
var CloudinaryContext = createContext(null);
|
|
1576
4083
|
var CloudinaryProvider = ({
|
|
@@ -2033,7 +4540,7 @@ var ListItem = ({
|
|
|
2033
4540
|
children: bullet
|
|
2034
4541
|
}
|
|
2035
4542
|
),
|
|
2036
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: TypographyComponent ?
|
|
4543
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: TypographyComponent ? React3.cloneElement(
|
|
2037
4544
|
TypographyComponent,
|
|
2038
4545
|
{
|
|
2039
4546
|
className: cn(
|
|
@@ -2067,7 +4574,7 @@ function normalizeItem(item, defaultBulletType) {
|
|
|
2067
4574
|
bulletType: defaultBulletType
|
|
2068
4575
|
};
|
|
2069
4576
|
}
|
|
2070
|
-
if (
|
|
4577
|
+
if (React3.isValidElement(item)) {
|
|
2071
4578
|
return {
|
|
2072
4579
|
content: item,
|
|
2073
4580
|
bulletType: defaultBulletType
|
|
@@ -2624,7 +5131,7 @@ function Tag({ text, className, ...rest }) {
|
|
|
2624
5131
|
);
|
|
2625
5132
|
}
|
|
2626
5133
|
var Tag_default = Tag;
|
|
2627
|
-
function
|
|
5134
|
+
function Tooltip9({
|
|
2628
5135
|
children,
|
|
2629
5136
|
show,
|
|
2630
5137
|
offsetX = 20,
|
|
@@ -14526,7 +17033,7 @@ function WorldMap({
|
|
|
14526
17033
|
]
|
|
14527
17034
|
}
|
|
14528
17035
|
) }),
|
|
14529
|
-
/* @__PURE__ */ jsx(
|
|
17036
|
+
/* @__PURE__ */ jsx(Tooltip9, { show: showTooltip, children: tooltipContent })
|
|
14530
17037
|
] });
|
|
14531
17038
|
}
|
|
14532
17039
|
var sizes4 = {
|
|
@@ -16326,7 +18833,7 @@ var Breadcrumb = ({
|
|
|
16326
18833
|
navigate(item.href);
|
|
16327
18834
|
}
|
|
16328
18835
|
};
|
|
16329
|
-
return /* @__PURE__ */ jsxs(
|
|
18836
|
+
return /* @__PURE__ */ jsxs(React3.Fragment, { children: [
|
|
16330
18837
|
/* @__PURE__ */ jsx(
|
|
16331
18838
|
BreadcrumbItem_default,
|
|
16332
18839
|
{
|
|
@@ -19100,6 +21607,6 @@ function ScrollToTop({
|
|
|
19100
21607
|
}
|
|
19101
21608
|
var ScrollToTop_default = ScrollToTop;
|
|
19102
21609
|
|
|
19103
|
-
export { Accordion_default as Accordion, AsyncComponentWrapper_default as AsyncComponentWrapper, Avatar, Backdrop_default as Backdrop, Badge, BarChart_default as BarChart, Block_default as Block, BlockGroup_default as BlockGroup, BoxNav_default as BoxNav, BoxNavItem_default as BoxNavItem, Brand_default as Brand, Breadcrumb, BreadcrumbItem_default as BreadcrumbItem, Button_default as Button, Caption, Card_default as Card, CardContent_default as CardContent, CardFooter_default as CardFooter, CardHeader_default as CardHeader, Chapter, Checkbox_default as Checkbox, Chip, CloudinaryImage_default as CloudinaryImage, CloudinaryProvider, CloudinaryVideo_default as CloudinaryVideo, Code, CommentThread_default as CommentThread, Content, ContentArea_default as ContentArea, DataView, DataViewTable_default as DataViewTable, DateSelector_default as DateSelector, DefaultLayout_default as DefaultLayout, Display, DocumentationPanel_default as DocumentationPanel, Drawer, DrawerToggler_default as DrawerToggler, EUIDevLayout_default as EUIDevLayout, EUIProvider, Flag, Flex, FlexCol_default as FlexCol, FlexRow_default as FlexRow, Footer, FooterNav_default as FooterNav, FooterNavGroup_default as FooterNavGroup, FooterNavItem, FooterNavItemContext, FooterNavItemTitle, Form, FormResponse_default as FormResponse, GenericLayout_default as GenericLayout, GlowWrapper_default as GlowWrapper, Graph,
|
|
21610
|
+
export { Accordion_default as Accordion, AreaGraph, AsyncComponentWrapper_default as AsyncComponentWrapper, Avatar, Backdrop_default as Backdrop, Badge, BarChart_default as BarChart, BarGraph, BaseGraphDataSource, Block_default as Block, BlockGroup_default as BlockGroup, BoxNav_default as BoxNav, BoxNavItem_default as BoxNavItem, Brand_default as Brand, Breadcrumb, BreadcrumbItem_default as BreadcrumbItem, Button_default as Button, Caption, Card_default as Card, CardContent_default as CardContent, CardFooter_default as CardFooter, CardHeader_default as CardHeader, Chapter, Checkbox_default as Checkbox, Chip, CloudinaryImage_default as CloudinaryImage, CloudinaryProvider, CloudinaryVideo_default as CloudinaryVideo, Code, CommentThread_default as CommentThread, Configurator, ConfiguratorError, Content, ContentArea_default as ContentArea, DEFAULT_GRAPH_THEME, DataView, DataViewTable_default as DataViewTable, DateSelector_default as DateSelector, DefaultLayout_default as DefaultLayout, Display, DocumentationPanel_default as DocumentationPanel, Drawer, DrawerToggler_default as DrawerToggler, EUIDevLayout_default as EUIDevLayout, EUIProvider, Flag, Flex, FlexCol_default as FlexCol, FlexRow_default as FlexRow, Footer, FooterNav_default as FooterNav, FooterNavGroup_default as FooterNavGroup, FooterNavItem, FooterNavItemContext, FooterNavItemTitle, Form, FormResponse_default as FormResponse, GRAPH_COLOR_PALETTE, GRAPH_DARK_THEME, GRAPH_DATA_MODES, GRAPH_DEFAULT_ACTIVE_DOT_RADIUS, GRAPH_DEFAULT_ANIMATION_DURATION, GRAPH_DEFAULT_BAR_RADIUS, GRAPH_DEFAULT_DOT_RADIUS, GRAPH_DEFAULT_HEIGHT, GRAPH_DEFAULT_MARGIN, GRAPH_DEFAULT_MAX_REALTIME_POINTS, GRAPH_DEFAULT_POLLING_INTERVAL, GRAPH_DEFAULT_STROKE_WIDTH, GRAPH_EMPTY_MESSAGE, GRAPH_ERROR_MESSAGE, GRAPH_LIGHT_THEME, GRAPH_LOADING_MESSAGE, GRAPH_STATUSES, GRAPH_STATUS_COLORS, GRAPH_VALUE_FORMATS, GaugeGraph, GenericLayout_default as GenericLayout, GlowWrapper_default as GlowWrapper, Graph, GraphContainer, GraphContext, GraphEmptyState, GraphErrorState, GraphHeader, GraphLegend, GraphLoadingState, GraphPanel, GraphProvider, GraphToolbar, GraphTooltip, Grid_default as Grid, Header, HeaderNav_default as HeaderNav, HeaderNavGroup_default as HeaderNavGroup, HeaderNavItem, HeaderNavItemContext, HeaderNavItemTitle, HomeLayout_default as HomeLayout, Image2 as Image, ImageInput_default as ImageInput, InfiniteScrollTrigger_default as InfiniteScrollTrigger, Info_default as Info, Input, InputFile, InputLabel_default as InputLabel, InputList, InputListGroup, InputResponse_default as InputResponse, Label, Layout, Lead, LineChart_default as LineChart, LineGraph, Link, List_default as List, ListItem_default as ListItem, MarkdownEditor_default as MarkdownEditor, MarkdownProvider_default as MarkdownProvider, MarkdownTOC_default as MarkdownTOC, MarkdownViewer_default as MarkdownViewer, Menu, MenuGroup, MenuItem, MenuItemTitle, Modal_default as Modal, MotionSurface_default as MotionSurface, MultiImageInput_default as MultiImageInput, NumericRating_default as NumericRating, Overline, Paragraph, PieChart_default as PieChart, PieGraph, PollingGraphDataSource, PriceTag, ProgressBar, ProgressBarRating_default as ProgressBarRating, Quote, Radio_default as Radio, RealtimeGraphDataSource, RouteTab_default as RouteTab, RouteTabs_default as RouteTabs, ScatterGraph, ScrollToTop_default as ScrollToTop, Section, Select_default as Select, ShapeSwitch, ShowMore_default as ShowMore, Sidebar_default as Sidebar, SidebarLayout_default as SidebarLayout, SidemenuLayout_default as SidemenuLayout, Skeleton, Slider_default as Slider, StarRating_default as StarRating, StarRatingDistribution_default as StarRatingDistribution, StarRatingInput_default as StarRatingInput, StatGraph, StaticGraphDataSource, Switch_default as Switch, TNDropdown, TNDropdownItem, TNDropdownTitle, TNGroup, Table_default as Table, Tag_default as Tag, Tags_default as Tags, TextArea_default as TextArea, ThemeContext, ThemeProvider, ThemeSwitch, TitleBanner, Toast, Tooltip9 as Tooltip, TopNav, Transition4 as Transition, TransitionDropdown_default as TransitionDropdown, TransitionFadeIn_default as TransitionFadeIn, Typography, UnderConstructionBanner, ValueBadge_default as ValueBadge, WorldMap, WorldMapCountryTable, YoutubeVideo_default as YoutubeVideoPlayer, addReplyToCache, applyReactionState, assertAbsoluteURL, buildURL, cn, createConfigurator, createInitialGraphState, createURLResolver, decrementReplyCount, enumValues, formatCommentDate, formatConfigError, formatGraphValue, getAllowedOrigins, getBrowserHref, getBrowserOrigin, getBrowserRedirectURL, getCurrencySymbol, getOptimisticDislikeState, getOptimisticLikeState, getSafeRedirect, graphReducer, incrementReplyCount, isMatch, isRenderFn, limitRealtimePoints, normalize, normalizeGraphData, normalizeGraphDataPoint, parseJson, parseJsonRecord, parseUrlMap, removeComment, removeCommentTreeFromCache, replaceRealtimePoints, resolveAppearanceStyles, resolveGraphColor, resolveGraphColors, resolveWithGlobal, sendToast, toConfiguratorError, updateComment, updateReplyCacheComment, useClickOutside, useCloudinaryConfig, useCurrentTheme_default as useCurrentTheme, useDrawer_default as useDrawer, useEUIConfig, useGraphContext, useGraphData, useGraphPolling, useGraphRealtime, useGraphSeries, useGraphTheme, useIsMobile_default as useIsMobile, useModal_default as useModal, useTheme_default as useTheme };
|
|
19104
21611
|
//# sourceMappingURL=index.mjs.map
|
|
19105
21612
|
//# sourceMappingURL=index.mjs.map
|