Files
railsgoat/app/views/performance/index.html.erb
T
Ken Johnson 1bc835c4c9 Add proper Turbolinks handling for Google Charts
Added comprehensive Turbolinks event handling and duplicate load
prevention for Google Charts on performance page.

Changes:
- Add turbolinks:load event listener for page navigations
- Prevent multiple google.load() calls with flag
- Check if visualization already loaded before loading again
- Add chart element existence check before drawing
- Call initializeChart() immediately for initial load
- Better error messages for debugging

This ensures charts render on both initial page load and Turbolinks
navigation, while preventing duplicate library loads.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-07 01:10:44 -05:00

162 lines
4.2 KiB
Plaintext

<div class="dashboard-wrapper">
<div class="main-container">
<div class="row-fluid">
<div class="span12">
<div class="widget">
<div class="widget-header">
<div class="title">
<span class="fs1" aria-hidden="true" data-icon="&#xe096;"></span> Performance History Visualization
</div>
</div>
<div class="widget-body">
<div id="line_chart"></div>
</div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<div class="widget">
<div class="widget-header">
<div class="title">
<span class="fs1" aria-hidden="true" data-icon="&#xe004;"></span> Performance History
</div>
</div>
<div class="widget-body">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width:16%">Reviewer</th>
<th style="width:16%">Date</th>
<th style="width:16%">Score</th>
<th style="width:16%">Comments</th>
</tr>
</thead>
<tbody>
<% @perf.each do |p| %>
<tr>
<td><%= p.reviewer_name %></td>
<td><%= p.date_submitted %></td>
<td><%= p.score %></td>
<td><%= p.comments %></td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
// Prevent multiple initializations with Turbolinks
if (typeof window.performanceChartLoaded === 'undefined') {
window.performanceChartLoaded = false;
}
function drawChart2() {
// Guard against calling before Google Charts is loaded
if (typeof google === 'undefined' || !google.visualization) {
console.warn('Google Charts not loaded yet');
return;
}
var chartElement = document.getElementById('line_chart');
if (!chartElement) {
console.warn('Chart element not found');
return;
}
var data = google.visualization.arrayToDataTable([
['Year', 'Score'],
<% @perf.each do |p| %>
// Let's just hope this data isn't suspectible during later releases ;-)
[ <%= "#{p.date_submitted}".inspect.html_safe %>, <%= p.score %> ],
<% end %>
]);
var options = {
min: 1,
max: 5,
width: 'auto',
height: '160',
backgroundColor: 'transparent',
colors: ['#e26666', '#579da9', '#1e825e', '#b5799e', '#dba26b'],
tooltip: {
textStyle: {
color: '#666666',
fontSize: 11
},
showColorCode: true
},
legend: {
textStyle: {
color: 'black',
fontSize: 12
}
},
chartArea: {
left: 100,
top: 10
},
focusTarget: 'category',
hAxis: {
textStyle: {
color: 'black',
fontSize: 12
}
},
vAxis: {
textStyle: {
color: 'black',
fontSize: 12
}
},
pointSize: 8,
chartArea: {
left: 60,
top: 10,
height: '80%'
},
lineWidth: 2,
};
var chart = new google.visualization.LineChart(chartElement);
chart.draw(data, options);
}
function makeActive(){
$('li[id="performance"]').addClass('active');
};
function initializeChart() {
makeActive();
// Check if Google Charts visualization is already loaded
if (typeof google !== 'undefined' && google.visualization && google.visualization.LineChart) {
drawChart2();
window.performanceChartLoaded = true;
} else if (typeof google !== 'undefined' && google.load && !window.performanceChartLoaded) {
// Load Google Charts
google.load("visualization", "1", {
packages: ["corechart"],
callback: function() {
drawChart2();
window.performanceChartLoaded = true;
}
});
} else {
console.error('Google JSAPI not available');
}
}
// Initialize immediately (page is already loaded with Turbolinks)
initializeChart();
// Handle Turbolinks page loads
$(document).on('turbolinks:load', function() {
initializeChart();
});
</script>