From 156c562cc05ed30e1212e1e08c604a023ba0b562 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:25:37 +0000 Subject: [PATCH 01/45] Initial plan From b7d8e206b395865ec24cbb8e70c96c2e7c51e506 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:30:08 +0000 Subject: [PATCH 02/45] Add Habit Tracker sample with two interactive tables Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 276 ++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 packages/web-deploy/json/habit-tracker.idoc.json diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json new file mode 100644 index 00000000..ef5e3d75 --- /dev/null +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -0,0 +1,276 @@ +{ + "$schema": "../../../docs/schema/idoc_v1.json", + "title": "Habit Tracker", + "style": { + "css": [ + "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", + "body { display: grid; grid-template-areas: 'header header' 'habits progress' 'stats stats'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", + ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", + "#habits { grid-area: habits; }", + "#progress { grid-area: progress; }", + "#stats { grid-area: stats; }", + "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", + "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", + "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", + ".stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 15px; }", + ".stat-card { background: #f7fafc; padding: 15px; border-radius: 8px; text-align: center; border: 1px solid #e2e8f0; }", + ".stat-number { font-size: 2em; font-weight: bold; color: #667eea; margin-bottom: 5px; }", + ".stat-label { color: #718096; font-size: 0.9em; }", + ".tabulator { border-radius: 8px; overflow: hidden; }", + ".tabulator .tabulator-header { background: #f7fafc; }", + ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", + ".tabulator .tabulator-row { border-bottom: 1px solid #f1f5f9; }", + ".tabulator .tabulator-row:hover { background: #f8fafc; }" + ] + }, + "dataLoaders": [ + { + "dataSourceName": "habitsData", + "type": "inline", + "format": "json", + "content": [ + { + "habit_id": 1, + "habit_name": "Morning Exercise", + "category": "Health", + "target_frequency": "Daily", + "current_streak": 5, + "best_streak": 12 + }, + { + "habit_id": 2, + "habit_name": "Read for 30min", + "category": "Learning", + "target_frequency": "Daily", + "current_streak": 3, + "best_streak": 21 + }, + { + "habit_id": 3, + "habit_name": "Meditate", + "category": "Wellness", + "target_frequency": "Daily", + "current_streak": 8, + "best_streak": 15 + }, + { + "habit_id": 4, + "habit_name": "Write Journal", + "category": "Wellness", + "target_frequency": "Daily", + "current_streak": 2, + "best_streak": 7 + }, + { + "habit_id": 5, + "habit_name": "Learn New Language", + "category": "Learning", + "target_frequency": "3x per week", + "current_streak": 1, + "best_streak": 4 + }, + { + "habit_id": 6, + "habit_name": "Call Family", + "category": "Social", + "target_frequency": "Weekly", + "current_streak": 2, + "best_streak": 8 + } + ] + }, + { + "dataSourceName": "progressData", + "type": "inline", + "format": "json", + "content": [ + {"date": "2024-01-15", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-15", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-15", "habit_id": 3, "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-16", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-16", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-16", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-16", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-17", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-17", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-17", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-18", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-18", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-18", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-18", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-01-19", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-19", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-19", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-19", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-01-19", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-01-20", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true} + ] + } + ], + "variables": [ + { + "variableId": "totalHabits", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "length(data('habitsData'))" + } + }, + { + "variableId": "completionRateData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressData"], + "dataFrameTransformations": [ + { + "type": "aggregate", + "ops": ["count", "sum"], + "fields": ["completed", "completed"], + "as": ["total_entries", "completed_count"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_entries * 100", + "as": "completion_rate" + } + ] + } + }, + { + "variableId": "overallCompletionRate", + "type": "string", + "initialValue": "0%", + "calculation": { + "vegaExpression": "format(data('completionRateData')[0] ? data('completionRateData')[0].completion_rate : 0, '.1f') + '%'" + } + }, + { + "variableId": "activeDaysData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressData"], + "dataFrameTransformations": [ + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["count"], + "fields": ["habit_id"], + "as": ["habits_tracked"] + } + ] + } + }, + { + "variableId": "totalActiveDays", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "length(data('activeDaysData'))" + } + }, + { + "variableId": "averageStreak", + "type": "string", + "initialValue": "0", + "calculation": { + "dataSourceNames": ["habitsData"], + "dataFrameTransformations": [ + { + "type": "aggregate", + "ops": ["mean"], + "fields": ["current_streak"], + "as": ["avg_streak"] + } + ] + } + }, + { + "variableId": "avgStreakFormatted", + "type": "string", + "initialValue": "0.0", + "calculation": { + "vegaExpression": "format(data('averageStreak')[0] ? data('averageStreak')[0].avg_streak : 0, '.1f')" + } + } + ], + "groups": [ + { + "groupId": "header", + "elements": [ + "# 🎯 Habit Tracker", + "Track your daily habits and build consistent routines for personal growth." + ] + }, + { + "groupId": "habits", + "elements": [ + "## 📋 My Habits", + { + "type": "tabulator", + "dataSourceName": "habitsData", + "tabulatorOptions": { + "columns": [ + {"field": "habit_name", "title": "Habit", "width": 150}, + {"field": "category", "title": "Category", "width": 100}, + {"field": "target_frequency", "title": "Target", "width": 120}, + {"field": "current_streak", "title": "Streak", "width": 80, "hozAlign": "center"}, + {"field": "best_streak", "title": "Best", "width": 70, "hozAlign": "center"} + ], + "layout": "fitColumns", + "height": "300px", + "rowHeader": { + "width": 40, + "hozAlign": "center", + "formatter": "rownum" + } + } + } + ] + }, + { + "groupId": "progress", + "elements": [ + "## 📈 Recent Progress", + { + "type": "tabulator", + "dataSourceName": "progressData", + "tabulatorOptions": { + "columns": [ + {"field": "date", "title": "Date", "width": 100}, + {"field": "habit_name", "title": "Habit", "width": 150}, + {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross"} + ], + "layout": "fitColumns", + "height": "300px", + "initialSort": [ + {"column": "date", "dir": "desc"} + ] + } + } + ] + }, + { + "groupId": "stats", + "elements": [ + "## 📊 Statistics", + "
", + "
{{totalHabits}}
Active Habits
", + "
{{overallCompletionRate}}
Completion Rate
", + "
{{totalActiveDays}}
Days Tracked
", + "
{{avgStreakFormatted}}
Avg Streak
", + "
" + ] + } + ] +} \ No newline at end of file From c67342c69b9255e0ca3ffa84c426cab41bfdf351 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 16:04:44 +0000 Subject: [PATCH 03/45] Remove HTML elements from habit tracker, use Markdown formatting Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .github/copilot-instructions.md | 3 +++ .../web-deploy/json/habit-tracker.idoc.json | 18 ++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index d60b5441..52371c6e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -42,7 +42,9 @@ Chartifact consists of several interoperating modules: 4. **Security**: - Documents are rendered in sandboxed iframes. + - **NO HTML elements are allowed** - use only Markdown formatting. - No custom JavaScript execution or raw HTML in Markdown. + - For layouts and styling, use only CSS classes applied to groups and standard Markdown elements. ## Examples @@ -50,6 +52,7 @@ Chartifact consists of several interoperating modules: - Examples in this repo use the json format and are compiled to markdown. - If you are asked to create an example, do it in the packages/web-deploy/json folder, do not modify the destination folder docs/assets/examples - this will be populated by a build. - The examples are built manually for now. +- **IMPORTANT**: When creating examples, use only Markdown formatting - NO HTML elements are allowed. Use plain text, Markdown headers, bold/italic formatting, and CSS styling for visual presentation. ## Runtime host diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index ef5e3d75..346d1866 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -13,10 +13,6 @@ "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", - ".stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-top: 15px; }", - ".stat-card { background: #f7fafc; padding: 15px; border-radius: 8px; text-align: center; border: 1px solid #e2e8f0; }", - ".stat-number { font-size: 2em; font-weight: bold; color: #667eea; margin-bottom: 5px; }", - ".stat-label { color: #718096; font-size: 0.9em; }", ".tabulator { border-radius: 8px; overflow: hidden; }", ".tabulator .tabulator-header { background: #f7fafc; }", ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", @@ -264,12 +260,14 @@ "groupId": "stats", "elements": [ "## 📊 Statistics", - "
", - "
{{totalHabits}}
Active Habits
", - "
{{overallCompletionRate}}
Completion Rate
", - "
{{totalActiveDays}}
Days Tracked
", - "
{{avgStreakFormatted}}
Avg Streak
", - "
" + "", + "**Active Habits:** {{totalHabits}}", + "", + "**Completion Rate:** {{overallCompletionRate}}", + "", + "**Days Tracked:** {{totalActiveDays}}", + "", + "**Average Streak:** {{avgStreakFormatted}} days" ] } ] From 9d7694c2ac74d93c4bab6e1d3601dbc6429e0c89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 16:20:03 +0000 Subject: [PATCH 04/45] Remove hardcoded streaks from habits table, calculate from progress data Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 346d1866..539891e2 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -30,49 +30,37 @@ "habit_id": 1, "habit_name": "Morning Exercise", "category": "Health", - "target_frequency": "Daily", - "current_streak": 5, - "best_streak": 12 + "target_frequency": "Daily" }, { "habit_id": 2, "habit_name": "Read for 30min", "category": "Learning", - "target_frequency": "Daily", - "current_streak": 3, - "best_streak": 21 + "target_frequency": "Daily" }, { "habit_id": 3, "habit_name": "Meditate", "category": "Wellness", - "target_frequency": "Daily", - "current_streak": 8, - "best_streak": 15 + "target_frequency": "Daily" }, { "habit_id": 4, "habit_name": "Write Journal", "category": "Wellness", - "target_frequency": "Daily", - "current_streak": 2, - "best_streak": 7 + "target_frequency": "Daily" }, { "habit_id": 5, "habit_name": "Learn New Language", "category": "Learning", - "target_frequency": "3x per week", - "current_streak": 1, - "best_streak": 4 + "target_frequency": "3x per week" }, { "habit_id": 6, "habit_name": "Call Family", "category": "Social", - "target_frequency": "Weekly", - "current_streak": 2, - "best_streak": 8 + "target_frequency": "Weekly" } ] }, @@ -176,27 +164,32 @@ } }, { - "variableId": "averageStreak", - "type": "string", - "initialValue": "0", + "variableId": "totalCompletedEntries", + "type": "object", + "isArray": true, + "initialValue": [], "calculation": { - "dataSourceNames": ["habitsData"], + "dataSourceNames": ["progressData"], "dataFrameTransformations": [ + { + "type": "filter", + "expr": "datum.completed === true" + }, { "type": "aggregate", - "ops": ["mean"], - "fields": ["current_streak"], - "as": ["avg_streak"] + "ops": ["count"], + "fields": ["completed"], + "as": ["completed_count"] } ] } }, { - "variableId": "avgStreakFormatted", - "type": "string", - "initialValue": "0.0", + "variableId": "totalCompleted", + "type": "number", + "initialValue": 0, "calculation": { - "vegaExpression": "format(data('averageStreak')[0] ? data('averageStreak')[0].avg_streak : 0, '.1f')" + "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" } } ], @@ -217,11 +210,9 @@ "dataSourceName": "habitsData", "tabulatorOptions": { "columns": [ - {"field": "habit_name", "title": "Habit", "width": 150}, - {"field": "category", "title": "Category", "width": 100}, - {"field": "target_frequency", "title": "Target", "width": 120}, - {"field": "current_streak", "title": "Streak", "width": 80, "hozAlign": "center"}, - {"field": "best_streak", "title": "Best", "width": 70, "hozAlign": "center"} + {"field": "habit_name", "title": "Habit", "width": 200}, + {"field": "category", "title": "Category", "width": 120}, + {"field": "target_frequency", "title": "Target", "width": 150} ], "layout": "fitColumns", "height": "300px", @@ -267,7 +258,7 @@ "", "**Days Tracked:** {{totalActiveDays}}", "", - "**Average Streak:** {{avgStreakFormatted}} days" + "**Total Completed:** {{totalCompleted}} habits" ] } ] From 985b366f0bc3313f844a2e7a46448b36d5cc4a68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 16:24:14 +0000 Subject: [PATCH 05/45] Update copilot instructions to always provide preview links automatically Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 52371c6e..2b1e8842 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -58,4 +58,4 @@ Chartifact consists of several interoperating modules: - There is a sandboxed runtime that securely renders documents available at https://microsoft.github.io/chartifact/view - The url above can accept a `load` parameter to specify the document to render, for example https://microsoft.github.io/chartifact/view/?load=https://raw.githubusercontent.com/microsoft/chartifact/562d086/packages/web-deploy/json/sales-dashboard.idoc.json -- If you are asked to create an example, please provide a link in the PR comments so it can be previewed. +- **ALWAYS provide a preview link when creating or modifying examples** - include the preview link in PR comments and descriptions automatically so examples can be tested immediately without being asked. From eb88f6cc1cbd17379954098a6446aba27cbbb322 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 17:43:50 +0000 Subject: [PATCH 06/45] Make both tables editable in habit tracker with proper editors and updated statistics Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 539891e2..4f7b5970 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -104,7 +104,7 @@ "type": "number", "initialValue": 0, "calculation": { - "vegaExpression": "length(data('habitsData'))" + "vegaExpression": "length(data('habitsDataTable'))" } }, { @@ -113,7 +113,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressData"], + "dataSourceNames": ["progressDataTable"], "dataFrameTransformations": [ { "type": "aggregate", @@ -143,7 +143,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressData"], + "dataSourceNames": ["progressDataTable"], "dataFrameTransformations": [ { "type": "aggregate", @@ -169,7 +169,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressData"], + "dataSourceNames": ["progressDataTable"], "dataFrameTransformations": [ { "type": "filter", @@ -208,11 +208,13 @@ { "type": "tabulator", "dataSourceName": "habitsData", + "variableId": "habitsDataTable", + "editable": true, "tabulatorOptions": { "columns": [ - {"field": "habit_name", "title": "Habit", "width": 200}, - {"field": "category", "title": "Category", "width": 120}, - {"field": "target_frequency", "title": "Target", "width": 150} + {"field": "habit_name", "title": "Habit", "width": 200, "editor": "input"}, + {"field": "category", "title": "Category", "width": 120, "editor": "input"}, + {"field": "target_frequency", "title": "Target", "width": 150, "editor": "input"} ], "layout": "fitColumns", "height": "300px", @@ -232,11 +234,13 @@ { "type": "tabulator", "dataSourceName": "progressData", + "variableId": "progressDataTable", + "editable": true, "tabulatorOptions": { "columns": [ - {"field": "date", "title": "Date", "width": 100}, - {"field": "habit_name", "title": "Habit", "width": 150}, - {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross"} + {"field": "date", "title": "Date", "width": 100, "editor": "date"}, + {"field": "habit_name", "title": "Habit", "width": 150, "editor": "input"}, + {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross", "editor": "tickCross"} ], "layout": "fitColumns", "height": "300px", From af42e92d051ea1edc10260307800ffbb3055080a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 18:23:38 +0000 Subject: [PATCH 07/45] Add month filter dropdown and heatmap visualization to habit tracker Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 158 +++++++++++++++++- 1 file changed, 152 insertions(+), 6 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 4f7b5970..92d64e46 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -4,9 +4,11 @@ "style": { "css": [ "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", - "body { display: grid; grid-template-areas: 'header header' 'habits progress' 'stats stats'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", + "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", + "#controls { grid-area: controls; }", + "#heatmap { grid-area: heatmap; }", "#habits { grid-area: habits; }", "#progress { grid-area: progress; }", "#stats { grid-area: stats; }", @@ -94,11 +96,98 @@ {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true} + {"date": "2024-01-22", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-22", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-23", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-23", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-24", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-24", "habit_id": 3, "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-25", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-25", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-26", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-26", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-27", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-27", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-28", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-28", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-01", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-02", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-02", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-03", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-02-03", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-04", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-05", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-05", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-02-06", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-06", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-07", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-07", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-08", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-02-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-09", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-10", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-10", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-03-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-02", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-03", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-03-03", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-04", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-04", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-03-05", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-03-06", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-06", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-07", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-07", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-08", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-03-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-09", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-10", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-10", "habit_id": 6, "habit_name": "Call Family", "completed": true} ] } ], "variables": [ + { + "variableId": "selectedMonth", + "type": "string", + "initialValue": "2024-01", + "input": { + "type": "dropdown", + "options": [ + {"value": "All", "label": "All Months"}, + {"value": "2024-01", "label": "January 2024"}, + {"value": "2024-02", "label": "February 2024"}, + {"value": "2024-03", "label": "March 2024"} + ] + } + }, + { + "variableId": "filteredProgressData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressDataTable"], + "dataFrameTransformations": [ + { + "type": "filter", + "expr": "selectedMonth === 'All' || slice(datum.date, 0, 7) === selectedMonth" + } + ] + } + }, { "variableId": "totalHabits", "type": "number", @@ -113,7 +202,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable"], + "dataSourceNames": ["filteredProgressData"], "dataFrameTransformations": [ { "type": "aggregate", @@ -143,7 +232,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable"], + "dataSourceNames": ["filteredProgressData"], "dataFrameTransformations": [ { "type": "aggregate", @@ -169,7 +258,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable"], + "dataSourceNames": ["filteredProgressData"], "dataFrameTransformations": [ { "type": "filter", @@ -201,6 +290,63 @@ "Track your daily habits and build consistent routines for personal growth." ] }, + { + "groupId": "controls", + "elements": [ + "## 🎛️ Filters", + "", + "**Month:** {{selectedMonth}}" + ] + }, + { + "groupId": "heatmap", + "elements": [ + "## 🗓️ Habit Completion Heatmap", + { + "type": "vega-lite", + "spec": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"name": "filteredProgressData"}, + "mark": {"type": "rect", "stroke": "#f1f5f9", "strokeWidth": 1}, + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date", + "axis": {"format": "%b %d", "labelAngle": -45} + }, + "y": { + "field": "habit_name", + "type": "nominal", + "title": "Habit", + "sort": null + }, + "color": { + "field": "completed", + "type": "nominal", + "scale": { + "domain": [true, false], + "range": ["#22c55e", "#ef4444"] + }, + "legend": { + "title": "Completed", + "values": [true, false], + "labelExpr": "datum.value ? 'Yes' : 'No'" + } + }, + "tooltip": [ + {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "habit_name", "type": "nominal", "title": "Habit"}, + {"field": "completed", "type": "nominal", "title": "Completed"} + ] + }, + "width": "container", + "height": 200, + "background": "transparent" + } + } + ] + }, { "groupId": "habits", "elements": [ @@ -230,7 +376,7 @@ { "groupId": "progress", "elements": [ - "## 📈 Recent Progress", + "## 📈 Progress (Filtered by Month)", { "type": "tabulator", "dataSourceName": "progressData", From 847450ca1541ab9d0740db9d8c2c7e1be9eb568b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 18:55:12 +0000 Subject: [PATCH 08/45] Fix dropdown and heatmap display in habit tracker - add dropdown element to controls group Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 92d64e46..89825c99 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -162,16 +162,7 @@ { "variableId": "selectedMonth", "type": "string", - "initialValue": "2024-01", - "input": { - "type": "dropdown", - "options": [ - {"value": "All", "label": "All Months"}, - {"value": "2024-01", "label": "January 2024"}, - {"value": "2024-02", "label": "February 2024"}, - {"value": "2024-03", "label": "March 2024"} - ] - } + "initialValue": "All" }, { "variableId": "filteredProgressData", @@ -295,7 +286,17 @@ "elements": [ "## 🎛️ Filters", "", - "**Month:** {{selectedMonth}}" + { + "type": "dropdown", + "variableId": "selectedMonth", + "label": "Select Month:", + "options": [ + {"value": "All", "label": "All Months"}, + {"value": "2024-01", "label": "January 2024"}, + {"value": "2024-02", "label": "February 2024"}, + {"value": "2024-03", "label": "March 2024"} + ] + } ] }, { From 01b8ef4d318257b77f5bb17aa3e4d0a4ebcfce67 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 21:40:32 +0000 Subject: [PATCH 09/45] Fix dropdown options display and heatmap visualization in habit tracker Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .github/copilot-instructions.md | 14 +++ .../web-deploy/json/habit-tracker.idoc.json | 110 ++++++++++-------- 2 files changed, 76 insertions(+), 48 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2b1e8842..0ac5f168 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -46,6 +46,20 @@ Chartifact consists of several interoperating modules: - No custom JavaScript execution or raw HTML in Markdown. - For layouts and styling, use only CSS classes applied to groups and standard Markdown elements. +## Component Capabilities and Constraints + +1. **Dropdown Components**: + - Dropdown options must be strings only - no objects with value/label properties + - Use simple string arrays for options: `"options": ["Option1", "Option2"]` + - For data-driven options, use `dynamicOptions` with a data source + - Objects in dropdown options will display as "[object Object]" + +2. **Chart Components**: + - Heatmaps and complex visualizations should use the `chart` type with `chartKey` + - Place chart specifications in the `resources.charts` section + - Reference charts using `{"type": "chart", "chartKey": "yourChartKey"}` + - Direct `vega-lite` type elements may not render properly for complex charts + ## Examples - Source code for examples is in the packages/web-deploy/json folder diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 89825c99..57ecf87e 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -23,6 +23,17 @@ ] }, "dataLoaders": [ + { + "dataSourceName": "monthOptions", + "type": "inline", + "format": "json", + "content": [ + {"value": "All", "label": "All Months"}, + {"value": "2024-01", "label": "January 2024"}, + {"value": "2024-02", "label": "February 2024"}, + {"value": "2024-03", "label": "March 2024"} + ] + }, { "dataSourceName": "habitsData", "type": "inline", @@ -290,12 +301,10 @@ "type": "dropdown", "variableId": "selectedMonth", "label": "Select Month:", - "options": [ - {"value": "All", "label": "All Months"}, - {"value": "2024-01", "label": "January 2024"}, - {"value": "2024-02", "label": "February 2024"}, - {"value": "2024-03", "label": "March 2024"} - ] + "dynamicOptions": { + "dataSourceName": "monthOptions", + "fieldName": "value" + } } ] }, @@ -304,47 +313,8 @@ "elements": [ "## 🗓️ Habit Completion Heatmap", { - "type": "vega-lite", - "spec": { - "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "filteredProgressData"}, - "mark": {"type": "rect", "stroke": "#f1f5f9", "strokeWidth": 1}, - "encoding": { - "x": { - "field": "date", - "type": "temporal", - "title": "Date", - "axis": {"format": "%b %d", "labelAngle": -45} - }, - "y": { - "field": "habit_name", - "type": "nominal", - "title": "Habit", - "sort": null - }, - "color": { - "field": "completed", - "type": "nominal", - "scale": { - "domain": [true, false], - "range": ["#22c55e", "#ef4444"] - }, - "legend": { - "title": "Completed", - "values": [true, false], - "labelExpr": "datum.value ? 'Yes' : 'No'" - } - }, - "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "habit_name", "type": "nominal", "title": "Habit"}, - {"field": "completed", "type": "nominal", "title": "Completed"} - ] - }, - "width": "container", - "height": 200, - "background": "transparent" - } + "type": "chart", + "chartKey": "heatmap" } ] }, @@ -412,5 +382,49 @@ "**Total Completed:** {{totalCompleted}} habits" ] } - ] + ], + "resources": { + "charts": { + "heatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"name": "filteredProgressData"}, + "mark": {"type": "rect", "stroke": "#f1f5f9", "strokeWidth": 1}, + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date", + "axis": {"format": "%b %d", "labelAngle": -45} + }, + "y": { + "field": "habit_name", + "type": "nominal", + "title": "Habit", + "sort": null + }, + "color": { + "field": "completed", + "type": "nominal", + "scale": { + "domain": [true, false], + "range": ["#22c55e", "#ef4444"] + }, + "legend": { + "title": "Completed", + "values": [true, false], + "labelExpr": "datum.value ? 'Yes' : 'No'" + } + }, + "tooltip": [ + {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "habit_name", "type": "nominal", "title": "Habit"}, + {"field": "completed", "type": "nominal", "title": "Completed"} + ] + }, + "width": "container", + "height": 200, + "background": "transparent" + } + } + } } \ No newline at end of file From 3cdcdc7a4eabe0bbf3b9750454a0279b1b2f4919 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 22:43:46 +0000 Subject: [PATCH 10/45] Fix heatmap to show proper calendar-style visualization with daily completion rates Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 79 ++++++++++++++----- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 57ecf87e..3b853f40 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -190,6 +190,29 @@ ] } }, + { + "variableId": "dailyCompletionData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["sum", "count"], + "fields": ["completed", "completed"], + "as": ["completed_count", "total_habits"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_habits", + "as": "completion_rate" + } + ] + } + }, { "variableId": "totalHabits", "type": "number", @@ -387,42 +410,60 @@ "charts": { "heatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "filteredProgressData"}, - "mark": {"type": "rect", "stroke": "#f1f5f9", "strokeWidth": 1}, + "data": {"name": "dailyCompletionData"}, + "title": "Daily Habit Completion Rate", + "config": { + "view": { + "strokeWidth": 0, + "step": 13 + }, + "axis": { + "domain": false + } + }, + "mark": { + "type": "rect", + "stroke": "#ffffff", + "strokeWidth": 2 + }, "encoding": { "x": { "field": "date", - "type": "temporal", - "title": "Date", - "axis": {"format": "%b %d", "labelAngle": -45} + "timeUnit": "date", + "type": "ordinal", + "title": "Day of Month", + "axis": { + "labelAngle": 0, + "format": "%e" + } }, "y": { - "field": "habit_name", - "type": "nominal", - "title": "Habit", - "sort": null + "field": "date", + "timeUnit": "month", + "type": "ordinal", + "title": "Month" }, "color": { - "field": "completed", - "type": "nominal", + "field": "completion_rate", + "type": "quantitative", "scale": { - "domain": [true, false], - "range": ["#22c55e", "#ef4444"] + "scheme": "greens", + "domain": [0, 1] }, "legend": { - "title": "Completed", - "values": [true, false], - "labelExpr": "datum.value ? 'Yes' : 'No'" + "title": "Completion Rate", + "format": ".0%" } }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "habit_name", "type": "nominal", "title": "Habit"}, - {"field": "completed", "type": "nominal", "title": "Completed"} + {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, + {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, + {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} ] }, "width": "container", - "height": 200, + "height": 150, "background": "transparent" } } From b1ee0a3054f93ed5cdfc7b64dca34dc9559539df Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 22:55:52 +0000 Subject: [PATCH 11/45] Fix heatmap temporal encoding - use temporal type for proper day display Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker.idoc.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 3b853f40..8c8d6b6e 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -209,6 +209,11 @@ "type": "formula", "expr": "datum.completed_count / datum.total_habits", "as": "completion_rate" + }, + { + "type": "formula", + "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", + "as": "date_parsed" } ] } @@ -424,13 +429,14 @@ "mark": { "type": "rect", "stroke": "#ffffff", - "strokeWidth": 2 + "strokeWidth": 2, + "opacity": 0.8 }, "encoding": { "x": { "field": "date", "timeUnit": "date", - "type": "ordinal", + "type": "temporal", "title": "Day of Month", "axis": { "labelAngle": 0, @@ -440,7 +446,7 @@ "y": { "field": "date", "timeUnit": "month", - "type": "ordinal", + "type": "temporal", "title": "Month" }, "color": { From 3c5bc2111ba9b7d747edbcb59abac09fdb9a5581 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 23:32:24 +0000 Subject: [PATCH 12/45] Fix data reactivity issue - add explicit boolean to numeric conversion for aggregations Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker.idoc.json | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json index 8c8d6b6e..675c04d2 100644 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -4,7 +4,7 @@ "style": { "css": [ "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", - "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", + "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'debug debug'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", "#controls { grid-area: controls; }", @@ -12,6 +12,7 @@ "#habits { grid-area: habits; }", "#progress { grid-area: progress; }", "#stats { grid-area: stats; }", + "#debug { grid-area: debug; }", "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", @@ -198,11 +199,16 @@ "calculation": { "dataSourceNames": ["filteredProgressData"], "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, { "type": "aggregate", "groupby": ["date"], "ops": ["sum", "count"], - "fields": ["completed", "completed"], + "fields": ["completed_numeric", "completed_numeric"], "as": ["completed_count", "total_habits"] }, { @@ -234,10 +240,15 @@ "calculation": { "dataSourceNames": ["filteredProgressData"], "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, { "type": "aggregate", "ops": ["count", "sum"], - "fields": ["completed", "completed"], + "fields": ["completed_numeric", "completed_numeric"], "as": ["total_entries", "completed_count"] }, { @@ -409,6 +420,16 @@ "", "**Total Completed:** {{totalCompleted}} habits" ] + }, + { + "groupId": "debug", + "elements": [ + "## 🔍 Debug: Daily Completion Data", + { + "type": "tabulator", + "dataSourceName": "dailyCompletionData" + } + ] } ], "resources": { From 91310f43989ec90db52aa2a12d0f3d6d6161bc03 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Sep 2025 23:57:22 +0000 Subject: [PATCH 13/45] Create enhanced habit tracker with category-based insights and separate monthly/all-time views Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-enhanced.idoc.json | 612 ++++++++++++++++++ 1 file changed, 612 insertions(+) create mode 100644 packages/web-deploy/json/habit-tracker-enhanced.idoc.json diff --git a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json new file mode 100644 index 00000000..e21626b5 --- /dev/null +++ b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json @@ -0,0 +1,612 @@ +{ + "$schema": "../../../docs/schema/idoc_v1.json", + "title": "Enhanced Habit Tracker", + "style": { + "css": [ + "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", + "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'alltime alltime'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1400px; margin: 0 auto; }", + ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", + "#controls { grid-area: controls; }", + "#heatmap { grid-area: heatmap; }", + "#habits { grid-area: habits; }", + "#progress { grid-area: progress; }", + "#stats { grid-area: stats; }", + "#alltime { grid-area: alltime; }", + "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", + "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", + "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", + ".tabulator { border-radius: 8px; overflow: hidden; }", + ".tabulator .tabulator-header { background: #f7fafc; }", + ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", + ".tabulator .tabulator-row { border-bottom: 1px solid #f1f5f9; }", + ".tabulator .tabulator-row:hover { background: #f8fafc; }" + ] + }, + "dataLoaders": [ + { + "dataSourceName": "monthOptions", + "type": "inline", + "format": "json", + "content": [ + "2024-01", + "2024-02", + "2024-03" + ] + }, + { + "dataSourceName": "habitsData", + "type": "inline", + "format": "json", + "content": [ + { + "habit_id": 1, + "habit_name": "Morning Exercise", + "category": "Health", + "target_frequency": "Daily" + }, + { + "habit_id": 2, + "habit_name": "Read for 30min", + "category": "Learning", + "target_frequency": "Daily" + }, + { + "habit_id": 3, + "habit_name": "Meditate", + "category": "Wellness", + "target_frequency": "Daily" + }, + { + "habit_id": 4, + "habit_name": "Write Journal", + "category": "Wellness", + "target_frequency": "Daily" + }, + { + "habit_id": 5, + "habit_name": "Learn New Language", + "category": "Learning", + "target_frequency": "3x per week" + }, + { + "habit_id": 6, + "habit_name": "Call Family", + "category": "Social", + "target_frequency": "Weekly" + } + ] + }, + { + "dataSourceName": "progressData", + "type": "inline", + "format": "json", + "content": [ + {"date": "2024-01-15", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-15", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-15", "habit_id": 3, "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-16", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-16", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-16", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-16", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-17", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-17", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-17", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-18", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-18", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-18", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-18", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-01-19", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-19", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-19", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-19", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-01-19", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-01-20", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-22", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-22", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-23", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-23", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-24", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-24", "habit_id": 3, "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-25", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-25", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-26", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-26", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-27", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-27", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-28", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-28", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-01", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-02", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-02", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-03", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-02-03", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-04", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-05", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-05", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-02-06", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-06", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-07", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-07", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-08", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-02-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-09", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-10", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-10", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-03-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-02", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-03", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-03-03", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-04", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-04", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-03-05", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-03-06", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-06", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-07", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-07", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-08", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-03-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-09", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-10", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-10", "habit_id": 6, "habit_name": "Call Family", "completed": true} + ] + } + ], + "variables": [ + { + "variableId": "selectedMonth", + "type": "string", + "initialValue": "2024-01" + }, + { + "variableId": "enrichedProgressData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressDataTable", "habitsDataTable"], + "dataFrameTransformations": [ + { + "type": "lookup", + "from": "habitsDataTable", + "key": "habit_id", + "fields": ["category", "target_frequency"], + "as": ["category", "target_frequency"] + } + ] + } + }, + { + "variableId": "filteredProgressData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["enrichedProgressData"], + "dataFrameTransformations": [ + { + "type": "filter", + "expr": "slice(datum.date, 0, 7) === selectedMonth" + } + ] + } + }, + { + "variableId": "monthlyHeatmapData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["sum", "count"], + "fields": ["completed_numeric", "completed_numeric"], + "as": ["completed_count", "total_habits"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_habits", + "as": "completion_rate" + }, + { + "type": "formula", + "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", + "as": "date_parsed" + }, + { + "type": "formula", + "expr": "date(datum.date)", + "as": "day_of_month" + } + ] + } + }, + { + "variableId": "allTimeHeatmapData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["enrichedProgressData"], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "groupby": ["date", "category"], + "ops": ["sum", "count"], + "fields": ["completed_numeric", "completed_numeric"], + "as": ["completed_count", "total_habits"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_habits", + "as": "completion_rate" + }, + { + "type": "formula", + "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", + "as": "date_parsed" + } + ] + } + }, + { + "variableId": "totalHabits", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "length(data('habitsDataTable'))" + } + }, + { + "variableId": "completionRateData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "ops": ["count", "sum"], + "fields": ["completed_numeric", "completed_numeric"], + "as": ["total_entries", "completed_count"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_entries * 100", + "as": "completion_rate" + } + ] + } + }, + { + "variableId": "overallCompletionRate", + "type": "string", + "initialValue": "0%", + "calculation": { + "vegaExpression": "format(data('completionRateData')[0] ? data('completionRateData')[0].completion_rate : 0, '.1f') + '%'" + } + }, + { + "variableId": "activeDaysData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["count"], + "fields": ["habit_id"], + "as": ["habits_tracked"] + } + ] + } + }, + { + "variableId": "totalActiveDays", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "length(data('activeDaysData'))" + } + }, + { + "variableId": "totalCompletedEntries", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "filter", + "expr": "datum.completed === true" + }, + { + "type": "aggregate", + "ops": ["count"], + "fields": ["completed"], + "as": ["completed_count"] + } + ] + } + }, + { + "variableId": "totalCompleted", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" + } + } + ], + "groups": [ + { + "groupId": "header", + "elements": [ + "# 🎯 Enhanced Habit Tracker", + "Track your daily habits with category-based insights and comprehensive visualizations." + ] + }, + { + "groupId": "controls", + "elements": [ + "## 🎛️ Month Filter", + "", + { + "type": "dropdown", + "variableId": "selectedMonth", + "label": "Select Month:", + "dynamicOptions": { + "dataSourceName": "monthOptions" + } + } + ] + }, + { + "groupId": "heatmap", + "elements": [ + "## 🗓️ Monthly Completion Calendar", + { + "type": "chart", + "chartKey": "monthlyHeatmap" + } + ] + }, + { + "groupId": "habits", + "elements": [ + "## 📋 My Habits", + { + "type": "tabulator", + "dataSourceName": "habitsData", + "variableId": "habitsDataTable", + "editable": true, + "tabulatorOptions": { + "columns": [ + {"field": "habit_name", "title": "Habit", "width": 200, "editor": "input"}, + {"field": "category", "title": "Category", "width": 120, "editor": "input"}, + {"field": "target_frequency", "title": "Target", "width": 150, "editor": "input"} + ], + "layout": "fitColumns", + "height": "300px", + "rowHeader": { + "width": 40, + "hozAlign": "center", + "formatter": "rownum" + } + } + } + ] + }, + { + "groupId": "progress", + "elements": [ + "## 📈 Progress (Filtered by Month)", + { + "type": "tabulator", + "dataSourceName": "progressData", + "variableId": "progressDataTable", + "editable": true, + "tabulatorOptions": { + "columns": [ + {"field": "date", "title": "Date", "width": 100, "editor": "date"}, + {"field": "habit_name", "title": "Habit", "width": 150, "editor": "input"}, + {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross", "editor": "tickCross"} + ], + "layout": "fitColumns", + "height": "300px", + "initialSort": [ + {"column": "date", "dir": "desc"} + ] + } + } + ] + }, + { + "groupId": "stats", + "elements": [ + "## 📊 Monthly Statistics", + "", + "**Active Habits:** {{totalHabits}}", + "", + "**Completion Rate:** {{overallCompletionRate}}", + "", + "**Days Tracked:** {{totalActiveDays}}", + "", + "**Total Completed:** {{totalCompleted}} habits" + ] + }, + { + "groupId": "alltime", + "elements": [ + "## 🌟 All-Time Habit Performance by Category", + { + "type": "chart", + "chartKey": "allTimeHeatmap" + } + ] + } + ], + "resources": { + "charts": { + "monthlyHeatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"name": "monthlyHeatmapData"}, + "title": "Daily Completion Rate - Selected Month", + "config": { + "view": { + "strokeWidth": 0, + "step": 18 + }, + "axis": { + "domain": false + } + }, + "mark": { + "type": "rect", + "stroke": "#ffffff", + "strokeWidth": 2, + "opacity": 0.8 + }, + "encoding": { + "x": { + "field": "day_of_month", + "type": "ordinal", + "title": "Day of Month", + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + }, + "axis": { + "labelAngle": 0 + } + }, + "y": { + "datum": 1, + "type": "ordinal", + "title": "" + }, + "color": { + "field": "completion_rate", + "type": "quantitative", + "scale": { + "scheme": "greens", + "domain": [0, 1] + }, + "legend": { + "title": "Completion Rate", + "format": ".0%" + } + }, + "tooltip": [ + {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, + {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, + {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + ] + }, + "width": "container", + "height": 60, + "background": "transparent" + }, + "allTimeHeatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"name": "allTimeHeatmapData"}, + "title": "All-Time Daily Completion by Category", + "config": { + "view": { + "strokeWidth": 0, + "step": 13 + }, + "axis": { + "domain": false + } + }, + "mark": { + "type": "rect", + "stroke": "#ffffff", + "strokeWidth": 1, + "opacity": 0.8 + }, + "encoding": { + "x": { + "field": "date", + "timeUnit": "date", + "type": "temporal", + "title": "Day of Month", + "axis": { + "labelAngle": 0, + "format": "%e" + } + }, + "y": { + "field": "category", + "type": "nominal", + "title": "Category", + "sort": ["Health", "Learning", "Wellness", "Social"] + }, + "color": { + "field": "completion_rate", + "type": "quantitative", + "scale": { + "scheme": "viridis", + "domain": [0, 1] + }, + "legend": { + "title": "Category Completion Rate", + "format": ".0%" + } + }, + "tooltip": [ + {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "category", "type": "nominal", "title": "Category"}, + {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, + {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, + {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + ] + }, + "width": "container", + "height": 150, + "background": "transparent" + } + } + } +} \ No newline at end of file From dbfe301d8a0907b408cd7f0aabe3084d5178b9ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:04:45 +0000 Subject: [PATCH 14/45] Fix dropdown field definition and simplify data flow for enhanced habit tracker Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-enhanced.idoc.json | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json index e21626b5..300ae517 100644 --- a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json +++ b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json @@ -29,9 +29,9 @@ "type": "inline", "format": "json", "content": [ - "2024-01", - "2024-02", - "2024-03" + {"value": "2024-01", "label": "January 2024"}, + {"value": "2024-02", "label": "February 2024"}, + {"value": "2024-03", "label": "March 2024"} ] }, { @@ -199,7 +199,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["enrichedProgressData"], + "dataSourceNames": ["progressDataTable"], "dataFrameTransformations": [ { "type": "filter", @@ -252,7 +252,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["enrichedProgressData"], + "dataSourceNames": ["progressDataTable"], "dataFrameTransformations": [ { "type": "formula", @@ -261,7 +261,7 @@ }, { "type": "aggregate", - "groupby": ["date", "category"], + "groupby": ["date", "habit_name"], "ops": ["sum", "count"], "fields": ["completed_numeric", "completed_numeric"], "as": ["completed_count", "total_habits"] @@ -396,7 +396,8 @@ "variableId": "selectedMonth", "label": "Select Month:", "dynamicOptions": { - "dataSourceName": "monthOptions" + "dataSourceName": "monthOptions", + "fieldName": "value" } } ] @@ -478,7 +479,7 @@ { "groupId": "alltime", "elements": [ - "## 🌟 All-Time Habit Performance by Category", + "## 🌟 All-Time Habit Performance", { "type": "chart", "chartKey": "allTimeHeatmap" @@ -550,7 +551,7 @@ "allTimeHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "allTimeHeatmapData"}, - "title": "All-Time Daily Completion by Category", + "title": "All-Time Daily Completion by Habit", "config": { "view": { "strokeWidth": 0, @@ -578,10 +579,9 @@ } }, "y": { - "field": "category", + "field": "habit_name", "type": "nominal", - "title": "Category", - "sort": ["Health", "Learning", "Wellness", "Social"] + "title": "Habit" }, "color": { "field": "completion_rate", @@ -591,13 +591,13 @@ "domain": [0, 1] }, "legend": { - "title": "Category Completion Rate", + "title": "Habit Completion Rate", "format": ".0%" } }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "category", "type": "nominal", "title": "Category"}, + {"field": "habit_name", "type": "nominal", "title": "Habit"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} From f57d7eb6b443b077de497fd03ea604f11cdac1c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:07:01 +0000 Subject: [PATCH 15/45] Restore category-based analytics to all-time heatmap with proper data joining Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-enhanced.idoc.json | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json index 300ae517..45eae154 100644 --- a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json +++ b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json @@ -199,7 +199,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable"], + "dataSourceNames": ["enrichedProgressData"], "dataFrameTransformations": [ { "type": "filter", @@ -252,7 +252,7 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable"], + "dataSourceNames": ["enrichedProgressData"], "dataFrameTransformations": [ { "type": "formula", @@ -261,7 +261,7 @@ }, { "type": "aggregate", - "groupby": ["date", "habit_name"], + "groupby": ["date", "category"], "ops": ["sum", "count"], "fields": ["completed_numeric", "completed_numeric"], "as": ["completed_count", "total_habits"] @@ -479,7 +479,7 @@ { "groupId": "alltime", "elements": [ - "## 🌟 All-Time Habit Performance", + "## 🌟 All-Time Habit Performance by Category", { "type": "chart", "chartKey": "allTimeHeatmap" @@ -551,7 +551,7 @@ "allTimeHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "allTimeHeatmapData"}, - "title": "All-Time Daily Completion by Habit", + "title": "All-Time Daily Completion by Category", "config": { "view": { "strokeWidth": 0, @@ -579,9 +579,10 @@ } }, "y": { - "field": "habit_name", + "field": "category", "type": "nominal", - "title": "Habit" + "title": "Category", + "sort": ["Health", "Learning", "Wellness", "Social"] }, "color": { "field": "completion_rate", @@ -591,13 +592,13 @@ "domain": [0, 1] }, "legend": { - "title": "Habit Completion Rate", + "title": "Category Completion Rate", "format": ".0%" } }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "habit_name", "type": "nominal", "title": "Habit"}, + {"field": "category", "type": "nominal", "title": "Category"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} From 356c2b700276cf3a3ef5d6a76efa4066e971a6ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:15:24 +0000 Subject: [PATCH 16/45] Fix heatmap axes: monthly view shows categories, annual view shows months, add mobile layout Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-enhanced.idoc.json | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json index 45eae154..6cd42a6c 100644 --- a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json +++ b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json @@ -5,6 +5,7 @@ "css": [ "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'alltime alltime'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1400px; margin: 0 auto; }", + "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'alltime'; grid-template-columns: 1fr; } }", ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", "#controls { grid-area: controls; }", @@ -223,7 +224,7 @@ }, { "type": "aggregate", - "groupby": ["date"], + "groupby": ["date", "category"], "ops": ["sum", "count"], "fields": ["completed_numeric", "completed_numeric"], "as": ["completed_count", "total_habits"] @@ -261,7 +262,7 @@ }, { "type": "aggregate", - "groupby": ["date", "category"], + "groupby": ["date"], "ops": ["sum", "count"], "fields": ["completed_numeric", "completed_numeric"], "as": ["completed_count", "total_habits"] @@ -275,6 +276,16 @@ "type": "formula", "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", "as": "date_parsed" + }, + { + "type": "formula", + "expr": "date(datum.date)", + "as": "day_of_month" + }, + { + "type": "formula", + "expr": "timeFormat(datum.date, '%B')", + "as": "month_name" } ] } @@ -441,7 +452,7 @@ { "groupId": "progress", "elements": [ - "## 📈 Progress (Filtered by Month)", + "## 📈 Progress", { "type": "tabulator", "dataSourceName": "progressData", @@ -479,7 +490,7 @@ { "groupId": "alltime", "elements": [ - "## 🌟 All-Time Habit Performance by Category", + "## 🌟 Annual Habit Performance", { "type": "chart", "chartKey": "allTimeHeatmap" @@ -492,7 +503,7 @@ "monthlyHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "monthlyHeatmapData"}, - "title": "Daily Completion Rate - Selected Month", + "title": "Daily Completion Rate by Category - Selected Month", "config": { "view": { "strokeWidth": 0, @@ -521,9 +532,10 @@ } }, "y": { - "datum": 1, - "type": "ordinal", - "title": "" + "field": "category", + "type": "nominal", + "title": "Category", + "sort": ["Health", "Learning", "Wellness", "Social"] }, "color": { "field": "completion_rate", @@ -539,19 +551,20 @@ }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "category", "type": "nominal", "title": "Category"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} ] }, "width": "container", - "height": 60, + "height": 120, "background": "transparent" }, "allTimeHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "allTimeHeatmapData"}, - "title": "All-Time Daily Completion by Category", + "title": "Annual Completion Calendar - All Categories", "config": { "view": { "strokeWidth": 0, @@ -569,20 +582,21 @@ }, "encoding": { "x": { - "field": "date", - "timeUnit": "date", - "type": "temporal", + "field": "day_of_month", + "type": "ordinal", "title": "Day of Month", + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + }, "axis": { - "labelAngle": 0, - "format": "%e" + "labelAngle": 0 } }, "y": { - "field": "category", + "field": "month_name", "type": "nominal", - "title": "Category", - "sort": ["Health", "Learning", "Wellness", "Social"] + "title": "Month", + "sort": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] }, "color": { "field": "completion_rate", @@ -592,13 +606,13 @@ "domain": [0, 1] }, "legend": { - "title": "Category Completion Rate", + "title": "Completion Rate", "format": ".0%" } }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "category", "type": "nominal", "title": "Category"}, + {"field": "month_name", "type": "nominal", "title": "Month"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} From abb3835279d8e9178b8542dbb3c5b08ccfb9822f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:30:34 +0000 Subject: [PATCH 17/45] Fix monthlyHeatmapData by using raw data sources instead of tabulator variables Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-enhanced.idoc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json index 6cd42a6c..f2280a71 100644 --- a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json +++ b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json @@ -182,11 +182,11 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable", "habitsDataTable"], + "dataSourceNames": ["progressData", "habitsData"], "dataFrameTransformations": [ { "type": "lookup", - "from": "habitsDataTable", + "from": "habitsData", "key": "habit_id", "fields": ["category", "target_frequency"], "as": ["category", "target_frequency"] From 21b7a89edd129b9969a07f4eaf34419e8ce1ebff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:39:15 +0000 Subject: [PATCH 18/45] Create complete habit tracker with monthly filtering, annual calendar view, and mobile layout Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 584 ++++++++++++++++++ 1 file changed, 584 insertions(+) create mode 100644 packages/web-deploy/json/habit-tracker-complete.idoc.json diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json new file mode 100644 index 00000000..6801ca8f --- /dev/null +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -0,0 +1,584 @@ +{ + "$schema": "../../../docs/schema/idoc_v1.json", + "title": "Complete Habit Tracker", + "style": { + "css": [ + "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", + "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'annual annual'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", + "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'annual'; grid-template-columns: 1fr; } }", + ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", + "#controls { grid-area: controls; }", + "#heatmap { grid-area: heatmap; }", + "#habits { grid-area: habits; }", + "#progress { grid-area: progress; }", + "#stats { grid-area: stats; }", + "#annual { grid-area: annual; }", + "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", + "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", + "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", + ".tabulator { border-radius: 8px; overflow: hidden; }", + ".tabulator .tabulator-header { background: #f7fafc; }", + ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", + ".tabulator .tabulator-row { border-bottom: 1px solid #f1f5f9; }", + ".tabulator .tabulator-row:hover { background: #f8fafc; }" + ] + }, + "dataLoaders": [ + { + "dataSourceName": "monthOptions", + "type": "inline", + "format": "json", + "content": [ + {"value": "2024-01", "label": "January 2024"}, + {"value": "2024-02", "label": "February 2024"}, + {"value": "2024-03", "label": "March 2024"} + ] + }, + { + "dataSourceName": "habitsData", + "type": "inline", + "format": "json", + "content": [ + { + "habit_id": 1, + "habit_name": "Morning Exercise", + "category": "Health", + "target_frequency": "Daily" + }, + { + "habit_id": 2, + "habit_name": "Read for 30min", + "category": "Learning", + "target_frequency": "Daily" + }, + { + "habit_id": 3, + "habit_name": "Meditate", + "category": "Wellness", + "target_frequency": "Daily" + }, + { + "habit_id": 4, + "habit_name": "Write Journal", + "category": "Wellness", + "target_frequency": "Daily" + }, + { + "habit_id": 5, + "habit_name": "Learn New Language", + "category": "Learning", + "target_frequency": "3x per week" + }, + { + "habit_id": 6, + "habit_name": "Call Family", + "category": "Social", + "target_frequency": "Weekly" + } + ] + }, + { + "dataSourceName": "progressData", + "type": "inline", + "format": "json", + "content": [ + {"date": "2024-01-15", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-15", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-15", "habit_id": 3, "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-16", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-16", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-16", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-16", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-17", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-17", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-17", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-18", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-18", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-18", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-18", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-01-19", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-19", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-19", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-19", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-01-19", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-01-20", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-22", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-22", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-23", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-23", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-24", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-24", "habit_id": 3, "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-25", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-25", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-26", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-26", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-27", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-27", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-28", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-28", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-01", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-02", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-02", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-03", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-02-03", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-04", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-05", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-05", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-02-06", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-06", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-07", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-07", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-08", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-02-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-09", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-10", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-10", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-03-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-02", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-03", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-03-03", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-04", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-04", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, + {"date": "2024-03-05", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, + {"date": "2024-03-06", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-06", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-07", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-07", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-08", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-03-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-09", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-10", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-10", "habit_id": 6, "habit_name": "Call Family", "completed": true} + ] + } + ], + "variables": [ + { + "variableId": "selectedMonth", + "type": "string", + "initialValue": "2024-01" + }, + { + "variableId": "filteredProgressData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressDataTable"], + "dataFrameTransformations": [ + { + "type": "filter", + "expr": "slice(datum.date, 0, 7) === selectedMonth" + } + ] + } + }, + { + "variableId": "dailyCompletionData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["sum", "count"], + "fields": ["completed_numeric", "completed_numeric"], + "as": ["completed_count", "total_habits"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_habits", + "as": "completion_rate" + }, + { + "type": "formula", + "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", + "as": "date_parsed" + } + ] + } + }, + { + "variableId": "annualCompletionData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressDataTable"], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["sum", "count"], + "fields": ["completed_numeric", "completed_numeric"], + "as": ["completed_count", "total_habits"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_habits", + "as": "completion_rate" + }, + { + "type": "formula", + "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", + "as": "date_parsed" + } + ] + } + }, + { + "variableId": "totalHabits", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "length(data('habitsDataTable'))" + } + }, + { + "variableId": "completionRateData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "ops": ["count", "sum"], + "fields": ["completed_numeric", "completed_numeric"], + "as": ["total_entries", "completed_count"] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_entries * 100", + "as": "completion_rate" + } + ] + } + }, + { + "variableId": "overallCompletionRate", + "type": "string", + "initialValue": "0%", + "calculation": { + "vegaExpression": "format(data('completionRateData')[0] ? data('completionRateData')[0].completion_rate : 0, '.1f') + '%'" + } + }, + { + "variableId": "activeDaysData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "aggregate", + "groupby": ["date"], + "ops": ["count"], + "fields": ["habit_id"], + "as": ["habits_tracked"] + } + ] + } + }, + { + "variableId": "totalActiveDays", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "length(data('activeDaysData'))" + } + }, + { + "variableId": "totalCompletedEntries", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["filteredProgressData"], + "dataFrameTransformations": [ + { + "type": "filter", + "expr": "datum.completed === true" + }, + { + "type": "aggregate", + "ops": ["count"], + "fields": ["completed"], + "as": ["completed_count"] + } + ] + } + }, + { + "variableId": "totalCompleted", + "type": "number", + "initialValue": 0, + "calculation": { + "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" + } + } + ], + "groups": [ + { + "groupId": "header", + "elements": [ + "# 🎯 Complete Habit Tracker", + "Track your daily habits with monthly filtering and annual insights for building consistent routines." + ] + }, + { + "groupId": "controls", + "elements": [ + "## 🎛️ Filters", + "", + { + "type": "dropdown", + "variableId": "selectedMonth", + "label": "Select Month:", + "dynamicOptions": { + "dataSourceName": "monthOptions", + "fieldName": "value" + } + } + ] + }, + { + "groupId": "heatmap", + "elements": [ + "## 🗓️ Monthly Habit Completion", + { + "type": "chart", + "chartKey": "monthlyHeatmap" + } + ] + }, + { + "groupId": "habits", + "elements": [ + "## 📋 My Habits", + { + "type": "tabulator", + "dataSourceName": "habitsData", + "variableId": "habitsDataTable", + "editable": true, + "tabulatorOptions": { + "columns": [ + {"field": "habit_name", "title": "Habit", "width": 200, "editor": "input"}, + {"field": "category", "title": "Category", "width": 120, "editor": "input"}, + {"field": "target_frequency", "title": "Target", "width": 150, "editor": "input"} + ], + "layout": "fitColumns", + "height": "300px", + "rowHeader": { + "width": 40, + "hozAlign": "center", + "formatter": "rownum" + } + } + } + ] + }, + { + "groupId": "progress", + "elements": [ + "## 📈 Progress", + { + "type": "tabulator", + "dataSourceName": "progressData", + "variableId": "progressDataTable", + "editable": true, + "tabulatorOptions": { + "columns": [ + {"field": "date", "title": "Date", "width": 100, "editor": "date"}, + {"field": "habit_name", "title": "Habit", "width": 150, "editor": "input"}, + {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross", "editor": "tickCross"} + ], + "layout": "fitColumns", + "height": "300px", + "initialSort": [ + {"column": "date", "dir": "desc"} + ] + } + } + ] + }, + { + "groupId": "stats", + "elements": [ + "## 📊 Statistics", + "", + "**Active Habits:** {{totalHabits}}", + "", + "**Completion Rate:** {{overallCompletionRate}}", + "", + "**Days Tracked:** {{totalActiveDays}}", + "", + "**Total Completed:** {{totalCompleted}} habits" + ] + }, + { + "groupId": "annual", + "elements": [ + "## 📅 Annual Calendar View", + { + "type": "chart", + "chartKey": "annualHeatmap" + } + ] + } + ], + "resources": { + "charts": { + "monthlyHeatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"name": "dailyCompletionData"}, + "title": "Daily Habit Completion Rate for Selected Month", + "config": { + "view": { + "strokeWidth": 0, + "step": 13 + }, + "axis": { + "domain": false + } + }, + "mark": { + "type": "rect", + "stroke": "#ffffff", + "strokeWidth": 2, + "opacity": 0.8 + }, + "encoding": { + "x": { + "field": "date", + "timeUnit": "date", + "type": "temporal", + "title": "Day of Month", + "axis": { + "labelAngle": 0, + "format": "%e" + } + }, + "color": { + "field": "completion_rate", + "type": "quantitative", + "scale": { + "scheme": "greens", + "domain": [0, 1] + }, + "legend": { + "title": "Completion Rate", + "format": ".0%" + } + }, + "tooltip": [ + {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, + {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, + {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + ] + }, + "width": "container", + "height": 100, + "background": "transparent" + }, + "annualHeatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"name": "annualCompletionData"}, + "title": "Annual Habit Completion Overview", + "config": { + "view": { + "strokeWidth": 0, + "step": 13 + }, + "axis": { + "domain": false + } + }, + "mark": { + "type": "rect", + "stroke": "#ffffff", + "strokeWidth": 2, + "opacity": 0.8 + }, + "encoding": { + "x": { + "field": "date", + "timeUnit": "date", + "type": "temporal", + "title": "Day of Month", + "axis": { + "labelAngle": 0, + "format": "%e" + } + }, + "y": { + "field": "date", + "timeUnit": "month", + "type": "temporal", + "title": "Month" + }, + "color": { + "field": "completion_rate", + "type": "quantitative", + "scale": { + "scheme": "blues", + "domain": [0, 1] + }, + "legend": { + "title": "Completion Rate", + "format": ".0%" + } + }, + "tooltip": [ + {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, + {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, + {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + ] + }, + "width": "container", + "height": 150, + "background": "transparent" + } + } + } +} \ No newline at end of file From 42c83d993cfb44d4603726d1794ab30649e2b997 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:49:28 +0000 Subject: [PATCH 19/45] Fix desktop styling and add debug table for joined data Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 6801ca8f..8a0e33c0 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -4,9 +4,9 @@ "style": { "css": [ "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", - "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'annual annual'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", - "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'annual'; grid-template-columns: 1fr; } }", - ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'annual annual' 'debug debug'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", + "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'annual' 'debug'; grid-template-columns: 1fr; } }", + "[id] { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", "#controls { grid-area: controls; }", "#heatmap { grid-area: heatmap; }", @@ -14,6 +14,7 @@ "#progress { grid-area: progress; }", "#stats { grid-area: stats; }", "#annual { grid-area: annual; }", + "#debug { grid-area: debug; }", "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", @@ -354,6 +355,24 @@ "calculation": { "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" } + }, + { + "variableId": "enrichedProgressData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["progressDataTable", "habitsDataTable"], + "dataFrameTransformations": [ + { + "type": "lookup", + "from": "habitsDataTable", + "key": "habit_id", + "fields": ["category", "target_frequency"], + "as": ["category", "target_frequency"] + } + ] + } } ], "groups": [ @@ -463,6 +482,29 @@ "chartKey": "annualHeatmap" } ] + }, + { + "groupId": "debug", + "elements": [ + "## 🔍 Debug: Progress with Categories", + { + "type": "tabulator", + "dataSourceName": "enrichedProgressData", + "tabulatorOptions": { + "columns": [ + {"field": "date", "title": "Date", "width": 100}, + {"field": "habit_name", "title": "Habit", "width": 150}, + {"field": "category", "title": "Category", "width": 100}, + {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross"} + ], + "layout": "fitColumns", + "height": "200px", + "initialSort": [ + {"column": "date", "dir": "desc"} + ] + } + } + ] } ], "resources": { From 0fa7923f2f1b243e4a9cf9e34beee756f6ce43e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 01:53:47 +0000 Subject: [PATCH 20/45] Fix data lookup with correct syntax and remove habit_id dependency Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 193 +++++++++--------- 1 file changed, 98 insertions(+), 95 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 8a0e33c0..565dd7c5 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -42,37 +42,31 @@ "format": "json", "content": [ { - "habit_id": 1, "habit_name": "Morning Exercise", "category": "Health", "target_frequency": "Daily" }, { - "habit_id": 2, "habit_name": "Read for 30min", "category": "Learning", "target_frequency": "Daily" }, { - "habit_id": 3, "habit_name": "Meditate", "category": "Wellness", "target_frequency": "Daily" }, { - "habit_id": 4, "habit_name": "Write Journal", "category": "Wellness", "target_frequency": "Daily" }, { - "habit_id": 5, "habit_name": "Learn New Language", "category": "Learning", "target_frequency": "3x per week" }, { - "habit_id": 6, "habit_name": "Call Family", "category": "Social", "target_frequency": "Weekly" @@ -84,90 +78,90 @@ "type": "inline", "format": "json", "content": [ - {"date": "2024-01-15", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-15", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-15", "habit_id": 3, "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-16", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-16", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-16", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-16", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-17", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-17", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-17", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-18", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-18", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-18", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-18", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-01-19", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-19", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-19", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-19", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-01-19", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-01-20", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-22", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-22", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-23", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-23", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-24", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-24", "habit_id": 3, "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-25", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-25", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-26", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-26", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-27", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-27", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-28", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-28", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-01", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-02", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-02", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-03", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-02-03", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-04", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-05", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-05", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-02-06", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-06", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-07", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-07", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-08", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-02-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-09", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-10", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-10", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-03-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-02", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-03", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-03-03", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-04", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-04", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-03-05", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-03-06", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-06", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-07", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-07", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-08", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-03-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-09", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-10", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-10", "habit_id": 6, "habit_name": "Call Family", "completed": true} + {"date": "2024-01-15", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-15", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-15", "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-16", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-16", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-16", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-16", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-17", "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-17", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-17", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-17", "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-18", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-18", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-18", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-18", "habit_name": "Call Family", "completed": true}, + {"date": "2024-01-19", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-19", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-19", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-19", "habit_name": "Write Journal", "completed": false}, + {"date": "2024-01-19", "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-01-20", "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-20", "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-01-20", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-21", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-22", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-22", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-22", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-23", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-23", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-24", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-24", "habit_name": "Meditate", "completed": false}, + {"date": "2024-01-25", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-01-25", "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-01-26", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-01-26", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-27", "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-01-27", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-01-28", "habit_name": "Meditate", "completed": true}, + {"date": "2024-01-28", "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-01", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-01", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-01", "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-02", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-02", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-02", "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-03", "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-02-03", "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-04", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-04", "habit_name": "Call Family", "completed": true}, + {"date": "2024-02-05", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-05", "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-05", "habit_name": "Write Journal", "completed": false}, + {"date": "2024-02-06", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-06", "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-02-07", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-07", "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-08", "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-02-08", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-02-09", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-02-09", "habit_name": "Meditate", "completed": true}, + {"date": "2024-02-10", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-02-10", "habit_name": "Learn New Language", "completed": false}, + {"date": "2024-03-01", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-01", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-02", "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-02", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-03", "habit_name": "Morning Exercise", "completed": false}, + {"date": "2024-03-03", "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-04", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-04", "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-04", "habit_name": "Call Family", "completed": true}, + {"date": "2024-03-05", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-05", "habit_name": "Write Journal", "completed": false}, + {"date": "2024-03-06", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-06", "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-07", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-07", "habit_name": "Learn New Language", "completed": true}, + {"date": "2024-03-08", "habit_name": "Read for 30min", "completed": false}, + {"date": "2024-03-08", "habit_name": "Write Journal", "completed": true}, + {"date": "2024-03-09", "habit_name": "Morning Exercise", "completed": true}, + {"date": "2024-03-09", "habit_name": "Meditate", "completed": true}, + {"date": "2024-03-10", "habit_name": "Read for 30min", "completed": true}, + {"date": "2024-03-10", "habit_name": "Call Family", "completed": true} ] } ], @@ -313,7 +307,7 @@ "type": "aggregate", "groupby": ["date"], "ops": ["count"], - "fields": ["habit_id"], + "fields": ["habit_name"], "as": ["habits_tracked"] } ] @@ -362,14 +356,23 @@ "isArray": true, "initialValue": [], "calculation": { - "dataSourceNames": ["progressDataTable", "habitsDataTable"], + "dataSourceNames": [ + "progressDataTable" + ], "dataFrameTransformations": [ { "type": "lookup", "from": "habitsDataTable", - "key": "habit_id", - "fields": ["category", "target_frequency"], - "as": ["category", "target_frequency"] + "key": "habit_name", + "fields": [ + "habit_name" + ], + "values": ["category", "target_frequency"] + }, + { + "type": "formula", + "expr": "datum.category || 'unknown'", + "as": "category" } ] } From 6b360c52aee20455c8c1efa1bcfe40386e8b6f62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 03:37:10 +0000 Subject: [PATCH 21/45] Fix calendar heatmap date positioning by changing from temporal to ordinal encoding Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-complete.idoc.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 565dd7c5..76570e45 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -535,7 +535,7 @@ "x": { "field": "date", "timeUnit": "date", - "type": "temporal", + "type": "ordinal", "title": "Day of Month", "axis": { "labelAngle": 0, @@ -588,7 +588,7 @@ "x": { "field": "date", "timeUnit": "date", - "type": "temporal", + "type": "ordinal", "title": "Day of Month", "axis": { "labelAngle": 0, @@ -598,7 +598,7 @@ "y": { "field": "date", "timeUnit": "month", - "type": "temporal", + "type": "ordinal", "title": "Month" }, "color": { From a721372afc1cdf04599699b28dbb408015792058 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 03:54:42 +0000 Subject: [PATCH 22/45] Fix calendar heatmap date positioning by removing UTC datetime conversion Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker-complete.idoc.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 76570e45..64ac24a5 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -210,11 +210,6 @@ "type": "formula", "expr": "datum.completed_count / datum.total_habits", "as": "completion_rate" - }, - { - "type": "formula", - "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", - "as": "date_parsed" } ] } @@ -243,11 +238,6 @@ "type": "formula", "expr": "datum.completed_count / datum.total_habits", "as": "completion_rate" - }, - { - "type": "formula", - "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", - "as": "date_parsed" } ] } From 2bdb4609341ee01df28d85af3df1299a665dae60 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 04:05:24 +0000 Subject: [PATCH 23/45] Fix calendar date positioning using utcParse for consistent UTC date parsing Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 64ac24a5..6f442e7c 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -506,6 +506,12 @@ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "dailyCompletionData"}, "title": "Daily Habit Completion Rate for Selected Month", + "transform": [ + { + "calculate": "utcParse(datum.date, '%Y-%m-%d')", + "as": "date_parsed" + } + ], "config": { "view": { "strokeWidth": 0, @@ -523,7 +529,7 @@ }, "encoding": { "x": { - "field": "date", + "field": "date_parsed", "timeUnit": "date", "type": "ordinal", "title": "Day of Month", @@ -545,7 +551,7 @@ } }, "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "date_parsed", "type": "temporal", "title": "Date"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} @@ -559,6 +565,12 @@ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "annualCompletionData"}, "title": "Annual Habit Completion Overview", + "transform": [ + { + "calculate": "utcParse(datum.date, '%Y-%m-%d')", + "as": "date_parsed" + } + ], "config": { "view": { "strokeWidth": 0, @@ -576,7 +588,7 @@ }, "encoding": { "x": { - "field": "date", + "field": "date_parsed", "timeUnit": "date", "type": "ordinal", "title": "Day of Month", @@ -586,7 +598,7 @@ } }, "y": { - "field": "date", + "field": "date_parsed", "timeUnit": "month", "type": "ordinal", "title": "Month" @@ -604,7 +616,7 @@ } }, "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, + {"field": "date_parsed", "type": "temporal", "title": "Date"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} From 390a4bbe51f65fc85914b0c28c339a3c803213f9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 06:53:39 +0000 Subject: [PATCH 24/45] Fix calendar date positioning with UTC timeUnit transforms and formatType Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 6f442e7c..e168dcd2 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -508,8 +508,10 @@ "title": "Daily Habit Completion Rate for Selected Month", "transform": [ { - "calculate": "utcParse(datum.date, '%Y-%m-%d')", - "as": "date_parsed" + "field": "date", + "type": "timeunit", + "units": ["utcdate"], + "as": ["date_date", "date_date_end"] } ], "config": { @@ -529,13 +531,13 @@ }, "encoding": { "x": { - "field": "date_parsed", - "timeUnit": "date", + "field": "date_date", "type": "ordinal", "title": "Day of Month", "axis": { "labelAngle": 0, - "format": "%e" + "format": "%e", + "formatType": "utc" } }, "color": { @@ -551,7 +553,7 @@ } }, "tooltip": [ - {"field": "date_parsed", "type": "temporal", "title": "Date"}, + {"field": "date", "type": "temporal", "title": "Date"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} @@ -567,8 +569,16 @@ "title": "Annual Habit Completion Overview", "transform": [ { - "calculate": "utcParse(datum.date, '%Y-%m-%d')", - "as": "date_parsed" + "field": "date", + "type": "timeunit", + "units": ["utcdate"], + "as": ["date_date", "date_date_end"] + }, + { + "field": "date", + "type": "timeunit", + "units": ["utcmonth"], + "as": ["month_date", "month_date_end"] } ], "config": { @@ -588,20 +598,23 @@ }, "encoding": { "x": { - "field": "date_parsed", - "timeUnit": "date", + "field": "date_date", "type": "ordinal", "title": "Day of Month", "axis": { "labelAngle": 0, - "format": "%e" + "format": "%e", + "formatType": "utc" } }, "y": { - "field": "date_parsed", - "timeUnit": "month", + "field": "month_date", "type": "ordinal", - "title": "Month" + "title": "Month", + "axis": { + "format": "%B", + "formatType": "utc" + } }, "color": { "field": "completion_rate", @@ -616,7 +629,7 @@ } }, "tooltip": [ - {"field": "date_parsed", "type": "temporal", "title": "Date"}, + {"field": "date", "type": "temporal", "title": "Date"}, {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} From 98dbfc4f83f3723b9c15eaf54878c8084439c7c0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 07:10:03 +0000 Subject: [PATCH 25/45] Fix x-axis undefined issue by using timeUnit in encoding instead of transform Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 40 +++++-------------- 1 file changed, 9 insertions(+), 31 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index e168dcd2..73423e16 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -506,14 +506,6 @@ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "dailyCompletionData"}, "title": "Daily Habit Completion Rate for Selected Month", - "transform": [ - { - "field": "date", - "type": "timeunit", - "units": ["utcdate"], - "as": ["date_date", "date_date_end"] - } - ], "config": { "view": { "strokeWidth": 0, @@ -531,13 +523,13 @@ }, "encoding": { "x": { - "field": "date_date", + "field": "date", + "timeUnit": "utcdate", "type": "ordinal", "title": "Day of Month", "axis": { "labelAngle": 0, - "format": "%e", - "formatType": "utc" + "format": "%e" } }, "color": { @@ -567,20 +559,6 @@ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "annualCompletionData"}, "title": "Annual Habit Completion Overview", - "transform": [ - { - "field": "date", - "type": "timeunit", - "units": ["utcdate"], - "as": ["date_date", "date_date_end"] - }, - { - "field": "date", - "type": "timeunit", - "units": ["utcmonth"], - "as": ["month_date", "month_date_end"] - } - ], "config": { "view": { "strokeWidth": 0, @@ -598,22 +576,22 @@ }, "encoding": { "x": { - "field": "date_date", + "field": "date", + "timeUnit": "utcdate", "type": "ordinal", "title": "Day of Month", "axis": { "labelAngle": 0, - "format": "%e", - "formatType": "utc" + "format": "%e" } }, "y": { - "field": "month_date", + "field": "date", + "timeUnit": "utcmonth", "type": "ordinal", "title": "Month", "axis": { - "format": "%B", - "formatType": "utc" + "format": "%B" } }, "color": { From a84d315ae3425261c198c3dd2566a7fcb5495516 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 14:34:05 +0000 Subject: [PATCH 26/45] Fix x-axis to always show all days 1-31 in habit tracker heatmaps Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-complete.idoc.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 73423e16..54edf944 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -527,6 +527,9 @@ "timeUnit": "utcdate", "type": "ordinal", "title": "Day of Month", + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + }, "axis": { "labelAngle": 0, "format": "%e" @@ -580,6 +583,9 @@ "timeUnit": "utcdate", "type": "ordinal", "title": "Day of Month", + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] + }, "axis": { "labelAngle": 0, "format": "%e" From 92a831bdf5645312dfd12fa32eedcc5316a02269 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 14:41:15 +0000 Subject: [PATCH 27/45] Fix heatmap date positioning by removing manual scale domain and using timeUnit date instead of utcdate Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker-complete.idoc.json | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 54edf944..ce13535a 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -524,12 +524,9 @@ "encoding": { "x": { "field": "date", - "timeUnit": "utcdate", + "timeUnit": "date", "type": "ordinal", "title": "Day of Month", - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - }, "axis": { "labelAngle": 0, "format": "%e" @@ -580,12 +577,9 @@ "encoding": { "x": { "field": "date", - "timeUnit": "utcdate", + "timeUnit": "date", "type": "ordinal", "title": "Day of Month", - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - }, "axis": { "labelAngle": 0, "format": "%e" @@ -593,7 +587,7 @@ }, "y": { "field": "date", - "timeUnit": "utcmonth", + "timeUnit": "month", "type": "ordinal", "title": "Month", "axis": { From bcfd56f2b48e2bbcff4dbc9ede0ccb270f2b82fd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 14:55:45 +0000 Subject: [PATCH 28/45] Fix heatmap to show complete calendar grid with proper date positioning using sequence data generation and lookup joins Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index ce13535a..6e8d669e 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -504,7 +504,31 @@ "charts": { "monthlyHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "dailyCompletionData"}, + "data": { + "sequence": { + "start": 1, + "stop": 32 + } + }, + "transform": [ + { + "calculate": "selectedMonth + '-' + format(datum.data, '02d')", + "as": "date_string" + }, + { + "calculate": "datetime(year(datetime(selectedMonth + '-01')), month(datetime(selectedMonth + '-01')), datum.data)", + "as": "date" + }, + { + "lookup": "date_string", + "from": { + "data": {"name": "dailyCompletionData"}, + "key": "date", + "fields": ["completion_rate", "completed_count", "total_habits"] + }, + "default": {"completion_rate": 0, "completed_count": 0, "total_habits": 0} + } + ], "title": "Daily Habit Completion Rate for Selected Month", "config": { "view": { @@ -557,7 +581,31 @@ }, "annualHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "annualCompletionData"}, + "data": { + "sequence": { + "start": 1, + "stop": 366 + } + }, + "transform": [ + { + "calculate": "datetime(2024, floor((datum.data - 1) / 31), ((datum.data - 1) % 31) + 1)", + "as": "date" + }, + { + "calculate": "year(datum.date) + '-' + format(month(datum.date) + 1, '02d') + '-' + format(date(datum.date), '02d')", + "as": "date_string" + }, + { + "lookup": "date_string", + "from": { + "data": {"name": "annualCompletionData"}, + "key": "date", + "fields": ["completion_rate", "completed_count", "total_habits"] + }, + "default": {"completion_rate": 0, "completed_count": 0, "total_habits": 0} + } + ], "title": "Annual Habit Completion Overview", "config": { "view": { From 28ab860eda4e8d36a48703e5aff6b8bfa36098f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 15:43:28 +0000 Subject: [PATCH 29/45] Simplify heatmap approach using explicit scale domains to ensure complete 1-31 day coverage with correct positioning Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 58 +++---------------- 1 file changed, 8 insertions(+), 50 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 6e8d669e..1ff83465 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -504,31 +504,7 @@ "charts": { "monthlyHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": { - "sequence": { - "start": 1, - "stop": 32 - } - }, - "transform": [ - { - "calculate": "selectedMonth + '-' + format(datum.data, '02d')", - "as": "date_string" - }, - { - "calculate": "datetime(year(datetime(selectedMonth + '-01')), month(datetime(selectedMonth + '-01')), datum.data)", - "as": "date" - }, - { - "lookup": "date_string", - "from": { - "data": {"name": "dailyCompletionData"}, - "key": "date", - "fields": ["completion_rate", "completed_count", "total_habits"] - }, - "default": {"completion_rate": 0, "completed_count": 0, "total_habits": 0} - } - ], + "data": {"name": "dailyCompletionData"}, "title": "Daily Habit Completion Rate for Selected Month", "config": { "view": { @@ -554,6 +530,9 @@ "axis": { "labelAngle": 0, "format": "%e" + }, + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] } }, "color": { @@ -581,31 +560,7 @@ }, "annualHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": { - "sequence": { - "start": 1, - "stop": 366 - } - }, - "transform": [ - { - "calculate": "datetime(2024, floor((datum.data - 1) / 31), ((datum.data - 1) % 31) + 1)", - "as": "date" - }, - { - "calculate": "year(datum.date) + '-' + format(month(datum.date) + 1, '02d') + '-' + format(date(datum.date), '02d')", - "as": "date_string" - }, - { - "lookup": "date_string", - "from": { - "data": {"name": "annualCompletionData"}, - "key": "date", - "fields": ["completion_rate", "completed_count", "total_habits"] - }, - "default": {"completion_rate": 0, "completed_count": 0, "total_habits": 0} - } - ], + "data": {"name": "annualCompletionData"}, "title": "Annual Habit Completion Overview", "config": { "view": { @@ -631,6 +586,9 @@ "axis": { "labelAngle": 0, "format": "%e" + }, + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] } }, "y": { From d8fea63dea43540d9d47cc071e13d2d8a7444dd0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:31:23 +0000 Subject: [PATCH 30/45] Fix signal error by temporarily using hardcoded filter to isolate the issue Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-complete.idoc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 1ff83465..e3c9db5a 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -181,7 +181,7 @@ "dataFrameTransformations": [ { "type": "filter", - "expr": "slice(datum.date, 0, 7) === selectedMonth" + "expr": "slice(datum.date, 0, 7) === '2024-01'" } ] } From 24ffdcbb460ea68072ec5f5d1433d7e54feb608e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:32:36 +0000 Subject: [PATCH 31/45] Fix selectedMonth variable reference by adding variableDependencies declaration Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-complete.idoc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index e3c9db5a..40daef15 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -178,10 +178,11 @@ "initialValue": [], "calculation": { "dataSourceNames": ["progressDataTable"], + "variableDependencies": ["selectedMonth"], "dataFrameTransformations": [ { "type": "filter", - "expr": "slice(datum.date, 0, 7) === '2024-01'" + "expr": "slice(datum.date, 0, 7) === selectedMonth" } ] } From a1daa2a7968af7432923eed2c0d52981b894b2b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 18:34:17 +0000 Subject: [PATCH 32/45] Restart heatmaps using Seattle weather pattern - direct data aggregation Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 53 ++++++------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 40daef15..4cf98aa2 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -505,7 +505,7 @@ "charts": { "monthlyHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "dailyCompletionData"}, + "data": {"name": "filteredProgressData"}, "title": "Daily Habit Completion Rate for Selected Month", "config": { "view": { @@ -516,28 +516,21 @@ "domain": false } }, - "mark": { - "type": "rect", - "stroke": "#ffffff", - "strokeWidth": 2, - "opacity": 0.8 - }, + "mark": "rect", "encoding": { "x": { "field": "date", "timeUnit": "date", "type": "ordinal", - "title": "Day of Month", + "title": "Day", "axis": { "labelAngle": 0, "format": "%e" - }, - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] } }, "color": { - "field": "completion_rate", + "field": "completed", + "aggregate": "mean", "type": "quantitative", "scale": { "scheme": "greens", @@ -550,18 +543,15 @@ }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, - {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, - {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + {"field": "completed", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} ] }, "width": "container", - "height": 100, - "background": "transparent" + "height": 100 }, "annualHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "annualCompletionData"}, + "data": {"name": "progressDataTable"}, "title": "Annual Habit Completion Overview", "config": { "view": { @@ -572,37 +562,27 @@ "domain": false } }, - "mark": { - "type": "rect", - "stroke": "#ffffff", - "strokeWidth": 2, - "opacity": 0.8 - }, + "mark": "rect", "encoding": { "x": { "field": "date", "timeUnit": "date", "type": "ordinal", - "title": "Day of Month", + "title": "Day", "axis": { "labelAngle": 0, "format": "%e" - }, - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] } }, "y": { "field": "date", "timeUnit": "month", "type": "ordinal", - "title": "Month", - "axis": { - "format": "%B" - } + "title": "Month" }, "color": { - "field": "completion_rate", + "field": "completed", + "aggregate": "mean", "type": "quantitative", "scale": { "scheme": "blues", @@ -615,14 +595,11 @@ }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, - {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, - {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + {"field": "completed", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} ] }, "width": "container", - "height": 150, - "background": "transparent" + "height": 150 } } } From 88af37d0b6ff6bccab6244f54a839a76e0c07f4a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 19:22:22 +0000 Subject: [PATCH 33/45] Fix boolean aggregation and add complete day domain for heatmaps Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 4cf98aa2..c5f1d970 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -517,6 +517,9 @@ } }, "mark": "rect", + "transform": [ + {"calculate": "datum.completed ? 1 : 0", "as": "completed_numeric"} + ], "encoding": { "x": { "field": "date", @@ -526,10 +529,13 @@ "axis": { "labelAngle": 0, "format": "%e" + }, + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] } }, "color": { - "field": "completed", + "field": "completed_numeric", "aggregate": "mean", "type": "quantitative", "scale": { @@ -543,7 +549,7 @@ }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + {"field": "completed_numeric", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} ] }, "width": "container", @@ -563,6 +569,9 @@ } }, "mark": "rect", + "transform": [ + {"calculate": "datum.completed ? 1 : 0", "as": "completed_numeric"} + ], "encoding": { "x": { "field": "date", @@ -572,6 +581,9 @@ "axis": { "labelAngle": 0, "format": "%e" + }, + "scale": { + "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] } }, "y": { @@ -581,7 +593,7 @@ "title": "Month" }, "color": { - "field": "completed", + "field": "completed_numeric", "aggregate": "mean", "type": "quantitative", "scale": { @@ -595,7 +607,7 @@ }, "tooltip": [ {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} + {"field": "completed_numeric", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} ] }, "width": "container", From 53ef2681398405dcc8cf94cf6b9954266d35797d Mon Sep 17 00:00:00 2001 From: Dan Marshall Date: Fri, 5 Sep 2025 13:21:47 -0700 Subject: [PATCH 34/45] Add initial implementation of Simple Habit Tracker with heatmap visualization --- .../json/habit-tracker-simple.idoc.json | 369 ++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 packages/web-deploy/json/habit-tracker-simple.idoc.json diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json new file mode 100644 index 00000000..921d9d31 --- /dev/null +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -0,0 +1,369 @@ +{ + "$schema": "../../../docs/schema/idoc_v1.json", + "title": "Simple Habit Tracker", + "style": { + "css": [ + "body { font-family: sans-serif; margin: 0; padding: 20px; background: #f8fafc; max-width: 1200px; margin: 0 auto; }", + "#header, #table, #heatmap { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white; text-align: center; }", + "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", + "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", + ".tabulator { max-width: 100%; overflow: auto; }", + ".tabulator .tabulator-table { min-width: fit-content; }", + "#heatmap .vega-embed .vega-actions { display: none; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr; grid-template-areas: 'header' 'table' 'heatmap'; }", + "#header { grid-area: header; }", + "#table { grid-area: table; min-width: 0; }", + "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }" + ] + }, + "dataLoaders": [ + { + "dataSourceName": "habitData", + "type": "inline", + "format": "json", + "content": [ + { + "date": "2024-01-01", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-01-01", + "habit": "Read", + "completed": false + }, + { + "date": "2024-01-15", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-01-15", + "habit": "Read", + "completed": true + }, + { + "date": "2024-01-31", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-01-31", + "habit": "Read", + "completed": true + }, + { + "date": "2024-02-01", + "habit": "Exercise", + "completed": false + }, + { + "date": "2024-02-01", + "habit": "Read", + "completed": true + }, + { + "date": "2024-02-14", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-02-14", + "habit": "Read", + "completed": false + }, + { + "date": "2024-02-29", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-02-29", + "habit": "Read", + "completed": true + }, + { + "date": "2024-03-01", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-03-01", + "habit": "Read", + "completed": false + }, + { + "date": "2024-03-17", + "habit": "Exercise", + "completed": false + }, + { + "date": "2024-03-17", + "habit": "Read", + "completed": false + }, + { + "date": "2024-03-31", + "habit": "Exercise", + "completed": false + }, + { + "date": "2024-03-31", + "habit": "Read", + "completed": true + }, + { + "date": "2024-04-01", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-04-01", + "habit": "Read", + "completed": true + }, + { + "date": "2024-04-15", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-04-15", + "habit": "Read", + "completed": true + }, + { + "date": "2024-04-30", + "habit": "Exercise", + "completed": true + }, + { + "date": "2024-04-30", + "habit": "Read", + "completed": false + } + ] + } + ], + "variables": [ + { + "variableId": "dailyCompletionData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": [ + "habitDataTable" + ], + "dataFrameTransformations": [ + { + "type": "formula", + "expr": "parseInt(slice(datum.date, 8, 10))", + "as": "day_of_month" + }, + { + "type": "formula", + "expr": "parseInt(slice(datum.date, 5, 7))", + "as": "month_number" + }, + { + "type": "formula", + "expr": "datum.completed ? 1 : 0", + "as": "completed_numeric" + }, + { + "type": "aggregate", + "groupby": [ + "date", + "day_of_month", + "month_number" + ], + "ops": [ + "sum", + "count" + ], + "fields": [ + "completed_numeric", + "completed_numeric" + ], + "as": [ + "completed_count", + "total_habits" + ] + }, + { + "type": "formula", + "expr": "datum.completed_count / datum.total_habits", + "as": "completion_rate" + } + ] + } + } + ], + "groups": [ + { + "groupId": "header", + "elements": [ + "# 🎯 Simple Habit Tracker", + "A minimal habit tracker with editable data and heatmap visualization." + ] + }, + { + "groupId": "table", + "elements": [ + "## 📋 Habit Data", + { + "type": "tabulator", + "dataSourceName": "habitData", + "variableId": "habitDataTable", + "editable": true, + "tabulatorOptions": { + "maxHeight": "210px", + "autoColumns": true, + "layout": "fitColumns" + } + } + ] + }, + { + "groupId": "heatmap", + "elements": [ + "## 🗓️ Completion Heatmap", + { + "type": "chart", + "chartKey": "completionHeatmap" + } + ] + } + ], + "resources": { + "charts": { + "completionHeatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": { + "name": "dailyCompletionData" + }, + "title": "Daily Habit Completion Rate", + "config": { + "view": { + "strokeWidth": 0, + "step": 13, + "fill": "transparent" + }, + "axis": { + "domain": false + }, + "background": "transparent" + }, + "mark": "rect", + "encoding": { + "x": { + "field": "day_of_month", + "type": "ordinal", + "title": "Day", + "scale": { + "domain": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ] + } + }, + "y": { + "field": "month_number", + "type": "ordinal", + "title": "Month", + "scale": { + "domain": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12 + ] + }, + "axis": { + "labelExpr": "['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][datum.value]" + } + }, + "color": { + "field": "completion_rate", + "type": "quantitative", + "scale": { + "scheme": "greens", + "domain": [ + 0, + 1 + ] + }, + "legend": { + "title": "Completion Rate", + "format": ".0%" + } + }, + "tooltip": [ + { + "field": "date", + "type": "temporal", + "title": "Date" + }, + { + "field": "completed_count", + "type": "quantitative", + "title": "Completed Habits" + }, + { + "field": "total_habits", + "type": "quantitative", + "title": "Total Habits" + }, + { + "field": "completion_rate", + "type": "quantitative", + "title": "Completion Rate", + "format": ".1%" + } + ] + }, + "width": "container", + "height": 150 + } + } + } +} \ No newline at end of file From 2f7b27b0306158e4839686158ff244728ba54988 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 20:28:29 +0000 Subject: [PATCH 35/45] Add habits table with categories and data joining to simple habit tracker Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-simple.idoc.json | 86 ++++++++++++++++++- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index 921d9d31..b25416c7 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -11,13 +11,33 @@ ".tabulator { max-width: 100%; overflow: auto; }", ".tabulator .tabulator-table { min-width: fit-content; }", "#heatmap .vega-embed .vega-actions { display: none; }", - "body { display: grid; gap: 20px; grid-template-columns: 1fr; grid-template-areas: 'header' 'table' 'heatmap'; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'habits table' 'debug debug' 'heatmap heatmap'; }", "#header { grid-area: header; }", + "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", - "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }" + "#debug { grid-area: debug; min-width: 0; }", + "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", + "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'debug' 'heatmap'; } }" ] }, "dataLoaders": [ + { + "dataSourceName": "habitsData", + "type": "inline", + "format": "json", + "content": [ + { + "habit_name": "Exercise", + "category": "Health", + "target_frequency": "Daily" + }, + { + "habit_name": "Read", + "category": "Learning", + "target_frequency": "Daily" + } + ] + }, { "dataSourceName": "habitData", "type": "inline", @@ -146,7 +166,35 @@ ] } ], + ], "variables": [ + { + "variableId": "enrichedHabitData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": [ + "habitDataTable" + ], + "dataFrameTransformations": [ + { + "type": "lookup", + "from": "habitsDataTable", + "key": "habit_name", + "fields": [ + "habit" + ], + "values": ["category", "target_frequency"] + }, + { + "type": "formula", + "expr": "datum.category || 'Unknown'", + "as": "category" + } + ] + } + }, { "variableId": "dailyCompletionData", "type": "object", @@ -209,10 +257,27 @@ "A minimal habit tracker with editable data and heatmap visualization." ] }, + { + "groupId": "habits", + "elements": [ + "## 🎯 Habits Configuration", + { + "type": "tabulator", + "dataSourceName": "habitsData", + "variableId": "habitsDataTable", + "editable": true, + "tabulatorOptions": { + "maxHeight": "180px", + "autoColumns": true, + "layout": "fitColumns" + } + } + ] + }, { "groupId": "table", "elements": [ - "## 📋 Habit Data", + "## 📋 Daily Progress", { "type": "tabulator", "dataSourceName": "habitData", @@ -226,6 +291,21 @@ } ] }, + { + "groupId": "debug", + "elements": [ + "## 🔍 Debug: Enriched Data", + { + "type": "tabulator", + "dataSourceName": "enrichedHabitData", + "tabulatorOptions": { + "maxHeight": "200px", + "autoColumns": true, + "layout": "fitColumns" + } + } + ] + }, { "groupId": "heatmap", "elements": [ From d52f70c4dc55659843d96269cc8856b6ebd79245 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 22:28:16 +0000 Subject: [PATCH 36/45] Add month picker and filtered enriched data to simple habit tracker Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-simple.idoc.json | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index b25416c7..deb90db6 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -11,16 +11,28 @@ ".tabulator { max-width: 100%; overflow: auto; }", ".tabulator .tabulator-table { min-width: fit-content; }", "#heatmap .vega-embed .vega-actions { display: none; }", - "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'habits table' 'debug debug' 'heatmap heatmap'; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'controls controls' 'habits table' 'debug debug' 'heatmap heatmap'; }", "#header { grid-area: header; }", + "#controls { grid-area: controls; min-width: 0; }", "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", "#debug { grid-area: debug; min-width: 0; }", "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", - "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'debug' 'heatmap'; } }" + "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'controls' 'habits' 'table' 'debug' 'heatmap'; } }" ] }, "dataLoaders": [ + { + "dataSourceName": "monthOptions", + "type": "inline", + "format": "json", + "content": [ + {"value": "2024-01", "label": "January 2024"}, + {"value": "2024-02", "label": "February 2024"}, + {"value": "2024-03", "label": "March 2024"}, + {"value": "2024-04", "label": "April 2024"} + ] + }, { "dataSourceName": "habitsData", "type": "inline", @@ -166,8 +178,12 @@ ] } ], - ], "variables": [ + { + "variableId": "selectedMonth", + "type": "string", + "initialValue": "2024-01" + }, { "variableId": "enrichedHabitData", "type": "object", @@ -195,6 +211,22 @@ ] } }, + { + "variableId": "filteredEnrichedData", + "type": "object", + "isArray": true, + "initialValue": [], + "calculation": { + "dataSourceNames": ["enrichedHabitData"], + "variableDependencies": ["selectedMonth"], + "dataFrameTransformations": [ + { + "type": "filter", + "expr": "slice(datum.date, 0, 7) === selectedMonth" + } + ] + } + }, { "variableId": "dailyCompletionData", "type": "object", @@ -257,6 +289,21 @@ "A minimal habit tracker with editable data and heatmap visualization." ] }, + { + "groupId": "controls", + "elements": [ + "## 🎛️ Month Filter", + { + "type": "dropdown", + "variableId": "selectedMonth", + "label": "Select Month:", + "dynamicOptions": { + "dataSourceName": "monthOptions", + "fieldName": "value" + } + } + ] + }, { "groupId": "habits", "elements": [ @@ -294,10 +341,10 @@ { "groupId": "debug", "elements": [ - "## 🔍 Debug: Enriched Data", + "## 🔍 Debug: Filtered Enriched Data (Selected Month)", { "type": "tabulator", - "dataSourceName": "enrichedHabitData", + "dataSourceName": "filteredEnrichedData", "tabulatorOptions": { "maxHeight": "200px", "autoColumns": true, From 4a35cde8d677ff92f0d1ced76f761f9fefb59dac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Sep 2025 23:37:26 +0000 Subject: [PATCH 37/45] Add monthly category heatmap to simple habit tracker Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-simple.idoc.json | 97 ++++++++++++++++++- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index deb90db6..9c40c84a 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -11,14 +11,15 @@ ".tabulator { max-width: 100%; overflow: auto; }", ".tabulator .tabulator-table { min-width: fit-content; }", "#heatmap .vega-embed .vega-actions { display: none; }", - "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'controls controls' 'habits table' 'debug debug' 'heatmap heatmap'; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'controls controls' 'habits table' 'debug debug' 'monthly monthly' 'heatmap heatmap'; }", "#header { grid-area: header; }", "#controls { grid-area: controls; min-width: 0; }", "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", "#debug { grid-area: debug; min-width: 0; }", + "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; }", "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", - "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'controls' 'habits' 'table' 'debug' 'heatmap'; } }" + "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'controls' 'habits' 'table' 'debug' 'monthly' 'heatmap'; } }" ] }, "dataLoaders": [ @@ -353,10 +354,20 @@ } ] }, + { + "groupId": "monthly", + "elements": [ + "## 📊 Monthly Heatmap by Category", + { + "type": "chart", + "chartKey": "monthlyHeatmap" + } + ] + }, { "groupId": "heatmap", "elements": [ - "## 🗓️ Completion Heatmap", + "## 🗓️ Annual Calendar View", { "type": "chart", "chartKey": "completionHeatmap" @@ -366,6 +377,86 @@ ], "resources": { "charts": { + "monthlyHeatmap": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": { + "name": "filteredEnrichedData" + }, + "title": "Daily Habit Completion by Category (Selected Month)", + "config": { + "view": { + "strokeWidth": 0, + "step": 13, + "fill": "transparent" + }, + "axis": { + "domain": false + }, + "background": "transparent" + }, + "transform": [ + { + "calculate": "parseInt(slice(datum.date, 8, 10))", + "as": "day_of_month" + }, + { + "calculate": "datum.completed ? 1 : 0", + "as": "completed_numeric" + } + ], + "mark": "rect", + "encoding": { + "x": { + "field": "day_of_month", + "type": "ordinal", + "title": "Day of Month", + "scale": { + "domain": [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + ] + } + }, + "y": { + "field": "category", + "type": "nominal", + "title": "Category" + }, + "color": { + "aggregate": "mean", + "field": "completed_numeric", + "type": "quantitative", + "scale": { + "scheme": "blues", + "domain": [0, 1] + }, + "legend": { + "title": "Completion Rate", + "format": ".0%" + } + }, + "tooltip": [ + { + "field": "category", + "type": "nominal", + "title": "Category" + }, + { + "field": "day_of_month", + "type": "ordinal", + "title": "Day" + }, + { + "aggregate": "mean", + "field": "completed_numeric", + "type": "quantitative", + "title": "Completion Rate", + "format": ".1%" + } + ] + }, + "width": "container", + "height": 120 + }, "completionHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": { From fd24d576901a19e415fc8f0cb1953fd8ea186017 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 6 Sep 2025 00:53:39 +0000 Subject: [PATCH 38/45] Remove debug table and fix rounded border styling for all groups Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-simple.idoc.json | 24 ++++--------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index 9c40c84a..49c2f9c1 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -4,22 +4,22 @@ "style": { "css": [ "body { font-family: sans-serif; margin: 0; padding: 20px; background: #f8fafc; max-width: 1200px; margin: 0 auto; }", - "#header, #table, #heatmap { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header, #controls, #habits, #table, #monthly, #heatmap { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white; text-align: center; }", "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", ".tabulator { max-width: 100%; overflow: auto; }", ".tabulator .tabulator-table { min-width: fit-content; }", "#heatmap .vega-embed .vega-actions { display: none; }", - "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'controls controls' 'habits table' 'debug debug' 'monthly monthly' 'heatmap heatmap'; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'controls controls' 'habits table' 'monthly monthly' 'heatmap heatmap'; }", "#header { grid-area: header; }", "#controls { grid-area: controls; min-width: 0; }", "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", - "#debug { grid-area: debug; min-width: 0; }", + "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; }", "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", - "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'controls' 'habits' 'table' 'debug' 'monthly' 'heatmap'; } }" + "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'controls' 'habits' 'table' 'monthly' 'heatmap'; } }" ] }, "dataLoaders": [ @@ -339,21 +339,7 @@ } ] }, - { - "groupId": "debug", - "elements": [ - "## 🔍 Debug: Filtered Enriched Data (Selected Month)", - { - "type": "tabulator", - "dataSourceName": "filteredEnrichedData", - "tabulatorOptions": { - "maxHeight": "200px", - "autoColumns": true, - "layout": "fitColumns" - } - } - ] - }, + { "groupId": "monthly", "elements": [ From a262dec2e28cae5cad04c2f4ce8ed57c93ebe971 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 6 Sep 2025 02:35:33 +0000 Subject: [PATCH 39/45] Enhance habit tracker with more categories and comprehensive data showing streaks Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-simple.idoc.json | 434 +++++++++++++----- 1 file changed, 324 insertions(+), 110 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index 49c2f9c1..c078b6d1 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -45,138 +45,349 @@ "target_frequency": "Daily" }, { - "habit_name": "Read", - "category": "Learning", + "habit_name": "Water Intake", + "category": "Health", "target_frequency": "Daily" - } - ] - }, - { - "dataSourceName": "habitData", - "type": "inline", - "format": "json", - "content": [ - { - "date": "2024-01-01", - "habit": "Exercise", - "completed": true }, { - "date": "2024-01-01", - "habit": "Read", - "completed": false - }, - { - "date": "2024-01-15", - "habit": "Exercise", - "completed": true - }, - { - "date": "2024-01-15", - "habit": "Read", - "completed": true - }, - { - "date": "2024-01-31", - "habit": "Exercise", - "completed": true - }, - { - "date": "2024-01-31", - "habit": "Read", - "completed": true - }, - { - "date": "2024-02-01", - "habit": "Exercise", - "completed": false - }, - { - "date": "2024-02-01", - "habit": "Read", - "completed": true - }, - { - "date": "2024-02-14", - "habit": "Exercise", - "completed": true - }, - { - "date": "2024-02-14", - "habit": "Read", - "completed": false - }, - { - "date": "2024-02-29", - "habit": "Exercise", - "completed": true - }, - { - "date": "2024-02-29", - "habit": "Read", - "completed": true - }, - { - "date": "2024-03-01", - "habit": "Exercise", - "completed": true - }, - { - "date": "2024-03-01", - "habit": "Read", - "completed": false - }, - { - "date": "2024-03-17", - "habit": "Exercise", - "completed": false + "habit_name": "Sleep 8 Hours", + "category": "Health", + "target_frequency": "Daily" }, { - "date": "2024-03-17", - "habit": "Read", - "completed": false + "habit_name": "Read", + "category": "Learning", + "target_frequency": "Daily" }, { - "date": "2024-03-31", - "habit": "Exercise", - "completed": false + "habit_name": "Language Learning", + "category": "Learning", + "target_frequency": "Daily" }, { - "date": "2024-03-31", - "habit": "Read", - "completed": true + "habit_name": "Online Course", + "category": "Learning", + "target_frequency": "3x/week" }, { - "date": "2024-04-01", - "habit": "Exercise", - "completed": true + "habit_name": "Call Family", + "category": "Social", + "target_frequency": "2x/week" }, { - "date": "2024-04-01", - "habit": "Read", - "completed": true + "habit_name": "Social Activity", + "category": "Social", + "target_frequency": "Weekly" }, { - "date": "2024-04-15", - "habit": "Exercise", - "completed": true + "habit_name": "Meditation", + "category": "Wellness", + "target_frequency": "Daily" }, { - "date": "2024-04-15", - "habit": "Read", - "completed": true + "habit_name": "Gratitude Journal", + "category": "Wellness", + "target_frequency": "Daily" }, { - "date": "2024-04-30", - "habit": "Exercise", - "completed": true + "habit_name": "Deep Work Session", + "category": "Work", + "target_frequency": "Daily" }, { - "date": "2024-04-30", - "habit": "Read", - "completed": false + "habit_name": "Planning", + "category": "Work", + "target_frequency": "Daily" } ] + }, + { + "dataSourceName": "habitData", + "type": "inline", + "format": "json", + "content": [ + {"date": "2024-01-01", "habit": "Exercise", "completed": true}, + {"date": "2024-01-01", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-01", "habit": "Sleep 8 Hours", "completed": false}, + {"date": "2024-01-01", "habit": "Read", "completed": true}, + {"date": "2024-01-01", "habit": "Meditation", "completed": true}, + {"date": "2024-01-01", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-01-02", "habit": "Exercise", "completed": true}, + {"date": "2024-01-02", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-02", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-02", "habit": "Read", "completed": true}, + {"date": "2024-01-02", "habit": "Meditation", "completed": true}, + {"date": "2024-01-02", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-01-03", "habit": "Exercise", "completed": true}, + {"date": "2024-01-03", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-03", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-03", "habit": "Read", "completed": true}, + {"date": "2024-01-03", "habit": "Meditation", "completed": false}, + {"date": "2024-01-03", "habit": "Online Course", "completed": true}, + {"date": "2024-01-03", "habit": "Call Family", "completed": true}, + + {"date": "2024-01-04", "habit": "Exercise", "completed": true}, + {"date": "2024-01-04", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-04", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-04", "habit": "Read", "completed": false}, + {"date": "2024-01-04", "habit": "Meditation", "completed": true}, + {"date": "2024-01-04", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-01-05", "habit": "Exercise", "completed": true}, + {"date": "2024-01-05", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-05", "habit": "Sleep 8 Hours", "completed": false}, + {"date": "2024-01-05", "habit": "Read", "completed": true}, + {"date": "2024-01-05", "habit": "Language Learning", "completed": true}, + {"date": "2024-01-05", "habit": "Online Course", "completed": true}, + {"date": "2024-01-05", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-01-06", "habit": "Exercise", "completed": true}, + {"date": "2024-01-06", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-06", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-06", "habit": "Read", "completed": true}, + {"date": "2024-01-06", "habit": "Meditation", "completed": true}, + {"date": "2024-01-06", "habit": "Social Activity", "completed": true}, + + {"date": "2024-01-07", "habit": "Exercise", "completed": true}, + {"date": "2024-01-07", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-07", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-07", "habit": "Read", "completed": false}, + {"date": "2024-01-07", "habit": "Meditation", "completed": true}, + {"date": "2024-01-07", "habit": "Planning", "completed": true}, + + {"date": "2024-01-08", "habit": "Exercise", "completed": false}, + {"date": "2024-01-08", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-08", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-08", "habit": "Read", "completed": true}, + {"date": "2024-01-08", "habit": "Language Learning", "completed": true}, + + {"date": "2024-01-10", "habit": "Exercise", "completed": true}, + {"date": "2024-01-10", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-10", "habit": "Read", "completed": true}, + {"date": "2024-01-10", "habit": "Call Family", "completed": true}, + {"date": "2024-01-10", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-01-12", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-12", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-12", "habit": "Read", "completed": true}, + {"date": "2024-01-12", "habit": "Online Course", "completed": true}, + {"date": "2024-01-12", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-01-15", "habit": "Exercise", "completed": true}, + {"date": "2024-01-15", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-15", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-01-15", "habit": "Read", "completed": true}, + {"date": "2024-01-15", "habit": "Language Learning", "completed": true}, + {"date": "2024-01-15", "habit": "Meditation", "completed": true}, + + {"date": "2024-01-20", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-20", "habit": "Read", "completed": false}, + {"date": "2024-01-20", "habit": "Deep Work Session", "completed": true}, + {"date": "2024-01-20", "habit": "Planning", "completed": true}, + + {"date": "2024-01-25", "habit": "Exercise", "completed": true}, + {"date": "2024-01-25", "habit": "Water Intake", "completed": true}, + {"date": "2024-01-25", "habit": "Sleep 8 Hours", "completed": false}, + {"date": "2024-01-25", "habit": "Read", "completed": true}, + {"date": "2024-01-25", "habit": "Social Activity", "completed": true}, + + {"date": "2024-02-01", "habit": "Exercise", "completed": false}, + {"date": "2024-02-01", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-01", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-01", "habit": "Read", "completed": true}, + {"date": "2024-02-01", "habit": "Meditation", "completed": true}, + {"date": "2024-02-01", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-02-02", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-02", "habit": "Read", "completed": true}, + {"date": "2024-02-02", "habit": "Meditation", "completed": true}, + {"date": "2024-02-02", "habit": "Language Learning", "completed": true}, + + {"date": "2024-02-03", "habit": "Exercise", "completed": true}, + {"date": "2024-02-03", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-03", "habit": "Read", "completed": true}, + {"date": "2024-02-03", "habit": "Meditation", "completed": true}, + {"date": "2024-02-03", "habit": "Call Family", "completed": true}, + + {"date": "2024-02-04", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-04", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-04", "habit": "Read", "completed": false}, + {"date": "2024-02-04", "habit": "Meditation", "completed": true}, + {"date": "2024-02-04", "habit": "Online Course", "completed": true}, + + {"date": "2024-02-05", "habit": "Exercise", "completed": true}, + {"date": "2024-02-05", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-05", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-05", "habit": "Read", "completed": true}, + {"date": "2024-02-05", "habit": "Meditation", "completed": true}, + {"date": "2024-02-05", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-02-06", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-06", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-06", "habit": "Read", "completed": true}, + {"date": "2024-02-06", "habit": "Meditation", "completed": true}, + {"date": "2024-02-06", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-02-07", "habit": "Exercise", "completed": true}, + {"date": "2024-02-07", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-07", "habit": "Read", "completed": true}, + {"date": "2024-02-07", "habit": "Meditation", "completed": true}, + {"date": "2024-02-07", "habit": "Language Learning", "completed": true}, + + {"date": "2024-02-08", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-08", "habit": "Sleep 8 Hours", "completed": false}, + {"date": "2024-02-08", "habit": "Read", "completed": true}, + {"date": "2024-02-08", "habit": "Meditation", "completed": true}, + {"date": "2024-02-08", "habit": "Online Course", "completed": true}, + + {"date": "2024-02-09", "habit": "Exercise", "completed": true}, + {"date": "2024-02-09", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-09", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-09", "habit": "Read", "completed": false}, + {"date": "2024-02-09", "habit": "Meditation", "completed": true}, + {"date": "2024-02-09", "habit": "Planning", "completed": true}, + + {"date": "2024-02-10", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-10", "habit": "Read", "completed": true}, + {"date": "2024-02-10", "habit": "Meditation", "completed": true}, + {"date": "2024-02-10", "habit": "Social Activity", "completed": true}, + + {"date": "2024-02-14", "habit": "Exercise", "completed": true}, + {"date": "2024-02-14", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-14", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-14", "habit": "Read", "completed": false}, + {"date": "2024-02-14", "habit": "Call Family", "completed": true}, + {"date": "2024-02-14", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-02-20", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-20", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-20", "habit": "Read", "completed": true}, + {"date": "2024-02-20", "habit": "Language Learning", "completed": true}, + {"date": "2024-02-20", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-02-25", "habit": "Exercise", "completed": true}, + {"date": "2024-02-25", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-25", "habit": "Read", "completed": true}, + {"date": "2024-02-25", "habit": "Online Course", "completed": true}, + {"date": "2024-02-25", "habit": "Planning", "completed": true}, + + {"date": "2024-02-29", "habit": "Exercise", "completed": true}, + {"date": "2024-02-29", "habit": "Water Intake", "completed": true}, + {"date": "2024-02-29", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-02-29", "habit": "Read", "completed": true}, + {"date": "2024-02-29", "habit": "Meditation", "completed": false}, + + {"date": "2024-03-01", "habit": "Exercise", "completed": true}, + {"date": "2024-03-01", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-01", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-03-01", "habit": "Read", "completed": true}, + {"date": "2024-03-01", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-03-02", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-02", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-03-02", "habit": "Read", "completed": true}, + {"date": "2024-03-02", "habit": "Language Learning", "completed": true}, + {"date": "2024-03-02", "habit": "Call Family", "completed": true}, + + {"date": "2024-03-03", "habit": "Exercise", "completed": true}, + {"date": "2024-03-03", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-03", "habit": "Read", "completed": true}, + {"date": "2024-03-03", "habit": "Meditation", "completed": true}, + {"date": "2024-03-03", "habit": "Online Course", "completed": true}, + + {"date": "2024-03-04", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-04", "habit": "Sleep 8 Hours", "completed": false}, + {"date": "2024-03-04", "habit": "Read", "completed": true}, + {"date": "2024-03-04", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-03-05", "habit": "Exercise", "completed": false}, + {"date": "2024-03-05", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-05", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-03-05", "habit": "Read", "completed": true}, + {"date": "2024-03-05", "habit": "Planning", "completed": true}, + + {"date": "2024-03-10", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-10", "habit": "Read", "completed": false}, + {"date": "2024-03-10", "habit": "Language Learning", "completed": true}, + {"date": "2024-03-10", "habit": "Social Activity", "completed": true}, + + {"date": "2024-03-15", "habit": "Exercise", "completed": true}, + {"date": "2024-03-15", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-15", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-03-15", "habit": "Read", "completed": true}, + {"date": "2024-03-15", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-03-17", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-17", "habit": "Read", "completed": false}, + {"date": "2024-03-17", "habit": "Call Family", "completed": true}, + {"date": "2024-03-17", "habit": "Meditation", "completed": true}, + + {"date": "2024-03-20", "habit": "Exercise", "completed": true}, + {"date": "2024-03-20", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-20", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-03-20", "habit": "Read", "completed": true}, + {"date": "2024-03-20", "habit": "Online Course", "completed": true}, + + {"date": "2024-03-25", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-25", "habit": "Read", "completed": true}, + {"date": "2024-03-25", "habit": "Language Learning", "completed": true}, + {"date": "2024-03-25", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-03-31", "habit": "Exercise", "completed": false}, + {"date": "2024-03-31", "habit": "Water Intake", "completed": true}, + {"date": "2024-03-31", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-03-31", "habit": "Read", "completed": true}, + {"date": "2024-03-31", "habit": "Planning", "completed": true}, + + {"date": "2024-04-01", "habit": "Exercise", "completed": true}, + {"date": "2024-04-01", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-01", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-04-01", "habit": "Read", "completed": true}, + {"date": "2024-04-01", "habit": "Deep Work Session", "completed": true}, + + {"date": "2024-04-02", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-02", "habit": "Read", "completed": true}, + {"date": "2024-04-02", "habit": "Language Learning", "completed": true}, + {"date": "2024-04-02", "habit": "Meditation", "completed": true}, + + {"date": "2024-04-05", "habit": "Exercise", "completed": true}, + {"date": "2024-04-05", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-05", "habit": "Sleep 8 Hours", "completed": false}, + {"date": "2024-04-05", "habit": "Read", "completed": true}, + {"date": "2024-04-05", "habit": "Call Family", "completed": true}, + + {"date": "2024-04-10", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-10", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-04-10", "habit": "Read", "completed": true}, + {"date": "2024-04-10", "habit": "Online Course", "completed": true}, + {"date": "2024-04-10", "habit": "Gratitude Journal", "completed": true}, + + {"date": "2024-04-15", "habit": "Exercise", "completed": true}, + {"date": "2024-04-15", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-15", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-04-15", "habit": "Read", "completed": true}, + {"date": "2024-04-15", "habit": "Language Learning", "completed": true}, + {"date": "2024-04-15", "habit": "Social Activity", "completed": true}, + + {"date": "2024-04-20", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-20", "habit": "Read", "completed": false}, + {"date": "2024-04-20", "habit": "Deep Work Session", "completed": true}, + {"date": "2024-04-20", "habit": "Planning", "completed": true}, + + {"date": "2024-04-25", "habit": "Exercise", "completed": true}, + {"date": "2024-04-25", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-25", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-04-25", "habit": "Read", "completed": true}, + {"date": "2024-04-25", "habit": "Meditation", "completed": true}, + + {"date": "2024-04-30", "habit": "Exercise", "completed": true}, + {"date": "2024-04-30", "habit": "Water Intake", "completed": true}, + {"date": "2024-04-30", "habit": "Sleep 8 Hours", "completed": true}, + {"date": "2024-04-30", "habit": "Read", "completed": false}, + {"date": "2024-04-30", "habit": "Call Family", "completed": true} + ] } ], "variables": [ @@ -405,7 +616,10 @@ "y": { "field": "category", "type": "nominal", - "title": "Category" + "title": "Category", + "scale": { + "domain": ["Health", "Learning", "Social", "Wellness", "Work"] + } }, "color": { "aggregate": "mean", From 92d4280d311d8932ac8c6829c525f5c8a51657f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 6 Sep 2025 05:25:38 +0000 Subject: [PATCH 40/45] Move month dropdown into monthly heatmap group Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-simple.idoc.json | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index c078b6d1..6389ec32 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -4,22 +4,21 @@ "style": { "css": [ "body { font-family: sans-serif; margin: 0; padding: 20px; background: #f8fafc; max-width: 1200px; margin: 0 auto; }", - "#header, #controls, #habits, #table, #monthly, #heatmap { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header, #habits, #table, #monthly, #heatmap { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white; text-align: center; }", "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", ".tabulator { max-width: 100%; overflow: auto; }", ".tabulator .tabulator-table { min-width: fit-content; }", "#heatmap .vega-embed .vega-actions { display: none; }", - "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'controls controls' 'habits table' 'monthly monthly' 'heatmap heatmap'; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'habits table' 'monthly monthly' 'heatmap heatmap'; }", "#header { grid-area: header; }", - "#controls { grid-area: controls; min-width: 0; }", "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; }", "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", - "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'controls' 'habits' 'table' 'monthly' 'heatmap'; } }" + "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'monthly' 'heatmap'; } }" ] }, "dataLoaders": [ @@ -501,21 +500,6 @@ "A minimal habit tracker with editable data and heatmap visualization." ] }, - { - "groupId": "controls", - "elements": [ - "## 🎛️ Month Filter", - { - "type": "dropdown", - "variableId": "selectedMonth", - "label": "Select Month:", - "dynamicOptions": { - "dataSourceName": "monthOptions", - "fieldName": "value" - } - } - ] - }, { "groupId": "habits", "elements": [ @@ -555,6 +539,15 @@ "groupId": "monthly", "elements": [ "## 📊 Monthly Heatmap by Category", + { + "type": "dropdown", + "variableId": "selectedMonth", + "label": "Select Month:", + "dynamicOptions": { + "dataSourceName": "monthOptions", + "fieldName": "value" + } + }, { "type": "chart", "chartKey": "monthlyHeatmap" From 548824a9c7affd8361e77d0f3f9edfd965264412 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 6 Sep 2025 09:39:15 +0000 Subject: [PATCH 41/45] Update heatmap legends and chart titles to be shorter and clearer Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-complete.idoc.json | 8 ++++---- packages/web-deploy/json/habit-tracker-simple.idoc.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index c5f1d970..6f8dbc0a 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -506,7 +506,7 @@ "monthlyHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "filteredProgressData"}, - "title": "Daily Habit Completion Rate for Selected Month", + "title": "Monthly progress by category", "config": { "view": { "strokeWidth": 0, @@ -543,7 +543,7 @@ "domain": [0, 1] }, "legend": { - "title": "Completion Rate", + "title": "% complete", "format": ".0%" } }, @@ -558,7 +558,7 @@ "annualHeatmap": { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "data": {"name": "progressDataTable"}, - "title": "Annual Habit Completion Overview", + "title": "Annual progress", "config": { "view": { "strokeWidth": 0, @@ -601,7 +601,7 @@ "domain": [0, 1] }, "legend": { - "title": "Completion Rate", + "title": "% complete", "format": ".0%" } }, diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index 6389ec32..ec7cb8d4 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -572,7 +572,7 @@ "data": { "name": "filteredEnrichedData" }, - "title": "Daily Habit Completion by Category (Selected Month)", + "title": "Monthly progress by category", "config": { "view": { "strokeWidth": 0, @@ -623,7 +623,7 @@ "domain": [0, 1] }, "legend": { - "title": "Completion Rate", + "title": "% complete", "format": ".0%" } }, @@ -655,7 +655,7 @@ "data": { "name": "dailyCompletionData" }, - "title": "Daily Habit Completion Rate", + "title": "Annual progress", "config": { "view": { "strokeWidth": 0, @@ -744,7 +744,7 @@ ] }, "legend": { - "title": "Completion Rate", + "title": "% complete", "format": ".0%" } }, From 21f433c559684c6f3f8febfda904b96e374565e9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Sep 2025 05:31:20 +0000 Subject: [PATCH 42/45] Fix heatmap grid layout by adding explicit grid-column spanning Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../web-deploy/json/habit-tracker-complete.idoc.json | 10 +++++----- .../web-deploy/json/habit-tracker-simple.idoc.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json index 6f8dbc0a..66f8c6cc 100644 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ b/packages/web-deploy/json/habit-tracker-complete.idoc.json @@ -7,13 +7,13 @@ "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'annual annual' 'debug debug'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'annual' 'debug'; grid-template-columns: 1fr; } }", "[id] { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", - "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", - "#controls { grid-area: controls; }", - "#heatmap { grid-area: heatmap; }", + "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; grid-column: 1 / -1; }", + "#controls { grid-area: controls; grid-column: 1 / -1; }", + "#heatmap { grid-area: heatmap; grid-column: 1 / -1; }", "#habits { grid-area: habits; }", "#progress { grid-area: progress; }", - "#stats { grid-area: stats; }", - "#annual { grid-area: annual; }", + "#stats { grid-area: stats; grid-column: 1 / -1; }", + "#annual { grid-area: annual; grid-column: 1 / -1; }", "#debug { grid-area: debug; }", "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index ec7cb8d4..a7dc32b4 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -16,8 +16,8 @@ "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", - "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; }", - "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", + "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; grid-column: 1 / -1; }", + "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; grid-column: 1 / -1; }", "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'monthly' 'heatmap'; } }" ] }, From 67e99a749ec2155eb4dde2a4236aa2f2852450cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Sep 2025 05:59:30 +0000 Subject: [PATCH 43/45] Revert complex grid-column changes to simplify layout Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- packages/web-deploy/json/habit-tracker-simple.idoc.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index a7dc32b4..ec7cb8d4 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -16,8 +16,8 @@ "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", - "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; grid-column: 1 / -1; }", - "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; grid-column: 1 / -1; }", + "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; }", + "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'monthly' 'heatmap'; } }" ] }, From 4dd3b5cce3399ce0c036592d5cd25217653d90c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:51:12 +0000 Subject: [PATCH 44/45] Rename heatmap to annual and delete other habit tracker files Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- .../json/habit-tracker-complete.idoc.json | 618 ----------------- .../json/habit-tracker-enhanced.idoc.json | 627 ------------------ .../json/habit-tracker-simple.idoc.json | 10 +- .../web-deploy/json/habit-tracker.idoc.json | 498 -------------- 4 files changed, 5 insertions(+), 1748 deletions(-) delete mode 100644 packages/web-deploy/json/habit-tracker-complete.idoc.json delete mode 100644 packages/web-deploy/json/habit-tracker-enhanced.idoc.json delete mode 100644 packages/web-deploy/json/habit-tracker.idoc.json diff --git a/packages/web-deploy/json/habit-tracker-complete.idoc.json b/packages/web-deploy/json/habit-tracker-complete.idoc.json deleted file mode 100644 index 66f8c6cc..00000000 --- a/packages/web-deploy/json/habit-tracker-complete.idoc.json +++ /dev/null @@ -1,618 +0,0 @@ -{ - "$schema": "../../../docs/schema/idoc_v1.json", - "title": "Complete Habit Tracker", - "style": { - "css": [ - "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", - "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'annual annual' 'debug debug'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", - "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'annual' 'debug'; grid-template-columns: 1fr; } }", - "[id] { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", - "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; grid-column: 1 / -1; }", - "#controls { grid-area: controls; grid-column: 1 / -1; }", - "#heatmap { grid-area: heatmap; grid-column: 1 / -1; }", - "#habits { grid-area: habits; }", - "#progress { grid-area: progress; }", - "#stats { grid-area: stats; grid-column: 1 / -1; }", - "#annual { grid-area: annual; grid-column: 1 / -1; }", - "#debug { grid-area: debug; }", - "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", - "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", - "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", - ".tabulator { border-radius: 8px; overflow: hidden; }", - ".tabulator .tabulator-header { background: #f7fafc; }", - ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", - ".tabulator .tabulator-row { border-bottom: 1px solid #f1f5f9; }", - ".tabulator .tabulator-row:hover { background: #f8fafc; }" - ] - }, - "dataLoaders": [ - { - "dataSourceName": "monthOptions", - "type": "inline", - "format": "json", - "content": [ - {"value": "2024-01", "label": "January 2024"}, - {"value": "2024-02", "label": "February 2024"}, - {"value": "2024-03", "label": "March 2024"} - ] - }, - { - "dataSourceName": "habitsData", - "type": "inline", - "format": "json", - "content": [ - { - "habit_name": "Morning Exercise", - "category": "Health", - "target_frequency": "Daily" - }, - { - "habit_name": "Read for 30min", - "category": "Learning", - "target_frequency": "Daily" - }, - { - "habit_name": "Meditate", - "category": "Wellness", - "target_frequency": "Daily" - }, - { - "habit_name": "Write Journal", - "category": "Wellness", - "target_frequency": "Daily" - }, - { - "habit_name": "Learn New Language", - "category": "Learning", - "target_frequency": "3x per week" - }, - { - "habit_name": "Call Family", - "category": "Social", - "target_frequency": "Weekly" - } - ] - }, - { - "dataSourceName": "progressData", - "type": "inline", - "format": "json", - "content": [ - {"date": "2024-01-15", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-15", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-15", "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-16", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-16", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-16", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-16", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-17", "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-17", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-17", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-18", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-18", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-18", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-18", "habit_name": "Call Family", "completed": true}, - {"date": "2024-01-19", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-19", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-19", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-19", "habit_name": "Write Journal", "completed": false}, - {"date": "2024-01-19", "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-01-20", "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-20", "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-20", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-21", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-22", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-22", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-22", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-23", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-23", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-24", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-24", "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-25", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-25", "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-26", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-26", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-27", "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-27", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-28", "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-28", "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-01", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-01", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-01", "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-02", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-02", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-02", "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-03", "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-02-03", "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-04", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-04", "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-05", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-05", "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-05", "habit_name": "Write Journal", "completed": false}, - {"date": "2024-02-06", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-06", "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-07", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-07", "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-08", "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-02-08", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-09", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-09", "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-10", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-10", "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-03-01", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-01", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-02", "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-02", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-03", "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-03-03", "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-04", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-04", "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-04", "habit_name": "Call Family", "completed": true}, - {"date": "2024-03-05", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-05", "habit_name": "Write Journal", "completed": false}, - {"date": "2024-03-06", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-06", "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-07", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-07", "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-08", "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-03-08", "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-09", "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-09", "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-10", "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-10", "habit_name": "Call Family", "completed": true} - ] - } - ], - "variables": [ - { - "variableId": "selectedMonth", - "type": "string", - "initialValue": "2024-01" - }, - { - "variableId": "filteredProgressData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["progressDataTable"], - "variableDependencies": ["selectedMonth"], - "dataFrameTransformations": [ - { - "type": "filter", - "expr": "slice(datum.date, 0, 7) === selectedMonth" - } - ] - } - }, - { - "variableId": "dailyCompletionData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["sum", "count"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["completed_count", "total_habits"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_habits", - "as": "completion_rate" - } - ] - } - }, - { - "variableId": "annualCompletionData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["progressDataTable"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["sum", "count"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["completed_count", "total_habits"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_habits", - "as": "completion_rate" - } - ] - } - }, - { - "variableId": "totalHabits", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "length(data('habitsDataTable'))" - } - }, - { - "variableId": "completionRateData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "ops": ["count", "sum"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["total_entries", "completed_count"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_entries * 100", - "as": "completion_rate" - } - ] - } - }, - { - "variableId": "overallCompletionRate", - "type": "string", - "initialValue": "0%", - "calculation": { - "vegaExpression": "format(data('completionRateData')[0] ? data('completionRateData')[0].completion_rate : 0, '.1f') + '%'" - } - }, - { - "variableId": "activeDaysData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["count"], - "fields": ["habit_name"], - "as": ["habits_tracked"] - } - ] - } - }, - { - "variableId": "totalActiveDays", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "length(data('activeDaysData'))" - } - }, - { - "variableId": "totalCompletedEntries", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "filter", - "expr": "datum.completed === true" - }, - { - "type": "aggregate", - "ops": ["count"], - "fields": ["completed"], - "as": ["completed_count"] - } - ] - } - }, - { - "variableId": "totalCompleted", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" - } - }, - { - "variableId": "enrichedProgressData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": [ - "progressDataTable" - ], - "dataFrameTransformations": [ - { - "type": "lookup", - "from": "habitsDataTable", - "key": "habit_name", - "fields": [ - "habit_name" - ], - "values": ["category", "target_frequency"] - }, - { - "type": "formula", - "expr": "datum.category || 'unknown'", - "as": "category" - } - ] - } - } - ], - "groups": [ - { - "groupId": "header", - "elements": [ - "# 🎯 Complete Habit Tracker", - "Track your daily habits with monthly filtering and annual insights for building consistent routines." - ] - }, - { - "groupId": "controls", - "elements": [ - "## 🎛️ Filters", - "", - { - "type": "dropdown", - "variableId": "selectedMonth", - "label": "Select Month:", - "dynamicOptions": { - "dataSourceName": "monthOptions", - "fieldName": "value" - } - } - ] - }, - { - "groupId": "heatmap", - "elements": [ - "## 🗓️ Monthly Habit Completion", - { - "type": "chart", - "chartKey": "monthlyHeatmap" - } - ] - }, - { - "groupId": "habits", - "elements": [ - "## 📋 My Habits", - { - "type": "tabulator", - "dataSourceName": "habitsData", - "variableId": "habitsDataTable", - "editable": true, - "tabulatorOptions": { - "columns": [ - {"field": "habit_name", "title": "Habit", "width": 200, "editor": "input"}, - {"field": "category", "title": "Category", "width": 120, "editor": "input"}, - {"field": "target_frequency", "title": "Target", "width": 150, "editor": "input"} - ], - "layout": "fitColumns", - "height": "300px", - "rowHeader": { - "width": 40, - "hozAlign": "center", - "formatter": "rownum" - } - } - } - ] - }, - { - "groupId": "progress", - "elements": [ - "## 📈 Progress", - { - "type": "tabulator", - "dataSourceName": "progressData", - "variableId": "progressDataTable", - "editable": true, - "tabulatorOptions": { - "columns": [ - {"field": "date", "title": "Date", "width": 100, "editor": "date"}, - {"field": "habit_name", "title": "Habit", "width": 150, "editor": "input"}, - {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross", "editor": "tickCross"} - ], - "layout": "fitColumns", - "height": "300px", - "initialSort": [ - {"column": "date", "dir": "desc"} - ] - } - } - ] - }, - { - "groupId": "stats", - "elements": [ - "## 📊 Statistics", - "", - "**Active Habits:** {{totalHabits}}", - "", - "**Completion Rate:** {{overallCompletionRate}}", - "", - "**Days Tracked:** {{totalActiveDays}}", - "", - "**Total Completed:** {{totalCompleted}} habits" - ] - }, - { - "groupId": "annual", - "elements": [ - "## 📅 Annual Calendar View", - { - "type": "chart", - "chartKey": "annualHeatmap" - } - ] - }, - { - "groupId": "debug", - "elements": [ - "## 🔍 Debug: Progress with Categories", - { - "type": "tabulator", - "dataSourceName": "enrichedProgressData", - "tabulatorOptions": { - "columns": [ - {"field": "date", "title": "Date", "width": 100}, - {"field": "habit_name", "title": "Habit", "width": 150}, - {"field": "category", "title": "Category", "width": 100}, - {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross"} - ], - "layout": "fitColumns", - "height": "200px", - "initialSort": [ - {"column": "date", "dir": "desc"} - ] - } - } - ] - } - ], - "resources": { - "charts": { - "monthlyHeatmap": { - "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "filteredProgressData"}, - "title": "Monthly progress by category", - "config": { - "view": { - "strokeWidth": 0, - "step": 13 - }, - "axis": { - "domain": false - } - }, - "mark": "rect", - "transform": [ - {"calculate": "datum.completed ? 1 : 0", "as": "completed_numeric"} - ], - "encoding": { - "x": { - "field": "date", - "timeUnit": "date", - "type": "ordinal", - "title": "Day", - "axis": { - "labelAngle": 0, - "format": "%e" - }, - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - } - }, - "color": { - "field": "completed_numeric", - "aggregate": "mean", - "type": "quantitative", - "scale": { - "scheme": "greens", - "domain": [0, 1] - }, - "legend": { - "title": "% complete", - "format": ".0%" - } - }, - "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed_numeric", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} - ] - }, - "width": "container", - "height": 100 - }, - "annualHeatmap": { - "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "progressDataTable"}, - "title": "Annual progress", - "config": { - "view": { - "strokeWidth": 0, - "step": 13 - }, - "axis": { - "domain": false - } - }, - "mark": "rect", - "transform": [ - {"calculate": "datum.completed ? 1 : 0", "as": "completed_numeric"} - ], - "encoding": { - "x": { - "field": "date", - "timeUnit": "date", - "type": "ordinal", - "title": "Day", - "axis": { - "labelAngle": 0, - "format": "%e" - }, - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - } - }, - "y": { - "field": "date", - "timeUnit": "month", - "type": "ordinal", - "title": "Month" - }, - "color": { - "field": "completed_numeric", - "aggregate": "mean", - "type": "quantitative", - "scale": { - "scheme": "blues", - "domain": [0, 1] - }, - "legend": { - "title": "% complete", - "format": ".0%" - } - }, - "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed_numeric", "aggregate": "mean", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} - ] - }, - "width": "container", - "height": 150 - } - } - } -} \ No newline at end of file diff --git a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json b/packages/web-deploy/json/habit-tracker-enhanced.idoc.json deleted file mode 100644 index f2280a71..00000000 --- a/packages/web-deploy/json/habit-tracker-enhanced.idoc.json +++ /dev/null @@ -1,627 +0,0 @@ -{ - "$schema": "../../../docs/schema/idoc_v1.json", - "title": "Enhanced Habit Tracker", - "style": { - "css": [ - "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", - "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'alltime alltime'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1400px; margin: 0 auto; }", - "@media (max-width: 768px) { body { grid-template-areas: 'header' 'controls' 'heatmap' 'habits' 'progress' 'stats' 'alltime'; grid-template-columns: 1fr; } }", - ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", - "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", - "#controls { grid-area: controls; }", - "#heatmap { grid-area: heatmap; }", - "#habits { grid-area: habits; }", - "#progress { grid-area: progress; }", - "#stats { grid-area: stats; }", - "#alltime { grid-area: alltime; }", - "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", - "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", - "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", - ".tabulator { border-radius: 8px; overflow: hidden; }", - ".tabulator .tabulator-header { background: #f7fafc; }", - ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", - ".tabulator .tabulator-row { border-bottom: 1px solid #f1f5f9; }", - ".tabulator .tabulator-row:hover { background: #f8fafc; }" - ] - }, - "dataLoaders": [ - { - "dataSourceName": "monthOptions", - "type": "inline", - "format": "json", - "content": [ - {"value": "2024-01", "label": "January 2024"}, - {"value": "2024-02", "label": "February 2024"}, - {"value": "2024-03", "label": "March 2024"} - ] - }, - { - "dataSourceName": "habitsData", - "type": "inline", - "format": "json", - "content": [ - { - "habit_id": 1, - "habit_name": "Morning Exercise", - "category": "Health", - "target_frequency": "Daily" - }, - { - "habit_id": 2, - "habit_name": "Read for 30min", - "category": "Learning", - "target_frequency": "Daily" - }, - { - "habit_id": 3, - "habit_name": "Meditate", - "category": "Wellness", - "target_frequency": "Daily" - }, - { - "habit_id": 4, - "habit_name": "Write Journal", - "category": "Wellness", - "target_frequency": "Daily" - }, - { - "habit_id": 5, - "habit_name": "Learn New Language", - "category": "Learning", - "target_frequency": "3x per week" - }, - { - "habit_id": 6, - "habit_name": "Call Family", - "category": "Social", - "target_frequency": "Weekly" - } - ] - }, - { - "dataSourceName": "progressData", - "type": "inline", - "format": "json", - "content": [ - {"date": "2024-01-15", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-15", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-15", "habit_id": 3, "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-16", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-16", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-16", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-16", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-17", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-17", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-17", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-18", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-18", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-18", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-18", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-01-19", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-19", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-19", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-19", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-01-19", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-01-20", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-22", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-22", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-23", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-23", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-24", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-24", "habit_id": 3, "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-25", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-25", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-26", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-26", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-27", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-27", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-28", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-28", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-01", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-02", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-02", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-03", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-02-03", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-04", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-05", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-05", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-02-06", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-06", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-07", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-07", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-08", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-02-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-09", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-10", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-10", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-03-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-02", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-03", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-03-03", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-04", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-04", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-03-05", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-03-06", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-06", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-07", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-07", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-08", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-03-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-09", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-10", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-10", "habit_id": 6, "habit_name": "Call Family", "completed": true} - ] - } - ], - "variables": [ - { - "variableId": "selectedMonth", - "type": "string", - "initialValue": "2024-01" - }, - { - "variableId": "enrichedProgressData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["progressData", "habitsData"], - "dataFrameTransformations": [ - { - "type": "lookup", - "from": "habitsData", - "key": "habit_id", - "fields": ["category", "target_frequency"], - "as": ["category", "target_frequency"] - } - ] - } - }, - { - "variableId": "filteredProgressData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["enrichedProgressData"], - "dataFrameTransformations": [ - { - "type": "filter", - "expr": "slice(datum.date, 0, 7) === selectedMonth" - } - ] - } - }, - { - "variableId": "monthlyHeatmapData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "groupby": ["date", "category"], - "ops": ["sum", "count"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["completed_count", "total_habits"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_habits", - "as": "completion_rate" - }, - { - "type": "formula", - "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", - "as": "date_parsed" - }, - { - "type": "formula", - "expr": "date(datum.date)", - "as": "day_of_month" - } - ] - } - }, - { - "variableId": "allTimeHeatmapData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["enrichedProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["sum", "count"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["completed_count", "total_habits"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_habits", - "as": "completion_rate" - }, - { - "type": "formula", - "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", - "as": "date_parsed" - }, - { - "type": "formula", - "expr": "date(datum.date)", - "as": "day_of_month" - }, - { - "type": "formula", - "expr": "timeFormat(datum.date, '%B')", - "as": "month_name" - } - ] - } - }, - { - "variableId": "totalHabits", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "length(data('habitsDataTable'))" - } - }, - { - "variableId": "completionRateData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "ops": ["count", "sum"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["total_entries", "completed_count"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_entries * 100", - "as": "completion_rate" - } - ] - } - }, - { - "variableId": "overallCompletionRate", - "type": "string", - "initialValue": "0%", - "calculation": { - "vegaExpression": "format(data('completionRateData')[0] ? data('completionRateData')[0].completion_rate : 0, '.1f') + '%'" - } - }, - { - "variableId": "activeDaysData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["count"], - "fields": ["habit_id"], - "as": ["habits_tracked"] - } - ] - } - }, - { - "variableId": "totalActiveDays", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "length(data('activeDaysData'))" - } - }, - { - "variableId": "totalCompletedEntries", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "filter", - "expr": "datum.completed === true" - }, - { - "type": "aggregate", - "ops": ["count"], - "fields": ["completed"], - "as": ["completed_count"] - } - ] - } - }, - { - "variableId": "totalCompleted", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" - } - } - ], - "groups": [ - { - "groupId": "header", - "elements": [ - "# 🎯 Enhanced Habit Tracker", - "Track your daily habits with category-based insights and comprehensive visualizations." - ] - }, - { - "groupId": "controls", - "elements": [ - "## 🎛️ Month Filter", - "", - { - "type": "dropdown", - "variableId": "selectedMonth", - "label": "Select Month:", - "dynamicOptions": { - "dataSourceName": "monthOptions", - "fieldName": "value" - } - } - ] - }, - { - "groupId": "heatmap", - "elements": [ - "## 🗓️ Monthly Completion Calendar", - { - "type": "chart", - "chartKey": "monthlyHeatmap" - } - ] - }, - { - "groupId": "habits", - "elements": [ - "## 📋 My Habits", - { - "type": "tabulator", - "dataSourceName": "habitsData", - "variableId": "habitsDataTable", - "editable": true, - "tabulatorOptions": { - "columns": [ - {"field": "habit_name", "title": "Habit", "width": 200, "editor": "input"}, - {"field": "category", "title": "Category", "width": 120, "editor": "input"}, - {"field": "target_frequency", "title": "Target", "width": 150, "editor": "input"} - ], - "layout": "fitColumns", - "height": "300px", - "rowHeader": { - "width": 40, - "hozAlign": "center", - "formatter": "rownum" - } - } - } - ] - }, - { - "groupId": "progress", - "elements": [ - "## 📈 Progress", - { - "type": "tabulator", - "dataSourceName": "progressData", - "variableId": "progressDataTable", - "editable": true, - "tabulatorOptions": { - "columns": [ - {"field": "date", "title": "Date", "width": 100, "editor": "date"}, - {"field": "habit_name", "title": "Habit", "width": 150, "editor": "input"}, - {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross", "editor": "tickCross"} - ], - "layout": "fitColumns", - "height": "300px", - "initialSort": [ - {"column": "date", "dir": "desc"} - ] - } - } - ] - }, - { - "groupId": "stats", - "elements": [ - "## 📊 Monthly Statistics", - "", - "**Active Habits:** {{totalHabits}}", - "", - "**Completion Rate:** {{overallCompletionRate}}", - "", - "**Days Tracked:** {{totalActiveDays}}", - "", - "**Total Completed:** {{totalCompleted}} habits" - ] - }, - { - "groupId": "alltime", - "elements": [ - "## 🌟 Annual Habit Performance", - { - "type": "chart", - "chartKey": "allTimeHeatmap" - } - ] - } - ], - "resources": { - "charts": { - "monthlyHeatmap": { - "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "monthlyHeatmapData"}, - "title": "Daily Completion Rate by Category - Selected Month", - "config": { - "view": { - "strokeWidth": 0, - "step": 18 - }, - "axis": { - "domain": false - } - }, - "mark": { - "type": "rect", - "stroke": "#ffffff", - "strokeWidth": 2, - "opacity": 0.8 - }, - "encoding": { - "x": { - "field": "day_of_month", - "type": "ordinal", - "title": "Day of Month", - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - }, - "axis": { - "labelAngle": 0 - } - }, - "y": { - "field": "category", - "type": "nominal", - "title": "Category", - "sort": ["Health", "Learning", "Wellness", "Social"] - }, - "color": { - "field": "completion_rate", - "type": "quantitative", - "scale": { - "scheme": "greens", - "domain": [0, 1] - }, - "legend": { - "title": "Completion Rate", - "format": ".0%" - } - }, - "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "category", "type": "nominal", "title": "Category"}, - {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, - {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, - {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} - ] - }, - "width": "container", - "height": 120, - "background": "transparent" - }, - "allTimeHeatmap": { - "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "allTimeHeatmapData"}, - "title": "Annual Completion Calendar - All Categories", - "config": { - "view": { - "strokeWidth": 0, - "step": 13 - }, - "axis": { - "domain": false - } - }, - "mark": { - "type": "rect", - "stroke": "#ffffff", - "strokeWidth": 1, - "opacity": 0.8 - }, - "encoding": { - "x": { - "field": "day_of_month", - "type": "ordinal", - "title": "Day of Month", - "scale": { - "domain": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] - }, - "axis": { - "labelAngle": 0 - } - }, - "y": { - "field": "month_name", - "type": "nominal", - "title": "Month", - "sort": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] - }, - "color": { - "field": "completion_rate", - "type": "quantitative", - "scale": { - "scheme": "viridis", - "domain": [0, 1] - }, - "legend": { - "title": "Completion Rate", - "format": ".0%" - } - }, - "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "month_name", "type": "nominal", "title": "Month"}, - {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, - {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, - {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} - ] - }, - "width": "container", - "height": 150, - "background": "transparent" - } - } - } -} \ No newline at end of file diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker-simple.idoc.json index ec7cb8d4..3ca5940c 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker-simple.idoc.json @@ -4,21 +4,21 @@ "style": { "css": [ "body { font-family: sans-serif; margin: 0; padding: 20px; background: #f8fafc; max-width: 1200px; margin: 0 auto; }", - "#header, #habits, #table, #monthly, #heatmap { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", + "#header, #habits, #table, #monthly, #annual { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", "#header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white; text-align: center; }", "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", ".tabulator { max-width: 100%; overflow: auto; }", ".tabulator .tabulator-table { min-width: fit-content; }", "#heatmap .vega-embed .vega-actions { display: none; }", - "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'habits table' 'monthly monthly' 'heatmap heatmap'; }", + "body { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; grid-template-areas: 'header header' 'habits table' 'monthly monthly' 'annual annual'; }", "#header { grid-area: header; }", "#habits { grid-area: habits; min-width: 0; }", "#table { grid-area: table; min-width: 0; }", "#monthly { grid-area: monthly; min-width: 0; overflow: hidden; }", - "#heatmap { grid-area: heatmap; min-width: 0; overflow: hidden; }", - "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'monthly' 'heatmap'; } }" + "#annual { grid-area: annual; min-width: 0; overflow: hidden; }", + "@media (max-width: 768px) { body { grid-template-columns: 1fr; grid-template-areas: 'header' 'habits' 'table' 'monthly' 'annual'; } }" ] }, "dataLoaders": [ @@ -555,7 +555,7 @@ ] }, { - "groupId": "heatmap", + "groupId": "annual", "elements": [ "## 🗓️ Annual Calendar View", { diff --git a/packages/web-deploy/json/habit-tracker.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json deleted file mode 100644 index 675c04d2..00000000 --- a/packages/web-deploy/json/habit-tracker.idoc.json +++ /dev/null @@ -1,498 +0,0 @@ -{ - "$schema": "../../../docs/schema/idoc_v1.json", - "title": "Habit Tracker", - "style": { - "css": [ - "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f8fafc; }", - "body { display: grid; grid-template-areas: 'header header' 'controls controls' 'heatmap heatmap' 'habits progress' 'stats stats' 'debug debug'; grid-template-columns: 1fr 1fr; gap: 20px; max-width: 1200px; margin: 0 auto; }", - ".group { background: white; padding: 20px; border-radius: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border: 1px solid #e2e8f0; }", - "#header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; border-radius: 12px; }", - "#controls { grid-area: controls; }", - "#heatmap { grid-area: heatmap; }", - "#habits { grid-area: habits; }", - "#progress { grid-area: progress; }", - "#stats { grid-area: stats; }", - "#debug { grid-area: debug; }", - "h1 { margin: 0; padding: 20px 0; font-size: 2em; font-weight: 600; }", - "h2 { margin: 0 0 15px 0; font-size: 1.4em; color: #2d3748; font-weight: 600; }", - "h3 { margin: 0 0 10px 0; font-size: 1.1em; color: #4a5568; font-weight: 500; }", - ".tabulator { border-radius: 8px; overflow: hidden; }", - ".tabulator .tabulator-header { background: #f7fafc; }", - ".tabulator .tabulator-header .tabulator-col { border-right: 1px solid #e2e8f0; }", - ".tabulator .tabulator-row { border-bottom: 1px solid #f1f5f9; }", - ".tabulator .tabulator-row:hover { background: #f8fafc; }" - ] - }, - "dataLoaders": [ - { - "dataSourceName": "monthOptions", - "type": "inline", - "format": "json", - "content": [ - {"value": "All", "label": "All Months"}, - {"value": "2024-01", "label": "January 2024"}, - {"value": "2024-02", "label": "February 2024"}, - {"value": "2024-03", "label": "March 2024"} - ] - }, - { - "dataSourceName": "habitsData", - "type": "inline", - "format": "json", - "content": [ - { - "habit_id": 1, - "habit_name": "Morning Exercise", - "category": "Health", - "target_frequency": "Daily" - }, - { - "habit_id": 2, - "habit_name": "Read for 30min", - "category": "Learning", - "target_frequency": "Daily" - }, - { - "habit_id": 3, - "habit_name": "Meditate", - "category": "Wellness", - "target_frequency": "Daily" - }, - { - "habit_id": 4, - "habit_name": "Write Journal", - "category": "Wellness", - "target_frequency": "Daily" - }, - { - "habit_id": 5, - "habit_name": "Learn New Language", - "category": "Learning", - "target_frequency": "3x per week" - }, - { - "habit_id": 6, - "habit_name": "Call Family", - "category": "Social", - "target_frequency": "Weekly" - } - ] - }, - { - "dataSourceName": "progressData", - "type": "inline", - "format": "json", - "content": [ - {"date": "2024-01-15", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-15", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-15", "habit_id": 3, "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-16", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-16", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-16", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-16", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-17", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-17", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-17", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-17", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-18", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-18", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-18", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-18", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-01-19", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-19", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-19", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-19", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-01-19", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-01-20", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-20", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-01-20", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-21", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-22", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-22", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-22", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-23", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-23", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-24", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-24", "habit_id": 3, "habit_name": "Meditate", "completed": false}, - {"date": "2024-01-25", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-01-25", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-01-26", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-01-26", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-27", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-01-27", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-01-28", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-01-28", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-01", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-02", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-02", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-03", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-02-03", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-04", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-02-05", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-05", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-02-06", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-06", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-02-07", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-07", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-08", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-02-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-02-09", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-02-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-02-10", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-02-10", "habit_id": 5, "habit_name": "Learn New Language", "completed": false}, - {"date": "2024-03-01", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-01", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-02", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-02", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-03", "habit_id": 1, "habit_name": "Morning Exercise", "completed": false}, - {"date": "2024-03-03", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-04", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-04", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-04", "habit_id": 6, "habit_name": "Call Family", "completed": true}, - {"date": "2024-03-05", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-05", "habit_id": 4, "habit_name": "Write Journal", "completed": false}, - {"date": "2024-03-06", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-06", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-07", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-07", "habit_id": 5, "habit_name": "Learn New Language", "completed": true}, - {"date": "2024-03-08", "habit_id": 2, "habit_name": "Read for 30min", "completed": false}, - {"date": "2024-03-08", "habit_id": 4, "habit_name": "Write Journal", "completed": true}, - {"date": "2024-03-09", "habit_id": 1, "habit_name": "Morning Exercise", "completed": true}, - {"date": "2024-03-09", "habit_id": 3, "habit_name": "Meditate", "completed": true}, - {"date": "2024-03-10", "habit_id": 2, "habit_name": "Read for 30min", "completed": true}, - {"date": "2024-03-10", "habit_id": 6, "habit_name": "Call Family", "completed": true} - ] - } - ], - "variables": [ - { - "variableId": "selectedMonth", - "type": "string", - "initialValue": "All" - }, - { - "variableId": "filteredProgressData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["progressDataTable"], - "dataFrameTransformations": [ - { - "type": "filter", - "expr": "selectedMonth === 'All' || slice(datum.date, 0, 7) === selectedMonth" - } - ] - } - }, - { - "variableId": "dailyCompletionData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["sum", "count"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["completed_count", "total_habits"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_habits", - "as": "completion_rate" - }, - { - "type": "formula", - "expr": "datetime(year(datum.date), month(datum.date), date(datum.date))", - "as": "date_parsed" - } - ] - } - }, - { - "variableId": "totalHabits", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "length(data('habitsDataTable'))" - } - }, - { - "variableId": "completionRateData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "formula", - "expr": "datum.completed ? 1 : 0", - "as": "completed_numeric" - }, - { - "type": "aggregate", - "ops": ["count", "sum"], - "fields": ["completed_numeric", "completed_numeric"], - "as": ["total_entries", "completed_count"] - }, - { - "type": "formula", - "expr": "datum.completed_count / datum.total_entries * 100", - "as": "completion_rate" - } - ] - } - }, - { - "variableId": "overallCompletionRate", - "type": "string", - "initialValue": "0%", - "calculation": { - "vegaExpression": "format(data('completionRateData')[0] ? data('completionRateData')[0].completion_rate : 0, '.1f') + '%'" - } - }, - { - "variableId": "activeDaysData", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "aggregate", - "groupby": ["date"], - "ops": ["count"], - "fields": ["habit_id"], - "as": ["habits_tracked"] - } - ] - } - }, - { - "variableId": "totalActiveDays", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "length(data('activeDaysData'))" - } - }, - { - "variableId": "totalCompletedEntries", - "type": "object", - "isArray": true, - "initialValue": [], - "calculation": { - "dataSourceNames": ["filteredProgressData"], - "dataFrameTransformations": [ - { - "type": "filter", - "expr": "datum.completed === true" - }, - { - "type": "aggregate", - "ops": ["count"], - "fields": ["completed"], - "as": ["completed_count"] - } - ] - } - }, - { - "variableId": "totalCompleted", - "type": "number", - "initialValue": 0, - "calculation": { - "vegaExpression": "data('totalCompletedEntries')[0] ? data('totalCompletedEntries')[0].completed_count : 0" - } - } - ], - "groups": [ - { - "groupId": "header", - "elements": [ - "# 🎯 Habit Tracker", - "Track your daily habits and build consistent routines for personal growth." - ] - }, - { - "groupId": "controls", - "elements": [ - "## 🎛️ Filters", - "", - { - "type": "dropdown", - "variableId": "selectedMonth", - "label": "Select Month:", - "dynamicOptions": { - "dataSourceName": "monthOptions", - "fieldName": "value" - } - } - ] - }, - { - "groupId": "heatmap", - "elements": [ - "## 🗓️ Habit Completion Heatmap", - { - "type": "chart", - "chartKey": "heatmap" - } - ] - }, - { - "groupId": "habits", - "elements": [ - "## 📋 My Habits", - { - "type": "tabulator", - "dataSourceName": "habitsData", - "variableId": "habitsDataTable", - "editable": true, - "tabulatorOptions": { - "columns": [ - {"field": "habit_name", "title": "Habit", "width": 200, "editor": "input"}, - {"field": "category", "title": "Category", "width": 120, "editor": "input"}, - {"field": "target_frequency", "title": "Target", "width": 150, "editor": "input"} - ], - "layout": "fitColumns", - "height": "300px", - "rowHeader": { - "width": 40, - "hozAlign": "center", - "formatter": "rownum" - } - } - } - ] - }, - { - "groupId": "progress", - "elements": [ - "## 📈 Progress (Filtered by Month)", - { - "type": "tabulator", - "dataSourceName": "progressData", - "variableId": "progressDataTable", - "editable": true, - "tabulatorOptions": { - "columns": [ - {"field": "date", "title": "Date", "width": 100, "editor": "date"}, - {"field": "habit_name", "title": "Habit", "width": 150, "editor": "input"}, - {"field": "completed", "title": "✓", "width": 50, "hozAlign": "center", "formatter": "tickCross", "editor": "tickCross"} - ], - "layout": "fitColumns", - "height": "300px", - "initialSort": [ - {"column": "date", "dir": "desc"} - ] - } - } - ] - }, - { - "groupId": "stats", - "elements": [ - "## 📊 Statistics", - "", - "**Active Habits:** {{totalHabits}}", - "", - "**Completion Rate:** {{overallCompletionRate}}", - "", - "**Days Tracked:** {{totalActiveDays}}", - "", - "**Total Completed:** {{totalCompleted}} habits" - ] - }, - { - "groupId": "debug", - "elements": [ - "## 🔍 Debug: Daily Completion Data", - { - "type": "tabulator", - "dataSourceName": "dailyCompletionData" - } - ] - } - ], - "resources": { - "charts": { - "heatmap": { - "$schema": "https://vega.github.io/schema/vega-lite/v5.json", - "data": {"name": "dailyCompletionData"}, - "title": "Daily Habit Completion Rate", - "config": { - "view": { - "strokeWidth": 0, - "step": 13 - }, - "axis": { - "domain": false - } - }, - "mark": { - "type": "rect", - "stroke": "#ffffff", - "strokeWidth": 2, - "opacity": 0.8 - }, - "encoding": { - "x": { - "field": "date", - "timeUnit": "date", - "type": "temporal", - "title": "Day of Month", - "axis": { - "labelAngle": 0, - "format": "%e" - } - }, - "y": { - "field": "date", - "timeUnit": "month", - "type": "temporal", - "title": "Month" - }, - "color": { - "field": "completion_rate", - "type": "quantitative", - "scale": { - "scheme": "greens", - "domain": [0, 1] - }, - "legend": { - "title": "Completion Rate", - "format": ".0%" - } - }, - "tooltip": [ - {"field": "date", "type": "temporal", "title": "Date"}, - {"field": "completed_count", "type": "quantitative", "title": "Completed Habits"}, - {"field": "total_habits", "type": "quantitative", "title": "Total Habits"}, - {"field": "completion_rate", "type": "quantitative", "title": "Completion Rate", "format": ".1%"} - ] - }, - "width": "container", - "height": 150, - "background": "transparent" - } - } - } -} \ No newline at end of file From 87d1794e1e0d6f7503d98e6bd76eb4c898d8df3d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:55:55 +0000 Subject: [PATCH 45/45] Remove 'simple' from habit tracker filename and content Co-authored-by: danmarshall <11507384+danmarshall@users.noreply.github.com> --- ...habit-tracker-simple.idoc.json => habit-tracker.idoc.json} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename packages/web-deploy/json/{habit-tracker-simple.idoc.json => habit-tracker.idoc.json} (99%) diff --git a/packages/web-deploy/json/habit-tracker-simple.idoc.json b/packages/web-deploy/json/habit-tracker.idoc.json similarity index 99% rename from packages/web-deploy/json/habit-tracker-simple.idoc.json rename to packages/web-deploy/json/habit-tracker.idoc.json index 3ca5940c..ab42dde3 100644 --- a/packages/web-deploy/json/habit-tracker-simple.idoc.json +++ b/packages/web-deploy/json/habit-tracker.idoc.json @@ -1,6 +1,6 @@ { "$schema": "../../../docs/schema/idoc_v1.json", - "title": "Simple Habit Tracker", + "title": "Habit Tracker", "style": { "css": [ "body { font-family: sans-serif; margin: 0; padding: 20px; background: #f8fafc; max-width: 1200px; margin: 0 auto; }", @@ -496,7 +496,7 @@ { "groupId": "header", "elements": [ - "# 🎯 Simple Habit Tracker", + "# 🎯 Habit Tracker", "A minimal habit tracker with editable data and heatmap visualization." ] },