dash_creator 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +170 -0
- data/Rakefile +36 -0
- data/app/assets/config/dash_creator_manifest.js +2 -0
- data/app/assets/javascripts/dash_creator/application.js +24 -0
- data/app/assets/javascripts/dash_creator/chart.js +2 -0
- data/app/assets/javascripts/dash_creator/dashboard.js +2 -0
- data/app/assets/javascripts/dash_creator/dashboard_object.js +2 -0
- data/app/assets/javascripts/dash_creator/filter.js +2 -0
- data/app/assets/javascripts/dash_creator/libs/Chart.js +12269 -0
- data/app/assets/javascripts/dash_creator/libs/bootstrap.js +3535 -0
- data/app/assets/javascripts/dash_creator/libs/chartCreator.js +1582 -0
- data/app/assets/javascripts/dash_creator/libs/dashboardCreator.js +531 -0
- data/app/assets/javascripts/dash_creator/libs/daterangepicker.js +1626 -0
- data/app/assets/javascripts/dash_creator/libs/filterCreator.js +733 -0
- data/app/assets/javascripts/dash_creator/libs/jquery-ui.js +18706 -0
- data/app/assets/javascripts/dash_creator/libs/jquery.minicolors.js +1108 -0
- data/app/assets/javascripts/dash_creator/libs/moment.js +4301 -0
- data/app/assets/javascripts/dash_creator/libs/tether.js +1811 -0
- data/app/assets/javascripts/dash_creator/user.js +2 -0
- data/app/assets/stylesheets/dash_creator/application.css +16 -0
- data/app/assets/stylesheets/dash_creator/chart.css +4 -0
- data/app/assets/stylesheets/dash_creator/dashboard.css +4 -0
- data/app/assets/stylesheets/dash_creator/dashboard_object.css +4 -0
- data/app/assets/stylesheets/dash_creator/filter.css +4 -0
- data/app/assets/stylesheets/dash_creator/fonts/FontAwesome.otf +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.eot +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.svg +2671 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.ttf +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.woff +0 -0
- data/app/assets/stylesheets/dash_creator/fonts/fontawesome-webfont.woff2 +0 -0
- data/app/assets/stylesheets/dash_creator/libs/font-awesome.css +2199 -0
- data/app/assets/stylesheets/dash_creator/libs/jquery.minicolors.css +319 -0
- data/app/assets/stylesheets/dash_creator/libs/jquery.minicolors.png +0 -0
- data/app/assets/stylesheets/dash_creator/libs/style.css +13714 -0
- data/app/assets/stylesheets/dash_creator/user.css +4 -0
- data/app/controllers/dash_creator/application_controller.rb +3 -0
- data/app/controllers/dash_creator/chart_controller.rb +81 -0
- data/app/controllers/dash_creator/dashboard_controller.rb +37 -0
- data/app/controllers/dash_creator/dashboard_object_controller.rb +34 -0
- data/app/controllers/dash_creator/filter_controller.rb +60 -0
- data/app/controllers/dash_creator/user_controller.rb +82 -0
- data/app/helpers/dash_creator/application_helper.rb +4 -0
- data/app/helpers/dash_creator/chart_helper.rb +829 -0
- data/app/helpers/dash_creator/dashboard_helper.rb +4 -0
- data/app/helpers/dash_creator/dashboard_object_helper.rb +4 -0
- data/app/helpers/dash_creator/filter_helper.rb +237 -0
- data/app/helpers/dash_creator/user_helper.rb +4 -0
- data/app/jobs/dash_creator/application_job.rb +4 -0
- data/app/mailers/dash_creator/application_mailer.rb +6 -0
- data/app/models/dash_creator/application_record.rb +5 -0
- data/app/models/dash_creator/chart.rb +21 -0
- data/app/models/dash_creator/dashboard.rb +13 -0
- data/app/models/dash_creator/dashboard_object.rb +7 -0
- data/app/models/dash_creator/filter.rb +22 -0
- data/app/views/dash_creator/chart/_chart_creator.html.erb +230 -0
- data/app/views/dash_creator/chart/_modals.html.erb +74 -0
- data/app/views/dash_creator/chart/_plot_chart.html.erb +45 -0
- data/app/views/dash_creator/chart/create_chart.js.erb +53 -0
- data/app/views/dash_creator/dashboard/_dashboard_creator.html.erb +182 -0
- data/app/views/dash_creator/dashboard/_modals.html.erb +74 -0
- data/app/views/dash_creator/dashboard_object/_chart.html.erb +9 -0
- data/app/views/dash_creator/dashboard_object/_stat.html.erb +24 -0
- data/app/views/dash_creator/dashboard_object/_table.html.erb +16 -0
- data/app/views/dash_creator/filter/_filtering_card.html.erb +132 -0
- data/app/views/dash_creator/filter/_modals.html.erb +51 -0
- data/app/views/dash_creator/filter/_result_tables.html.erb +55 -0
- data/app/views/dash_creator/filter/apply_filtering.js.erb +46 -0
- data/app/views/dash_creator/filter/create_stat.js.erb +20 -0
- data/app/views/dash_creator/layouts/application.html.erb +64 -0
- data/app/views/dash_creator/layouts/menu/_left_menu.html.erb +12 -0
- data/app/views/dash_creator/user/_section_card.html.erb +17 -0
- data/app/views/dash_creator/user/creator.html.erb +11 -0
- data/app/views/dash_creator/user/dashboard.html.erb +10 -0
- data/config/initializers/dash_creator.rb +0 -0
- data/config/routes.rb +30 -0
- data/lib/dash_creator.rb +87 -0
- data/lib/dash_creator/acts_as_dash_creator.rb +16 -0
- data/lib/dash_creator/acts_as_dashboard_object.rb +19 -0
- data/lib/dash_creator/engine.rb +11 -0
- data/lib/dash_creator/version.rb +3 -0
- data/lib/generators/dash_creator/install/install_generator.rb +70 -0
- data/lib/generators/dash_creator/install/templates/_chart.html.erb +9 -0
- data/lib/generators/dash_creator/install/templates/_section_card.html.erb +17 -0
- data/lib/generators/dash_creator/install/templates/_stat.html.erb +24 -0
- data/lib/generators/dash_creator/install/templates/_table.html.erb +16 -0
- data/lib/generators/dash_creator/install/templates/add_indexes_to_dash_creator_tables.rb +15 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_charts.rb +25 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_dashboard_objects.rb +36 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_dashboards.rb +28 -0
- data/lib/generators/dash_creator/install/templates/create_dash_creator_filters.rb +22 -0
- data/lib/generators/dash_creator/install/templates/dashboard.html.erb +10 -0
- data/lib/generators/dash_creator/install/templates/initializer.rb +48 -0
- data/lib/tasks/dash_creator_tasks.rake +4 -0
- metadata +196 -0
@@ -0,0 +1,237 @@
|
|
1
|
+
module DashCreator
|
2
|
+
module FilterHelper
|
3
|
+
def filter_data(data)
|
4
|
+
mods = {}
|
5
|
+
data.keys.each do |k|
|
6
|
+
filter_hash = data[k]
|
7
|
+
|
8
|
+
mods[k] = filter_model(k.safe_constantize, filter_hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
mods
|
12
|
+
end
|
13
|
+
|
14
|
+
def prepare_data(params)
|
15
|
+
mods = filter_data(params['filters'])
|
16
|
+
|
17
|
+
data = params
|
18
|
+
|
19
|
+
data['y_data'] = data['y_data'].map { |d| mods[d] }
|
20
|
+
|
21
|
+
x_model_data = mods[data['x_data']['attribute']]
|
22
|
+
data['x_data'] = x_model_data unless x_model_data.nil?
|
23
|
+
|
24
|
+
data
|
25
|
+
end
|
26
|
+
|
27
|
+
# Query on model with data from filter_hash
|
28
|
+
def filter_model(model, filter_hash)
|
29
|
+
mods = model.all
|
30
|
+
# For each key of the model, recursively query (attributes, submodels)
|
31
|
+
filter_hash.keys.each do |k|
|
32
|
+
next if k == 'num_records'
|
33
|
+
attribute = k.split('_').last == 'id' ? k[0..-4] : k
|
34
|
+
mods = recursive_filter_attribute(mods, attribute, filter_hash[k])
|
35
|
+
end
|
36
|
+
return nil if mods.nil?
|
37
|
+
|
38
|
+
# Limit results if num_records is given
|
39
|
+
limit = filter_hash['num_records']
|
40
|
+
return mods.limit(limit.to_i) unless limit.empty?
|
41
|
+
mods
|
42
|
+
end
|
43
|
+
|
44
|
+
# Recursively query attributes depending on type associated to hash
|
45
|
+
def recursive_filter_attribute(models, attribute, filter_hash)
|
46
|
+
return nil if models.nil? || models.empty?
|
47
|
+
|
48
|
+
case filter_hash['type']
|
49
|
+
when 'datetime'
|
50
|
+
mods = filter_datetime(models, attribute, filter_hash)
|
51
|
+
|
52
|
+
when 'text'
|
53
|
+
mods = filter_text(models, attribute, filter_hash)
|
54
|
+
|
55
|
+
when 'numeric'
|
56
|
+
mods = filter_numeric(models, attribute, filter_hash)
|
57
|
+
|
58
|
+
when 'boolean'
|
59
|
+
mods = filter_boolean(models, attribute, filter_hash)
|
60
|
+
|
61
|
+
when 'has'
|
62
|
+
mods = filter_has(models, attribute, filter_hash)
|
63
|
+
|
64
|
+
when 'ref'
|
65
|
+
mods = filter_ref(models, attribute, filter_hash)
|
66
|
+
|
67
|
+
else
|
68
|
+
raise ArgumentError, 'type_' + filter_hash['type'] + '_is_unknown'
|
69
|
+
end
|
70
|
+
mods
|
71
|
+
end
|
72
|
+
|
73
|
+
# Helper functions for each type
|
74
|
+
# Query on models for attribute according to data in filter_hash
|
75
|
+
|
76
|
+
def filter_datetime(models, attribute, filter_hash)
|
77
|
+
mods = models
|
78
|
+
model_string = models.first.class.name.underscore
|
79
|
+
query_attribute = model_string.pluralize + '.' + attribute
|
80
|
+
start_date = DateTime.strptime(filter_hash['start'], '%b %d, %Y').beginning_of_day
|
81
|
+
end_date = DateTime.strptime(filter_hash['end'], '%b %d, %Y').beginning_of_day + 1.days
|
82
|
+
mods = mods.where("#{query_attribute}": start_date..end_date) if filter_hash.key?('start')
|
83
|
+
mods
|
84
|
+
end
|
85
|
+
|
86
|
+
def filter_text(models, attribute, filter_hash)
|
87
|
+
return models unless filter_hash.key?('present')
|
88
|
+
mods = models
|
89
|
+
|
90
|
+
model_string = models.first.class.name.underscore
|
91
|
+
query_attribute = model_string.pluralize + '.' + attribute
|
92
|
+
|
93
|
+
if !true_string?(filter_hash['present'])
|
94
|
+
mods = mods.where("#{attribute}": [nil, ''])
|
95
|
+
else
|
96
|
+
if filter_hash.key?('contains')
|
97
|
+
mods = mods.where(query_attribute + ' ~* ?', filter_hash['contains'])
|
98
|
+
else
|
99
|
+
mods = mods.where.not("#{attribute}": [nil, ''])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
mods
|
103
|
+
end
|
104
|
+
|
105
|
+
def filter_numeric(models, attribute, filter_hash)
|
106
|
+
return models unless filter_hash.key?('value')
|
107
|
+
|
108
|
+
mods = models.where("#{attribute}": filter_hash['value'].to_i)
|
109
|
+
mods
|
110
|
+
end
|
111
|
+
|
112
|
+
def filter_boolean(models, attribute, filter_hash)
|
113
|
+
return models unless filter_hash.key?('value')
|
114
|
+
|
115
|
+
mods = models.where("#{attribute}": true_string?(filter_hash['value']))
|
116
|
+
mods
|
117
|
+
end
|
118
|
+
|
119
|
+
def filter_has(models, attribute, filter_hash)
|
120
|
+
return models unless filter_hash.key?('has')
|
121
|
+
mods = models
|
122
|
+
|
123
|
+
has_models = attribute.pluralize
|
124
|
+
model_string = models.first.class.name.underscore
|
125
|
+
|
126
|
+
if true_string?(filter_hash['has'])
|
127
|
+
mods = mods.includes("#{has_models}")
|
128
|
+
.where.not("#{has_models}": {"#{model_string}_id": nil})
|
129
|
+
|
130
|
+
mods = mods.joins("LEFT JOIN #{has_models} ON #{has_models}.#{model_string}_id = #{model_string.pluralize}.id")
|
131
|
+
.group("#{model_string.pluralize}.id")
|
132
|
+
.having("count(#{has_models}.id) >= ?", filter_hash['has-inf'].to_i) if filter_hash.key?('has-inf')
|
133
|
+
mods = mods.joins("LEFT JOIN #{has_models} ON #{has_models}.#{model_string}_id = #{model_string.pluralize}.id")
|
134
|
+
.group("#{model_string.pluralize}.id")
|
135
|
+
.having("count(#{has_models}.id) <= ?", filter_hash['has-sup'].to_i) if filter_hash.key?('has-sup')
|
136
|
+
return nil if mods.nil?
|
137
|
+
|
138
|
+
# Go recursively through has model params
|
139
|
+
attribute_models = attribute.classify.safe_constantize.where("#{model_string}": mods)
|
140
|
+
main_keys = %w[has-sup has-inf has type]
|
141
|
+
filter_hash.keys.each do |k|
|
142
|
+
attribute_models = recursive_filter_attribute(attribute_models, k.underscore, filter_hash[k]) unless main_keys.include?(k)
|
143
|
+
end
|
144
|
+
return nil if attribute_models.nil?
|
145
|
+
mods_ids = []
|
146
|
+
attribute_models.each { |m| mods_ids.push(m[model_string + '_id']) }
|
147
|
+
mods = mods.where(id: mods_ids)
|
148
|
+
else
|
149
|
+
mods = mods.includes(:"#{has_models}")
|
150
|
+
.where("#{has_models}": {"#{model_string}_id": nil})
|
151
|
+
end
|
152
|
+
mods
|
153
|
+
end
|
154
|
+
|
155
|
+
def filter_ref(models, attribute, filter_hash)
|
156
|
+
return models unless filter_hash.key?('ref')
|
157
|
+
mods = models
|
158
|
+
|
159
|
+
if true_string?(filter_hash['ref'])
|
160
|
+
mods = mods.where.not("#{attribute}": nil)
|
161
|
+
return nil if mods.nil?
|
162
|
+
|
163
|
+
# Go recursively through ref model params
|
164
|
+
attributes_ids = []
|
165
|
+
mods.each { |m| attributes_ids.push(m[attribute + '_id']) }
|
166
|
+
attribute_models = attribute.classify.safe_constantize
|
167
|
+
.where(id: attributes_ids)
|
168
|
+
main_keys = %w[ref type]
|
169
|
+
filter_hash.keys.each do |k|
|
170
|
+
attribute_models = recursive_filter_attribute(attribute_models, k.underscore, filter_hash[k]) unless main_keys.include?(k)
|
171
|
+
end
|
172
|
+
mods = mods.where("#{attribute}": attribute_models)
|
173
|
+
else
|
174
|
+
mods = mods.where("#{attribute}": nil)
|
175
|
+
end
|
176
|
+
mods
|
177
|
+
end
|
178
|
+
|
179
|
+
def filter_data_count_from_redis(data)
|
180
|
+
redis_data = nil
|
181
|
+
refresh = data.delete('refresh')
|
182
|
+
redis_filter_data = encode_filter_data(data)
|
183
|
+
|
184
|
+
unless refresh == true || DashCreator.redis_store_variable.nil?
|
185
|
+
redis_data = DashCreator.redis_store_variable.get(redis_filter_data)
|
186
|
+
end
|
187
|
+
|
188
|
+
unless redis_data.nil?
|
189
|
+
processed_data = JSON.parse(redis_data)
|
190
|
+
else
|
191
|
+
processed_data = filter_data(data).deep_stringify_keys
|
192
|
+
processed_data.keys.each { |k| processed_data[k] = processed_data[k].count }
|
193
|
+
processed_data['last_updated'] = DateTime.now.strftime('%d/%m/%Y - %T')
|
194
|
+
|
195
|
+
# Add chart data to redis
|
196
|
+
DashCreator.redis_store_variable.set(redis_filter_data, processed_data.to_json) unless DashCreator.redis_store_variable.nil?
|
197
|
+
end
|
198
|
+
|
199
|
+
processed_data
|
200
|
+
end
|
201
|
+
|
202
|
+
def encode_filter_data(data)
|
203
|
+
# Prepare data to encode
|
204
|
+
encoded_data = data.clone
|
205
|
+
encoded_data = encoded_data.to_unsafe_h unless encoded_data.is_a?(Hash)
|
206
|
+
|
207
|
+
# Encode
|
208
|
+
hash_hash(encoded_data)
|
209
|
+
end
|
210
|
+
|
211
|
+
# This helper function is used in create_chart.js.erb to hash param hash to store it in Redis
|
212
|
+
def hash_hash(h)
|
213
|
+
require 'digest/sha1'
|
214
|
+
str = recursive_flatten(h).sort.join
|
215
|
+
Digest::SHA1.hexdigest(str)
|
216
|
+
end
|
217
|
+
|
218
|
+
def recursive_flatten(h)
|
219
|
+
h.flatten(-1).map{|el| el.is_a?(Hash) ? recursive_flatten(el) : el}.flatten
|
220
|
+
end
|
221
|
+
|
222
|
+
# Check if string is 'true'
|
223
|
+
def true_string?(string)
|
224
|
+
string == 'true'
|
225
|
+
end
|
226
|
+
|
227
|
+
def get_csv(models)
|
228
|
+
CSV.generate do |csv|
|
229
|
+
columns = models.first.keys.map { |k| k.to_s }
|
230
|
+
csv << columns
|
231
|
+
models.each do |m|
|
232
|
+
csv << m.attributes.values_at(*columns)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DashCreator
|
2
|
+
class Chart < ApplicationRecord
|
3
|
+
attr_accessor :user_id
|
4
|
+
belongs_to :user, class_name: DashCreator.user_class.to_s
|
5
|
+
|
6
|
+
before_validation :set_user
|
7
|
+
|
8
|
+
def as_json(options = {})
|
9
|
+
json = {
|
10
|
+
name: name,
|
11
|
+
data: data
|
12
|
+
}
|
13
|
+
json
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def set_user
|
18
|
+
self.user = DashCreator.user_class.find(user_id)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module DashCreator
|
2
|
+
class Dashboard < ApplicationRecord
|
3
|
+
attr_accessor :user_id
|
4
|
+
belongs_to :user, class_name: DashCreator.user_class.to_s
|
5
|
+
|
6
|
+
before_validation :set_user
|
7
|
+
|
8
|
+
private
|
9
|
+
def set_user
|
10
|
+
self.user = DashCreator.user_class.find(user_id)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module DashCreator
|
2
|
+
class Filter < ApplicationRecord
|
3
|
+
attr_accessor :user_id
|
4
|
+
belongs_to :user, class_name: DashCreator.user_class.to_s
|
5
|
+
|
6
|
+
before_validation :set_user
|
7
|
+
|
8
|
+
def as_json (opts={})
|
9
|
+
json = {
|
10
|
+
'id': id,
|
11
|
+
'name': name,
|
12
|
+
'options': options
|
13
|
+
}
|
14
|
+
json
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def set_user
|
19
|
+
self.user = DashCreator.user_class.find(user_id)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
<div class="row">
|
2
|
+
<div class="col-md-12">
|
3
|
+
<div class="card">
|
4
|
+
<div class="card-header">
|
5
|
+
Super Amazing Chart Creator
|
6
|
+
</div>
|
7
|
+
<div class="card-block" id="chart-creator" style="margin:20px 50px;">
|
8
|
+
|
9
|
+
</div>
|
10
|
+
<div class="card-footer">
|
11
|
+
<button type="submit" class="pull-left btn btn-success" id="chart-submit-btn">Draw Chart</button>
|
12
|
+
<a href="#" data-toggle="modal" data-target="#delete_charts_modal" class="pull-right btn btn-sm btn-danger" id="chart-unsave-btn"><%=t :delete_charts%></a>
|
13
|
+
<a href="#" data-toggle="modal" data-target="#edit_chart_modal" class="pull-right btn btn-sm btn-primary" id="chart-edit-btn"><%=t :modify_chart%></a>
|
14
|
+
<a href="#" data-toggle="modal" data-target="#save_chart_modal" class="pull-right btn btn-sm btn-success"><%=t :save_new_chart%></a>
|
15
|
+
<%= select_tag 'chart-select', options_for_select([]), prompt: 'Choose a chart', id: '', class: 'form-control pull-right', style: 'width: 20%; margin-right: 10%;' %>
|
16
|
+
</div>
|
17
|
+
</div>
|
18
|
+
<!--/.card-->
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<script>
|
23
|
+
var charts = <%= raw @charts %>;
|
24
|
+
|
25
|
+
// TODO: JSON handling ??
|
26
|
+
// TODO: for date charts, always calculate day values and then gather ? so that changing day/week/month display doesn't need a reload
|
27
|
+
// TODO: if only bar/line change don't refresh
|
28
|
+
// TODO: Stats creator: take a filter, simply return the count of objects
|
29
|
+
// TODO: minicolors issue ?? Too much JS to handle for the browser when many color fields in chart creator
|
30
|
+
|
31
|
+
// Style presets
|
32
|
+
var minicolors_swatches = [
|
33
|
+
'rgb(255, 99, 132)',
|
34
|
+
'rgb(54, 162, 235)',
|
35
|
+
'rgb(255, 206, 86)',
|
36
|
+
'rgb(75, 192, 192)',
|
37
|
+
'rgb(153, 102, 255)',
|
38
|
+
'rgb(255, 159, 64)',
|
39
|
+
'rgb(216, 247, 147)',
|
40
|
+
'rgb(52, 85, 17)',
|
41
|
+
'rgb(220, 255, 253)',
|
42
|
+
'rgb(1, 17, 10)',
|
43
|
+
'rgb(219, 153, 90)',
|
44
|
+
'rgb(153, 134, 80)'
|
45
|
+
];
|
46
|
+
var minicolors_options = {theme: 'bootstrap', format: 'rgb', swatches: minicolors_swatches};
|
47
|
+
|
48
|
+
$('#chart-creator').chartCreator({
|
49
|
+
models_data: <%= raw @models_data.to_json %>,
|
50
|
+
attributes_aliases: <%= raw DashCreator.attributes_aliases.to_json %>,
|
51
|
+
displayed_model_names: <%= raw DashCreator.displayed_model_names.to_json %>,
|
52
|
+
displayed_attribute_names: <%= raw DashCreator.displayed_attribute_names.to_json %>,
|
53
|
+
filter_creator: $('#filter-creator'),
|
54
|
+
minicolors_options: minicolors_options
|
55
|
+
});
|
56
|
+
var chart_creator = $('#chart-creator').data('chartCreator');
|
57
|
+
|
58
|
+
|
59
|
+
// --------------- Send chart data to controller ---------------
|
60
|
+
chart_creator.labelOptionsContainer.on('click', '#pluck-labels-btn', labelsFromPluck);
|
61
|
+
function labelsFromPluck() {
|
62
|
+
var limit = chart_creator.labelOptionsContainer.find('[name="pluck-num"]').val();
|
63
|
+
|
64
|
+
var x = chart_creator.xContainer.find('[name="x-axis"]').val().split('-');
|
65
|
+
var model, attribute;
|
66
|
+
if (x[1] === 'has' || x[1] === 'ref') {
|
67
|
+
model = x[0].classify();
|
68
|
+
attribute = chart_creator.labelOptionsContainer.find('[name="x-sub"]').val().split('-')[0];
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
model = chart_creator.yContainer.find('[name="y-axis"]:first').val();
|
72
|
+
attribute = x[0];
|
73
|
+
}
|
74
|
+
|
75
|
+
var params = {
|
76
|
+
model: model,
|
77
|
+
attribute: attribute,
|
78
|
+
limit: limit
|
79
|
+
};
|
80
|
+
|
81
|
+
$.post('<%= pluck_labels_path %>', params, function(data) {
|
82
|
+
var labels = data['labels'];
|
83
|
+
|
84
|
+
chart_creator.labelOptionsContainer.find('[name="labels-num"]').val(labels.length).change();
|
85
|
+
chart_creator.labelOptionsContainer.find('.limit-label').each(function() {
|
86
|
+
$(this).val(labels.shift());
|
87
|
+
});
|
88
|
+
});
|
89
|
+
}
|
90
|
+
|
91
|
+
|
92
|
+
// --------------- Send chart data to controller ---------------
|
93
|
+
// Send data for controller chart actions
|
94
|
+
function sendChartDataCreate(chart_data) {
|
95
|
+
$.post("<%= create_chart_path %>", chart_data);
|
96
|
+
}
|
97
|
+
|
98
|
+
function sendChartDataSave(chart_data) {
|
99
|
+
$.post("<%= save_chart_path %>", chart_data, function(data) {
|
100
|
+
var chart_id = data['chart_id'], chart_name = chart_data['chart_name'];
|
101
|
+
charts.push([chart_name, chart_id]);
|
102
|
+
|
103
|
+
var dashboard_creator_objects_data = $('#dashboard-creator').data('dashboardCreator').objects_data;
|
104
|
+
dashboard_creator_objects_data['chart']['objects'].push({id: chart_id, name: chart_name});
|
105
|
+
});
|
106
|
+
}
|
107
|
+
|
108
|
+
function sendChartDataEdit(chart_data) {
|
109
|
+
$.post("<%= edit_chart_path %>", chart_data);
|
110
|
+
}
|
111
|
+
|
112
|
+
// Handle submit
|
113
|
+
$('#chart-submit-btn').click(function() {
|
114
|
+
var chart_data = chart_creator.getChartData();
|
115
|
+
chart_data['refresh'] = false;
|
116
|
+
sendChartDataCreate(chart_data);
|
117
|
+
});
|
118
|
+
|
119
|
+
|
120
|
+
// --------------- Save, unsave, show saved charts ---------------
|
121
|
+
var chart_id = '';
|
122
|
+
|
123
|
+
// Save a chart config
|
124
|
+
$(document).on('click', '#save-chart-btn', function() {
|
125
|
+
var chart_data = chart_creator.getChartData();
|
126
|
+
|
127
|
+
// Get the chart name
|
128
|
+
chart_data['chart_name'] = $('.modal#save_chart_modal').find('[name="chart-name"]').val();
|
129
|
+
|
130
|
+
// Post data with chart-save request
|
131
|
+
sendChartDataSave(chart_data);
|
132
|
+
});
|
133
|
+
|
134
|
+
// Prepare modal display for edit
|
135
|
+
$('#chart-edit-btn').click(function() {
|
136
|
+
var confirm_edit_chart_btn = $('#confirm-edit-chart-btn');
|
137
|
+
|
138
|
+
var h3_div = $('.modal#edit_chart_modal .modal-body #edit-message');
|
139
|
+
h3_div.empty();
|
140
|
+
confirm_edit_chart_btn.prop('disabled', false);
|
141
|
+
|
142
|
+
var h3_div_text;
|
143
|
+
if (chart_id !== '') {
|
144
|
+
h3_div_text = 'Are you sure you want to edit chart ';
|
145
|
+
for (var i = 0; i < charts.length; i++) {
|
146
|
+
var chart_name = charts[i][0], id = charts[i][1];
|
147
|
+
if (chart_id === id) {
|
148
|
+
h3_div_text += chart_name;
|
149
|
+
break;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
h3_div_text += ' ?'
|
153
|
+
}
|
154
|
+
else {
|
155
|
+
h3_div_text = 'No chart to edit.';
|
156
|
+
confirm_edit_chart_btn.prop('disabled', true);
|
157
|
+
}
|
158
|
+
h3_div.text(h3_div_text);
|
159
|
+
});
|
160
|
+
|
161
|
+
// Prepare and send new chart data on chart edit confirm
|
162
|
+
$(document).on('click', '#confirm-edit-chart-btn', function() {
|
163
|
+
var chart_data = chart_creator.getChartData();
|
164
|
+
chart_data['chart_id'] = chart_id;
|
165
|
+
|
166
|
+
sendChartDataEdit(chart_data);
|
167
|
+
});
|
168
|
+
|
169
|
+
// Prepare list of charts for delete charts modal
|
170
|
+
$('#chart-unsave-btn').click(function() {
|
171
|
+
var checkbox_list = $('#charts-checkbox-list');
|
172
|
+
// First empty the checkbox list
|
173
|
+
checkbox_list.children().remove();
|
174
|
+
|
175
|
+
// Append charts list to div in modal
|
176
|
+
var checkbox_string_start = '<div class="col-sm-12"><div class="form-group">'
|
177
|
+
+ '<input type="checkbox" class="form-control" name="chart" value="';
|
178
|
+
for (var i = 0; i < charts.length; i++) {
|
179
|
+
var chart_name = charts[i][0], id = charts[i][1];
|
180
|
+
var chart_string = checkbox_string_start + id + '"><label>' + chart_name + '</label><br>';
|
181
|
+
$(chart_string).appendTo(checkbox_list);
|
182
|
+
}
|
183
|
+
$('</div></div>').appendTo(checkbox_list);
|
184
|
+
});
|
185
|
+
|
186
|
+
// Delete charts
|
187
|
+
$(document).on('click', '#delete-charts-btn', function() {
|
188
|
+
// Get the charts ids
|
189
|
+
var charts_ids = [];
|
190
|
+
$(this).closest('.modal').find('[type="checkbox"]:checked').each(function() {
|
191
|
+
charts_ids.push($(this).attr("value"));
|
192
|
+
});
|
193
|
+
|
194
|
+
var params = {charts_ids: charts_ids};
|
195
|
+
|
196
|
+
$.post("<%= delete_charts_path %>", params, function() {
|
197
|
+
// Remove from charts list
|
198
|
+
for (var i = 0; i < charts.length; i++) {
|
199
|
+
var id = charts[i][1];
|
200
|
+
if ($.inArray(id, charts_ids) !== -1) {
|
201
|
+
charts.splice(i, 1);
|
202
|
+
i--;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
});
|
206
|
+
});
|
207
|
+
|
208
|
+
$('[name="chart-select"]')
|
209
|
+
.focusin(displayChartList)
|
210
|
+
.change(displayChart);
|
211
|
+
|
212
|
+
// Display chart select list
|
213
|
+
function displayChartList() {
|
214
|
+
$(this).children().not('[value=""]').remove();
|
215
|
+
for (var i = 0; i < charts.length; i++) {
|
216
|
+
var chart_name = charts[i][0], id = charts[i][1];
|
217
|
+
$('<option value="' + id + '">' + chart_name + '</option>').appendTo($('[name="chart-select"]'));
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
// Display chosen chart
|
222
|
+
function displayChart() {
|
223
|
+
if ($(this).val() === '') { return false; }
|
224
|
+
|
225
|
+
chart_id = $(this).val();
|
226
|
+
var params = {chart_id: chart_id};
|
227
|
+
|
228
|
+
$.post("<%= get_chart_path %>", params);
|
229
|
+
}
|
230
|
+
</script>
|