@@ -123,8 +123,10 @@ function createChart(data, containerId, type) {
123123 }
124124
125125 const ctx = document . getElementById ( containerId ) . getContext ( '2d' ) ;
126+
126127 const options = {
127128 responsive : true ,
129+ maintainAspectRatio : false ,
128130 plugins : {
129131 title : {
130132 display : true ,
@@ -157,6 +159,13 @@ function createChart(data, containerId, type) {
157159 }
158160 }
159161 } ,
162+ legend : {
163+ position : 'top' ,
164+ labels : {
165+ boxWidth : 12 ,
166+ padding : 10 ,
167+ }
168+ } ,
160169 annotation : type === 'time' ? {
161170 annotations : { }
162171 } : undefined
@@ -227,6 +236,32 @@ function createChart(data, containerId, type) {
227236 const chart = new Chart ( ctx , chartConfig ) ;
228237 chartInstances . set ( containerId , chart ) ;
229238
239+ // Set explicit canvas size after chart creation to ensure proper sizing
240+ const canvas = document . getElementById ( containerId ) ;
241+ const rect = canvas . getBoundingClientRect ( ) ;
242+ const dpr = window . devicePixelRatio || 1 ;
243+
244+ // Calculate dynamic height based on number of legend items
245+ const legendItemCount = type === 'time' ?
246+ Object . values ( data . runs ) . length :
247+ data . datasets . length ;
248+
249+ // Base chart height + legend height (25px per line + padding)
250+ const baseChartHeight = 350 ;
251+ const legendHeight = Math . max ( legendItemCount * 25 , 50 ) ; // minimum 50px for legend
252+ const totalHeight = baseChartHeight + legendHeight ;
253+
254+ // Set canvas dimensions for crisp rendering
255+ canvas . width = rect . width * dpr ;
256+ canvas . height = totalHeight * dpr ;
257+
258+ // Scale the context to ensure correct drawing operations
259+ const context = canvas . getContext ( '2d' ) ;
260+ context . scale ( dpr , dpr ) ;
261+
262+ // Force chart to use these exact dimensions
263+ chart . resize ( rect . width , totalHeight ) ;
264+
230265 // Add annotation interaction handlers for time-series charts
231266 if ( type === 'time' ) {
232267 ChartAnnotations . setupAnnotationListeners ( chart , ctx , options ) ;
@@ -306,6 +341,10 @@ function createChartContainer(data, canvasId, type) {
306341 container . setAttribute ( 'data-label' , data . label ) ;
307342 container . setAttribute ( 'data-suite' , data . suite ) ;
308343
344+ // Create header section for metadata
345+ const headerSection = document . createElement ( 'div' ) ;
346+ headerSection . className = 'chart-header' ;
347+
309348 // Check if this benchmark is marked as unstable
310349 const metadata = metadataForLabel ( data . label , type ) ;
311350 if ( metadata && metadata . unstable ) {
@@ -316,15 +355,17 @@ function createChartContainer(data, canvasId, type) {
316355 unstableWarning . className = 'benchmark-unstable' ;
317356 unstableWarning . textContent = metadata . unstable ;
318357 unstableWarning . style . display = isUnstableEnabled ( ) ? 'block' : 'none' ;
319- container . appendChild ( unstableWarning ) ;
358+ unstableWarning . style . marginBottom = '5px' ;
359+ headerSection . appendChild ( unstableWarning ) ;
320360 }
321361
322- // Add description if present in metadata (moved outside of details)
362+ // Add description if present in metadata
323363 if ( metadata && metadata . description ) {
324364 const descElement = document . createElement ( 'div' ) ;
325365 descElement . className = 'benchmark-description' ;
326366 descElement . textContent = metadata . description ;
327- container . appendChild ( descElement ) ;
367+ descElement . style . marginBottom = '5px' ;
368+ headerSection . appendChild ( descElement ) ;
328369 }
329370
330371 // Add notes if present
@@ -333,7 +374,7 @@ function createChartContainer(data, canvasId, type) {
333374 noteElement . className = 'benchmark-note' ;
334375 noteElement . textContent = metadata . notes ;
335376 noteElement . style . display = isNotesEnabled ( ) ? 'block' : 'none' ;
336- container . appendChild ( noteElement ) ;
377+ headerSection . appendChild ( noteElement ) ;
337378 }
338379
339380 // Add tags if present
@@ -358,12 +399,31 @@ function createChartContainer(data, canvasId, type) {
358399 tagsContainer . appendChild ( tagElement ) ;
359400 } ) ;
360401
361- container . appendChild ( tagsContainer ) ;
402+ headerSection . appendChild ( tagsContainer ) ;
362403 }
363404
405+ // Add header section to container
406+ container . appendChild ( headerSection ) ;
407+
408+ // Create main content section (chart + legend area)
409+ const contentSection = document . createElement ( 'div' ) ;
410+ contentSection . className = 'chart-content' ;
411+
412+ // Canvas for the chart - fixed position in content flow
364413 const canvas = document . createElement ( 'canvas' ) ;
365414 canvas . id = canvasId ;
366- container . appendChild ( canvas ) ;
415+ canvas . style . width = '100%' ;
416+
417+ // Set a default height - will be properly sized later in createChart
418+ canvas . style . height = '400px' ;
419+ canvas . style . marginBottom = '10px' ;
420+ contentSection . appendChild ( canvas ) ;
421+
422+ container . appendChild ( contentSection ) ;
423+
424+ // Create footer section for details
425+ const footerSection = document . createElement ( 'div' ) ;
426+ footerSection . className = 'chart-footer' ;
367427
368428 // Create details section for extra info
369429 const details = document . createElement ( 'details' ) ;
@@ -387,7 +447,8 @@ function createChartContainer(data, canvasId, type) {
387447 extraInfo . innerHTML = generateExtraInfo ( data , 'benchmark' ) ;
388448 details . appendChild ( extraInfo ) ;
389449
390- container . appendChild ( details ) ;
450+ footerSection . appendChild ( details ) ;
451+ container . appendChild ( footerSection ) ;
391452
392453 return container ;
393454}
0 commit comments