Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Chartwrapper #95

Merged
merged 9 commits into from
Jul 14, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/daru/view/adapters/datatables.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module DatatablesAdapter
# the datatables option concept.
#
# TODO : this docs must be improved
def init_table(data=[], options={})
def init_table(data=[], options={}, _user_options={})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In _user_options , _ is not required, right ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless user_options is used in the method (in which it has been passed as a parameter), we need to prefix it with _ as rubocop was throwing Lint/UnusedMethodArgument error.

# TODO : create data array from the df and vector data. So that
# we can directly use the array.(No need to create df or vector and
# generate the html table using to_html)
Expand Down
6 changes: 4 additions & 2 deletions lib/daru/view/adapters/googlecharts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ module GooglechartsAdapter
# data << query
# options = {type: :area}
# chart = Daru::View::Plot.new(data, options)
def init(data=[], options={})
def init(data=[], options={}, user_options={})
@table = GoogleVisualr::DataTable.new
@table = get_table(data) unless data.is_a?(String)
validate_url(data) if data.is_a?(String)
@chart_type = extract_chart_type(options)
@chart = GoogleVisualr::Interactive.const_get(
@chart_type
).new(@table, options)
@chart.user_options = user_options
@chart.data = data
@chart
end
Expand Down Expand Up @@ -109,7 +110,7 @@ def init(data=[], options={})
# query = 'SELECT A, H, O, Q, R, U LIMIT 5 OFFSET 8'
# data << query
# chart = Daru::View::Table.new(data)
def init_table(data=[], options={})
def init_table(data=[], options={}, user_options={})
# if `options` is something like this :
# {
# cols: [{id: 'task', label: 'Employee Name', type: 'string'},
Expand All @@ -125,6 +126,7 @@ def init_table(data=[], options={})
# then directly DataTable is created using options. Use data=[] or nil
@table = GoogleVisualr::DataTable.new(options)
@table.data = data
@table.user_options = user_options
# When data is the URL of the spreadsheet then plot.table will
# contain the empty table as the DataTable is generated in query
# response in js and we can not retrieve the data from google
Expand Down
45 changes: 25 additions & 20 deletions lib/daru/view/adapters/googlecharts/base_chart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,35 @@ class BaseChart
# @return [Array, Daru::DataFrame, Daru::Vector, Daru::View::Table, String]
# Data of GoogleVisualr Chart
attr_accessor :data
# @return [Hash] Various options created to facilitate more features.
# These will be provided by the user
attr_accessor :user_options

# @see #GoogleVisualr::DataTable.query_response_function_name
def query_response_function_name(element_id)
"handleQueryResponse_#{element_id.tr('-', '_')}"
include GoogleVisualr::HelperMethods

# @see #GooleVisualr::DataTable.extract_option_view
def extract_option_view
return js_parameters(@options.delete('view')) unless @options['view'].nil?
'\'\''
end

# Generates JavaScript when data is imported from spreadsheet and renders
# the Google Chart in the final HTML output when data is URL of the
# google spreadsheet
# Generates JavaScript function for rendering the chartwrapper
#
# @param data [String] URL of the google spreadsheet in the specified
# format: https://developers.google.com/chart/interactive/docs
# /spreadsheets
# Query string can be appended to retrieve the data accordingly
# @param element_id [String] The ID of the DIV element that the Google
# Chart should be rendered in
# @return [String] Javascript code to render the Google Chart when data is
# given as the URL of the google spreadsheet
def to_js_spreadsheet(data, element_id=SecureRandom.uuid)
js = ''
js << "\n<script type='text/javascript'>"
js << load_js(element_id)
js << draw_js_spreadsheet(data, element_id)
js << "\n</script>"
# @param (see #to_js_chart_wrapper)
# @return [String] JS function to render the chartwrapper
def draw_js_chart_wrapper(data, element_id)
js = ''
js << "\n function #{chart_function_name(element_id)}() {"
js << "\n \t#{@data_table.to_js}"
js << "\n \tvar wrapper = new google.visualization.ChartWrapper({"
js << "\n \t\tchartType: '#{chart_name}',"
js << append_data(data)
js << "\n \t\toptions: #{js_parameters(@options)},"
js << "\n \t\tcontainerId: '#{element_id}',"
js << "\n \t\tview: #{extract_option_view}"
js << "\n \t});"
js << draw_wrapper
js << "\n };"
js
end

Expand Down
68 changes: 36 additions & 32 deletions lib/daru/view/adapters/googlecharts/data_table_iruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ class DataTable
# options will enable us to give some styling for table.
# E.g. pagination, row numbers, etc
attr_accessor :options
# @return [Hash] Various options created to facilitate more features.
# These will be provided by the user
attr_accessor :user_options

# included to use `js_parameters` method
include GoogleVisualr::ParamHelpers
include GoogleVisualr::HelperMethods

# overiding the current initialze method (of the google_visualr).
# This might be not a good idea. But right now I need these lines in it :
Expand Down Expand Up @@ -50,37 +54,10 @@ def to_js_full_script(element_id=SecureRandom.uuid)
js
end

# Generates JavaScript and renders the Google Chart DataTable in the
# final HTML output when data is URL of the google spreadsheet
#
# @param data [String] URL of the google spreadsheet in the specified
# format: https://developers.google.com/chart/interactive/docs
# /spreadsheets
# Query string can be appended to retrieve the data accordingly
# @param element_id [String] The ID of the DIV element that the Google
# Chart DataTable should be rendered in
# @return [String] Javascript code to render the Google Chart DataTable
# when data is given as the URL of the google spreadsheet
def to_js_full_script_spreadsheet(data, element_id=SecureRandom.uuid)
js = ''
js << '\n<script type=\'text/javascript\'>'
js << load_js(element_id)
js << draw_js_spreadsheet(data, element_id)
js << '\n</script>'
js
end

def chart_function_name(element_id)
"draw_#{element_id.tr('-', '_')}"
end

# @param element_id [String] The ID of the DIV element that the Google
# Chart DataTable should be rendered in
# @return [String] unique function name to handle query response
def query_response_function_name(element_id)
"handleQueryResponse_#{element_id.tr('-', '_')}"
end

def google_table_version
'1.0'.freeze
end
Expand All @@ -89,6 +66,13 @@ def package_name
'table'
end

# @return [String] Returns value of the view option provided by the user
# and '' otherwise
def extract_option_view
return js_parameters(@options.delete(:view)) unless @options[:view].nil?
'\'\''
end

# Generates JavaScript for loading the appropriate Google Visualization
# package, with callback to render chart.
#
Expand Down Expand Up @@ -119,6 +103,26 @@ def draw_js(element_id)
js
end

# Generates JavaScript function for rendering the chartwrapper
#
# @param (see #to_js_chart_wrapper)
# @return [String] JS function to render the chartwrapper
def draw_js_chart_wrapper(data, element_id)
js = ''
js << "\n function #{chart_function_name(element_id)}() {"
js << "\n \t#{to_js}"
js << "\n \tvar wrapper = new google.visualization.ChartWrapper({"
js << "\n \t\tchartType: 'Table',"
js << append_data(data)
js << "\n \t\toptions: #{js_parameters(@options)},"
js << "\n \t\tcontainerId: '#{element_id}',"
js << "\n \t\tview: #{extract_option_view}"
js << "\n \t});"
js << draw_wrapper
js << "\n };"
js
end

# Generates JavaScript function for rendering the google chart table when
# data is URL of the google spreadsheet
#
Expand All @@ -128,14 +132,14 @@ def draw_js(element_id)
def draw_js_spreadsheet(data, element_id)
js = ''
js << "\n function #{chart_function_name(element_id)}() {"
js << "\n var query = new google.visualization.Query('#{data}');"
js << "\n query.send(#{query_response_function_name(element_id)});"
js << "\n var query = new google.visualization.Query('#{data}');"
js << "\n query.send(#{query_response_function_name(element_id)});"
js << "\n }"
js << "\n function #{query_response_function_name(element_id)}(response) {"
js << "\n var data_table = response.getDataTable();"
js << "\n var table = new google.visualization.Table"\
js << "\n var data_table = response.getDataTable();"
js << "\n var table = new google.visualization.Table"\
"(document.getElementById('#{element_id}'));"
js << "\n table.draw(data_table, #{js_parameters(@options)});"
js << "\n table.draw(data_table, #{js_parameters(@options)});"
js << "\n };"
js
end
Expand Down
26 changes: 18 additions & 8 deletions lib/daru/view/adapters/googlecharts/display.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
require 'securerandom'
require 'erb'
require_relative 'table_chart_common_methods'
require_relative 'data_table_iruby'
require_relative 'base_chart'
require 'daru/view/constants'

module GoogleVisualr
def self.init_script(
dependent_js=['google_visualr.js', 'loader.js']
dependent_js=GOOGLECHARTS_DEPENDENCIES
)
js = ''
js << "\n<script type='text/javascript'>"
Expand All @@ -24,6 +26,8 @@ def show_script(dom=SecureRandom.uuid, options={})
script_tag = options.fetch(:script_tag) { true }
if script_tag
show_script_with_script_tag(dom)
elsif user_options[:chart_class].to_s.capitalize == 'Chartwrapper'
get_html_chart_wrapper(data, dom)
elsif data.is_a?(String)
get_html_spreadsheet(data, dom)
else
Expand All @@ -35,14 +39,13 @@ def show_script(dom=SecureRandom.uuid, options={})
# Chart should be rendered in
# @return [String] js code to render the chart with script tag
def show_script_with_script_tag(dom=SecureRandom.uuid)
# if it is data table and importing data from spreadsheet
if is_a?(GoogleVisualr::DataTable) && data.is_a?(String)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How your changes is handling this if condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have kept the same method name for both table and chart, and now have put that method in the common module.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Prakriti-nith , I don't think your replay is relevant . Now are you using the method to_js_full_script_spreadsheet ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed to_js_full_script_spreadsheet method from data_table_iruby here and have added to_js_spreadsheet in the common module (display) here. Now, this method can be used both for tables as well as charts which is checked here.

to_js_full_script_spreadsheet(data, dom)
elsif is_a?(GoogleVisualr::DataTable)
to_js_full_script(dom)
# Importing data from spreadsheet
# if it is data table
if user_options[:chart_class].to_s.capitalize == 'Chartwrapper'
to_js_chart_wrapper(data, dom)
elsif data.is_a?(String)
to_js_spreadsheet(data, dom)
elsif is_a?(GoogleVisualr::DataTable)
to_js_full_script(dom)
else
to_js(dom)
end
Expand Down Expand Up @@ -74,6 +77,13 @@ def get_html_spreadsheet(data, dom)
html
end

def get_html_chart_wrapper(data, dom)
html = ''
html << load_js(dom)
html << draw_js_chart_wrapper(data, dom)
html
end

def to_html(id=nil, options={})
path = File.expand_path(
'../../templates/googlecharts/chart_div.erb', __dir__
Expand All @@ -86,7 +96,7 @@ def to_html(id=nil, options={})
end

def show_in_iruby(dom=SecureRandom.uuid)
IRuby.html(to_html(dom))
IRuby.html to_html(dom)
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/daru/view/adapters/googlecharts/iruby_notebook.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'daru/view/constants'

module GoogleVisualr
# generate initializing code
def self.generate_init_code(dependent_js)
Expand All @@ -8,7 +10,7 @@ def self.generate_init_code(dependent_js)
end

# Enable to show plots on IRuby notebook
def self.init_iruby(dependent_js=['google_visualr.js', 'loader.js'])
def self.init_iruby(dependent_js=GOOGLECHARTS_DEPENDENCIES)
js = generate_init_code(dependent_js)
IRuby.display(IRuby.javascript(js))
end
Expand Down
68 changes: 68 additions & 0 deletions lib/daru/view/adapters/googlecharts/table_chart_common_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require 'google_visualr'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is already one module is added for display purpose , please check display module.
Isn't it display module contains similar methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved the common methods to display module. Sorry, I got confused. Actually, display module contained methods that called the methods of base_chart.rb and data_table.rb (like to_js and others) and there was no method that was called back from these files to display.


module GoogleVisualr
module HelperMethods
# @param element_id [String] The ID of the DIV element that the Google
# Chart DataTable should be rendered in
# @return [String] unique function name to handle query response
def query_response_function_name(element_id)
"handleQueryResponse_#{element_id.tr('-', '_')}"
end

# @param data [Array, Daru::DataFrame, Daru::Vector, String] Data
# of GoogleVisualr DataTable
# @return [String] Data option (dataSourceUrl or dataTable) required to
# draw the Chartwrapper based upon the data provided.
def append_data(data)
return "\n \t\tdataSourceUrl: '#{data}'," if data.is_a? String
"\n \t\tdataTable: data_table,"
end

# So that it can be used in ChartEditor also
#
# @return [String] Returns string to draw the Chartwrapper and '' otherwise
def draw_wrapper
return "\n \twrapper.draw();" if
user_options[:chart_class].to_s.capitalize == 'Chartwrapper'
''
end

# Generates JavaScript and renders the Google Chartwrapper in the
# final HTML output.
#
# @param data [Array, Daru::DataFrame, Daru::Vector, Daru::View::Table, String]
# Data of GoogleVisualr Chart
# @param element_id [String] The ID of the DIV element that the Google
# Chartwrapper should be rendered in
# @return [String] Javascript code to render the Google Chartwrapper
def to_js_chart_wrapper(data, element_id=SecureRandom.uuid)
js = ''
js << "\n<script type='text/javascript'>"
js << load_js(element_id)
js << draw_js_chart_wrapper(data, element_id)
js << "\n</script>"
js
end

# Generates JavaScript when data is imported from spreadsheet and renders
# the Google Chart in the final HTML output when data is URL of the
# google spreadsheet
#
# @param data [String] URL of the google spreadsheet in the specified
# format: https://developers.google.com/chart/interactive/docs
# /spreadsheets
# Query string can be appended to retrieve the data accordingly
# @param element_id [String] The ID of the DIV element that the Google
# Chart should be rendered in
# @return [String] Javascript code to render the Google Chart when data is
# given as the URL of the google spreadsheet
def to_js_spreadsheet(data, element_id=SecureRandom.uuid)
js = ''
js << "\n<script type='text/javascript'>"
js << load_js(element_id)
js << draw_js_spreadsheet(data, element_id)
js << "\n</script>"
js
end
end
end
2 changes: 1 addition & 1 deletion lib/daru/view/adapters/highcharts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module HighchartsAdapter
#
# @param [Array/Daru::DataFrame/Daru::Vector] data
#
def init(data=[], options={})
def init(data=[], options={}, _user_options={})
# Alternate way is using `add_series` method.
#
# There are many options present in Highcharts so it is better to use
Expand Down
2 changes: 1 addition & 1 deletion lib/daru/view/adapters/nyaplot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module View
module Adapter
module NyaplotAdapter
extend self # rubocop:disable Style/ModuleFunction
def init(data, options)
def init(data, options, _user_options={})
data_new = guess_data(data)
data_new.plot(options)
end
Expand Down
3 changes: 3 additions & 0 deletions lib/daru/view/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
DATA = 'modules/data.js'.freeze
HIGHCHARTS_DEPENDENCIES = [HIGHSTOCK, MAP, EXPORTING, HIGHCHARTS_3D, DATA].freeze

# Dependent GoogleCharts JS constants for web frameworks and IRuby notebook
GOOGLECHARTS_DEPENDENCIES = ['google_visualr.js', 'loader.js'].freeze

# Regex pattern to match a valid URL
PATTERN_URL = Regexp.new(
'^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?\/.*)?$'
Expand Down
Loading