Skip to content

Commit

Permalink
Merge pull request #20 from Prakriti-nith/convert_to_array
Browse files Browse the repository at this point in the history
Load large set of data
  • Loading branch information
Shekharrajak committed Jul 22, 2018
2 parents 9881ea9 + 5d05ead commit e47615f
Show file tree
Hide file tree
Showing 16 changed files with 874 additions and 623 deletions.
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ AllCops:
- 'daru-data_tables.gemspec'
- '**/*.rake'
DisplayCopNames: true
TargetRubyVersion: 2.0
TargetRubyVersion: 2.2

# Preferred codebase style ---------------------------------------------
Layout/ExtraSpacing:
Expand Down
8 changes: 8 additions & 0 deletions lib/daru/data_tables/constants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# DataTables CSS dependencies
DATATABLES_DEPENDENCIES_CSS = ['jquery.dataTables.css'].freeze

# Dependent DataTables JS constants for IRuby notebook
DATATABLES_DEPENDENCIES_IRUBY = ['jquery.dataTables.js'].freeze

# Dependent DataTables JS constants for web frameworks
DATATABLES_DEPENDENCIES_WEB = ['jquery-latest.min.js', 'jquery.dataTables.js'].freeze
10 changes: 10 additions & 0 deletions lib/daru/data_tables/core_ext/string.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class String
def js_code(true_or_false=true)
@_datatables_js_code = true_or_false
self
end

def js_code?
@_datatables_js_code || false
end
end
68 changes: 65 additions & 3 deletions lib/daru/data_tables/data_table.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,72 @@
module Daru
module DataTables
class DataTable
attr_accessor :html_options, :element_id, :options
def initialize(options={})
attr_accessor :html_options, :element_id, :options, :data
# @param data [Array, Daru::DataFrame, Daru::Vector] The data provided
# by the user to generate the datatable
# @param options [Hash] Various options provided by the user to
# incorporate in datatable
# @return Initializes the Daru::DataTables::DataTable object
# @example
# vec = Daru::Vector.new([1, 2, 3], name: :a)
# opts = {searching: false}
# table = Daru::DataTables::DataTable.new(vec, opts)
def initialize(data=[], options={})
@element_id = options.delete(:element_id) unless options[:element_id].nil?
@options = options.empty? ? nil : options
@html_options = options.delete(:html_options) unless options[:html_options].nil?
@html_options ||= default_html_options
@data = data
@options = options
@options[:data] = to_data_array(data)
row_number = 0
@options[:data].each do |array|
array.unshift(row_number)
row_number += 1
end
end

private

def default_html_options
table_opts = {
class: 'display',
cellspacing: '0',
width: '100%'
}
html_options = {
table_options: table_opts
}
html_options
end

# DataTables accept the data as Array of array.
#
# TODO : I didn't find use case for Daru::MultiIndex.
def to_data_array(data_set)
case
when data_set.is_a?(Daru::DataFrame)
return ArgumentError unless data_set.index.is_a?(Daru::Index)
rows = data_set.access_row_tuples_by_indexs(*data_set.index.to_a)
convert_to_array_of_array(rows)
when data_set.is_a?(Daru::Vector)
rows = []
data_set.to_a.each { |a| rows << [a] }
rows
when data_set.is_a?(Array)
convert_to_array_of_array(data_set)
else
raise ArgumentError, 'Invalid Argument Passed!'
end
end

def convert_to_array_of_array(rows)
if rows.all? { |row| row.class==Array }
rows
else
tuples = []
rows.each { |row| tuples << [row] }
tuples
end
end
end
end
Expand Down
118 changes: 86 additions & 32 deletions lib/daru/data_tables/display/display.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,57 @@
require_relative 'iruby_notebook'
require_relative '../generate_js/generate_js'
require 'action_view'
require 'daru/data_tables/constants'

module Daru
module DataTables
# dependent script for the library. It must be added in the head tag
# of the web application.
#
# @example
#
# dep_js = DataTables.init_script
#
# use in Rails app : <%=raw dep_js %>
#
def self.init_script(
dependent_js=[
'jquery-latest.min.js', 'jquery.dataTables.js'
],
dependent_css=['jquery.dataTables.css']
# @param dependent_js [Array] dependent js files required
# @return [String] js code of the dependent files
def self.init_javascript(
dependent_js=DATATABLES_DEPENDENCIES_WEB
)
# TODO: there are many js and css files, that must be added for
# more features. Refer: https://datatables.net/download/index
js = ''
js << "\n<script type='text/javascript'>"
js << Daru::DataTables.generate_init_code_js(dependent_js)
js << "\n</script>"
js << "\n<style type='text/css'>"
js << Daru::DataTables.generate_init_code_css(dependent_css)
js << "\n</style>"
js
end

# @param [Array] dependent css files required
# @return [String] CSS code of the dependent file(s)
def self.init_css(
dependent_css=DATATABLES_DEPENDENCIES_CSS
)
css = ''
css << "\n<style type='text/css'>"
css << Daru::DataTables.generate_init_code_css(dependent_css)
css << "\n</style>"
css
end

# dependent script for the library. It must be added in the head tag
# of the web application.
#
# @return [String] code of the dependent css and js file(s)
# @example
#
# dep_js = DataTables.init_script
#
# use in Rails app : <%=raw dep_js %>
def self.init_script
init_code = ''
init_code << init_css
init_code << init_javascript
init_code
end

module Display
# @param dom [String] The ID of the DIV element that the DataTable
# should be rendered in
# @param options [Hash] options provided
# @return [String] js script to render the table
def show_script(dom=SecureRandom.uuid, options={})
script_tag = options.fetch(:script_tag) { true }
if script_tag
Expand All @@ -48,42 +68,76 @@ def show_script(dom=SecureRandom.uuid, options={})
# If table_options is not present then it will assume that table tag is
# already present in the web page source, where we are pasting the
# html code.
# @param id [String] The ID of the DIV element that the DataTable
# should be rendered in
# @param options [Hash] options provided
# @return [String] Generates JavaScript and renders the table in the
# final HTML output.
def to_html(id=nil, options={})
# More things can be added into table_script.erb
path = File.expand_path('../../templates/table_script.erb', __FILE__)
path = File.expand_path('../templates/table_script.erb', __dir__)
template = File.read(path)
id ||= SecureRandom.uuid # TODO: remove it or Use it for table tag.
table_script = show_script(id, script_tag: false)
element_id ||= id
table_script = show_script(element_id, script_tag: false)
html_code = ERB.new(template).result(binding)
# table_options is given. That means table html code is not present in
# the webpage. So it must generate table code with given options.
unless options[:table_options].nil?
options[:table_options][:id] = id
table_thead_tbody = options[:table_options].delete(:table_html)
table_thead_tbody ||= ''
html_code.concat(
content_tag('table', table_thead_tbody.html_safe, options[:table_options])
)
end
table_thead = extract_table
draw_table_thead(element_id, html_code, table_thead)
html_code
end

# @param dom [String] The ID of the DIV element that the DataTable
# should be rendered in
# @return [void] shows the datatable in IRuby notebook
def show_in_iruby(dom=SecureRandom.uuid)
IRuby.html(to_html(dom))
end

# Generates JavaScript and renders the tabke in the final HTML output.
#
# Parameters:
# *element_id [Required] The ID of the DIV element that the table should be rendered in.
# @param element_id [String] The ID of the DIV element that the DataTable
# should be rendered in
# @return [String] returns the javascript of the DataTable
def to_js(element_id)
js = ''
js << "\n<script type='text/javascript'>"
js << draw_js(element_id)
js << "\n</script>"
js
end
end # module Display end

private

def extract_table
return data.to_html_thead unless data.is_a?(Array)
path = File.expand_path('../templates/thead.erb', __dir__)
template = File.read(path)
ERB.new(template).result(binding)
end

def draw_table_thead(element_id, html_code, table_thead)
if html_options && html_options[:table_options]
draw_table_thead_from_html_options(element_id, html_code, table_thead)
# if user provided html_options but not provided html_options[:table_options]
else
html_code.concat(
content_tag(
'table', table_thead.html_safe, id: element_id, class: 'display'
)
)
end
end

def draw_table_thead_from_html_options(element_id, html_code, table_thead)
html_options[:table_options][:id] = element_id
html_options[:table_options][:class] ||= 'display'
table_thead = html_options[:table_options].delete(:table_thead) if
html_options[:table_options][:table_thead]
html_code.concat(
content_tag('table', table_thead.html_safe, html_options[:table_options])
)
end
end

class DataTable
include ActionView::Helpers::TagHelper # to use content_tag
Expand Down
12 changes: 7 additions & 5 deletions lib/daru/data_tables/display/iruby_notebook.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
require 'daru/data_tables/constants'

module Daru
module DataTables
# generate initializing code
def self.generate_init_code_js(dependent_js)
js_dir = File.expand_path('../../js', __FILE__)
path = File.expand_path('../../templates/init.inline.js.erb', __FILE__)
js_dir = File.expand_path('../js', __dir__)
path = File.expand_path('../templates/init.inline.js.erb', __dir__)
template = File.read(path)
ERB.new(template).result(binding)
end

def self.generate_init_code_css(dependent_css)
css_dir = File.expand_path('../../css', __FILE__)
path = File.expand_path('../../templates/init.inline.css.erb', __FILE__)
css_dir = File.expand_path('../css', __dir__)
path = File.expand_path('../templates/init.inline.css.erb', __dir__)
template = File.read(path)
ERB.new(template).result(binding)
end
Expand All @@ -25,7 +27,7 @@ def self.generate_init_code_css(dependent_css)
# DataTables.init_iruby
#
def self.init_iruby(
dependent_js=['jquery.dataTables.js']
dependent_js=DATATABLES_DEPENDENCIES_IRUBY
)
# dependent_css=['jquery.dataTables.css']
# Note: Jquery is dependecy for DataTables.
Expand Down
Loading

0 comments on commit e47615f

Please sign in to comment.