如何在Chartkick图表中为各部门添加工单状态统计总数?
如何在Chartkick图表的悬停提示中添加部门工单总数?
现有查询与返回结果
我使用以下Ruby on Rails查询语句,获取按工单状态名称和部门名称分组的工单数量:
Ticket.joins(:assigned_user => :department, :ticket_status) .group("ticket_statuses.name", "departments.name") .where("ticket_statuses.status = ?", 1) .count
注:原代码中departament为拼写错误,已修正为department
该查询返回的结果结构如下:
{ ["Open", "BROWSER"] => 2, ["Open", "MARKETING"] => 5, ["Open", "MONITORING"] => 2, # ... 其他分组结果省略 ["In process", "SALES"] => 1 }
当前Chartkick悬停提示效果
将上述查询结果配合Chartkick gem使用,生成按部门分组的图表后,鼠标悬停时的提示信息如下:
Marketing Open:5 Close:1 Attended:2 In process:4 Monitoring Open:2 Close:7 Attended:3 In process:4
期望的提示效果
希望在悬停提示中添加各部门的工单总数,达到如下效果:
Marketing Open:5 Close:1 Attended:2 In process:4 Total:12 Monitoring Open:2 Close:7 Attended:3 In process:4 Total:16
解决方案
1. 预处理查询数据,计算部门总数
先将查询返回的双层键哈希转换为按部门分组的结构,同时计算每个部门的工单总数:
# 执行查询 ticket_counts = Ticket.joins(:assigned_user => :department, :ticket_status) .group("ticket_statuses.name", "departments.name") .where("ticket_statuses.status = ?", 1) .count # 转换数据结构:按部门分组,存储各状态数量和总数 formatted_ticket_data = ticket_counts.each_with_object(Hash.new { |h,k| h[k] = { statuses: {}, total: 0 } }) do |((status, dept), count), result| result[dept][:statuses][status] = count result[dept][:total] += count end
2. 自定义Chartkick的悬停提示内容
利用Chartkick的tooltip选项自定义提示格式,将总数添加到提示末尾。以柱形图为例:
<%= column_chart formatted_ticket_data.transform_values { |data| data[:statuses] }, tooltip: { formatter: -> { # 拼接部门名称和各状态数量 content = "<strong>#{@point.x}</strong><br/>" @point.series.each { |s| content += "#{s.name}: #{s.value}<br/>" } # 计算并添加总数 total = @point.series.sum { |s| s.value } content += "<br/><strong>Total: #{total}</strong>" content } } %>
说明
- 数据预处理步骤将原查询结果重新组织,方便获取每个部门的所有状态计数和总数。
- Chartkick的
tooltip.formatter是回调函数,可完全自定义悬停提示的HTML内容,这里通过计算当前部门所有状态数量之和,拼接出总数行添加到提示中。 - 如果希望在图表中也显示"Total"系列,可修改
transform_values为data[:statuses].merge("Total" => data[:total]),图表会新增代表总数的柱子,提示中也会包含该数据。
内容的提问来源于stack exchange,提问作者Memories
相关产品推荐
相关产品推荐

