feat(chart-area): replace ApexCharts with Lightweight Charts for area chart rendering

This commit is contained in:
2026-04-03 10:11:38 +00:00
parent 99a531ee74
commit b38bd28360
10 changed files with 502 additions and 579 deletions

View File

@@ -1,5 +1,12 @@
# Changelog # Changelog
## 2026-04-03 - 3.51.0 - feat(chart-area)
replace ApexCharts with Lightweight Charts for area chart rendering
- switch chart dependency and CDN loader from apexcharts to lightweight-charts
- update dees-chart-area styling and tooltip support for the new chart engine
- adjust appdash terminal overlay sizing with automatic height
## 2026-04-02 - 3.50.2 - fix(chart,dashboardgrid demos) ## 2026-04-02 - 3.50.2 - fix(chart,dashboardgrid demos)
use dees-button text property consistently in demo interactions and update dataset button highlighting reliably use dees-button text property consistently in demo interactions and update dataset button highlighting reliably

View File

@@ -34,7 +34,7 @@
"@tiptap/extension-underline": "^2.23.0", "@tiptap/extension-underline": "^2.23.0",
"@tiptap/starter-kit": "^2.23.0", "@tiptap/starter-kit": "^2.23.0",
"@tsclass/tsclass": "^9.5.0", "@tsclass/tsclass": "^9.5.0",
"apexcharts": "^5.10.4", "lightweight-charts": "^5.1.0",
"highlight.js": "11.11.1", "highlight.js": "11.11.1",
"ibantools": "^4.5.1", "ibantools": "^4.5.1",
"lucide": "^0.577.0", "lucide": "^0.577.0",

18
pnpm-lock.yaml generated
View File

@@ -62,15 +62,15 @@ importers:
'@tsclass/tsclass': '@tsclass/tsclass':
specifier: ^9.5.0 specifier: ^9.5.0
version: 9.5.0 version: 9.5.0
apexcharts:
specifier: ^5.10.4
version: 5.10.4
highlight.js: highlight.js:
specifier: 11.11.1 specifier: 11.11.1
version: 11.11.1 version: 11.11.1
ibantools: ibantools:
specifier: ^4.5.1 specifier: ^4.5.1
version: 4.5.1 version: 4.5.1
lightweight-charts:
specifier: ^5.1.0
version: 5.1.0
lucide: lucide:
specifier: ^0.577.0 specifier: ^0.577.0
version: 0.577.0 version: 0.577.0
@@ -2648,6 +2648,9 @@ packages:
resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==}
engines: {node: '>=18'} engines: {node: '>=18'}
fancy-canvas@2.1.0:
resolution: {integrity: sha512-nifxXJ95JNLFR2NgRV4/MxVP45G9909wJTEKz5fg/TZS20JJZA6hfgRVh/bC9bwl2zBtBNcYPjiBE4njQHVBwQ==}
fast-deep-equal@3.1.3: fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -2996,6 +2999,9 @@ packages:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
lightweight-charts@5.1.0:
resolution: {integrity: sha512-jEAYR4ODYeyNZcWUigsoLTl52rbPmgXnvd5FLIv/ZoA/2sSDw63YKnef8n4yhzum7W926yHeFwlm7ididKb7YQ==}
lines-and-columns@1.2.4: lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@@ -7810,6 +7816,8 @@ snapshots:
fake-indexeddb@6.2.5: {} fake-indexeddb@6.2.5: {}
fancy-canvas@2.1.0: {}
fast-deep-equal@3.1.3: {} fast-deep-equal@3.1.3: {}
fast-fifo@1.3.2: {} fast-fifo@1.3.2: {}
@@ -8229,6 +8237,10 @@ snapshots:
kind-of@6.0.3: {} kind-of@6.0.3: {}
lightweight-charts@5.1.0:
dependencies:
fancy-canvas: 2.1.0
lines-and-columns@1.2.4: {} lines-and-columns@1.2.4: {}
linkify-it@5.0.0: linkify-it@5.0.0:

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-catalog', name: '@design.estate/dees-catalog',
version: '3.50.2', version: '3.51.0',
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
} }

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,6 @@ export const chartAreaStyles = [
:host { :host {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')}; color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')};
font-weight: 400;
font-size: 14px; font-size: 14px;
} }
.mainbox { .mainbox {
@@ -18,7 +17,6 @@ export const chartAreaStyles = [
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
} }
.chartTitle { .chartTitle {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -34,27 +32,22 @@ export const chartAreaStyles = [
} }
.chartContainer { .chartContainer {
position: absolute; position: absolute;
top: 0px; top: 44px;
left: 0px; left: 0;
bottom: 0px; bottom: 0;
right: 0px; right: 0;
padding: 44px 16px 16px 0px;
overflow: hidden;
background: transparent; /* Ensure container doesn't override chart background */
} }
.lw-tooltip {
/* ApexCharts theme overrides */ position: absolute;
.apexcharts-canvas { z-index: 100;
background: transparent !important; pointer-events: none;
} padding: 12px;
border-radius: 6px;
.apexcharts-inner { border: 1px solid;
background: transparent !important; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
} font-size: 12px;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
.apexcharts-graphical { min-width: 140px;
background: transparent !important;
} }
`, `,
]; ];

View File

@@ -710,6 +710,7 @@ export class DeesSimpleAppDash extends DeesElement {
terminal.style.top = 'var(--banner-area-height, 0px)'; terminal.style.top = 'var(--banner-area-height, 0px)';
terminal.style.left = '240px'; terminal.style.left = '240px';
terminal.style.right = '0px'; terminal.style.right = '0px';
terminal.style.height = 'auto';
terminal.style.bottom = '24px'; terminal.style.bottom = '24px';
terminal.style.opacity = '0'; terminal.style.opacity = '0';
terminal.style.transform = 'translateY(8px) scale(0.99)'; terminal.style.transform = 'translateY(8px) scale(0.99)';

View File

@@ -4,7 +4,15 @@ import { CDN_BASE, CDN_VERSIONS } from './versions.js';
import type { Terminal, ITerminalOptions } from 'xterm'; import type { Terminal, ITerminalOptions } from 'xterm';
import type { FitAddon } from 'xterm-addon-fit'; import type { FitAddon } from 'xterm-addon-fit';
import type { HLJSApi } from 'highlight.js'; import type { HLJSApi } from 'highlight.js';
import type ApexChartsType from 'apexcharts'; import type {
createChart as createChartType,
IChartApi,
ISeriesApi,
UTCTimestamp,
MouseEventParams,
DeepPartial,
TimeChartOptions,
} from 'lightweight-charts';
import type { Editor, EditorOptions } from '@tiptap/core'; import type { Editor, EditorOptions } from '@tiptap/core';
import type { StarterKitOptions } from '@tiptap/starter-kit'; import type { StarterKitOptions } from '@tiptap/starter-kit';
import type { UnderlineOptions } from '@tiptap/extension-underline'; import type { UnderlineOptions } from '@tiptap/extension-underline';
@@ -43,6 +51,29 @@ export interface IXtermSearchAddon {
findPrevious(term: string, searchOptions?: { regex?: boolean; wholeWord?: boolean; caseSensitive?: boolean; incremental?: boolean }): boolean; findPrevious(term: string, searchOptions?: { regex?: boolean; wholeWord?: boolean; caseSensitive?: boolean; incremental?: boolean }): boolean;
} }
/**
* Bundle type for TradingView Lightweight Charts
*/
export interface ILightweightChartsBundle {
createChart: typeof createChartType;
AreaSeries: any;
LineSeries: any;
ColorType: {
Solid: string;
VerticalGradient: string;
};
LineType: {
Simple: number;
WithSteps: number;
Curved: number;
};
CrosshairMode: {
Normal: number;
Magnet: number;
Hidden: number;
};
}
/** /**
* Bundle type for Tiptap editor and extensions * Bundle type for Tiptap editor and extensions
*/ */
@@ -76,7 +107,7 @@ export class DeesServiceLibLoader {
private xtermFitAddonLib: IXtermFitAddonBundle | null = null; private xtermFitAddonLib: IXtermFitAddonBundle | null = null;
private xtermSearchAddonLib: IXtermSearchAddonBundle | null = null; private xtermSearchAddonLib: IXtermSearchAddonBundle | null = null;
private highlightJsLib: HLJSApi | null = null; private highlightJsLib: HLJSApi | null = null;
private apexChartsLib: typeof ApexChartsType | null = null; private lightweightChartsLib: ILightweightChartsBundle | null = null;
private tiptapLib: ITiptapBundle | null = null; private tiptapLib: ITiptapBundle | null = null;
// Loading promises to prevent duplicate concurrent loads // Loading promises to prevent duplicate concurrent loads
@@ -84,7 +115,7 @@ export class DeesServiceLibLoader {
private xtermFitAddonLoadingPromise: Promise<IXtermFitAddonBundle> | null = null; private xtermFitAddonLoadingPromise: Promise<IXtermFitAddonBundle> | null = null;
private xtermSearchAddonLoadingPromise: Promise<IXtermSearchAddonBundle> | null = null; private xtermSearchAddonLoadingPromise: Promise<IXtermSearchAddonBundle> | null = null;
private highlightJsLoadingPromise: Promise<HLJSApi> | null = null; private highlightJsLoadingPromise: Promise<HLJSApi> | null = null;
private apexChartsLoadingPromise: Promise<typeof ApexChartsType> | null = null; private lightweightChartsLoadingPromise: Promise<ILightweightChartsBundle> | null = null;
private tiptapLoadingPromise: Promise<ITiptapBundle> | null = null; private tiptapLoadingPromise: Promise<ITiptapBundle> | null = null;
private constructor() {} private constructor() {}
@@ -235,27 +266,34 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
} }
/** /**
* Load ApexCharts charting library from CDN * Load TradingView Lightweight Charts from CDN
* @returns Promise resolving to ApexCharts constructor * @returns Promise resolving to Lightweight Charts bundle
*/ */
public async loadApexCharts(): Promise<typeof ApexChartsType> { public async loadLightweightCharts(): Promise<ILightweightChartsBundle> {
if (this.apexChartsLib) { if (this.lightweightChartsLib) {
return this.apexChartsLib; return this.lightweightChartsLib;
} }
if (this.apexChartsLoadingPromise) { if (this.lightweightChartsLoadingPromise) {
return this.apexChartsLoadingPromise; return this.lightweightChartsLoadingPromise;
} }
this.apexChartsLoadingPromise = (async () => { this.lightweightChartsLoadingPromise = (async () => {
const url = `${CDN_BASE}/apexcharts@${CDN_VERSIONS.apexcharts}/+esm`; const url = `${CDN_BASE}/lightweight-charts@${CDN_VERSIONS.lightweightCharts}/+esm`;
const module = await import(/* @vite-ignore */ url); const module = await import(/* @vite-ignore */ url);
this.apexChartsLib = module.default; this.lightweightChartsLib = {
return this.apexChartsLib!; createChart: module.createChart,
AreaSeries: module.AreaSeries,
LineSeries: module.LineSeries,
ColorType: module.ColorType,
LineType: module.LineType,
CrosshairMode: module.CrosshairMode,
};
return this.lightweightChartsLib;
})(); })();
return this.apexChartsLoadingPromise; return this.lightweightChartsLoadingPromise;
} }
/** /**
@@ -316,7 +354,7 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
this.loadXtermFitAddon(), this.loadXtermFitAddon(),
this.loadXtermSearchAddon(), this.loadXtermSearchAddon(),
this.loadHighlightJs(), this.loadHighlightJs(),
this.loadApexCharts(), this.loadLightweightCharts(),
this.loadTiptap(), this.loadTiptap(),
]); ]);
} }
@@ -324,7 +362,7 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
/** /**
* Check if a specific library is already loaded * Check if a specific library is already loaded
*/ */
public isLoaded(library: 'xterm' | 'xtermFitAddon' | 'xtermSearchAddon' | 'highlightJs' | 'apexCharts' | 'tiptap'): boolean { public isLoaded(library: 'xterm' | 'xtermFitAddon' | 'xtermSearchAddon' | 'highlightJs' | 'lightweightCharts' | 'tiptap'): boolean {
switch (library) { switch (library) {
case 'xterm': case 'xterm':
return this.xtermLib !== null; return this.xtermLib !== null;
@@ -334,8 +372,8 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
return this.xtermSearchAddonLib !== null; return this.xtermSearchAddonLib !== null;
case 'highlightJs': case 'highlightJs':
return this.highlightJsLib !== null; return this.highlightJsLib !== null;
case 'apexCharts': case 'lightweightCharts':
return this.apexChartsLib !== null; return this.lightweightChartsLib !== null;
case 'tiptap': case 'tiptap':
return this.tiptapLib !== null; return this.tiptapLib !== null;
default: default:

View File

@@ -1,3 +1,3 @@
export { DeesServiceLibLoader } from './DeesServiceLibLoader.js'; export { DeesServiceLibLoader } from './DeesServiceLibLoader.js';
export type { IXtermBundle, IXtermFitAddonBundle, IXtermSearchAddonBundle, IXtermSearchAddon, ITiptapBundle } from './DeesServiceLibLoader.js'; export type { IXtermBundle, IXtermFitAddonBundle, IXtermSearchAddonBundle, IXtermSearchAddon, ITiptapBundle, ILightweightChartsBundle } from './DeesServiceLibLoader.js';
export { CDN_BASE, CDN_VERSIONS } from './versions.js'; export { CDN_BASE, CDN_VERSIONS } from './versions.js';

View File

@@ -7,7 +7,7 @@ export const CDN_VERSIONS = {
xtermAddonFit: '0.8.0', xtermAddonFit: '0.8.0',
xtermAddonSearch: '0.13.0', xtermAddonSearch: '0.13.0',
highlightJs: '11.11.1', highlightJs: '11.11.1',
apexcharts: '5.10.4', lightweightCharts: '5.1.0',
tiptap: '2.27.2', tiptap: '2.27.2',
fontawesome: '7.2.0', fontawesome: '7.2.0',
} as const; } as const;