Created
March 31, 2022 23:11
-
-
Save retsef/d6dffcc0b792bce66bd9038bd8646388 to your computer and use it in GitHub Desktop.
Chartkick with stimulus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Controller } from "@hotwired/stimulus" | |
import Chartkick from "chartkick"; | |
export default class extends Controller { | |
static targets = []; | |
static values = { | |
type: String, | |
data: Array, | |
options: Object | |
}; | |
chart = null; | |
connect() { | |
this.chart = new Chartkick[this.typeValue]( | |
this.element.id, | |
this.dataValue, | |
this.optionsValue); | |
} | |
disconnect() { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Chartkick::Helper.module_eval do | |
private | |
# don't break out options since need to merge with default options | |
def chartkick_chart(klass, data_source, **options) | |
options = chartkick_deep_merge(Chartkick.options, options) | |
@chartkick_chart_id ||= 0 | |
element_id = options.delete(:id) || "chart-#{@chartkick_chart_id += 1}" | |
height = (options.delete(:height) || '300px').to_s | |
width = (options.delete(:width) || '100%').to_s | |
# html vars | |
html_vars = { | |
id: element_id, | |
height: height, | |
width: width, | |
# don't delete loading option since it needs to be passed to JS | |
loading: options[:loading] || 'Loading...' | |
} | |
%i[height width].each do |k| | |
# limit to alphanumeric and % for simplicity | |
# this prevents things like calc() but safety is the priority | |
# dot does not need escaped in square brackets | |
raise ArgumentError, "Invalid #{k}" unless /\A[a-zA-Z0-9%.]*\z/.match?(html_vars[k]) | |
end | |
html_vars.each_key do |k| | |
# escape all variables | |
# we already limit height and width above, but escape for safety as fail-safe | |
# to prevent XSS injection in worse-case scenario | |
html_vars[k] = ERB::Util.html_escape(html_vars[k]) | |
end | |
# js vars | |
js_vars = { | |
type: klass, | |
id: element_id, | |
data: data_source.respond_to?(:chart_json) ? data_source.chart_json : data_source.to_json, | |
options: options.to_json | |
} | |
html = content_tag(:div, id: html_vars[:id], | |
style: "height: #{html_vars[:height]}; width: #{html_vars[:width]}; line-height: #{html_vars[:height]}; text-align: center; color: #999; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;", | |
'data-controller': 'chart', | |
'data-chart-type-value': js_vars[:type], | |
'data-chart-data-value': js_vars[:data], | |
'data-chart-options-value': js_vars[:options]) do | |
html_vars[:loading] | |
end | |
html.respond_to?(:html_safe) ? html.html_safe : html | |
end | |
end |
Hi @elalemanyo I'm using this patch in a similar environment. At our company we have a dashboard with many charts and with a range picker we update the charts. In our case we trigger the request from javascript and we ask for a turbo-stream
response.
Like this:
import { FetchRequest } from '@rails/request.js'
const request = new FetchRequest("get", url.toString(), { responseKind: "turbo-stream" })
const response = await request.perform()
In your case try to check for the request to includes a turbo-stream
mime. If not try to investigate further on the correct scope of the target with data-turbo-target
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@retsef Thanks for your gist. Unfortunately it does not work in my case 😞
I am using Chartkick inside a turbo frame, and because I use
turbo_action: "advance"
to change the url the charts are not showing up, not sure why. Maybe you have an idea.Thanks