@@ -789,10 +789,58 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
789789 position: relative;
790790 height: 300px;
791791 width: 100%;
792+ display: flex;
793+ align-items: center;
792794 }
793795 .search-results-chart {
794796 height: 400px;
795797 }
798+ .search-results-chart .chart-wrapper {
799+ height: 350px;
800+ }
801+ .chart-canvas {
802+ flex: 1;
803+ max-width: 60%;
804+ }
805+ .custom-legend {
806+ max-height: 300px;
807+ overflow-y: auto;
808+ overflow-x: hidden;
809+ padding-right: 5px;
810+ padding-left: 10px;
811+ }
812+ .search-results-chart .custom-legend {
813+ max-height: 350px;
814+ }
815+ .custom-legend::-webkit-scrollbar {
816+ width: 6px;
817+ }
818+ .custom-legend::-webkit-scrollbar-track {
819+ background: var(--vscode-scrollbarSlider-background);
820+ border-radius: 3px;
821+ }
822+ .custom-legend::-webkit-scrollbar-thumb {
823+ background: var(--vscode-scrollbarSlider-hoverBackground);
824+ border-radius: 3px;
825+ }
826+ .custom-legend::-webkit-scrollbar-thumb:hover {
827+ background: var(--vscode-scrollbarSlider-activeBackground);
828+ }
829+ .legend-item {
830+ display: flex;
831+ align-items: center;
832+ margin-bottom: 8px;
833+ font-size: 12px;
834+ font-weight: 500;
835+ color: var(--vscode-foreground);
836+ }
837+ .legend-color {
838+ width: 12px;
839+ height: 12px;
840+ border-radius: 50%;
841+ margin-right: 8px;
842+ border: 1px solid var(--vscode-panel-border);
843+ }
796844 </style>
797845 </head>
798846 <body>
@@ -913,7 +961,9 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
913961 <div class="chart-container search-results-chart" style="display: none;">
914962 <div class="chart-title">Search Results</div>
915963 <div class="chart-wrapper">
916- <canvas id="searchChart"></canvas>
964+ <div class="chart-canvas">
965+ <canvas id="searchChart"></canvas>
966+ </div>
917967 </div>
918968 </div>
919969 </div>
@@ -2122,7 +2172,9 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
21222172 <div class="chart-container search-results-chart">
21232173 <div class="chart-title">Project Distribution</div>
21242174 <div class="chart-wrapper">
2125- <canvas id="searchChart"></canvas>
2175+ <div class="chart-canvas">
2176+ <canvas id="searchChart"></canvas>
2177+ </div>
21262178 </div>
21272179 </div>
21282180 </div>
@@ -2232,7 +2284,7 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
22322284 const allProjectData = Object.entries(data.projectSummary)
22332285 .sort((a, b) => b[1] - a[1]);
22342286
2235- new Chart(searchCtx, {
2287+ const searchChart = new Chart(searchCtx, {
22362288 type: 'pie',
22372289 data: {
22382290 labels: allProjectData.map(([project]) => project),
@@ -2242,18 +2294,7 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
22422294 hours: Math.floor(minutes / 60),
22432295 mins: Math.round(minutes % 60)
22442296 })),
2245- backgroundColor: [
2246- 'rgba(255, 99, 132, 0.7)', // Red
2247- 'rgba(54, 162, 235, 0.7)', // Blue
2248- 'rgba(255, 206, 86, 0.7)', // Yellow
2249- 'rgba(75, 192, 192, 0.7)', // Teal
2250- 'rgba(153, 102, 255, 0.7)', // Purple
2251- 'rgba(255, 159, 64, 0.7)', // Orange
2252- 'rgba(199, 199, 199, 0.7)', // Gray
2253- 'rgba(83, 102, 255, 0.7)', // Indigo
2254- 'rgba(40, 167, 69, 0.7)', // Green
2255- 'rgba(220, 53, 69, 0.7)' // Dark Red
2256- ],
2297+ backgroundColor: generateChartColors(allProjectData.length),
22572298 borderColor: chartColors.background,
22582299 borderWidth: 1
22592300 }]
@@ -2263,16 +2304,7 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
22632304 maintainAspectRatio: false,
22642305 plugins: {
22652306 legend: {
2266- position: 'right',
2267- labels: {
2268- color: chartColors.text,
2269- font: {
2270- size: 12,
2271- weight: '500'
2272- },
2273- padding: 20,
2274- usePointStyle: true
2275- }
2307+ display: false
22762308 },
22772309 tooltip: {
22782310 backgroundColor: isDarkTheme ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)',
@@ -2291,6 +2323,9 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
22912323 }
22922324 }
22932325 });
2326+
2327+ // Create custom scrollable legend
2328+ createCustomLegend(searchChart, allProjectData, chartColors);
22942329 }
22952330
22962331 function displaySearchResult(entries) {
@@ -2358,7 +2393,9 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
23582393 <div class="chart-container">
23592394 <div class="chart-title">Project Distribution (Total Time: \${formatTime(totalTime)})</div>
23602395 <div class="chart-wrapper">
2361- <canvas id="searchChart"></canvas>
2396+ <div class="chart-canvas">
2397+ <canvas id="searchChart"></canvas>
2398+ </div>
23622399 </div>
23632400 </div>
23642401 \`;
@@ -2481,7 +2518,7 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
24812518 const searchChartData = Object.entries(projectData)
24822519 .sort((a, b) => b[1] - a[1]);
24832520
2484- new Chart(searchCtx, {
2521+ const searchChart2 = new Chart(searchCtx, {
24852522 type: 'pie',
24862523 data: {
24872524 labels: searchChartData.map(([project]) => project),
@@ -2491,18 +2528,7 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
24912528 hours: Math.floor(minutes / 60),
24922529 mins: Math.round(minutes % 60)
24932530 })),
2494- backgroundColor: [
2495- 'rgba(255, 99, 132, 0.7)', // Red
2496- 'rgba(54, 162, 235, 0.7)', // Blue
2497- 'rgba(255, 206, 86, 0.7)', // Yellow
2498- 'rgba(75, 192, 192, 0.7)', // Teal
2499- 'rgba(153, 102, 255, 0.7)', // Purple
2500- 'rgba(255, 159, 64, 0.7)', // Orange
2501- 'rgba(199, 199, 199, 0.7)', // Gray
2502- 'rgba(83, 102, 255, 0.7)', // Indigo
2503- 'rgba(40, 167, 69, 0.7)', // Green
2504- 'rgba(220, 53, 69, 0.7)' // Dark Red
2505- ],
2531+ backgroundColor: generateChartColors(searchChartData.length),
25062532 borderColor: chartColors.background,
25072533 borderWidth: 1
25082534 }]
@@ -2512,16 +2538,7 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
25122538 maintainAspectRatio: false,
25132539 plugins: {
25142540 legend: {
2515- position: 'right',
2516- labels: {
2517- color: chartColors.text,
2518- font: {
2519- size: 12,
2520- weight: '500'
2521- },
2522- padding: 20,
2523- usePointStyle: true
2524- }
2541+ display: false
25252542 },
25262543 tooltip: {
25272544 backgroundColor: isDarkTheme ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)',
@@ -2540,6 +2557,70 @@ export class SummaryViewProvider implements vscode.WebviewViewProvider {
25402557 }
25412558 }
25422559 });
2560+
2561+ // Create custom scrollable legend
2562+ createCustomLegend(searchChart2, searchChartData, chartColors);
2563+ }
2564+
2565+ function generateChartColors(count) {
2566+ const baseColors = [
2567+ 'rgba(255, 99, 132, 0.7)', // Red
2568+ 'rgba(54, 162, 235, 0.7)', // Blue
2569+ 'rgba(255, 206, 86, 0.7)', // Yellow
2570+ 'rgba(75, 192, 192, 0.7)', // Teal
2571+ 'rgba(153, 102, 255, 0.7)', // Purple
2572+ 'rgba(255, 159, 64, 0.7)', // Orange
2573+ 'rgba(199, 199, 199, 0.7)', // Gray
2574+ 'rgba(83, 102, 255, 0.7)', // Indigo
2575+ 'rgba(40, 167, 69, 0.7)', // Green
2576+ 'rgba(220, 53, 69, 0.7)' // Dark Red
2577+ ];
2578+
2579+ const colors = [];
2580+ for (let i = 0; i < count; i++) {
2581+ if (i < baseColors.length) {
2582+ colors.push(baseColors[i]);
2583+ } else {
2584+ // Generate additional colors using HSL
2585+ const hue = (i * 137.5) % 360; // Golden angle approximation
2586+ const saturation = 70;
2587+ const lightness = 50;
2588+ colors.push(\`hsla(\${hue}, \${saturation}%, \${lightness}%, 0.7)\`);
2589+ }
2590+ }
2591+ return colors;
2592+ }
2593+
2594+ function createCustomLegend(chart, projectData, chartColors) {
2595+ // Find the chart wrapper (parent of chart-canvas)
2596+ const chartWrapper = chart.canvas.parentElement.parentElement;
2597+
2598+ // Create legend container
2599+ const legendContainer = document.createElement('div');
2600+ legendContainer.className = 'custom-legend';
2601+
2602+ // Create legend items
2603+ projectData.forEach(([project, minutes], index) => {
2604+ const hours = Math.floor(minutes / 60);
2605+ const mins = Math.round(minutes % 60);
2606+
2607+ const legendItem = document.createElement('div');
2608+ legendItem.className = 'legend-item';
2609+
2610+ const colorDot = document.createElement('div');
2611+ colorDot.className = 'legend-color';
2612+ colorDot.style.backgroundColor = chart.data.datasets[0].backgroundColor[index];
2613+
2614+ const label = document.createElement('span');
2615+ label.textContent = \`\${project}: \${hours}h \${mins}m\`;
2616+
2617+ legendItem.appendChild(colorDot);
2618+ legendItem.appendChild(label);
2619+ legendContainer.appendChild(legendItem);
2620+ });
2621+
2622+ // Insert legend into the chart wrapper
2623+ chartWrapper.appendChild(legendContainer);
25432624 }
25442625
25452626 function formatTime(minutes) {
0 commit comments