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

Multiple charts in a row #97

Merged
merged 17 commits into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 7 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ AllCops:
- 'daru-view.gemspec'
- '**/*.rake'
DisplayCopNames: true
TargetRubyVersion: 2.1
TargetRubyVersion: 2.2
Copy link
Member

Choose a reason for hiding this comment

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

Why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated target ruby version to 2.2 in .rubocoop.yml file as rubocop was producing this error:

Error: Unsupported Ruby version 2.1 found in TargetRubyVersion parameter (in .rubocop.yml). 2.1-compatible analysis was dropped after version 0.58.


# Preferred codebase style ---------------------------------------------
Layout/ExtraSpacing:
Expand Down Expand Up @@ -65,6 +65,12 @@ Style/SingleLineBlockParams:
Style/PerlBackrefs:
Enabled: false

# Tried to disable in the file itself but this style rubocop was not there in
# ruby 2.0, so it threw Lint/UnneededDisable rubocop offence.
Style/MixinUsage:
Exclude:
- 'lib/daru/view/plot_list.rb'

Layout/SpaceAfterComma:
Enabled: false

Expand Down
1 change: 1 addition & 0 deletions lib/daru/view.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'daru/view/version'
require 'daru/view/plot'
require 'daru/view/plot_list'
require 'daru/view/adapters/highcharts/display'
require 'daru/view/adapters/nyaplot/display'
require 'daru/view/adapters/googlecharts/display'
Expand Down
5 changes: 5 additions & 0 deletions lib/daru/view/adapters/googlecharts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ module GooglechartsAdapter
# data << query
# options = {type: :area}
# chart = Daru::View::Plot.new(data, options)
#
# @example Multiple Charts in a row
# Draw the Daru::View::PlotList object with the data as an array of
# Daru::View::Plots(s) or Daru::View::Table(s) or both
# combined = Daru::View::PlotList([line_chart, bar_chart])
def init(data=[], options={})
@table = GoogleVisualr::DataTable.new
@table = get_table(data) unless data.is_a?(String)
Expand Down
2 changes: 1 addition & 1 deletion lib/daru/view/adapters/highcharts/display.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def to_html(placeholder=random_canvas_id)

def show_in_iruby(placeholder=random_canvas_id)
# TODO : placeholder pass, in plot#div
load_dependencies('iruby')
IRuby.html to_html_iruby(placeholder)
end

Expand All @@ -89,6 +88,7 @@ def show_in_iruby(placeholder=random_canvas_id)
# `high_chart_iruby` which doesn't use `onload` in chart script.
def to_html_iruby(placeholder=random_canvas_id)
# TODO : placeholder pass, in plot#div
load_dependencies('iruby')
Copy link
Member

Choose a reason for hiding this comment

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

to_html_iruby is for generating the html and javascript only. At that time will don't want to load the dependent files, 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.

load_dependecies is used to load the dependencies for HighCharts modules (provided in the modules option) and HighMaps dependent files. Right now, in web frameworks too, these dependencies are loaded in to_html.

Copy link
Member

Choose a reason for hiding this comment

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

Okay in this case we have to load it during the generation of body html code.

chart_hash_must_be_present
script = high_chart_css(placeholder)
script << high_chart_iruby(extract_chart_class, placeholder, self)
Expand Down
102 changes: 102 additions & 0 deletions lib/daru/view/plot_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
require 'erb'
require 'daru/view/adapters/highcharts/display'
require 'daru/view/adapters/nyaplot/display'
require 'daru/view/adapters/googlecharts/display'

# Otherwise Daru::IRuby module was used and IRuby.html method was not working.
# Have disabled rubocop Style/Mixin for this in .rubocop.yml file
include IRuby::Utils if defined?(IRuby)

module Daru
module View
class PlotList
attr_reader :data

# @param data [Daru::View::Plot, Daru::View::Table] data to visualize
# @return [void] initialize PlotList with data
# @example
#
# df = Daru::DataFrame.new({a:['A', 'B', 'C', 'D', 'E'], b:[10,20,30,40,50]})
# plot1 = Daru::View::Plot.new(
# df, type: :bar, x: :a, y: :b, adapter: :googlecharts
# )
# plot2 = Daru::View::Plot.new(
# df, chart: { type: 'line' }, adapter: :highcharts
# )
# plots = Daru::View::PlotList.new([plot1, plot2])
#
def initialize(data=[])
unless data.is_a?(Array) && data.all? { |plot|
plot.is_a?(Daru::View::Plot) ||
plot.is_a?(Daru::View::Table)
}
raise ArgumentError, 'Invalid Argument Passed! Valid Arguments '\
'consists an Array of: Daru::View::Plot or '\
'Daru::View::Table (Right now, it is not '\
'implemented for DataTables)'
end
@data = data
end

# @return [void] display in IRuby notebook
def show_in_iruby
IRuby.html(div)
end

# @return [String] generates html code to include in body tag
def div
path = File.expand_path('templates/multiple_charts_div.erb', __dir__)
template = File.read(path)
charts_id_div_tag = []
charts_script = extract_charts_script(charts_id_div_tag)
ERB.new(template).result(binding)
end

# @return [void] writes a html file to disk
def export_html_file(path='./plot.html')
path = File.expand_path(path, Dir.pwd)
str = generate_html
File.write(path, str)
end

private

def extract_charts_script(charts_id_div_tag=[])
charts_script = ''
@data.each do |plot|
chart_script = extract_chart_script(plot)
charts_id_div_tag << chart_script.partition(%r{<div(.*?)<\/div>}ixm)[1]
chart_script.sub!(%r{<div(.*?)<\/div>}ixm, '')
charts_script << chart_script
end
charts_script
end

def extract_chart_script(plot)
# TODO: Implement this for datatables too
return plot.div unless defined?(IRuby.html) &&
plot.is_a?(Daru::View::Plot) &&
plot.chart.is_a?(LazyHighCharts::HighChart)
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to check HighCharts explicitly ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In HighCharts, js for web frameworks (includes onload) and IRuby notebook is generated separately. So, plot.div would generate the wrong script for HighCharts in case of IRuby notebook. That's why I have checked it separately.

plot.chart.to_html_iruby
end

def generate_html
path = File.expand_path(
'templates/static_html_multiple_charts.erb', __dir__
)
template = File.read(path)
charts_script = div
set_init_script = {}
initial_script = ''
@data.each do |plot|
adapter = plot.adapter
unless set_init_script[adapter]
set_init_script[adapter] = true
initial_script << plot.adapter.init_script
end
end
ERB.new(template).result(binding)
end
end
end
end
8 changes: 8 additions & 0 deletions lib/daru/view/templates/multiple_charts_div.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<table>
<tr>
<% charts_id_div_tag.each do |chart_div_tag| %>
<td><%= chart_div_tag %></td>
<% end %>
</tr>
</table>
<%= charts_script %>
10 changes: 10 additions & 0 deletions lib/daru/view/templates/static_html_multiple_charts.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<html lang='en'>
<head>
<!-- TODO: extend and display with table and chart both in html table -->
<title>Multiple Charts</title>
<%= initial_script %>
</head>
<body>
<%= charts_script %>
</body>
</html>
1 change: 0 additions & 1 deletion spec/adapters/googlecharts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
let(:column_chart_chart) {Daru::View::Plot.
new(data_table.table, column_chart_options)}


describe "initialization Charts" do
it "Default chart GoogleVisualr::Interactive::LineChart " do
expect(Daru::View::Plot.new.chart)
Expand Down
25 changes: 0 additions & 25 deletions spec/adapters/highcharts/display_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -328,31 +328,6 @@
end
end

describe "#to_html_iruby" do
it "should plot HighMap when chart_class is set to map" do
@hc.options[:chart_class] = "Map";
expect(@hc.chart.to_html_iruby(
@placeholder)
).to match(/window\.chart_placeholder\s+=\s+new\s+Highcharts.Map/)
end
it "should plot HighStock when chart_class is set to stock" do
@hc.options[:chart_class] = "SToCk";
expect(@hc.chart.to_html_iruby(
@placeholder)
).to match(/window\.chart_placeholder\s+=\s+new\s+Highcharts.StockChart/)
end
it "should plot HighChart otherwise" do
expect(@hc.chart.to_html_iruby(
@placeholder)
).to match(/window\.chart_placeholder\s+=\s+new\s+Highcharts.Chart/)
end
it "should set css correctly" do
expect(@hc.chart.to_html_iruby(
@placeholder)
).to match(/#placeholder .highcharts-background {fill/)
end
end

describe "#extract_chart_class" do
it "should return Map class when chart_class is set to map" do
@hc.options[:chart_class] = "map";
Expand Down
Loading