如何从Rails将ID与名称传递至D3图表并在图例显示名称
解决方案
步骤1:控制器中关联数据并包含名称字段
修改控制器代码,预加载macro_series关联以避免N+1查询,同时将series_name字段纳入查询结果:
@income_equality1 = MacroSeries.where(series_code: ['WFRBSTP1300', 'WFRBSB50215']) # 预加载关联并选择所需字段 @mv1 = MacroValue.where(macro_series_id: @income_equality1, geography_id: @geography_id) .includes(:macro_series) .select('macro_values.*, macro_series.series_name')
步骤2:视图中修改分类字段参数
将视图渲染参数里的cat1从macro_series_id替换为series_name:
<%= render 'macro_values/macro_values_chart', chart_num: 1, chart_data1: @mv1, chart_type: 'area_stacked', x_value: 'date', y_value: 'value', cat1: 'series_name' %>
步骤3:D3代码适配名称字段
不需要大幅修改D3逻辑,只需确保图例和提示文本使用名称字段:
- 堆叠数据的key自动变为
series_name,因为cat1参数已更新:
var series = d3.stack() .keys(d3.union(data.map(d => d[cat1]))) .value(([, D], key) => D.get(key)[y_value]) (d3.index(data, d => d3.timeParse(date_format)(d[x_value]), d => d[cat1]));
- 图例文本直接使用
d.key(已映射为名称):
legend.append("text") .attr("x", margin.left) .attr("y", size / 2) .attr("dy", ".35em") .style("fill", d => color(d.key)) .text(d => d.key) .on("mouseover", highlight) .on("mouseleave", noHighlight);
- 提示框文本同步更新:
.append("title") .text(d => d.key);
备选方案:ID-名称映射哈希(不修改分类字段时用)
若需保留macro_series_id作为分类字段,可在控制器创建ID到名称的映射:
# 控制器新增代码 @series_name_map = @income_equality1.index_by(&:id).transform_values(&:series_name)
视图传递映射参数:
<%= render 'macro_values/macro_values_chart', chart_num: 1, chart_data1: @mv1, chart_type: 'area_stacked', x_value: 'date', y_value: 'value', cat1: 'macro_series_id', series_name_map: @series_name_map %>
D3代码中调用映射替换ID:
var series_name_map = <%= raw(series_name_map.to_json) %>; // 图例文本替换 .text(d => series_name_map[d.key]); // 提示框文本替换 .text(d => series_name_map[d.key]);
内容的提问来源于stack exchange,提问作者Anne Lalsingh
相关产品推荐
相关产品推荐

