I am using the following:
gem "rails", "7.0.8"
gem "sprockets-rails"
gem "jsbundling-rails"
gem 'turbo-rails', '~> 1.5'
gem 'stimulus-rails', '~> 1.3'
gem "cssbundling-rails"
gem 'importmap-rails', '~> 1.2', '>= 1.2.3'
gem 'rails_charts', '~> 0.0.6'
#gem 'chartkick', '~>5.0.5'
With this code below I can basically, follow the flow all the way through. That is the turbo_stream.update will render the partial, fill in the data, then send the response back to the browser and replace foobar with the rails_charts script. But it seems the script code does not execute and therefore not render chart. I tried adding console.log JS calls in the partial and these do not render either. When I switch this to a turbo_frame, the test console.log JS calls render, but the chart still does not. I tried with chartkick as well - same difference.
I looked many of the diff stack overflow Q&A including this one Chartkick not loading in Ruby on Rails 7 https://github.com/hotwired/turbo-rails/issues/416 and several others, nothing has helped.
I did see that https://github.com/railsjazz/rails_charts in the "Contributing section" has "support turbo streams?" - which indicates turbo is not supported - but then I see the JS below and it has the turbo event listeners in there.
I feel this will be an amazing flow if I can get them working. For now, am reverting back to full page loads sadly until I can sort this out - any thoughts or help possible?
===
format.turbo_stream do
render turbo_stream: [
turbo_stream.update("avg_wait_area",
partial: "wait_stats/avg_wait_chart",
locals: { mon_stats: @mon_stats })
]
end
in _avg_wait_chart.turbo_stream.erb
<div id="avg_wait_area">
foobar
</div>
div id="rails_charts_339d948522be9104817e0757052eebc2663a61dc" class="box" style="width: 100%; height: 450px">
<script>
if (!window.RailsCharts) {
window.RailsCharts = {}
window.RailsCharts.charts = {}
}
function init_rails_charts_339d948522be9104817e0757052eebc2663a61dc(e) {
if (document.documentElement.hasAttribute("data-turbolinks-preview")) return;
if (document.documentElement.hasAttribute("data-turbo-preview")) return;
<!-- RailsCharts::StackedBarChart -->
var chartDom = document.getElementById('rails_charts_339d948522be9104817e0757052eebc2663a61dc');
if (!chartDom) { return }
var lib = ("echarts" in window) ? window.echarts : echarts;
var chart = lib.init(chartDom, null, { "locale": null, "renderer": "canvas" });
var option = {"series":[{"data":[0.24,2.15,3.1,3.1,4.54,5.3,5.77,6.25,9.36,16.81,22.97],"type":"bar","stack":{}}],"xAxis":{"type":"value"},"yAxis":{"type":"category","data":["A","b","c","d","f","g","h","i","j","k","l"]},"tooltip":{"trigger":"axis","axisPointer":{"type":"shadow"}},"toolbox":{"feature":{"saveAsImage":{}}},"title":{"text":"Average Wait Days - Dec-2023"},"visualMap":{"show":false,"min":0,"max":25,"orient":"horizontal"},"grid":{"containLabel":true,"left":0}};
option && chart.setOption(option);
window.RailsCharts.charts["rails_charts_339d948522be9104817e0757052eebc2663a61dc"] = chart;
}
function destroy_rails_charts_339d948522be9104817e0757052eebc2663a61dc(e) {
var chart = window.RailsCharts.charts["rails_charts_339d948522be9104817e0757052eebc2663a61dc"];
if (chart) {
chart.dispose()
}
delete window.RailsCharts.charts["rails_charts_339d948522be9104817e0757052eebc2663a61dc"];
}
window.addEventListener('load', init_rails_charts_339d948522be9104817e0757052eebc2663a61dc);
window.addEventListener('turbo:load', init_rails_charts_339d948522be9104817e0757052eebc2663a61dc);
window.addEventListener('turbolinks:load', init_rails_charts_339d948522be9104817e0757052eebc2663a61dc);
document.addEventListener("turbolinks:before-render", destroy_rails_charts_339d948522be9104817e0757052eebc2663a61dc);
document.addEventListener("turbo:before-render", destroy_rails_charts_339d948522be9104817e0757052eebc2663a61dc);
</script>
</div>
Again, I tried all of the above.
Problem is none of those events are fired when rendering a turbo_stream which means chart is not initialized. Solution is pretty simple: don't use event listeners at all. To make it even better wrap it in Stimulus:
Override
generate_rails_charthelper to use this stimulus controller instead of generating inline javascript:Render on a page or in a turbo stream partial:
or from controller:
This is what should be generated by chart helpers, there is no javascript code here:
Stimulus takes care of the rest, regardless of how you render it: on a page or turbo stream. I've tested it.