Skip to content

Commit

Permalink
Merge pull request #98 from Prakriti-nith/export_googlechart
Browse files Browse the repository at this point in the history
Export Googlecharts: PNG
  • Loading branch information
Shekharrajak authored Aug 4, 2018
2 parents 6c5b0e7 + 439a32b commit 5bce655
Show file tree
Hide file tree
Showing 11 changed files with 804 additions and 48 deletions.
1 change: 1 addition & 0 deletions lib/daru/view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'daru/view/adapters/highcharts/display'
require 'daru/view/adapters/nyaplot/display'
require 'daru/view/adapters/googlecharts/display'
require 'daru/view/adapters/googlecharts/google_visualr'
require 'daru/view/table'

# needed in load_lib_in_iruby method
Expand Down
18 changes: 14 additions & 4 deletions lib/daru/view/adapters/googlecharts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,24 @@ def export_html_file(plot, path='./plot.html')
File.write(path, str)
end

def export(_plot, _export_type='png', _file_name='chart')
raise 'Not implemented yet'
end

def show_in_iruby(plot)
plot.show_in_iruby
end

# Exporting a googlchart to pdf is not working in IRuby notebook because
# the dependency of jspdf is not properly loaded in IRuby notebook.
# TODO: Need to find some other way to export the chart to pdf in
# IRuby notebook.
#
# @see #Daru::View::Plot.export
def export(plot, export_type='png', file_name='chart')
raise NotImplementedError, 'Not yet implemented!' unless
export_type == 'png'
plot.export_iruby(export_type, file_name) if defined? IRuby
rescue NameError
plot.export(export_type, file_name)
end

def generate_html(plot)
path = File.expand_path(
'../templates/googlecharts/static_html.erb', __dir__
Expand Down
28 changes: 28 additions & 0 deletions lib/daru/view/adapters/googlecharts/display.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,34 @@ def get_html_spreadsheet(data, dom)
html
end

# @see #Daru::View::Plot.export
def export(export_type='png', file_name='chart')
add_listener('ready', extract_export_code(export_type, file_name))
to_html
end

# Exports chart to different formats in IRuby notebook
#
# @param type [String] format to which chart has to be exported
# @param file_name [String] The name of the file after exporting the chart
# @return [void] loads the js code of chart along with the code to export
# in IRuby notebook
def export_iruby(export_type='png', file_name='chart')
IRuby.html(export(export_type, file_name))
end

# Returns the script to export the chart in different formats
#
# @param type [String] format to which chart has to be exported
# @param file_name [String] The name of the file after exporting the chart
# @return [String] the script to export the chart
def extract_export_code(export_type='png', file_name='chart')
case export_type
when 'png'
extract_export_png_code(file_name)
end
end

def to_html(id=nil, options={})
path = File.expand_path(
'../../templates/googlecharts/chart_div.erb', __dir__
Expand Down
13 changes: 13 additions & 0 deletions lib/daru/view/adapters/googlecharts/generate_javascript.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ def draw_wrapper(element_id)
js
end

# @param file_name [String] The name of the file after exporting the chart
# @return [String] the script to export the chart in png format
def extract_export_png_code(file_name)
js = ''
js << "\n \tvar a = document.createElement('a');"
js << "\n \ta.href = chart.getImageURI();"
js << "\n \ta.download = '#{file_name}.png';"
js << "\n \tdocument.body.appendChild(a);"
js << "\n \ta.click();"
js << "\n \tdocument.body.removeChild(a);"
js
end

# Generates JavaScript and renders the Google Chartwrapper in the
# final HTML output.
#
Expand Down
6 changes: 3 additions & 3 deletions lib/daru/view/plot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ def export_html_file(path='./plot.html')
# @param file_name [String] The name of the file after exporting the chart
# @return [String, void] js code of chart along with the code to export it
# and loads the js code to export it in IRuby.
# @example Export a HighChart
# @example
# data = Daru::Vector.new([5 ,3, 4])
# hchart = Daru::View::Plot.new(data)
# hchart.export('png', 'daru')
# chart = Daru::View::Plot.new(data)
# chart.export('png', 'daru')
def export(export_type='png', file_name='chart')
@adapter.export(@chart, export_type, file_name)
end
Expand Down
33 changes: 31 additions & 2 deletions spec/adapters/googlecharts/base_chart_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@
{type: :column, width: 800}
)
}

let(:data_array) do
[
['Year'],
['2013'],
]
end
let(:user_options) {{
listeners: {
select: "alert('A table row was selected');"
}
}}
let(:column_chart) { Daru::View::Plot.new(
data_spreadsheet,
data_array,
{ type: :column },
user_options)
}
Expand Down Expand Up @@ -83,4 +90,26 @@
expect(js).to match(/chart.draw\(data_table, \{width: 800\}/i)
end
end
end

describe "#draw_chart_js" do
subject(:js) { column_chart.chart.draw_chart_js('id') }
it "adds correct data" do
expect(js).to match(
/data_table.addColumn\({"type":"string","label":"Year"}\)/
)
expect(js).to match(/data_table.addRow\(\[{v: "2013"}\]\)/)
end
it "adds correct listener" do
column_chart.chart.add_listener('ready', "alert('hi');")
expect(js).to match(
/google.visualization.events.addListener\(chart, 'ready', function \(e\) {/
)
expect(js).to match(/alert\('hi'\);/)
end
it "generates the valid chart script" do
expect(js).to match(/new google.visualization.DataTable/)
expect(js).to match(/new google.visualization.ColumnChart/)
expect(js).to match(/chart.draw\(data_table, {}\)/)
end
end
end
16 changes: 16 additions & 0 deletions spec/adapters/googlecharts/data_table_iruby_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@
end
end

describe "#add_listener" do
it "adds ready listener for Google datatables" do
data_table.table.add_listener('ready', 'callback')
expect(data_table.table.listeners[0][:event]).to eq('ready')
expect(data_table.table.listeners[0][:callback]).to eq('callback')
end
end

describe "#load_js" do
it "loads valid packages" do
js = data_table.table.load_js('id')
Expand All @@ -85,6 +93,14 @@
/data_table.addRow\(\[\{v: \"2013\"\}\]\);/i)
expect(js).to match(/google.visualization.Table/i)
expect(js).to match(/table.draw\(data_table, \{\}/i)
end
it "adds correct listener" do
data_table.table.add_listener('ready', "alert('hi');")
js = data_table.table.draw_js('id')
expect(js).to match(
/google.visualization.events.addListener\(table, 'ready', function \(e\) {/
)
expect(js).to match(/alert\('hi'\);/)
end
end

Expand Down
38 changes: 38 additions & 0 deletions spec/adapters/googlecharts/display_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,44 @@
end
end

describe "#export" do
it "adds ready listener" do
area_chart_chart.chart.export
expect(area_chart_chart.chart.listeners[0][:event]).to eq('ready')
end
it "generates correct code of the chart" do
js = area_chart_chart.chart.export
expect(js).to match(/google.visualization.DataTable\(\);/i)
expect(js).to match(
/data_table.addColumn\(\{\"type\":\"string\",\"label\":\"Year\"\}\);/)
expect(js).to match(
/data_table.addRow\(\[\{v: \"2013\"\}\]\);/)
expect(js).to match(/google.visualization.AreaChart/i)
expect(js).to match(
/google.visualization.events.addListener\(chart, 'ready'/)
expect(js).to match(/chart.draw\(data_table, \{\}/i)
end
it "generates correct png code" do
js = area_chart_chart.chart.export
expect(js).to match(/document.createElement\('a'\);/)
expect(js).to match(/a.href = chart.getImageURI()/)
expect(js).to match(/a.download = 'chart.png'/)
end
end

describe "#extract_export_code" do
it "extracts correct png code" do
area_chart_chart.chart.html_id = 'id'
js = area_chart_chart.chart.extract_export_code('png', 'daru')
expect(js).to match(/document.createElement\('a'\);/)
expect(js).to match(/a.href = chart.getImageURI()/)
expect(js).to match(/a.download = 'daru.png'/)
expect(js).to match(/document.body.appendChild\(a\)/)
expect(js).to match(/a.click\(\)/)
expect(js).to match(/document.body.removeChild\(a\)/)
end
end

describe "#add_listener_to_chart" do
it "adds the listener mentioned in user_options to the chart" do
column_chart_chart.chart.add_listener_to_chart
Expand Down
14 changes: 14 additions & 0 deletions spec/adapters/googlecharts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,20 @@
end
end

describe "#export" do
it "generates valid script to export a chart to png" do
js = area_chart_chart.adapter.export(area_chart_chart.chart)
expect(js).to match(/google.visualization.DataTable\(\);/)
expect(js).to match(/google.visualization.AreaChart/)
expect(js).to match(/a.href = chart.getImageURI()/)
expect(js).to match(/a.download = 'chart.png'/)
end
it 'raises error for not implemented export types' do
expect{area_chart_chart.adapter.export(area_chart_chart.chart, 'jpeg')}
.to raise_error(NotImplementedError, 'Not yet implemented!')
end
end

describe "#export_html_file" do
it "writes valid html code of the Area Chart to the file" do
area_chart_chart.export_html_file('./plot.html')
Expand Down
Loading

0 comments on commit 5bce655

Please sign in to comment.