fix(dees-chart-area): Improve resize handling and initial rendering for better responsiveness
fix(dees-chart-log): Simplify firstUpdated method by removing unnecessary variable
This commit is contained in:
@ -8,8 +8,10 @@
|
|||||||
### dees-chart-area
|
### dees-chart-area
|
||||||
- Fully functional area chart component using ApexCharts
|
- Fully functional area chart component using ApexCharts
|
||||||
- Displays time-series data with gradient fills
|
- Displays time-series data with gradient fills
|
||||||
- Responsive with ResizeObserver
|
- Responsive with ResizeObserver (debounced to prevent flicker)
|
||||||
- Demo shows CPU and memory usage metrics
|
- Demo shows CPU and memory usage metrics
|
||||||
|
- Fixed: Chart now properly respects container boundaries on initial render
|
||||||
|
- Overflow prevention with proper CSS containment
|
||||||
|
|
||||||
### dees-chart-log
|
### dees-chart-log
|
||||||
- Server log viewer component (not a chart despite the name)
|
- Server log viewer component (not a chart despite the name)
|
||||||
|
@ -33,27 +33,40 @@ export class DeesChartArea extends DeesElement {
|
|||||||
public label: string = 'Untitled Chart';
|
public label: string = 'Untitled Chart';
|
||||||
|
|
||||||
private resizeObserver: ResizeObserver;
|
private resizeObserver: ResizeObserver;
|
||||||
|
private resizeTimeout: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
domtools.elementBasic.setup();
|
domtools.elementBasic.setup();
|
||||||
|
|
||||||
this.resizeObserver = new ResizeObserver((entries) => {
|
this.resizeObserver = new ResizeObserver((entries) => {
|
||||||
for (let entry of entries) {
|
// Debounce resize calls to prevent excessive updates
|
||||||
if (entry.target.classList.contains('mainbox')) {
|
if (this.resizeTimeout) {
|
||||||
this.resizeChart(); // Call resizeChart when the .mainbox size changes
|
clearTimeout(this.resizeTimeout);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.resizeTimeout = window.setTimeout(() => {
|
||||||
|
for (let entry of entries) {
|
||||||
|
if (entry.target.classList.contains('mainbox') && this.chart) {
|
||||||
|
this.resizeChart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100); // 100ms debounce
|
||||||
});
|
});
|
||||||
|
|
||||||
this.registerStartupFunction(async () => {
|
this.registerStartupFunction(async () => {
|
||||||
this.updateComplete.then(() => {
|
this.updateComplete.then(() => {
|
||||||
const mainbox = this.shadowRoot.querySelector('.mainbox');
|
const mainbox = this.shadowRoot.querySelector('.mainbox');
|
||||||
if (mainbox) {
|
if (mainbox) {
|
||||||
this.resizeObserver.observe(mainbox); // Start observing the .mainbox element
|
this.resizeObserver.observe(mainbox);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.registerGarbageFunction(async () => {
|
this.registerGarbageFunction(async () => {
|
||||||
|
if (this.resizeTimeout) {
|
||||||
|
clearTimeout(this.resizeTimeout);
|
||||||
|
}
|
||||||
this.resizeObserver.disconnect();
|
this.resizeObserver.disconnect();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -73,6 +86,7 @@ export class DeesChartArea extends DeesElement {
|
|||||||
height: 400px;
|
height: 400px;
|
||||||
background: #111;
|
background: #111;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chartTitle {
|
.chartTitle {
|
||||||
@ -82,6 +96,7 @@ export class DeesChartArea extends DeesElement {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
.chartContainer {
|
.chartContainer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -90,6 +105,7 @@ export class DeesChartArea extends DeesElement {
|
|||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
padding: 32px 16px 16px 0px;
|
padding: 32px 16px 16px 0px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
@ -104,7 +120,30 @@ export class DeesChartArea extends DeesElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async firstUpdated() {
|
public async firstUpdated() {
|
||||||
const domtoolsInstance = await this.domtoolsPromise;
|
await this.domtoolsPromise;
|
||||||
|
|
||||||
|
// Wait for next animation frame to ensure layout is complete
|
||||||
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||||
|
|
||||||
|
// Get actual dimensions of the container
|
||||||
|
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
|
||||||
|
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
|
||||||
|
|
||||||
|
if (!mainbox || !chartContainer) {
|
||||||
|
console.error('Chart containers not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate initial dimensions
|
||||||
|
const styleChartContainer = window.getComputedStyle(chartContainer);
|
||||||
|
const paddingTop = parseInt(styleChartContainer.paddingTop, 10);
|
||||||
|
const paddingBottom = parseInt(styleChartContainer.paddingBottom, 10);
|
||||||
|
const paddingLeft = parseInt(styleChartContainer.paddingLeft, 10);
|
||||||
|
const paddingRight = parseInt(styleChartContainer.paddingRight, 10);
|
||||||
|
|
||||||
|
const initialWidth = mainbox.clientWidth - paddingLeft - paddingRight;
|
||||||
|
const initialHeight = mainbox.offsetHeight - paddingTop - paddingBottom;
|
||||||
|
|
||||||
var options: ApexCharts.ApexOptions = {
|
var options: ApexCharts.ApexOptions = {
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@ -129,12 +168,20 @@ export class DeesChartArea extends DeesElement {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
chart: {
|
chart: {
|
||||||
width: 0, // Adjusted for responsive width
|
width: initialWidth || 100, // Use actual width or fallback
|
||||||
height: 0, // Adjusted for responsive height
|
height: initialHeight || 100, // Use actual height or fallback
|
||||||
type: 'area',
|
type: 'area',
|
||||||
toolbar: {
|
toolbar: {
|
||||||
show: false, // This line disables the toolbar
|
show: false, // This line disables the toolbar
|
||||||
},
|
},
|
||||||
|
animations: {
|
||||||
|
enabled: true,
|
||||||
|
speed: 400,
|
||||||
|
animateGradually: {
|
||||||
|
enabled: true,
|
||||||
|
delay: 150
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@ -184,14 +231,11 @@ export class DeesChartArea extends DeesElement {
|
|||||||
x: {
|
x: {
|
||||||
format: 'dd/MM/yy HH:mm',
|
format: 'dd/MM/yy HH:mm',
|
||||||
},
|
},
|
||||||
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
|
custom: function ({ series, dataPointIndex, w }: any) {
|
||||||
// Get the x value
|
|
||||||
const xValue = w.globals.labels[dataPointIndex];
|
|
||||||
// Iterate through each series and get its value
|
// Iterate through each series and get its value
|
||||||
let tooltipContent = `<div style="padding: 10px; background: #1e1e2f; color: white; border-radius: 5px;">`;
|
let tooltipContent = `<div style="padding: 10px; background: #1e1e2f; color: white; border-radius: 5px;">`;
|
||||||
tooltipContent += ``; // `<strong>Time:</strong> ${xValue}<br/>`;
|
|
||||||
|
|
||||||
series.forEach((s, index) => {
|
series.forEach((s: number[], index: number) => {
|
||||||
const label = w.globals.seriesNames[index]; // Get series label
|
const label = w.globals.seriesNames[index]; // Get series label
|
||||||
const value = s[dataPointIndex]; // Get value at data point
|
const value = s[dataPointIndex]; // Get value at data point
|
||||||
tooltipContent += `<strong>${label}:</strong> ${value} Mbps<br/>`;
|
tooltipContent += `<strong>${label}:</strong> ${value} Mbps<br/>`;
|
||||||
@ -235,15 +279,25 @@ export class DeesChartArea extends DeesElement {
|
|||||||
};
|
};
|
||||||
this.chart = new ApexCharts(this.shadowRoot.querySelector('.chartContainer'), options);
|
this.chart = new ApexCharts(this.shadowRoot.querySelector('.chartContainer'), options);
|
||||||
await this.chart.render();
|
await this.chart.render();
|
||||||
|
|
||||||
|
// Give the chart a moment to fully initialize before resizing
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
await this.resizeChart();
|
await this.resizeChart();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async resizeChart() {
|
public async resizeChart() {
|
||||||
|
if (!this.chart) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
|
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
|
||||||
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
|
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
|
||||||
|
|
||||||
|
if (!mainbox || !chartContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get computed style of the element
|
// Get computed style of the element
|
||||||
const styleMainbox = window.getComputedStyle(mainbox);
|
|
||||||
const styleChartContainer = window.getComputedStyle(chartContainer);
|
const styleChartContainer = window.getComputedStyle(chartContainer);
|
||||||
|
|
||||||
// Extract padding values
|
// Extract padding values
|
||||||
|
@ -5,8 +5,6 @@ import {
|
|||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
property,
|
property,
|
||||||
state,
|
|
||||||
type CSSResult,
|
|
||||||
type TemplateResult,
|
type TemplateResult,
|
||||||
} from '@design.estate/dees-element';
|
} from '@design.estate/dees-element';
|
||||||
|
|
||||||
@ -259,7 +257,7 @@ export class DeesChartLog extends DeesElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async firstUpdated() {
|
public async firstUpdated() {
|
||||||
const domtoolsInstance = await this.domtoolsPromise;
|
await this.domtoolsPromise;
|
||||||
this.logContainer = this.shadowRoot.querySelector('.logContainer');
|
this.logContainer = this.shadowRoot.querySelector('.logContainer');
|
||||||
|
|
||||||
// Initialize with demo server logs
|
// Initialize with demo server logs
|
||||||
|
Reference in New Issue
Block a user