David Wang David Wang - 1 year ago 71
jQuery Question

How to pass string variables to labels option in Morris.js

I am using Morris.js for rendering charts in Rails project. There is a problem that I have no idea how to pass values from JSON string to labels option in Morris.js.

Below are contents from a helper method:

def worst_yield_chart_data(reports)
start_time = reports.last.published_at
end_time = reports.first.published_at
datetime = Report.where("config = ? AND published_at BETWEEN ? AND ?", 'ALL', start_time, end_time).select("distinct(published_at)")
datetime.map do |date|
published_at: date.published_at.to_datetime.to_formatted_s(:long),
# Top1 worst yield rate & station name
worst_accu_yield: Report.group_accu_yield_by_date(date.published_at).first.try(:worst_accu_yield),
worst_daily_yield: Report.group_daily_yield_by_date(date.published_at).first.try(:worst_daily_yield),
worst_accu_yield_station: Report.group_accu_yield_by_date(date.published_at).first.try(:station_name) || 'No Input',
worst_daily_yield_station: Report.group_daily_yield_by_date(date.published_at).first.try(:station_name) || 'No Input',
# Top2 Worst yield rate & station name
worse_accu_yield: Report.group_accu_yield_by_date(date.published_at).offset(2).first.try(:worst_accu_yield),
worse_daily_yield: Report.group_daily_yield_by_date(date.published_at).offset(2).first.try(:worst_daily_yield),
worse_accu_yield_station: Report.group_accu_yield_by_date(date.published_at).offset(2).first.try(:station_name) || 'No Input',
worse_daily_yield_station: Report.group_daily_yield_by_date(date.published_at).offset(2).first.try(:station_name) || 'No Input',
# Top3 worst yield rate & station name
bad_accu_yield: Report.group_accu_yield_by_date(date.published_at).offset(3).first.try(:worst_accu_yield),
bad_daily_yield: Report.group_daily_yield_by_date(date.published_at).offset(3).first.try(:worst_daily_yield),
bad_accu_yield_station: Report.group_accu_yield_by_date(date.published_at).offset(3).first.try(:station_name) || 'No Input',
bad_daily_yield_station: Report.group_daily_yield_by_date(date.published_at).offset(3).first.try(:station_name) || 'No Input'

The view contents as below:

= content_tag :div, "", id: "worst-accu-yield-data", data: {reports: worst_yield_chart_data(@reports_for_cart)}

And the javascript codes in HAML file is like below:

jQuery(function() {
element: 'worst-accu-yield-data',
resize: true,
hideHover: 'auto',
continuousLine: true,
data: $('#worst-accu-yield-data').data('reports'),
goals: [90, 95.5, 100],
goalLineColors: ['#e74c3c', '#e67e22', '#2ecc71'],
xkey: 'published_at',
ykeys: ['worst_accu_yield', 'worse_accu_yield', 'bad_accu_yield'],
labels: ['worst_accu_yield_station', 'worse_accu_yield_station', 'bad_accu_yield_station'],
trendLine: true,
postUnits: '%',
ymin: 'auto',
ymax: 'auto',
parseTime: false,
barColors: ['#cb4b4b', '#f8aa33', '#1fbba6'],
barOpacity: 0.7,
behaveLikeLine: true

The purpose is to get Top3 Worst station name with its' yield rate in bar cart.
I am able to get string values in "xkey" and "ykeys" correctly.
Also, I would like to pass each station's name to label option in morris.js (ex: Station A, Station B, Station C).
But in this case, it shows hardcoded string for me: worst_accu_yield_station, worse_accu_yield_station, bad_accu_yield_station.

My Bar Cart

Is it possible to pass each station name to label option? Any help will be greatly appreciated!

Answer Source

The problem can be solved by customizing the hover option.

"hoverCallback":  function(index, options, content){
    var row = options.data[index]
    datetime = '<p><b>' + row.published_at + '</b></p>'
    station1 = '<div style="color: #cb4b4b;">Worst: ' + row.worst_accu_station + ' (' + row.worst_accu_yield + '%)</div>'
    station2 = '<div style="color: #f8aa33;">Worse: ' + row.worse_accu_station + ' ('  + row.worse_accu_yield + '%)</div>'
    station3 = '<div style="color: #1fbba6;">Bad: ' + row.bad_accu_station + ' ('  + row.bad_accu_yield + '%)</div>'
    return [datetime, station1, station2, station3]