Skip to content

Instantly share code, notes, and snippets.

@tywhang
Last active June 26, 2024 15:04
Show Gist options
  • Save tywhang/b4a67180da816eb0695f to your computer and use it in GitHub Desktop.
Save tywhang/b4a67180da816eb0695f to your computer and use it in GitHub Desktop.
Easily add Charts into Dashing with Chartjs (Line, Bar, Radar, Polar Area, Pie, Doughnut)

smashing-chartjs

An easy interface to use all of chartjs.org's charts.

Inspired by my own pain and suffering of trying to add a simple chart to smashing

Make awesome charts like these:

## Installation ##### 1. Import Chartjs library In `dashboards/layout.erb`, add this script tag:

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>

before this script tag:

<script type="text/javascript" src="/assets/application.js"></script>

2. Install smashing-chartjs

Run in terminal in project directory

smashing install b4a67180da816eb0695f

Example

Let's create a simple line chart!

Usage

Line Chart

<div
  data-id="line-chart"
  data-view="Chartjs"
  data-type="line"
  data-labels="Week 1,Week 2,Week 3,Week 4,Week 5"
  data-colornames="blue,blue,blue,blue,blue"
  data-datasets="10,39,20,49,87"
  data-height="400"
  data-width="400"
></div>

Bar Charts

<div
  data-id="bar-chart"
  data-view="Chartjs"
  data-type="bar"
  data-labels="Day 1,Day 2,Day 3,Day 4,Day 5"
  data-colornames="yellow,yellow,yellow,yellow,yellow"
  data-datasets="210,339,220,494,109"
  data-height="400"
  data-width="400"
></div>

Radar Charts

<div
  data-id="radar-chart"
  data-view="Chartjs"
  data-type="radar"
  data-labels="Crossfit,Yoga,Weight Lifting,Running,Swimming,Watching TV"
  data-colornames="yellow,yellow,yellow,yellow,yellow,yellow"
  data-datasets="210,339,220,234,311,494"
  data-height="400"
  data-width="400"
></div>

Polar Area Charts

<div
  data-id="chart-polarArea"
  data-view="Chartjs"
  data-type="polarArea"
  data-labels="Week 1,Week 2,Week 3,Week 4,Week 5"
  data-colornames="blue,yellow,green,cyan,gray"
  data-datasets="10,39,20,49,87"
  data-height="400"
  data-width="400"
></div>

Pie Charts

@pieChart(elementId, dataSets)

<div
  data-id="chart-pie"
  data-view="Chartjs"
  data-type="pie"
  data-labels="Pumpkin,Apple,Pizza,Rhubarb"
  data-colornames="red,green,yellow,gray"
  data-datasets="13,32,40,20"
  data-height="400"
  data-width="400"
></div>

Doughnut Charts

@doughnutChart(elementId, dataSets)

<div
  data-id="doughnut-pie"
  data-view="Chartjs"
  data-type="doughnut"
  data-labels="Apple Fritter,Chocolate,Maple"
  data-colornames="green,blue,darkgray"
  data-datasets="20,13,12"
  data-height="400"
  data-width="400"
></div>

Colors

Currently available colors

blue | cyan | darkgray | gray | green | lightgray | magenta | red | yellow

class Dashing.Chartjs extends Dashing.Widget
constructor: ->
super
@id = @get("id")
@type = @get("type")
@labels = @get("labels") && @get("labels").split(",")
@datasets = @get("datasets") && @get("datasets").split(",")
@colorNames = @get("colornames") && @get("colornames").split(",")
ready: ->
switch @type
when 'pie', 'doughnut', 'polarArea'
@circularChart @id, type: @type, labels: @labels, colors: @colorNames, datasets: @datasets
when 'line', 'bar', 'radar'
@linearChart @id, type: @type, labels: @labels, colors: @colorNames, datasets: @datasets
else
return
circularChart: (id, { type, labels, colors, datasets, options={} }) ->
data = @merge labels: labels, datasets: [@merge data: datasets, @colors(colors)]
new Chart(document.getElementById(id), { type: type, data: data }, options)
linearChart: (id, { type, labels, colors, datasets, options={} }) ->
data = @merge labels: labels, datasets: [@merge(@colors(colors), data: datasets)]
new Chart(document.getElementById(id), { type: type, data: data }, options)
merge: (xs...) =>
if xs?.length > 0
@tap {}, (m) -> m[k] = v for k, v of x for x in xs
tap: (o, fn) -> fn(o); o
colorCode: ->
blue: "151, 187, 205"
cyan: "0, 255, 255"
darkgray: "77, 83, 96"
gray: "148, 159, 177"
green: "70, 191, 189"
lightgray: "220, 220, 220"
magenta: "255, 0, 255"
red: "247, 70, 74"
yellow: "253, 180, 92"
colors: (colorNames) ->
backgroundColor: colorNames.map (colorName) => @backgroundColor(colorName)
borderColor: colorNames.map (colorName) => @borderColor(colorName)
borderWidth: colorNames.map (colorName) -> 1
pointBackgroundColor: colorNames.map (colorName) => @pointBackgroundColor(colorName)
pointBorderColor: colorNames.map (colorName) => @pointBorderColor(colorName)
pointHoverBackgroundColor: colorNames.map (colorName) => @pointHoverBackgroundColor(colorName)
pointHoverBorderColor: colorNames.map (colorName) => @pointHoverBorderColor(colorName)
color: (colorName) ->
backgroundColor: @backgroundColor(colorName)
borderColor: @borderColor(colorName)
borderWidth: 1
pointBackgroundColor: @pointBackgroundColor(colorName)
pointBorderColor: @pointBorderColor(colorName)
pointHoverBackgroundColor: @pointHoverBackgroundColor()
pointHoverBorderColor: @pointBackgroundColor(colorName)
backgroundColor: (colorName) -> "rgba(#{ @colorCode()[colorName] }, 0.2)"
borderColor: (colorName) -> "rgba(#{ @colorCode()[colorName] }, 1)"
pointBackgroundColor: (colorName) -> "rgba(#{ @colorCode()[colorName] }, 1)"
pointBorderColor: (colorName) -> "rgba(#{ @colorCode()[colorName] }, 1)"
pointHoverBackgroundColor: -> "fff"
pointHoverBorderColor: (colorName) -> "rgba(#{ @colorCode()[colorName] }, 0.8)"
circleColor: (colorName) ->
backgroundColor: "rgba(#{ @colorCode()[colorName] }, 0.2)"
borderColor: "rgba(#{ @colorCode()[colorName] }, 1)"
borderWidth: 1
hoverBackgroundColor: "#fff"
hoverBorderColor: "rgba(#{ @colorCode()['blue'] },0.8)"
<canvas data-bind-id="id" data-bind-data-height="height | default 200" data-bind-data-width="width | default 200"></canvas>
SCHEDULER.every "2s" do |job|
send_event("chart", {
type: "bar",
header: "Calories Burned",
labels: ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5"],
colorNames: ["yellow", "yellow", "yellow", "yellow", "yellow"],
datasets: [210, 339, 220, 494, 109]
})
end
@caitfriedlander
Copy link

Hi! I'm a totally novice with both Smashing and Chart.js and I'm running into an issue where my charts will not resize properly when I'm resizing the dahsboard. I'm wondering if anyone has ever had a similar experience? (I'll write a much more thorough post tonight but I'm just wondering if anyone has been able to solve any sort of similar issue where charts just aren't resizing correctly.

@tywhang
Copy link
Author

tywhang commented Oct 26, 2018

@caitfriedlander Are you having issues with this library in particular? You can customize the height and width of your charts by passing in the proper attributes. If you're wondering about dynamic resizing, I'm not so sure if Smashing is intended to be used for constantly changing heights and widths.

Here's a repository of a full example you can look at: https://github.com/tywhang/smashing-chartjs-example
Live example: https://github.com/tywhang/smashing-chartjs-example

@cevapIT
Copy link

cevapIT commented Nov 7, 2018

First of all: thanks for the widget, it's great!

Is there any way to change the labels size and color or let the axes start by zero?
I tried this in the job file, but it didn't work:
send_event("myChart", { type: "bar", header: "Bar chart demo", labels: ["first bar'", "second bar'"], colorNames: ["green", "blue"], datasets: [display_firstValue, display_secondValue], options: { legend: { labels: { fontColor: "white", fontSize: 30 } }, scales: { yAxes: [{ ticks: { fontColor: "white", fontSize: 30, stepSize: 300, beginAtZero: true } }], xAxes: [{ ticks: { fontColor: "white", fontSize: 26, stepSize: 300, beginAtZero: true } }] } } })

@brieuclambert
Copy link

Hi! Thanks a lot for the amazing work ! It's really great and easy to use.

Although I'm facing an issue with passing options to the charts, and nothing that I've tried seems to have any effect on the chart. I tried passing the options in the job file as in the comment above, putting the options in multiple places in the chartjs.coffee file, but none seems to work. Do you have an example of working chart with custom options? It would be amazing.

Thanks in advance!

@tywhang
Copy link
Author

tywhang commented Apr 19, 2019

Hello @cevapIT and @brieuclambert.

I unfortunately haven't had as much time as I would like to put in this project.
I'm happily accepting any PRs! This project definitely could use the love.

Thanks for using it though!

@grubbychicken
Copy link

Thanks @tywhang for this, it's great.
Any chance you can help me pass options to the charts please? I'm looking to disable the legend on a doughnut chart with something like this:

options: { legend: { display: false }

I'm sure there is a simple way to do this as I see you have accounted for the options in the coffee script. I just can't seem to pass the options so they work. Thanks in advance.

@tywhang
Copy link
Author

tywhang commented Apr 16, 2020

@grubbychicken Getting those options passed correctly is definitely on my TO-DO list. I haven't worked on this project in a while. It could take some time for me to get to it.

You are welcome to make a Pull Request! :D

@strelexx
Copy link

@grubbychicken Getting those options passed correctly is definitely on my TO-DO list. I haven't worked on this project in a while. It could take some time for me to get to it.

You are welcome to make a Pull Request! :D

Hi @tywhang
Thanks for the solution.
Could you please explain what options now available to pass and how to do this. I tried everything from above. It didn't work

@curi0sity97
Copy link

Hi,
I am having trouble setting up a pie chart with an additional layer. Havent been able to correclty pass a second dataset. Does anyone have a quick example/tip of how to do it? Thx!

@pvaramballypivot
Copy link

@tywhang I am seeing this error when I run smashing install b4a67180da816eb0695f

.rbenv/versions/3.0.1/lib/ruby/gems/3.0.0/gems/smashing-1.3.4/lib/dashing/downloader.rb:14:in `initialize': No such file or directory @ rb_sysopen - https://api.github.com/gists/b4a67180da816eb0695f (Errno::ENOENT)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment