@@ -597,10 +597,16 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
597597 </div>
598598 </div>
599599 <div class="chart-container">
600- <div class="chart-title">Daily Summary (Last 7 Days)</div>
600+ <div class="chart-title">Daily Summary (Last 30 Days)</div>
601601 <div class="chart-wrapper">
602602 <canvas id="dailyChart"></canvas>
603603 </div>
604+ <div class="chart-container search-results-chart">
605+ <div class="chart-title">Project Distribution</div>
606+ <div class="chart-wrapper">
607+ <canvas id="searchChart"></canvas>
608+ </div>
609+ </div>
604610 </div>
605611 \`;
606612
@@ -644,11 +650,11 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
644650 }
645651 });
646652
647- // Daily summary chart
653+ // Daily summary chart - showing last 30 days
648654 const dailyCtx = document.getElementById('dailyChart').getContext('2d');
649655 const dailyData = Object.entries(data.dailySummary)
650656 .sort((a, b) => new Date(a[0]).getTime() - new Date(b[0]).getTime())
651- .slice(-7);
657+ .slice(-30); // Show last 30 days instead of 7
652658
653659 new Chart(dailyCtx, {
654660 type: 'line',
@@ -702,6 +708,71 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
702708 }
703709 }
704710 });
711+
712+ // Initialize the search chart with all data
713+ const searchCtx = document.getElementById('searchChart').getContext('2d');
714+ const allProjectData = Object.entries(data.projectSummary)
715+ .sort((a, b) => b[1] - a[1]);
716+
717+ new Chart(searchCtx, {
718+ type: 'pie',
719+ data: {
720+ labels: allProjectData.map(([project]) => project),
721+ datasets: [{
722+ data: allProjectData.map(([_, minutes]) => ({
723+ value: minutes,
724+ hours: Math.floor(minutes / 60),
725+ mins: Math.round(minutes % 60)
726+ })),
727+ backgroundColor: [
728+ 'rgba(255, 99, 132, 0.7)', // Red
729+ 'rgba(54, 162, 235, 0.7)', // Blue
730+ 'rgba(255, 206, 86, 0.7)', // Yellow
731+ 'rgba(75, 192, 192, 0.7)', // Teal
732+ 'rgba(153, 102, 255, 0.7)', // Purple
733+ 'rgba(255, 159, 64, 0.7)', // Orange
734+ 'rgba(199, 199, 199, 0.7)', // Gray
735+ 'rgba(83, 102, 255, 0.7)', // Indigo
736+ 'rgba(40, 167, 69, 0.7)', // Green
737+ 'rgba(220, 53, 69, 0.7)' // Dark Red
738+ ],
739+ borderColor: chartColors.background,
740+ borderWidth: 1
741+ }]
742+ },
743+ options: {
744+ responsive: true,
745+ maintainAspectRatio: false,
746+ plugins: {
747+ legend: {
748+ position: 'right',
749+ labels: {
750+ color: chartColors.text,
751+ font: {
752+ size: 12,
753+ weight: '500'
754+ },
755+ padding: 20,
756+ usePointStyle: true
757+ }
758+ },
759+ tooltip: {
760+ backgroundColor: isDarkTheme ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)',
761+ titleColor: chartColors.text,
762+ bodyColor: chartColors.text,
763+ borderColor: chartColors.grid,
764+ borderWidth: 1,
765+ padding: 12,
766+ callbacks: {
767+ label: function(context) {
768+ const data = context.raw;
769+ return \`\${context.label}: \${data.hours} hour\${data.hours !== 1 ? 's' : ''} and \${data.mins} minute\${data.mins !== 1 ? 's' : ''}\`;
770+ }
771+ }
772+ }
773+ }
774+ }
775+ });
705776 }
706777
707778 function displaySearchResult(entries) {
@@ -710,31 +781,151 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
710781 content.innerHTML = '<p>No results found.</p>';
711782 return;
712783 }
713-
784+
785+ // Calculate data for all charts
714786 let totalTime = 0;
715- const searchData = entries.reduce((acc, entry) => {
787+ const projectData = {};
788+ const dailyData = {};
789+
790+ // Process entries for both project and daily summaries
791+ entries.forEach(entry => {
716792 totalTime += entry.timeSpent;
717- if (!acc[entry.project]) {
718- acc[entry.project] = 0;
793+
794+ // Update project data
795+ if (!projectData[entry.project]) {
796+ projectData[entry.project] = 0;
719797 }
720- acc[entry.project] += entry.timeSpent;
721- return acc;
722- }, {});
723-
798+ projectData[entry.project] += entry.timeSpent;
799+
800+ // Update daily data
801+ if (!dailyData[entry.date]) {
802+ dailyData[entry.date] = 0;
803+ }
804+ dailyData[entry.date] += entry.timeSpent;
805+ });
806+
807+ // Update the content with all three charts
724808 content.innerHTML = \`
725- <div class="chart-container search-results-chart">
726- <div class="chart-title">Search Results (Total Time: \${formatTime(totalTime)})</div>
809+ <div class="chart-container">
810+ <div class="chart-title">Project Summary (Filtered)</div>
811+ <div class="chart-wrapper">
812+ <canvas id="projectChart"></canvas>
813+ </div>
814+ </div>
815+ <div class="chart-container">
816+ <div class="chart-title">Daily Summary (Filtered)</div>
817+ <div class="chart-wrapper">
818+ <canvas id="dailyChart"></canvas>
819+ </div>
820+ </div>
821+ <div class="chart-container">
822+ <div class="chart-title">Project Distribution (Total Time: \${formatTime(totalTime)})</div>
727823 <div class="chart-wrapper">
728824 <canvas id="searchChart"></canvas>
729825 </div>
730826 </div>
731827 \`;
732-
733- // Create search results chart
828+
829+ // Create Project Summary Bar Chart
830+ const projectCtx = document.getElementById('projectChart').getContext('2d');
831+ const projectChartData = Object.entries(projectData)
832+ .sort((a, b) => b[1] - a[1])
833+ .slice(0, 5);
834+
835+ new Chart(projectCtx, {
836+ type: 'bar',
837+ data: {
838+ labels: projectChartData.map(([project]) => project),
839+ datasets: [{
840+ label: 'Coding Time',
841+ data: projectChartData.map(([_, time]) => time/60),
842+ backgroundColor: chartColors.chartBlues,
843+ borderColor: chartColors.grid,
844+ borderWidth: 1
845+ }]
846+ },
847+ options: {
848+ ...commonChartConfig,
849+ indexAxis: 'y',
850+ plugins: {
851+ ...commonChartConfig.plugins,
852+ tooltip: {
853+ ...commonChartConfig.plugins.tooltip,
854+ callbacks: {
855+ label: function(context) {
856+ const hours = Math.floor(context.raw);
857+ const mins = Math.round((context.raw % 1) * 60);
858+ return \`\${context.label}: \${hours} hour\${hours !== 1 ? 's' : ''} and \${mins} minute\${mins !== 1 ? 's' : ''}\`;
859+ }
860+ }
861+ }
862+ }
863+ }
864+ });
865+
866+ // Create Daily Summary Line Chart
867+ const dailyCtx = document.getElementById('dailyChart').getContext('2d');
868+ const dailyChartData = Object.entries(dailyData)
869+ .sort((a, b) => new Date(a[0]).getTime() - new Date(b[0]).getTime());
870+
871+ new Chart(dailyCtx, {
872+ type: 'line',
873+ data: {
874+ labels: dailyChartData.map(([date]) => {
875+ const d = new Date(date);
876+ return d.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
877+ }),
878+ datasets: [{
879+ label: 'Coding Time',
880+ data: dailyChartData.map(([_, time]) => time / 60),
881+ fill: true,
882+ backgroundColor: \`\${chartColors.accent}33\`,
883+ borderColor: chartColors.accent,
884+ borderWidth: 2,
885+ tension: 0.4,
886+ pointBackgroundColor: chartColors.accent,
887+ pointBorderColor: chartColors.background,
888+ pointBorderWidth: 2,
889+ pointRadius: 4,
890+ pointHoverRadius: 6
891+ }]
892+ },
893+ options: {
894+ ...commonChartConfig,
895+ scales: {
896+ ...commonChartConfig.scales,
897+ y: {
898+ ...commonChartConfig.scales.y,
899+ ticks: {
900+ ...commonChartConfig.scales.y.ticks,
901+ callback: function(value) {
902+ return \`\${value}h\`;
903+ }
904+ }
905+ }
906+ },
907+ plugins: {
908+ ...commonChartConfig.plugins,
909+ tooltip: {
910+ ...commonChartConfig.plugins.tooltip,
911+ callbacks: {
912+ label: function(context) {
913+ const hours = Math.floor(context.raw);
914+ const mins = Math.round((context.raw % 1) * 60);
915+ const date = new Date(context.label);
916+ return \`\${date.toLocaleDateString('en-US', { weekday: 'long' })}: \${hours} hour\${hours !== 1 ? 's' : ''} and \${mins} minute\${mins !== 1 ? 's' : ''}\`;
917+ }
918+ }
919+ }
920+ }
921+ }
922+ });
923+
924+ // Create Project Distribution Pie Chart
734925 const searchCtx = document.getElementById('searchChart').getContext('2d');
735- const searchChartData = Object.entries(searchData )
926+ const searchChartData = Object.entries(projectData )
736927 .sort((a, b) => b[1] - a[1]);
737-
928+
738929 new Chart(searchCtx, {
739930 type: 'pie',
740931 data: {
@@ -747,15 +938,15 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
747938 })),
748939 backgroundColor: [
749940 'rgba(255, 99, 132, 0.7)', // Red
750- 'rgba(54, 162, 235, 0.7)', // Blue
751- 'rgba(255, 206, 86, 0.7)', // Yellow
752- 'rgba(75, 192, 192, 0.7)', // Teal
753- 'rgba(153, 102, 255, 0.7)', // Purple
754- 'rgba(255, 159, 64, 0.7)', // Orange
755- 'rgba(199, 199, 199, 0.7)', // Gray
756- 'rgba(83, 102, 255, 0.7)', // Indigo
757- 'rgba(40, 167, 69, 0.7)', // Green
758- 'rgba(220, 53, 69, 0.7)' // Dark Red
941+ 'rgba(54, 162, 235, 0.7)', // Blue
942+ 'rgba(255, 206, 86, 0.7)', // Yellow
943+ 'rgba(75, 192, 192, 0.7)', // Teal
944+ 'rgba(153, 102, 255, 0.7)', // Purple
945+ 'rgba(255, 159, 64, 0.7)', // Orange
946+ 'rgba(199, 199, 199, 0.7)', // Gray
947+ 'rgba(83, 102, 255, 0.7)', // Indigo
948+ 'rgba(40, 167, 69, 0.7)', // Green
949+ 'rgba(220, 53, 69, 0.7)' // Dark Red
759950 ],
760951 borderColor: chartColors.background,
761952 borderWidth: 1
0 commit comments