filter
This commit is contained in:
parent
6c01e71d04
commit
aade12d6ff
@ -1,7 +1,9 @@
|
||||
.chart-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
|
||||
.chart-header {
|
||||
padding: 10px 15px;
|
||||
@ -12,6 +14,9 @@
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,5 +24,45 @@
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
|
||||
// Ensure chart containers fill available space
|
||||
::ng-deep canvas {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive adjustments
|
||||
@media (max-width: 768px) {
|
||||
.chart-wrapper {
|
||||
.chart-header {
|
||||
padding: 8px 12px;
|
||||
|
||||
h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.chart-wrapper {
|
||||
.chart-header {
|
||||
padding: 6px 10px;
|
||||
|
||||
h5 {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, Input, OnInit, OnDestroy, ComponentRef, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { Component, Input, OnInit, OnDestroy, ComponentRef, ViewChild, ViewContainerRef, HostListener } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { FilterService } from './filter.service';
|
||||
|
||||
@ -42,6 +42,27 @@ export class ChartWrapperComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle window resize events
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: any) {
|
||||
// Notify the chart component to resize if it has a resize method
|
||||
if (this.componentRef && this.componentRef.instance) {
|
||||
const chartInstance = this.componentRef.instance;
|
||||
|
||||
// If it's a chart component with an onResize method, call it
|
||||
if (chartInstance.onResize && typeof chartInstance.onResize === 'function') {
|
||||
chartInstance.onResize();
|
||||
}
|
||||
|
||||
// If it's a chart component with a chart property (from BaseChartDirective), resize it
|
||||
if (chartInstance.chart && typeof chartInstance.chart.resize === 'function') {
|
||||
setTimeout(() => {
|
||||
chartInstance.chart.resize();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private loadChartComponent(): void {
|
||||
if (this.chartContainer && this.chartComponent) {
|
||||
this.chartContainer.clear();
|
||||
|
||||
@ -4,16 +4,26 @@
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.filter-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,21 +34,44 @@
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
select {
|
||||
flex: 1;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.save-preset-section {
|
||||
margin-bottom: 15px;
|
||||
|
||||
.clr-input-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
|
||||
.clr-input {
|
||||
flex: 1;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.clr-input-group-btn {
|
||||
.btn {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filters-form {
|
||||
.filters-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 15px;
|
||||
|
||||
.filter-item {
|
||||
@ -46,6 +79,8 @@
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.filter-header {
|
||||
display: flex;
|
||||
@ -56,6 +91,10 @@
|
||||
.filter-label {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,22 +108,29 @@
|
||||
|
||||
input, select, textarea {
|
||||
width: 100%;
|
||||
min-width: 0; // Allow flexbox to shrink items
|
||||
}
|
||||
}
|
||||
|
||||
.date-range-controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-direction: column;
|
||||
|
||||
.clr-form-control {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
@ -101,3 +147,46 @@
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive design for smaller screens
|
||||
@media (max-width: 768px) {
|
||||
.common-filter-container {
|
||||
padding: 10px;
|
||||
|
||||
.filters-form {
|
||||
.filters-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.presets-section {
|
||||
.preset-controls {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.save-preset-section {
|
||||
.clr-input-group {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.common-filter-container {
|
||||
.date-range-controls {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, Input, HostListener } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Filter, FilterService, FilterType } from './filter.service';
|
||||
@ -61,6 +61,16 @@ export class CommonFilterComponent implements OnInit, OnDestroy {
|
||||
this.subscriptions.forEach(sub => sub.unsubscribe());
|
||||
}
|
||||
|
||||
// Handle window resize events
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize(event: any) {
|
||||
// Trigger change detection to reflow the layout
|
||||
setTimeout(() => {
|
||||
// This will cause the grid to recalculate its layout
|
||||
this.filters = [...this.filters];
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Build the form based on current filters
|
||||
private buildForm(): void {
|
||||
// Clear existing form controls
|
||||
|
||||
@ -208,7 +208,9 @@ export class EditnewdashComponent implements OnInit {
|
||||
},
|
||||
displayGrid: "always",
|
||||
minCols: 10,
|
||||
minRows: 10
|
||||
minRows: 10,
|
||||
// Add resize callback to handle chart resizing
|
||||
itemResizeCallback: this.itemResize.bind(this)
|
||||
};
|
||||
|
||||
this.editId = this.route.snapshot.params.id;
|
||||
@ -1273,4 +1275,17 @@ export class EditnewdashComponent implements OnInit {
|
||||
// When disabling, the user can edit the filters normally
|
||||
}
|
||||
}
|
||||
|
||||
// Add method to handle item resize events
|
||||
itemResize(item: any, itemComponent: any) {
|
||||
console.log('Item resized:', item);
|
||||
// Trigger a window resize event to notify charts to resize
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
// Also try to directly notify the chart component if possible
|
||||
if (itemComponent && itemComponent.item && itemComponent.item.component) {
|
||||
// If the resized item contains a chart, we could try to call its resize method directly
|
||||
// This would require the chart component to have a public resize method
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div style="display: block">
|
||||
<div style="display: block; height: 100%; width: 100%;">
|
||||
<!-- No filter controls needed with the new simplified approach -->
|
||||
<!-- Filters are now configured at the drilldown level -->
|
||||
|
||||
@ -19,13 +19,14 @@
|
||||
</div>
|
||||
|
||||
<!-- Chart display -->
|
||||
<div *ngIf="!noDataAvailable">
|
||||
<div *ngIf="!noDataAvailable" style="position: relative; height: calc(100% - 50px);">
|
||||
<canvas baseChart
|
||||
[datasets]="barChartData"
|
||||
[labels]="barChartLabels"
|
||||
[type]="barChartType"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)">
|
||||
</canvas>
|
||||
[datasets]="barChartData"
|
||||
[labels]="barChartLabels"
|
||||
[type]="barChartType"
|
||||
[options]="barChartOptions"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)">
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,31 @@
|
||||
// Bar Chart Component Styles
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bar-chart-container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
// Responsive design for chart container
|
||||
@media (max-width: 768px) {
|
||||
.bar-chart-container {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.bar-chart-container {
|
||||
height: 250px;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,9 @@
|
||||
import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
|
||||
import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { Dashboard3Service } from '../../../../../../services/builder/dashboard3.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { FilterService } from '../../common-filter/filter.service';
|
||||
// Add BaseChartDirective import for chart resizing
|
||||
import { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bar-chart',
|
||||
@ -35,6 +37,9 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
// Multi-layer drilldown configuration inputs
|
||||
@Input() drilldownLayers: any[] = []; // Array of drilldown layer configurations
|
||||
|
||||
// Add ViewChild to access the chart directive
|
||||
@ViewChild(BaseChartDirective) chart?: BaseChartDirective;
|
||||
|
||||
barChartLabels: string[] = ['Apple', 'Banana', 'Kiwifruit', 'Blueberry', 'Orange', 'Grapes'];
|
||||
barChartType: string = 'bar';
|
||||
barChartPlugins = [];
|
||||
@ -43,6 +48,33 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
];
|
||||
barChartLegend: boolean = true;
|
||||
|
||||
// Add responsive chart options
|
||||
barChartOptions: any = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
autoSkip: false,
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Multi-layer drilldown state tracking
|
||||
drilldownStack: any[] = []; // Stack to track drilldown navigation history
|
||||
currentDrilldownLevel: number = 0; // Current drilldown level (0 = base level)
|
||||
@ -104,6 +136,7 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
// Update legend visibility if it changed
|
||||
if (changes.chartlegend !== undefined) {
|
||||
this.barChartLegend = changes.chartlegend.currentValue;
|
||||
this.barChartOptions.plugins.legend.display = this.barChartLegend;
|
||||
console.log('Chart legend changed to:', this.barChartLegend);
|
||||
}
|
||||
}
|
||||
@ -536,6 +569,13 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.fetchChartData();
|
||||
}
|
||||
|
||||
// Method to handle window resize events
|
||||
onResize(): void {
|
||||
if (this.chart) {
|
||||
this.chart.chart?.resize();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure labels and data arrays have the same length
|
||||
private syncLabelAndDataArrays(): void {
|
||||
// For bar charts, we need to ensure all datasets have the same number of data points
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user