Skip to content

Instantly share code, notes, and snippets.

@joshmcarthur
Created March 29, 2012 22:42
Show Gist options
  • Save joshmcarthur/2244508 to your computer and use it in GitHub Desktop.
Save joshmcarthur/2244508 to your computer and use it in GitHub Desktop.
Base Chart Class
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
#
#= require jquery.jqplot
#= require jqplot.dateAxisRenderer
#= require jqplot.enhancedLegendRenderer
#= require jqplot.highlighter
class LolChart
# The default options for a chart.
# Default options include nice colors for series legend
# floating tooltips on data points
# A 'No data' message
# A nicer legend
# Date axis rendering
@chart_options = {
seriesColors: ["#134A9F", "#4B9468", "#CF4042"]
highlighter:
show: true
tooltipLocation: 'nw'
sizeAdjust: 10
tooltipContentEditor: (content, series_index, point_index, plot) ->
$('<h1></h1>').text(
"#{plot.legend.labels[series_index]}: #{plot.series[series_index].data[point_index][1]}"
).html()
grid:
background: '#FFF'
shadow: false
borderWidth: 1.0
noDataIndicator:
show: true
indicator: 'No data with these filters'
legend:
show: true
fontSize: '10px'
renderer: $.jqplot.EnhancedLegendRenderer
axes:
yaxis:
pad: 1.0
xaxis:
pad: 2
renderer: $.jqplot.DateAxisRenderer
}
# Call with new LolChart(options)
# Creates options for a chart, and extends the default chart
# options with any customizations
constructor: (options) ->
@options = $.extend {
chart_div: $('#chart')
dataURL: "/dashboard/scan_summary_graph.json"
ajaxRequestParamsFunc: ->
chart_options: {}
},
options
@chart_options = $.extend(@chart_options, options.chart_options)
# Load the data from the datasource, and then call
# the chart rendering function
@reload()
# Load the data from the AJAX data source, and then call a callback function
# A note on chart data
# jqPlot requires series are handled in the following way:
# * Each series is passed in as a 2D array to the 'data' option
# * Series labels are applied in the options JSON object which follows the data
# For this reason, chart data is split into an array with two values - one with all of the names of the series
# and one with the value pairs
loadData: (callback) ->
$.getJSON(
@options.dataURL,
@options.ajaxRequestParamsFunc(),
callback
)
# Just an accessor function to have a more sensical function to call for reloading
reload: ->
@loadData(@renderChart)
# The big'un! This function performs a number of..er... functions.
# First of all, it checks we have some data to work with
# Next, it destroys any old chart, and unbinds events
# Next, it uses jqPlot to render the new chart, and binds to
# the window resize event to re-plot the chart on window sizing
# Finally, it replots the chart
renderChart: (chart_data) =>
@chart_data = chart_data
unless @chart_data and @chart_data.series[0].length > 0
@renderEmpty()
return false
@setChartOptions()
@destroyChart()
@chart.destroy() if @chart
@chart = $.jqplot @options.chart_div.attr('id'), @chart_data.series[1], @chart_options
$(window).bind 'resize', =>
@chart.replot({ resetAxes: false })
$(window).trigger('resize')
# Clear the chart by destroying the old chart instance, and clearing the window resize event
destroyChart: ->
if @chart
@chart.destroy()
$(window).unbind('resize')
# Replace the contents of the chart with an 'empty dataset' message
renderEmpty: ->
message = $("<div></div>", { class: 'empty' }).append($("<h3></h3>").css({'text-align': 'center'}).text("No data to display."))
@options.chart_div.append(message)
# Calculate some chart options which are dependent
# on the chart data being present
# This function should be called immediately before calling the jqPlot function
setChartOptions: ->
@chart_options.title = @chart_data.title
@chart_options.legend.labels = @chart_data.series[0]
@chart_options.axes.yaxis.max = @yAxisMax(@chart_data)
# A helper function to work out the maximum value of the y axis series data
# Caveat: there must be series, series y data must be a number
yAxisMax: (chart_data) ->
max = 1
$.each chart_data.series[1], (index, series) ->
$.each series, (index, node) ->
if node[1] > max then max = node[1]
parseInt(max * 1.5)
# Finally, add this class to the global context (the window object)
window.LolChart = LolChart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment