fix(dees-statsgrid): Adjust stats grid styling for better alignment and improved visualizations in gauge and trend tiles.

This commit is contained in:
Juergen Kunz
2025-06-10 18:58:05 +00:00
parent f7e4582fde
commit cd86001713
4 changed files with 268 additions and 26 deletions

View File

@ -1,5 +1,14 @@
# Changelog # Changelog
## 2025-06-10 - 1.8.1 - fix(dees-statsgrid)
Adjust stats grid styling for better alignment and improved visualizations in gauge and trend tiles.
- Center-align tile header elements by setting align-items to center and ensuring full width.
- Increase tile content height to 90px and center its content.
- Update gauge visualization: reduce circle radius from 40 to 30, adjust stroke dasharray (from 251.2 to 188.5), and decrease gauge text font size.
- Refine trend chart layout: set trend-svg height to 40px, center trend value and adjust typography to larger, bolder text.
- Ensure overall grid responsiveness with adjusted gap and column sizing.
## 2025-04-25 - 1.8.0 - feat(dees-pagination) ## 2025-04-25 - 1.8.0 - feat(dees-pagination)
Add new pagination component to the library along with its demo and integration in the main export. Add new pagination component to the library along with its demo and integration in the main export.

209
readme.md
View File

@ -15,7 +15,7 @@ npm install @design.estate/dees-catalog
| Core UI | `DeesButton`, `DeesBadge`, `DeesChips`, `DeesIcon`, `DeesLabel`, `DeesSpinner`, `DeesToast` | | Core UI | `DeesButton`, `DeesBadge`, `DeesChips`, `DeesIcon`, `DeesLabel`, `DeesSpinner`, `DeesToast` |
| Forms | `DeesForm`, `DeesInputText`, `DeesInputCheckbox`, `DeesInputDropdown`, `DeesInputRadio`, `DeesInputFileupload`, `DeesInputIban`, `DeesInputPhone`, `DeesInputQuantitySelector`, `DeesInputMultitoggle`, `DeesFormSubmit` | | Forms | `DeesForm`, `DeesInputText`, `DeesInputCheckbox`, `DeesInputDropdown`, `DeesInputRadio`, `DeesInputFileupload`, `DeesInputIban`, `DeesInputPhone`, `DeesInputQuantitySelector`, `DeesInputMultitoggle`, `DeesFormSubmit` |
| Layout | `DeesAppuiBase`, `DeesAppuiMainmenu`, `DeesAppuiMainselector`, `DeesAppuiMaincontent`, `DeesAppuiAppbar`, `DeesMobileNavigation` | | Layout | `DeesAppuiBase`, `DeesAppuiMainmenu`, `DeesAppuiMainselector`, `DeesAppuiMaincontent`, `DeesAppuiAppbar`, `DeesMobileNavigation` |
| Data Display | `DeesTable`, `DeesDataviewCodebox`, `DeesDataviewStatusobject`, `DeesPdf` | | Data Display | `DeesTable`, `DeesDataviewCodebox`, `DeesDataviewStatusobject`, `DeesPdf`, `DeesStatsGrid` |
| Visualization | `DeesChartArea`, `DeesChartLog` | | Visualization | `DeesChartArea`, `DeesChartLog` |
| Dialogs & Overlays | `DeesModal`, `DeesContextmenu`, `DeesSpeechbubble`, `DeesWindowlayer` | | Dialogs & Overlays | `DeesModal`, `DeesContextmenu`, `DeesSpeechbubble`, `DeesWindowlayer` |
| Navigation | `DeesStepper`, `DeesProgressbar` | | Navigation | `DeesStepper`, `DeesProgressbar` |
@ -528,6 +528,213 @@ Key Features:
- Responsive layout - Responsive layout
- Loading states - Loading states
#### `DeesStatsGrid`
A responsive grid component for displaying statistical data with various visualization types including numbers, gauges, percentages, and trends.
```typescript
<dees-statsgrid
.tiles=${[
{
id: 'revenue',
title: 'Total Revenue',
value: 125420,
unit: '$',
type: 'number',
icon: 'faDollarSign',
description: '+12.5% from last month',
color: '#22c55e',
actions: [
{
name: 'View Details',
iconName: 'faChartLine',
action: async () => {
console.log('Viewing revenue details');
}
},
{
name: 'Export Data',
iconName: 'faFileExport',
action: async () => {
console.log('Exporting revenue data');
}
}
]
},
{
id: 'cpu',
title: 'CPU Usage',
value: 73,
type: 'gauge',
icon: 'faMicrochip',
gaugeOptions: {
min: 0,
max: 100,
thresholds: [
{ value: 0, color: '#22c55e' },
{ value: 60, color: '#f59e0b' },
{ value: 80, color: '#ef4444' }
]
}
},
{
id: 'storage',
title: 'Storage Used',
value: 65,
type: 'percentage',
icon: 'faHardDrive',
description: '650 GB of 1 TB',
color: '#3b82f6'
},
{
id: 'requests',
title: 'API Requests',
value: '1.2k',
unit: '/min',
type: 'trend',
icon: 'faServer',
trendData: [45, 52, 38, 65, 72, 68, 75, 82, 79, 85, 88, 92]
},
{
id: 'uptime',
title: 'System Uptime',
value: '99.95%',
type: 'text',
icon: 'faCheckCircle',
color: '#22c55e',
description: 'Last 30 days'
}
]}
.gridActions=${[
{
name: 'Refresh',
iconName: 'faSync',
action: async () => {
console.log('Refreshing stats...');
}
},
{
name: 'Export Report',
iconName: 'faFileExport',
action: async () => {
console.log('Exporting stats report...');
}
}
]}
.minTileWidth=${250} // Minimum tile width in pixels
.gap=${16} // Gap between tiles in pixels
></dees-statsgrid>
```
Key Features:
- Auto-responsive grid layout with configurable minimum tile width
- Multiple tile types for different data visualizations
- Full theme support (light/dark mode)
- Interactive tiles with action support
- Grid-level and tile-level actions
- Smooth animations and transitions
- Icon support for visual hierarchy
Tile Types:
1. **`number`** - Display numeric values with optional units
- Large, prominent value display
- Optional unit display
- Custom color support
- Description text
2. **`gauge`** - Circular gauge visualization
- Min/max value configuration
- Color thresholds for visual alerts
- Animated value transitions
- Compact circular design
3. **`percentage`** - Progress bar visualization
- Horizontal progress bar
- Percentage display overlay
- Custom color support
- Ideal for capacity metrics
4. **`trend`** - Mini sparkline chart
- Array of numeric values for trend data
- Area chart visualization
- Current value display
- Responsive SVG rendering
5. **`text`** - Simple text display
- Flexible text content
- Custom color support
- Ideal for status messages
Action System:
- **Grid Actions**: Displayed as buttons in the grid header
- Apply to the entire stats grid
- Use standard `dees-button` components
- Support icons and text
- **Tile Actions**: Context-specific actions per tile
- Single action: Direct click on tile
- Multiple actions: Right-click context menu
- Actions access tile data through closures
- Consistent with other library components
Configuration Options:
- `tiles`: Array of `IStatsTile` objects defining the grid content
- `gridActions`: Array of actions for the entire grid
- `minTileWidth`: Minimum width for tiles (default: 250px)
- `gap`: Space between tiles (default: 16px)
Best Practices:
1. **Data Organization**
- Group related metrics together
- Use consistent units and scales
- Provide meaningful descriptions
- Choose appropriate tile types for data
2. **Visual Hierarchy**
- Use colors strategically for alerts
- Include relevant icons
- Keep titles concise
- Balance tile types for visual interest
3. **Interactivity**
- Provide relevant actions for detailed views
- Use tile actions for item-specific operations
- Use grid actions for global operations
- Keep action names clear and concise
4. **Performance**
- Update only changed tiles
- Use reasonable update intervals
- Batch updates when possible
- Consider data volume for trends
Common Use Cases:
- System monitoring dashboards
- Business intelligence displays
- Performance metrics
- Resource utilization
- Real-time statistics
- KPI tracking
Integration Example:
```typescript
// Real-time updates
setInterval(() => {
const grid = document.querySelector('dees-statsgrid');
const updatedTiles = [...grid.tiles];
// Update specific tile
const cpuTile = updatedTiles.find(t => t.id === 'cpu');
cpuTile.value = Math.round(Math.random() * 100);
// Update trend data
const trendTile = updatedTiles.find(t => t.id === 'requests');
trendTile.trendData = [...trendTile.trendData.slice(1),
Math.round(Math.random() * 100)];
grid.tiles = updatedTiles;
}, 3000);
```
### Visualization Components ### Visualization Components
#### `DeesChartArea` #### `DeesChartArea`

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-catalog', name: '@design.estate/dees-catalog',
version: '1.8.0', version: '1.8.1',
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.'
} }

View File

@ -136,8 +136,9 @@ export class DeesStatsGrid extends DeesElement {
.tile-header { .tile-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-start; align-items: center;
margin-bottom: 12px; margin-bottom: 12px;
width: 100%;
} }
.tile-title { .tile-title {
@ -152,10 +153,12 @@ export class DeesStatsGrid extends DeesElement {
} }
.tile-content { .tile-content {
min-height: 60px; height: 90px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center;
position: relative;
} }
.tile-value { .tile-value {
@ -165,7 +168,9 @@ export class DeesStatsGrid extends DeesElement {
line-height: 1.2; line-height: 1.2;
display: flex; display: flex;
align-items: baseline; align-items: baseline;
justify-content: center;
gap: 6px; gap: 6px;
width: 100%;
} }
.tile-unit { .tile-unit {
@ -182,8 +187,11 @@ export class DeesStatsGrid extends DeesElement {
.gauge-container { .gauge-container {
width: 100%; width: 100%;
height: 120px; height: 80px;
position: relative; position: relative;
display: flex;
align-items: center;
justify-content: center;
} }
.gauge-svg { .gauge-svg {
@ -194,22 +202,21 @@ export class DeesStatsGrid extends DeesElement {
.gauge-background { .gauge-background {
fill: none; fill: none;
stroke: ${cssManager.bdTheme('#e0e0e0', '#2a2a2a')}; stroke: ${cssManager.bdTheme('#e0e0e0', '#2a2a2a')};
stroke-width: 8; stroke-width: 6;
} }
.gauge-fill { .gauge-fill {
fill: none; fill: none;
stroke-width: 8; stroke-width: 6;
stroke-linecap: round; stroke-linecap: round;
transition: stroke-dashoffset 0.5s ease; transition: stroke-dashoffset 0.5s ease;
} }
.gauge-text { .gauge-text {
fill: ${cssManager.bdTheme('#333', '#fff')}; fill: ${cssManager.bdTheme('#333', '#fff')};
font-size: 24px; font-size: 18px;
font-weight: 600; font-weight: 600;
text-anchor: middle; text-anchor: middle;
alignment-baseline: middle;
} }
.percentage-container { .percentage-container {
@ -240,13 +247,19 @@ export class DeesStatsGrid extends DeesElement {
.trend-container { .trend-container {
width: 100%; width: 100%;
height: 60px; height: 100%;
position: relative; position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 4px;
} }
.trend-svg { .trend-svg {
width: 100%; width: 100%;
height: 100%; height: 40px;
flex-shrink: 0;
} }
.trend-line { .trend-line {
@ -260,11 +273,24 @@ export class DeesStatsGrid extends DeesElement {
} }
.text-value { .text-value {
font-size: 18px; font-size: 32px;
font-weight: 500; font-weight: 600;
color: ${cssManager.bdTheme('#333', '#fff')}; color: ${cssManager.bdTheme('#333', '#fff')};
} }
.trend-value {
font-size: 32px;
font-weight: 600;
color: ${cssManager.bdTheme('#333', '#fff')};
display: flex;
align-items: baseline;
gap: 6px;
}
.trend-value .tile-unit {
font-size: 18px;
}
dees-contextmenu { dees-contextmenu {
position: fixed; position: fixed;
z-index: 1000; z-index: 1000;
@ -370,7 +396,7 @@ export class DeesStatsGrid extends DeesElement {
const value = typeof tile.value === 'number' ? tile.value : parseFloat(tile.value); const value = typeof tile.value === 'number' ? tile.value : parseFloat(tile.value);
const options = tile.gaugeOptions || { min: 0, max: 100 }; const options = tile.gaugeOptions || { min: 0, max: 100 };
const percentage = ((value - options.min) / (options.max - options.min)) * 100; const percentage = ((value - options.min) / (options.max - options.min)) * 100;
const strokeDasharray = 251.2; // Circumference of circle with r=40 const strokeDasharray = 188.5; // Circumference of circle with r=30
const strokeDashoffset = strokeDasharray - (strokeDasharray * percentage) / 100; const strokeDashoffset = strokeDasharray - (strokeDasharray * percentage) / 100;
let strokeColor = tile.color || cssManager.bdTheme('#0084ff', '#0066cc'); let strokeColor = tile.color || cssManager.bdTheme('#0084ff', '#0066cc');
@ -385,25 +411,25 @@ export class DeesStatsGrid extends DeesElement {
return html` return html`
<div class="gauge-container"> <div class="gauge-container">
<svg class="gauge-svg" viewBox="0 0 120 120"> <svg class="gauge-svg" viewBox="0 0 80 80">
<circle <circle
class="gauge-background" class="gauge-background"
cx="60" cx="40"
cy="60" cy="40"
r="40" r="30"
transform="rotate(-90 60 60)" transform="rotate(-90 40 40)"
/> />
<circle <circle
class="gauge-fill" class="gauge-fill"
cx="60" cx="40"
cy="60" cy="40"
r="40" r="30"
transform="rotate(-90 60 60)" transform="rotate(-90 40 40)"
stroke="${strokeColor}" stroke="${strokeColor}"
stroke-dasharray="${strokeDasharray}" stroke-dasharray="${strokeDasharray}"
stroke-dashoffset="${strokeDashoffset}" stroke-dashoffset="${strokeDashoffset}"
/> />
<text class="gauge-text" x="60" y="60"> <text class="gauge-text" x="40" y="40" dy="0.35em">
${value}${tile.unit || ''} ${value}${tile.unit || ''}
</text> </text>
</svg> </svg>
@ -436,7 +462,7 @@ export class DeesStatsGrid extends DeesElement {
const min = Math.min(...data); const min = Math.min(...data);
const range = max - min || 1; const range = max - min || 1;
const width = 200; const width = 200;
const height = 60; const height = 40;
const points = data.map((value, index) => { const points = data.map((value, index) => {
const x = (index / (data.length - 1)) * width; const x = (index / (data.length - 1)) * width;
const y = height - ((value - min) / range) * height; const y = height - ((value - min) / range) * height;
@ -451,7 +477,7 @@ export class DeesStatsGrid extends DeesElement {
<polygon class="trend-area" points="${areaPoints}" /> <polygon class="trend-area" points="${areaPoints}" />
<polyline class="trend-line" points="${points}" /> <polyline class="trend-line" points="${points}" />
</svg> </svg>
<div class="tile-value" style="margin-top: 8px"> <div class="trend-value">
<span>${tile.value}</span> <span>${tile.value}</span>
${tile.unit ? html`<span class="tile-unit">${tile.unit}</span>` : ''} ${tile.unit ? html`<span class="tile-unit">${tile.unit}</span>` : ''}
</div> </div>