Skip to content

Instantly share code, notes, and snippets.

@masha256
Last active August 3, 2017 08:53
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masha256/e12f31bf7e6a602f3229 to your computer and use it in GitHub Desktop.
Save masha256/e12f31bf7e6a602f3229 to your computer and use it in GitHub Desktop.
Google Column Chart for Dashing

Description

A Dashing widget to show a Google Visualizations Column Chart on a dashboard.

Installation

Copy the google_column.coffee, google_column.html and google_column.scss file to into /widgets/google_column directory.

Add the following to the dashboard layout file:

    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
        google.load("visualization", "1", {packages:["corechart"]});
    </script>

Then to include the widget on the dashboard, add the following item to your dashboard file:

    <li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
      <div data-id="mychart" data-view="GoogleColumn"  data-title="My Chart"></div>
    </li>

Options

The following options can be added to the <div> of the chart object (defaults in parenthesis):

  • data-title - (no title) Title of the chart
  • data-is_stacked - (false) Set to true to enable stacking of the y axis values.
  • data-colors - (Googles default colors) A comma separated list of colors to use for the chart bars
  • data-legend_position - (right) Position of the legend. One of 'bottom', 'left', 'in', 'none', 'right' or 'top'

Complex Example

The following would stack the y axis values, remove the legend and plot a two-valued chart using purple and black bars:

    <li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
      <div data-id="mychart" data-view="GoogleColumn" data-is_stacked="true" data-legend_position="none" data-colors="purple, black" data-title="My Chart"></div>
    </li>

Populating the Chart

To send data to the chart, use send_event to send an item called points with a two dimensional array. Make sure the first "row" in the array is an array of headers for the data.

For example:

send_event('mychart', points: [
      ['Year', 'Sales', 'Expenses'],
      ['2004',  1000,      400],
      ['2005',  1170,      460],
      ['2006',  660,       1120],
      ['2007',  1030,      540]
  ])
class Dashing.GoogleColumn extends Dashing.Widget
@accessor 'current', ->
return @get('displayedValue') if @get('displayedValue')
points = @get('points')
if points
points[points.length - 1].y
ready: ->
container = $(@node).parent()
# Gross hacks. Let's fix this.
width = (Dashing.widget_base_dimensions[0] * container.data("sizex")) + Dashing.widget_margins[0] * 2 * (container.data("sizex") - 1)
height = (Dashing.widget_base_dimensions[1] * container.data("sizey"))
colors = null
if @get('colors')
colors = @get('colors').split(/\s*,\s*/)
@chart = new google.visualization.ColumnChart($(@node).find(".chart")[0])
@options =
height: height
width: width
colors: colors
backgroundColor:
fill:'transparent'
isStacked: @get('is_stacked')
legend:
position: @get('legend_position')
animation:
duration: 500,
easing: 'out'
if @get('points')
@data = google.visualization.arrayToDataTable @get('points')
else
@data = google.visualization.arrayToDataTable []
@chart.draw @data, @options
onData: (data) ->
if @chart
@data = google.visualization.arrayToDataTable data.points
@chart.draw @data, @options
<h1 class="title" data-bind="title"></h1>
<div class="chart"></div>
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #fb9618;
// ----------------------------------------------------------------------------
// Widget-GoogleGauge styles
// ----------------------------------------------------------------------------
.widget-google-column {
background-color: $background-color;
position: relative;
.title {
position: absolute;
top: 5px;
left: 0px;
right: 0px;
}
.chart {
position: absolute;
left: 0px;
top: 0px;
}
}
@mg786
Copy link

mg786 commented Sep 30, 2014

Would it be possible to change the colour of the legend text?

@masha256
Copy link
Author

@mg786, sure!

Just change the @options in the .coffee file like so:

@options =
      height: height
      width: width
      colors: colors
      backgroundColor:
        fill:'transparent'
      isStacked: @get('is_stacked')
      legend:
        position: @get('legend_position')
        textStyle:
          color: @get('legend_color')
      vAxis:
        textStyle:
          color: @get('vaxis_color')
      hAxis:
        textStyle:
          color: @get('haxis_color')
      tooltip:
        textStyle:
          color: @get('tooltip_color')
      animation:
        duration: 500,
        easing: 'out'

And then adjust the div in your dashboard erb file like so:

<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
   <div data-id="mychart" data-view="GoogleColumn" data-legend_position="in" data-title="My Chart" data-legend_color="green" data-vaxis_color="red" data-tooltip_color="purple" data-haxis_color="blue"></div>
</li>

@bendraske
Copy link

*** Updated **** I got it working and created a 2D array

I'm trying to send data to a google_column table based on results of a MSSQL query. I have the query results returned and formated as a string variable. When I use the rcvalues variable in the send_event command, the google_column widget does not have a graph. Is google_column capable of interpreting values from a parameter?

require 'json'
require 'tiny_tds'

SCHEDULER.every '60s', :first_in => 0 do |job|
points = []
client = <hidden connection string>
 rs = client.execute("SELECT top(7) convert(varchar,DATEADD(dd, DATEDIFF(dd, 0, SessionTime_Time_I0018), 0),110) as ReportedDate,COUNT(SessionTime_Time_I0018) as ReportedCount FROM [EDSMReporting].[dbo].[urcconnections] GROUP BY DATEADD(dd, DATEDIFF(dd, 0, SessionTime_Time_I0018), 0) Order by ReportedDate desc
")
subpoints = []
subpoints.push('Reported Date')
subpoints.push('Reported Count')
points.push(subpoints)

rs.each do |row|
  subpoints = []
  subpoints.push(row['ReportedDate'])
  subpoints.push(row['ReportedCount'])
  points.push(subpoints)
 end
send_event('rcactivity', points: points)

client.close

end

@ahmedrad
Copy link

I think I'm following the instructions to the letter but I keep getting this error for some reason http://screencast.com/t/nMeROhLh

I'm kinda new to dashing so maybe I'm doing some stupid mistake that I can't see, any ideas?

@jorjahung
Copy link

@ahmedrad in case you haven't solved this issue, it's usually because the .html for the widget is not found.

@Bran-Ko
Copy link

Bran-Ko commented Feb 18, 2015

@ahmedrad
I think that mistake is in first line of .coffee
widgets name don't have more upper case letters (I don't know why)
class Dashing.Googlecolumn extends Dashing.Widget

@rickypotato
Copy link

Can anyone tell me how to set the font size of the title in this column chart? I am also new to dashing. Thanks a lot!

@7Prasanna
Copy link

vAxis: {textStyle : {fontSize:15}}

@derwin12
Copy link

Just a simple example of how to call this via command line:

x1=$(( ( RANDOM % 100 ) + 1 ))
y1=$(( ( RANDOM % 100 ) + 1 ))
x2=$(( ( RANDOM % 100 ) + 1 ))
y2=$(( ( RANDOM % 100 ) + 1 ))

curl -d '{ "auth_token": "MY_TOKEN", "points": [ ["Year", "Sales", "Expenses"], ["2014", '$x1', '$y1'], ["2015", '$x2','$y2'] ] }' http://myhostname:3030/widgets/mychart

@ayb
Copy link

ayb commented Dec 10, 2015

Is there a way to do a horizontal bar chart with this?

@Skillz0r
Copy link

Skillz0r commented Feb 3, 2016

Hey Mike. First of all, keep the good work! I've been using your charts on my dashing dashboards since the first day I met dashing.
I would like to ask you if there is a way of adding Trendlines on this graph. I've tried to adapt the code, but it seems like nothing works.
I tough it would be an easy task, but aparently I was wrong eheh
While using the font code of google charts, all you have to do is add " trendlines: { 0: {type: 'exponential', lineWidth: 5, opacity: .3}}, on your chart options. Is it this easy in dashing?

Thx in advance

@masha256
Copy link
Author

masha256 commented Feb 5, 2016

@Skillz0r

Trendlines look like a great feature! I dug in and couldn't get them to work either. After much head scratching, learning more coffeescript and the debug features of chrome, I did the old fashioned thing and googled for it, and I think I found the issue:

http://stackoverflow.com/questions/19642276/google-charts-trendline-not-showing

The dates are strings, so the trendlines cannot build a valid numerical model from the x axis. For my charts, I will have to dig in and see what it would take to get the X axis as a numerical date value, but perhaps your data is easier to get into numeric form. Hope this helps!

@Litwilly
Copy link

@ayb

I was able to convert this widget to a horizontal bar by making this change to the google_column.coffee file:

Change line 19 from google.visualization.ColumnChart to google.visualization.BarChart

So you would have:

@chart = new google.visualization.BarChart($(@node).find(".chart")[0])

@alexsheehan1
Copy link

does anyone know how to apply labels to the bar chart? i've tried merging the javascript from https://developers.google.com/chart/interactive/docs/gallery/barchart#labeling-bars into the .coffee file but no luck yet.

@Atishdharvesh
Copy link

Hi Everyone,

i've been strugling with this for almost 2weeks now and i'd hope someone might help me out on how to convert my sql query from mysql db into 2D array for sending into the google charts widgets please?

My actual script is >

require 'mysql2'

SCHEDULER.every '1m', :first_in => 0 do |job|
points = []

Myql connection

db = Mysql2::Client.new(:host => "192.168.46.2", :username => "AT-DBA", :password => "P0werLin", :port => 3306, :database => "lbn_kpi" )

Mysql query

sql = "SELECT <Field 1>, <Field 2> FROM Table"

Field 1 is Integer

Field 2 is Decimal(65,30)

rs = db.query(sql, :as => :array)

subpoints = []
subpoints.push('Week')
subpoints.push('MTV')
points.push(subpoints)

rs.each do |row|
subpoints = []
subpoints.push(row['Field 1'])
subpoints.push(row['Field 2'])
points.push(subpoints)
end

Update the List widget

send_event('mychart01', points: points)

Mysql2.close

I get the error:
./mysql_chart_01.rb:23:in []': no implicit conversion of String into Integer (TypeError) from ./mysql_chart_01.rb:23:inblock in

'
from ./mysql_chart_01.rb:21:in each' from ./mysql_chart_01.rb:21:in'

actually i'm not even sure to be able to make it work this way.
If anyone has better suggestion or ruby script for google charts ?

Best regards,

@krzysiod
Copy link

krzysiod commented Aug 3, 2017

any chance on logscale: true ? does not work for me :\

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