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 Charteditor #96

Merged
merged 18 commits into from
Aug 2, 2018
Merged
Show file tree
Hide file tree
Changes from 11 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
34 changes: 17 additions & 17 deletions lib/daru/view/adapters/googlecharts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,6 @@ def init_table(data=[], options={}, user_options={})
@table
end

# @param data [Array, Daru::DataFrame, Daru::Vector, Daru::View::Table]
# The data provided by the user to generate the google datatable.
# Data in String format represents the URL of the google spreadsheet
# from which data has to invoked
# @return [GoogleVisualr::DataTable] the table object will the data
# filled
def get_table(data)
if data.is_a?(Daru::View::Table) &&
data.table.is_a?(GoogleVisualr::DataTable)
data.table
elsif data.is_a?(GoogleVisualr::DataTable)
data
else
add_data_in_table(data)
end
end

# @param data [String] URL of the google spreadsheet from which data
# has to invoked
# @return [Boolean, void] returns true for valid URL and raises error
Expand Down Expand Up @@ -216,6 +199,23 @@ def add_series(plot, opts={})

private

# @param data [Array, Daru::DataFrame, Daru::Vector, Daru::View::Table]
# The data provided by the user to generate the google datatable.
# Data in String format represents the URL of the google spreadsheet
# from which data has to invoked
# @return [GoogleVisualr::DataTable] the table object with the data
# filled
def get_table(data)
if data.is_a?(Daru::View::Table) &&
data.table.is_a?(GoogleVisualr::DataTable)
data.table
elsif data.is_a?(GoogleVisualr::DataTable)
data
else
add_data_in_table(data)
end
end

def extract_chart_type(options)
# TODO: Imprvoe this method.
chart_type = options[:type].nil? ? 'Line' : options.delete(:type)
Expand Down
24 changes: 17 additions & 7 deletions lib/daru/view/adapters/googlecharts/base_chart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,32 @@ def extract_option_view
'\'\''
end

# @param element_id [String] The ID of the DIV element that the Google
# ChartEditor should be rendered in
# @return [String] Generates JavaScript for loading the charteditor package,
# with callback to render ChartEditor
def load_js_chart_editor(element_id)
js = ''
js << "\n google.load('visualization', '#{version}', "
js << " {packages: ['charteditor'], callback:"
js << " #{chart_function_name(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 var wrapper_#{element_id.tr('-', '_')} = null;"
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 \twrapper_#{element_id.tr('-', '_')} = "\
'new google.visualization.ChartWrapper({'
js << extract_chart_wrapper_options(data, element_id)
js << "\n \t});"
js << draw_wrapper
js << draw_wrapper(element_id)
js << "\n };"
js
end
Expand Down
20 changes: 10 additions & 10 deletions lib/daru/view/adapters/googlecharts/data_table_iruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ def google_table_version
end

def package_name
'table'
return 'table' unless
Copy link
Member

Choose a reason for hiding this comment

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

ChartEditor is going through data_table_iruby.rb :O . But why ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ChartEditor works for both google charts and tables, and code to generate the table is written in data_table_iruby.rb. charteditor package is loaded in Google Datatables when chart_class is set to Charteditor.

Copy link
Member

Choose a reason for hiding this comment

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

Is there any example or documentation written, which describes this usecase ?

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 written the rails examples in demo_daru-view and also in the method documentation here.

Copy link
Member

Choose a reason for hiding this comment

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

Write examples in web apps and iruby as well, if haven't.

user_options && user_options[:chart_class].to_s.capitalize == 'Charteditor'
'charteditor'
end

# @return [String] Returns value of the view option provided by the user
Expand All @@ -81,8 +83,8 @@ def extract_option_view
def load_js(element_id)
js = ''
js << "\n google.load('visualization', #{google_table_version}, "
js << "\n {packages: ['#{package_name}'], callback:"
js << "\n #{chart_function_name(element_id)}});"
js << " {packages: ['#{package_name}'], callback:"
js << " #{chart_function_name(element_id)}});"
js
end

Expand All @@ -108,16 +110,14 @@ def draw_js(element_id)
# @return [String] JS function to render the chartwrapper
def draw_js_chart_wrapper(data, element_id)
js = ''
js << "\n var wrapper_#{element_id.tr('-', '_')} = null;"
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 \twrapper_#{element_id.tr('-', '_')} = "\
Copy link
Member

Choose a reason for hiding this comment

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

Same code 2 times ??

'new google.visualization.ChartWrapper({'
js << extract_chart_wrapper_options(data, element_id)
js << "\n \t});"
js << draw_wrapper
js << draw_wrapper(element_id)
js << "\n };"
js
end
Expand Down
101 changes: 88 additions & 13 deletions lib/daru/view/adapters/googlecharts/display.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ def show_script(dom=SecureRandom.uuid, options={})
if script_tag
show_script_with_script_tag(dom)
# Without checking for user_options, data as hash was not working!
elsif user_options &&
user_options[:chart_class].to_s.capitalize == 'Chartwrapper'
get_html_chart_wrapper(data, dom)
elsif user_options && user_options[:chart_class]
case user_options[:chart_class].to_s.capitalize
when 'Chartwrapper'
get_html_chart_wrapper(data, dom)
when 'Charteditor'
get_html_chart_editor(data, dom)
end
elsif data.is_a?(String)
get_html_spreadsheet(data, dom)
else
Expand Down Expand Up @@ -63,6 +67,34 @@ def get_html(dom)
html
end

# @param data [Array, Daru::DataFrame, Daru::Vector, Daru::View::Table, String]
# Data of GoogleVisualr Chart or GoogleVisualr DataTable
# @param dom [String] The ID of the DIV element that the Google
# Chart should be rendered in
# @return [String] js code to render the chart
def get_html_chart_wrapper(data, dom)
html = ''
html << load_js(dom)
html << draw_js_chart_wrapper(data, dom)
html
end

# @param data [Array, Daru::DataFrame, Daru::Vector, Daru::View::Table, String]
# Data of GoogleVisualr Chart or GoogleVisualr DataTable
# @param dom [String] The ID of the DIV element that the Google
# Chart should be rendered in
# @return [String] js code to render the charteditor
def get_html_chart_editor(data, dom)
html = ''
html << if is_a?(GoogleVisualr::DataTable)
load_js(dom)
else
load_js_chart_editor(dom)
end
html << draw_js_chart_editor(data, dom)
html
end

# @param data [String] URL of the google spreadsheet in the specified
# format: https://developers.google.com/chart/interactive/docs
# /spreadsheets
Expand All @@ -79,13 +111,6 @@ 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 Down Expand Up @@ -117,13 +142,43 @@ def append_data(data)
"\n \t\tdataTable: data_table,"
end

# @param element_id [String] The ID of the DIV element that the Google
# Chart should be rendered in
# @return [String] unique function name to save the chart
def save_chart_function_name(element_id)
"saveChart_#{element_id.tr('-', '_')}"
end

# @param (see #draw_js_chart_editor)
# @return [String] options of the ChartWrapper
def extract_chart_wrapper_options(data, element_id)
js = ''
js << if is_a?(GoogleVisualr::DataTable)
"\n \t\tchartType: 'Table',"
else
"\n \t\tchartType: '#{chart_name}',"
end
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
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
def draw_wrapper(element_id)
return "\n \twrapper_#{element_id.tr('-', '_')}.draw();" if
Copy link
Member

Choose a reason for hiding this comment

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

Just want to know, what if we don't provide element_id ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we use only the wrapper (without id) then the chart editor will work only on the last chart. That is, edit button (of any chart) will show the dialog box for the last chart only.

user_options[:chart_class].to_s.capitalize == 'Chartwrapper'
''
js = ''
js << "\n \twrapper_#{element_id.tr('-', '_')}.draw();"
Copy link
Member

Choose a reason for hiding this comment

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

same line at 172 .

js << "\n \tchartEditor_#{element_id.tr('-', '_')} = "\
'new google.visualization.ChartEditor();'
js << "\n \tgoogle.visualization.events.addListener("\
"chartEditor_#{element_id.tr('-', '_')},"\
" 'ok', #{save_chart_function_name(element_id)});"
js
end

# Generates JavaScript and renders the Google Chartwrapper in the
Expand Down Expand Up @@ -163,6 +218,26 @@ def to_js_spreadsheet(data, element_id=SecureRandom.uuid)
js << "\n</script>"
js
end

# @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
# ChartEditor should be rendered in
# @return [String] JS function to render the ChartEditor
def draw_js_chart_editor(data, element_id)
js = ''
js << "\n var chartEditor_#{element_id.tr('-', '_')} = null;"
js << draw_js_chart_wrapper(data, element_id)
js << "\n function #{save_chart_function_name(element_id)}(){"
js << "\n \tchartEditor_#{element_id.tr('-', '_')}.getChartWrapper()."\
"draw(document.getElementById('#{element_id}'));"
js << "\n }"
js << "\n function loadEditor_#{element_id.tr('-', '_')}(){"
js << "\n \tchartEditor_#{element_id.tr('-', '_')}.openDialog("\
"wrapper_#{element_id.tr('-', '_')}, {});"
js << "\n }"
js
end
end

class DataTable
Expand Down
3 changes: 3 additions & 0 deletions lib/daru/view/templates/googlecharts/chart_div.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<% if user_options && user_options[:chart_class].to_s.capitalize == 'Charteditor' %>
<input id="loadcharteditor_<%= id %>" value="Edit" onclick="loadEditor_<%= id.tr('-', '_') %>()" type="submit">
<% end %>
<div id='<%= id %>'></div>
<script>
<%= chart_script %>
Expand Down
25 changes: 12 additions & 13 deletions spec/adapters/googlecharts/base_chart_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
chart_class: 'ChartWrapper'
)
}
let (:plot_spreadsheet_charteditor) {
Daru::View::Plot.new(
data_spreadsheet, {width: 800, view: {columns: [0, 1]}}, chart_class: 'Charteditor'
Copy link
Member

Choose a reason for hiding this comment

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

line length

)
}
let(:plot_charteditor) {Daru::View::Plot.new(data, {}, chart_class: 'Charteditor')}

describe "#extract_option_view" do
it "should return value of view option if view option is provided" do
Expand All @@ -47,19 +53,12 @@
end
end

describe "#to_js_chart_wrapper" do
it "draws valid JS of the ChartWrapper when data is URL of the spreadsheet" do
js = area_chart_spreadsheet.chart.to_js_chart_wrapper(
data_spreadsheet,
'id'
)
expect(js).to match(/google.load\('visualization'/)
expect(js).to match(/callback: draw_id/)
expect(js).to match(/new google.visualization.ChartWrapper/)
expect(js).to match(/chartType: 'AreaChart'/)
expect(js).to match(/dataSourceUrl: 'https:\/\/docs.google/)
expect(js).to match(/options: {}/)
expect(js).to match(/containerId: 'id'/)
describe "#load_js_chart_editor" do
it "loads valid packages" do
js = plot_charteditor.chart.load_js_chart_editor('id')
expect(js).to match(/google.load\('visualization', '1.0',/i)
expect(js).to match(/\{packages: \['charteditor'\], callback:/i)
expect(js).to match(/draw_id\}\)/i)
end
end

Expand Down
51 changes: 33 additions & 18 deletions spec/adapters/googlecharts/data_table_iruby_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
let(:table_chartwrapper) {
Daru::View::Table.new(data, {}, chart_class: 'ChartWrapper')
}
let (:table_spreadsheet_charteditor) {
Daru::View::Table.new(
data_spreadsheet,
{width: 800, view: {columns: [0, 1]}}, chart_class: 'Charteditor'
)
}
let(:table_charteditor) {
Daru::View::Table.new(data, {}, chart_class: 'Charteditor')
}

describe "#to_js_full_script" do
it "generates valid JS of the table" do
Expand Down Expand Up @@ -57,12 +66,18 @@
end

describe "#load_js" do
it "loads valid packages" do
js = data_table.table.load_js('id')
expect(js).to match(/google.load\('visualization', 1.0,/i)
expect(js).to match(/\{packages: \['table'\], callback:/i)
expect(js).to match(/draw_id\}\)/i)
end
it "loads valid packages" do
js = data_table.table.load_js('id')
expect(js).to match(/google.load\('visualization', 1.0,/i)
expect(js).to match(/\{packages: \['table'\], callback:/i)
expect(js).to match(/draw_id\}\)/i)
end
it "loads valid packages" do
js = table_charteditor.table.load_js('id')
expect(js).to match(/google.load\('visualization', 1.0,/i)
expect(js).to match(/\{packages: \['charteditor'\], callback:/i)
expect(js).to match(/draw_id\}\)/i)
end
end

describe "#draw_js" do
Expand All @@ -79,6 +94,18 @@
end
end

describe "#draw_js_chart_wrapper" do
it "draws valid JS of the ChartWrapper" do
js = table_chartwrapper.table.draw_js_chart_wrapper(data, 'id')
expect(js).to match(/new google.visualization.DataTable/)
expect(js).to match(/new google.visualization.ChartWrapper/)
expect(js).to match(/chartType: 'Table'/)
expect(js).to match(/dataTable: data_table/)
expect(js).to match(/options: {}/)
expect(js).to match(/containerId: 'id'/)
end
end

describe "#draw_js_spreadsheet" do
it "draws valid JS of the table when "\
"data is imported from google spreadsheets" do
Expand All @@ -93,16 +120,4 @@
expect(js).to match(/table.draw\(data_table, \{width: 800\}/i)
end
end

describe "#draw_js_chart_wrapper" do
it "draws valid JS of the ChartWrapper" do
js = table_chartwrapper.table.draw_js_chart_wrapper(data, 'id')
expect(js).to match(/new google.visualization.DataTable/)
expect(js).to match(/new google.visualization.ChartWrapper/)
expect(js).to match(/chartType: 'Table'/)
expect(js).to match(/dataTable: data_table/)
expect(js).to match(/options: \{\}/)
expect(js).to match(/containerId: 'id'/)
end
end
end
Loading