Skip to content

Commit bf58f56

Browse files
omachalaOndrej Machala
andauthored
feat: add sparklines to show historical data trends (#9)
* feat: add sparklines to show historical data trends - Show mini line charts at the bottom of each rectangle - Support configurable periods: 12h, 24h, 7d, 30d - Customizable line and fill styles via CSS - Use HA statistics API for efficient data fetching - Cache history data with 5-minute TTL - Fix icon contrast to match label contrast logic * feat: add sparkline.attribute for JSON mode, unify config naming - Add sparkline.attribute to use inline data arrays in JSON mode - Unify config to use 'attribute' everywhere (param is deprecated alias) - Add dev sandbox with mock HA data for rapid testing - Fix HVAC icons (fire/snowflake) by removing hardcoded icon attr - Improve sparkline styling (gradient fill, line opacity 0.15/0.25) - Add opacity defaults for labels (0.9), icons (0.85), values (0.85) - Update README: remove param mentions, add JSON sparkline docs - Update contribution section with coffee joke * fix: pass sparklineData through squarify layout * chore: add eslint-plugin-unicorn for better code quality - Enforces descriptive variable names (prevent-abbreviations) - Uses Number.parseInt/parseFloat instead of global functions - Uses String.slice() instead of substring() - Uses for-of loops instead of forEach - Various code style improvements * refactor: remove eslint-plugin-unicorn, improve code style - Remove unicorn plugin (too many disabled rules for little value) - Keep good changes: Number.parseInt, slice(), function scoping - Apply parameter destructuring in extractClimateInfo, extractLightInfo - Use descriptive callback names (rect instead of r) * refactor: extract utility functions from treemap-card - Move squarify.ts to utils/ - Extract matchesPattern to utils/predicates.ts - Extract getGradientColor, getHvacColor, applyOpacity to utils/colors.ts - Extract getLightBackgroundColor to utils/lights.ts - Add sparkline unit tests (100% coverage) - Exclude index.ts, types.ts from coverage * perf: extract and optimize data preparation with single-pass algorithm - Extract prepareTreemapData to src/utils/data.ts - Single-pass algorithm for calculating min/max stats (~2x faster) - Add performance regression test to catch future slowdowns - Add vitest bench file for interactive benchmarking - Fix TypeScript errors in test helpers (callWS mock) * perf: add shouldUpdate, caching, and debouncing optimizations - Add shouldUpdate() to skip re-renders when irrelevant hass changes - Cache _resolveData() result based on entity states hash - Debounce sparkline fetching (100ms) to reduce API calls - Add disconnectedCallback() cleanup for debounce timer These optimizations significantly reduce CPU usage when multiple treemap cards are on the same dashboard with frequent hass updates. * test: lock in 1.7x performance gain threshold (measured ~2x) * docs: add 'Why Treemap Card?' sales pitch to README * docs: rewrite sales pitch to be more human * docs: use simple bullet points * chore: remove local dev scripts from package.json * docs: simplify installation, remove horizontal lines * test: separate performance tests from unit tests * docs: add individual card screenshots for light/dark modes * docs: add light/dark mode screenshots to README * docs: center and add spacing to inline images * docs: try borderless table for screenshots * docs: revert top to single screenshot, add table to sparkline section * chore: add changeset for sparklines release * docs: update sparkline note - climate entities have statistics * feat: add HVAC action bars and climate temperature fallback for sparklines - Climate entities now show temperature sparklines using associated temperature sensor if the climate entity has no statistics data - Added HVAC action bars at the bottom of sparklines showing when heating/cooling was active over the time period - Configurable via sparkline.hvac options (show, height, colors) - Bars automatically use orange for heating, blue for cooling * docs: add climate HVAC bars to changeset * feat(sandbox): add climate HVAC bars example and mock history * feat: render HVAC activity as colored sparkline fill - Color sparkline fill sections where heating/cooling was active - Quantize HVAC segments to 15-minute blocks for cleaner visualization - Climate entities show line only by default, fill only where HVAC active - Extract temperature from climate entity history (current_temperature attr) - Remove debug console.log statements - Add tests for HVAC sparkline rendering * docs: update climate sparkline screenshots * docs: add climate sparkline section to README * docs: fix climate image formatting in README --------- Co-authored-by: Ondrej Machala <[email protected]>
1 parent cf5616f commit bf58f56

29 files changed

+2978
-518
lines changed

.changeset/sparklines-feature.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
'ha-treemap-card': minor
3+
---
4+
5+
Sparklines are here! Each rectangle now shows a mini chart of historical data.
6+
7+
- **Enabled by default** - to disable, add `sparkline.show: false` to your config
8+
- Configurable time periods: `12h`, `24h` (default), `7d`, or `30d`
9+
- Works with entity sensors (uses HA long-term statistics) and JSON mode (uses data array from attribute)
10+
- Fully customizable line and fill styles via CSS
11+
- **Climate entities**: Shows temperature history with HVAC action bars (heating/cooling periods displayed at the bottom)
12+
13+
Major performance overhaul - the card is now industry-grade:
14+
15+
- Render multiple cards with hundreds of rectangles without breaking a sweat
16+
- Runs smoothly on low-end devices like Raspberry Pi
17+
- Added performance regression tests to keep the bar high
18+
19+
Other improvements:
20+
21+
- Icons now adapt to background color for better readability (same as labels)
22+
- Config cleanup: use `attribute` everywhere (old `param` still works)

README.md

Lines changed: 168 additions & 47 deletions
Large diffs are not rendered by default.

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export default tseslint.config(
103103
complexity: 'off', // Render functions can be complex
104104

105105
// ===== Code Style =====
106-
'prefer-destructuring': 'off', // Not always clearer
106+
// prefer-destructuring is off - too many dynamic property accesses in this codebase
107107
'object-shorthand': ['error', 'always'],
108108

109109
// Allow unbound methods for Lit event handlers

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
"main": "dist/treemap-card.js",
77
"packageManager": "[email protected]",
88
"scripts": {
9-
"dev": "vite build --watch --outDir /home/ondrej/dockers/homeassistant/config/www --emptyOutDir=false",
9+
"dev": "vite serve --config vite.dev.config.ts",
1010
"build": "vite build",
11-
"ha": "./deploy.sh",
1211
"test": "vitest",
1312
"test:run": "vitest run",
13+
"test:perf": "vitest run --config vitest.perf.config.ts",
1414
"typecheck": "tsc --noEmit",
1515
"lint": "eslint src/",
1616
"lint:fix": "eslint src/ --fix",
1717
"format": "prettier --write .",
1818
"format:check": "prettier --check .",
19-
"check": "pnpm typecheck && pnpm format:check && pnpm lint && pnpm test:run",
19+
"check": "pnpm typecheck && pnpm format:check && pnpm lint && pnpm test:run && pnpm test:perf",
2020
"fix": "pnpm format && pnpm lint:fix",
2121
"prepare": "simple-git-hooks"
2222
},

0 commit comments

Comments
 (0)