dees-catalog/ts_web/elements/dees-chart-area.ts
2024-02-05 13:11:05 +01:00

215 lines
5.2 KiB
TypeScript

import {
DeesElement,
css,
cssManager,
customElement,
html,
property,
state,
type CSSResult,
type TemplateResult,
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
import { demoFunc } from './dees-chart-area.demo.js';
import ApexCharts from 'apexcharts';
declare global {
interface HTMLElementTagNameMap {
'dees-chart-area': DeesChartArea;
}
}
@customElement('dees-chart-area')
export class DeesChartArea extends DeesElement {
public static demo = demoFunc;
// instance
@state()
public chart: ApexCharts;
@property()
public label: string = 'Untitled Chart';
private resizeObserver: ResizeObserver;
constructor() {
super();
domtools.elementBasic.setup();
this.resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.target.classList.contains('mainbox')) {
this.resizeChart(); // Call resizeChart when the .mainbox size changes
}
}
});
this.registerStartupFunction(async () => {
this.updateComplete.then(() => {
const mainbox = this.shadowRoot.querySelector('.mainbox');
if (mainbox) {
this.resizeObserver.observe(mainbox); // Start observing the .mainbox element
}
});
});
this.registerGarbageFunction(async () => {
this.resizeObserver.disconnect();
})
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
font-family: 'Roboto', sans-serif;
color: #ccc;
font-weight: 600;
font-size: 12px;
}
.mainbox {
position: relative;
width: 100%;
height: 400px;
background: #222;
border-radius: 8px;
}
.chartTitle {
position: absolute;
top: 0;
left: 0;
width: 100%;
text-align: center;
padding-top: 16px;
}
.chartContainer {
position: absolute;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
padding: 32px 16px 16px 0px;
}
`,
];
public render(): TemplateResult {
return html` <div class="mainbox">
<div class="chartTitle">${this.label}</div>
<div class="chartContainer"></div>
</div> `;
}
public async firstUpdated() {
const domtoolsInstance = await this.domtoolsPromise;
var options: ApexCharts.ApexOptions = {
series: [
{
name: 'cpu',
data: [31, 40, 28, 51, 42, 109, 100],
},
{
name: 'memory',
data: [11, 32, 45, 32, 34, 52, 41],
},
],
chart: {
width: 0, // Adjusted for responsive width
height: 0, // Adjusted for responsive height
type: 'area',
toolbar: {
show: false, // This line disables the toolbar
},
},
dataLabels: {
enabled: false,
},
stroke: {
width: 1,
curve: 'smooth',
},
xaxis: {
crosshairs: {
stroke: {
width: 1,
color: '#444',
},
},
type: 'datetime',
categories: [
'2018-09-19T00:00:00.000Z',
'2018-09-19T01:30:00.000Z',
'2018-09-19T02:30:00.000Z',
'2018-09-19T03:30:00.000Z',
'2018-09-19T04:30:00.000Z',
'2018-09-19T05:30:00.000Z',
'2018-09-19T06:30:00.000Z',
],
},
yaxis: {
crosshairs: {
stroke: {
width: 1,
color: '#444',
},
},
},
tooltip: {
x: {
format: 'dd/MM/yy HH:mm',
},
},
grid: {
xaxis: {
lines: {
show: true, // This enables the grid lines along the x-axis
},
},
yaxis: {
lines: {
show: true,
},
},
borderColor: '#666', // Set the color of the grid lines
strokeDashArray: 2, // Solid line
row: {
colors: [], // This can be used to alternate the shading of the horizontal rows
opacity: 0.1,
},
column: {
colors: [], // For vertical column bands, not needed here but available for customization
opacity: 0.1,
},
},
};
this.chart = new ApexCharts(this.shadowRoot.querySelector('.chartContainer'), options);
await this.chart.render();
await this.resizeChart();
}
public async resizeChart() {
const element = this.shadowRoot.querySelector('.chartContainer');
// Get computed style of the element
const style = window.getComputedStyle(element);
// Extract padding values
const paddingTop = parseInt(style.paddingTop, 10);
const paddingBottom = parseInt(style.paddingBottom, 10);
const paddingLeft = parseInt(style.paddingLeft, 10);
const paddingRight = parseInt(style.paddingRight, 10);
// Calculate the actual width and height to use, subtracting padding
const actualWidth = element.clientWidth - paddingLeft - paddingRight;
const actualHeight = element.clientHeight - paddingTop - paddingBottom;
await this.chart.updateOptions({
chart: {
width: actualWidth,
height: actualHeight,
},
});
}
}