如何在Ruby on Rails中不用Chartkick,将数据库数据接入Highcharts做自定义图表
解决方案
完全可以在不修改原有控制器数据逻辑、不使用Chartkick的前提下对接Highcharts,具体操作步骤如下:
步骤1:准备图表容器
在ERB视图中替换原有line_chart代码,新增一个DOM元素作为Highcharts的渲染容器,同时把需要从Ruby侧传递的参数存入元素的data-*属性,避免直接拼接JS代码的转义和安全问题:
<div id="hotWaterStatusChart" data-data-url="<%= graphs_site_hot_water_status_path(@site) %>" data-colors="<%= ['#AE42CE', '#DD6539','#093FF7', '#B2461F', '#A8BCFD', '#E68F6F'].to_json %>" data-refresh-rate="<%= @refresh_rate %>" data-y-title="<%= t(".fahrenheit") %>" data-x-title="<%= t(".timestamp") %>" style="height: 400px; width: 100%;" ></div>
步骤2:编写JS逻辑对接数据和渲染图表
通过Fetch API调用原有接口获取数据,适配后初始化Highcharts即可,同时可以保留原有的自动刷新逻辑:
document.addEventListener('DOMContentLoaded', function () { const chartEl = document.getElementById('hotWaterStatusChart'); const chartDataUrl = chartEl.dataset.dataUrl; const chartColors = JSON.parse(chartEl.dataset.colors); const refreshRate = parseInt(chartEl.dataset.refreshRate) * 1000; // 单位转换为毫秒 const yTitle = chartEl.dataset.yTitle; const xTitle = chartEl.dataset.xTitle; let chartInstance = null; // 加载数据并渲染/更新图表的函数 function loadAndRenderChart() { fetch(chartDataUrl) .then(response => response.json()) .then(rawData => { // 原有接口返回的Chartkick标准格式与Highcharts的series配置完全兼容,可直接使用 const series = rawData; const chartOptions = { chart: { type: 'line', renderTo: chartEl }, title: null, xAxis: { title: { text: xTitle }, type: 'datetime' }, yAxis: { title: { text: yTitle } }, colors: chartColors, series: series, // 可在此处添加任意Highcharts支持的自定义配置 tooltip: { xDateFormat: '%Y-%m-%d %H:%M:%S' } }; if (chartInstance) { // 刷新时仅更新数据,避免重复初始化 chartInstance.update({series: series}, true); } else { chartInstance = new Highcharts.Chart(chartOptions); } }); } // 首次加载渲染 loadAndRenderChart(); // 按配置启动定时刷新 if (refreshRate > 0) { setInterval(loadAndRenderChart, refreshRate); } });
适配说明
- 原有控制器返回的是Chartkick兼容的标准时间序列JSON格式,无需修改任何后端逻辑即可直接适配Highcharts
- 你可以在
chartOptions配置项中添加任意Highcharts支持的自定义规则,实现完全定制化的图表效果 - 所有原有Chartkick的配置参数(颜色、刷新间隔、轴标题)都完整保留,没有功能损失
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

