golang.org/x/build@v0.0.0-20240506185731-218518f32b70/devapp/templates/stats.tmpl (about) 1 <!DOCTYPE html> 2 <html lang="en"> 3 <meta charset="utf-8"> 4 <meta name="viewport" content="width=device-width, initial-scale=1"> 5 <link rel="preconnect" href="https://www.gstatic.com"> 6 <title>Go Stats</title> 7 <style> 8 * { 9 box-sizing: border-box; 10 margin: 0; 11 padding: 0; 12 } 13 body { 14 font: 13px system-ui, sans-serif; 15 padding: 1rem; 16 } 17 .Chart { 18 border: 1px solid #999; 19 height: 400px; 20 padding: 1rem; 21 } 22 .Chart + .Chart { 23 margin-top: 1rem; 24 } 25 @media only screen and (min-device-width: 37.5rem) { 26 .ChartsContainer { 27 display: grid; 28 grid-template-columns: repeat(auto-fill, minmax(37.5rem, 1fr)); 29 grid-gap: 1rem; 30 } 31 .Chart + .Chart { 32 margin-top: 0; 33 } 34 } 35 </style> 36 <header> 37 <h1>Go Stats</h1> 38 </header> 39 <main> 40 <div class="ChartsContainer js-chartContainer"></div> 41 </main> 42 <script src="https://www.gstatic.com/charts/loader.js"></script> 43 <script> 44 const CHART_DATA = {{.DataJSON}}; 45 for (let chart of CHART_DATA.Charts) { 46 const dateColumns = new Set(); // index -> date type 47 for (let i = 0; i < chart.columns.length; i++) { 48 if (chart.columns[i].type === 'date' || chart.columns[i].type === 'datetime') { 49 dateColumns.add(i); 50 } 51 } 52 if (dateColumns.size > 0) { 53 for (let row = 0; row < chart.data.length; row++) { 54 for (let col of dateColumns) { 55 chart.data[row][col] = new Date(chart.data[row][col]); 56 } 57 } 58 } 59 } 60 const data = []; // indexed by charts entry 61 const googCharts = []; // indexed by charts entry 62 63 google.charts.load('current', {packages:['corechart']}); 64 google.charts.setOnLoadCallback(() => { 65 for (let i = 0; i < CHART_DATA.Charts.length; i++) { 66 const chart = CHART_DATA.Charts[i]; 67 data[i] = new google.visualization.DataTable(); 68 for (let col of chart.columns) { 69 data[i].addColumn(col.type, col.label); 70 } 71 data[i].addRows(chart.data); 72 const containerEl = document.createElement('div'); 73 containerEl.classList.add('Chart'); 74 document.querySelector('.js-chartContainer').appendChild(containerEl); 75 googCharts[i] = new google.visualization.LineChart(containerEl); 76 } 77 drawCharts(); 78 }); 79 80 const drawCharts = () => { 81 for (let i = 0; i < CHART_DATA.Charts.length; i++) { 82 googCharts[i].draw(data[i], { 83 title: CHART_DATA.Charts[i].title, 84 chartArea: {width: '100%', height: '80%'}, 85 legend: {position: 'top', alignment: 'end'}, 86 }); 87 } 88 }; 89 90 let debounceTimerId; 91 window.addEventListener('resize', e => { 92 if (debounceTimerId != null) { 93 window.clearTimeout(debounceTimerId); 94 debounceTimerId = null; 95 } 96 debounceTimerId = window.setTimeout(() => { drawCharts(); }, 50); 97 }); 98 </script>