quick_search-core 0.1.1 → 0.2.0
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 +4 -4
- data/README.md +7 -6
- data/app/assets/javascripts/quick_search.js.erb +9 -0
- data/app/assets/javascripts/quick_search/appstats.js.erb +73 -0
- data/app/assets/javascripts/quick_search/appstats_best_bets.js.erb +905 -0
- data/app/assets/javascripts/quick_search/appstats_clicks_overview.js.erb +719 -0
- data/app/assets/javascripts/quick_search/appstats_general_statistics.js.erb +908 -0
- data/app/assets/javascripts/quick_search/appstats_sessions_details.js.erb +660 -0
- data/app/assets/javascripts/quick_search/appstats_sessions_overview.js.erb +481 -0
- data/app/assets/javascripts/quick_search/appstats_spelling_suggestions.js.erb +902 -0
- data/app/assets/javascripts/quick_search/appstats_top_searches.js.erb +633 -0
- data/app/assets/javascripts/quick_search/event_tracking.js.erb +22 -33
- data/app/assets/javascripts/quick_search/xhr_search.js +7 -3
- data/app/assets/stylesheets/quick_search/appstats.scss +148 -0
- data/app/assets/stylesheets/quick_search/quick_search.scss +0 -16
- data/app/controllers/concerns/quick_search/doi_trap.rb +1 -1
- data/app/controllers/quick_search/appstats_controller.rb +267 -144
- data/app/controllers/quick_search/logging_controller.rb +165 -0
- data/app/controllers/quick_search/search_controller.rb +1 -23
- data/app/controllers/quick_search/typeahead_controller.rb +48 -0
- data/app/models/event.rb +6 -0
- data/app/models/search.rb +7 -0
- data/app/models/session.rb +9 -0
- data/app/searchers/quick_search/best_bets_searcher.rb +1 -1
- data/app/views/layouts/quick_search/_google_analytics.html.erb +4 -9
- data/app/views/layouts/quick_search/_search_form.html.erb +2 -2
- data/app/views/layouts/quick_search/application.html.erb +4 -0
- data/app/views/quick_search/appstats/_date_range.html.erb +14 -13
- data/app/views/quick_search/appstats/_graph_best_bets.html.erb +6 -0
- data/app/views/quick_search/appstats/_graph_clicks_overview.html.erb +12 -0
- data/app/views/quick_search/appstats/_graph_general_statistics.html.erb +19 -0
- data/app/views/quick_search/appstats/_graph_sessions_details.html.erb +19 -0
- data/app/views/quick_search/appstats/_graph_sessions_overview.html.erb +9 -0
- data/app/views/quick_search/appstats/_graph_spelling_suggestions.html.erb +6 -0
- data/app/views/quick_search/appstats/_graph_top_searches.html.erb +6 -0
- data/app/views/quick_search/appstats/_menu.html.erb +16 -3
- data/app/views/quick_search/appstats/_sessions_details_device_filters.html.erb +9 -0
- data/app/views/quick_search/appstats/_sessions_details_location_filters.html.erb +9 -0
- data/app/views/quick_search/appstats/_sessions_overview_graph_filters.html.erb +9 -0
- data/app/views/quick_search/appstats/clicks_overview.html.erb +3 -14
- data/app/views/quick_search/appstats/index.html.erb +3 -23
- data/app/views/quick_search/appstats/sessions_details.html.erb +9 -0
- data/app/views/quick_search/appstats/sessions_overview.html.erb +9 -0
- data/app/views/quick_search/appstats/top_searches.html.erb +3 -32
- data/app/views/quick_search/appstats/top_spot.html.erb +7 -7
- data/app/views/quick_search/search/_module_with_paging.html.erb +1 -1
- data/app/views/quick_search/search/_result_title.html.erb +1 -1
- data/config/quicksearch_config.yml.example +3 -0
- data/config/routes.rb +31 -3
- data/db/migrate/20161201141003_create_sessions.rb +12 -0
- data/db/migrate/20161201142811_change_event_columns.rb +11 -0
- data/db/migrate/20161201143901_add_session_id_to_searches.rb +5 -0
- data/db/migrate/20161212192454_add_date_string_columns.rb +11 -0
- data/db/seeds.rb +83 -7
- data/lib/generators/quick_search/templates/quick_search_typeahead.js +253 -0
- data/lib/generators/quick_search/typeahead_generator.rb +162 -0
- data/lib/quick_search/engine.rb +1 -0
- data/lib/quick_search/version.rb +1 -1
- data/test/dummy/db/schema.rb +25 -6
- data/test/dummy/log/benchmark.log +121 -241
- data/test/dummy/log/development.log +236 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0b/0bXp2nnjPLNuYQRAMo1RkhNr8RSC8vqZo_7soo0XZTE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3p/3pAfj3gt9c9rLmOrDkMvW2r6Swm5YhuGQ1EN3va9LDE.cache +6 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3r/3r7qg-LCIcD5882b6GKgRTZycpAlhoSNJccVH06yRCQ.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{UA/UAOIipK_ejTAUFI6XxASoweyUiC3t64VfVzV-MfsFD8.cache → 4h/4hLiHzJdffGLMZCeIkbisOdFQSyqs54YkoZpBpGotVk.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Hr/Hr-kCuPY72nIKAdnsDTz9JqXd_z1WL6FSGMAq4HppZg.cache → 5Y/5Yh8GnSzywqhuMWMloKnL9FnuIxa9rBw6hN2Ecv0urw.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/8h/8hHsBZ0Il3GVKNj0HgTh-s-XpPVkHrcSY0EJ4v548sk.cache +4 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{fI/fInu_Gja7ik39t207tqj4CtlL0akQRbjD2T7qEtd0zE.cache → 8n/8nKAboU_CeVIX30-Q9BtSV5TXdE07WU8hO0OQ0N3KOs.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{dz/dzCaa80YgyvJINTgsyrVhKv9UQ1OC82GfAsA-IP96iQ.cache → Af/Afug8duevWkZFPkOMnZ5z_IbRT6JMZo4jw1QFmLiXXA.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/C2/C24SLDoUbdiHRmPZx5lIZ3XPXmn9FDq7j7gZmbpDtcE.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/CH/CHuDjj47dHGqRD3uN1JNwnlFyjjEKB09KR6WVsLj2Do.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ci/Cif3NOwhu5i6Qm3iRv2gNJLi_cu8yDVz0Nrq8TZu1tc.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/FQ/FQWd8V-Pek1LBAfW9vzcG-FpWySsPRhMVzH9DlPxLWU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fa/FaYEz8CfLTkxVZvnbgKGvJMhhBwNvEgsZgUwaHNRlaQ.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/IA/IALQq6ICbs3VBSRsaUmGuN73Qv5wDfWTP86VmMh_sVs.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/K1/K1jnTrW-_s64kqCA6fnoQ-ID-rDaGX34J-TNPyzDbLs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Mz/MzXE1Go_GKyu6AvJPhw394BtPM_jVTf0hMwobBi15tk.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Os/OsIhoBDw5N2AWGQ-EMK79tgwPS1AC6Dy_gMSJdOv2Ss.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{B5/B5ptGSZGmgHvoK2UDCAtpMhWxJEKxKFhyL9ACeBfzQk.cache → PC/PCth9nzoRrp5GI3Ut8FxlGpXjH63V7k2p4PRwfyu2sQ.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pw/Pw3Jv2p7MsQz6pttCZig6VMVQ30sRyIDRS-2nM32yqY.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/RI/RIOgtcuvLAJZl62RvAzqine3jCO3i2qyhswiW2G1bw8.cache +3 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/R_/R_6WhfFaPUAOAFfFd4bgUonI5aB4Fa6iOMY2J6G3U98.cache +4 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pj/pjJDYrBipDo6Tr9_-W4UDzfZZ4UPTy9YpXrBQFRXnlo.cache → S3/S3gPdA-Zqya5r6wNhnlwqGV3B3-GDaA8i1fL_jo66AI.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/SS/SS3eYrFE6ghi5G_3POW760Y4BWo5OAaK5QjDrRGXOcs.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{jj/jjdQCKZsewws2eRP7b2AVxRMvseOp8djjlDkB8UOtac.cache → Sq/SqjdxmYsdurpx9xk1ks32WEtf3D9_2BysE7RMxnOlmU.cache} +1 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{os/os0qWv3yDfep0e7vVSGTgfn_n3xc4C4QZgmMzLQn0Ks.cache → Ta/TaJnQ_l0sfSsDOyVoi-S-KZQ6vIwzBhmS6hmNA_n8ug.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{o6/o6ZQbq1aBFuVrE2xLbSbyZH2736sWM3Yj4ky9chT1bI.cache → X_/X_CxFXEdZo2C_in7FopAuAbplHn6W_V0SXyVQAMnTzI.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{sR/sRU-UT8qK_38kkiFDXKBPogO1oOZuSvJFH-pgqPL_Ms.cache → Yh/YhRWll6bzgYE6Dmc5fVKbHyv5om4y3-27UrWeUbQcGk.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{OD/ODHapE0li3WI1laVJoksoI5nmQd-8dDJXq_VxS4XefE.cache → _u/_uiA10I5HyJR94Tbc4a06CzdrQCAXX7Iz86WS5PKDQo.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ai/ainCVF4dxXf85KoOLUSHvMMGg0qBNc7Vg-s-9v2ENJI.cache +4 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/cQ/cQqt0ri9GFvVnIs1pJUugIJs5tDuGQMMntW5CwpK6YY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{1n/1nStVaWIQEwAlksUpB1fInwq6v3TikPvuRaSwwCnCLQ.cache → e0/e0Y2Gz8ftaW2O0RjoN2iWguitI-JQZckScAZqlQYkng.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/iH/iHnlNNY3rfdbVqt8LZBfcDQYONR8dA8LmxA9fv5paro.cache +2 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{F0/F0oWBwLHpGFYNNtnGav-dJFH8rMDpNA5L8_aWm5Wq34.cache → ir/irxgIDPIY6Wz6fHWYp1dIrqAT1_8oa6-oiwqbFE_e-w.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/kn/knUtyVrg7nMIPldZa4MHhe7cC9eMchLZS4mc5HDWgDY.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ks/ks4DoIuUV6oUzoiXoPh7sW1k5ExNoUkR7ICjwuRnAT0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/m3/m375QQakjXd_2Trpvdot-i90nmeCCh0HWtzS66ZvxUU.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/rQ/rQ_FgYkT2hdw9A6XmJKGgVb2dMtCrWWHwtS0X1_kdl0.cache +1 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pw/pwiIhcWPwTuy5Miz5zqOQGYFx-K3TbaCVQ6ls7EBkk0.cache → rU/rUqFWwHqrT5jeIFCEezOPsMMZiAU7ri6RKBGS2ezAfg.cache} +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/{pO/pO8hHVwybv1ZJBdPa2YC6bjqmk020OYFl85TYxtmrWQ.cache → rq/rqf5-J6k_zLc9ZlUgMj28nviKtRsko3-iEp_m_uNeY0.cache} +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- metadata +143 -119
- data/app/assets/javascripts/quick_search/appstats.js +0 -8
- data/app/views/quick_search/appstats/_click_count_table.html.erb +0 -23
- data/app/views/quick_search/appstats/_top_spot_report_table.html.erb +0 -33
- data/app/views/quick_search/appstats/module_click_detail.html.erb +0 -32
- data/app/views/quick_search/appstats/top_spot_detail.html.erb +0 -35
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/0_/0_w_ydOOEFQOoETxJa-IxKppQocaiDwM5V08djCPYso.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/3m/3mWfBeEpm_bJvaPQZYvnnAVtE_2helOWh_Tv-cEflrk.cache +0 -5
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/4s/4sg52OgD5l4qx4GnojCVxg2itqwqb-KRanEdmdMus3Y.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/5U/5UPnsccuZFLk9OqbmFMvB55mbvGptApx9Z55HWjEN90.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/9a/9acKNgyVD8_WK401tMy6Ce98g-LS4VpwFvGQdzCV9mI.cache +0 -0
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ba/BaymviI8cwAJQMOIzWCf6Lt-PM2sNFTvY9hQKsfDNNw.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dd/DdFHg3C_voetfvKGKX7t8PGzZlkO45-huHNtaou5rxg.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fp/FprCQeeZguht46WNSpA3Y3JHKehovFXrj63nDrvvwFE.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/GJ/GJrfWiarIi0Dt6sdKVMfUF1cdZ6NbqZxXHhzNbFtpBw.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gp/GpoziOxxB-hisco0rl7Nnsnw0UWud7R9Yge2Q3o1eN4.cache +0 -2
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/It/It5VkJv-53-LICLKZWWyp2WcbD86DGotAL0MY3hhfpg.cache +0 -6
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/O6/O6dw148Xya7NYlsRFMEzJyvRcySM6iOL1jRUpdQo9B8.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Oj/OjMkKTW7OkthjJAQHDID8GV30IZC9F0dJ1zGiFame9U.cache +0 -4
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/SU/SUtZ_ltPqy9A9A-_zqNPhNPvjxCOnrdqXHSZv5S9mOk.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tv/TvZgmm69VEMHUJQIBoij61oXMkgzp6whVo7l8mJ9qpw.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/YJ/YJZdK01T1KTS84Mb6p_2TasmJNZeGZc4FMtBPCKGr_M.cache +0 -3
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/ah/ahhhd3ysbQmVDNzq2L_rb4t6rqqdnqeY6ujztBoZDA8.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/gv/gvZKkbgiExbcQrT4eo0HB-j4JoDRAxdmDjKRxeEdK0Y.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/hj/hj_r-O1QjHJIPcZVnlB_FGPdIRAi9NkxpT2oXDRIsGE.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/o2/o2V1ahk8vFR6sXWNh5BB7w6MBj04zCyX-o1xFZONydE.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tE/tEO71oPPFXN_2c4p39nU0OiF9ARg13fjdQlnPqAx1KY.cache +0 -4
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/tW/tWFRsAv4WWu2ch-x3AJZd3KOvBXG3MwH6Q6Xn-tFBtw.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/x6/x6W754ylumshr3wBUHHmcgyWs8UR3Od7FaI6tqvjKmk.cache +0 -1
- data/test/dummy/tmp/cache/assets/sprockets/v3.0/yy/yyJ1P7RQciOiW8TgQiu1RMDdbWd4rqxd2BGU9HkY3L8.cache +0 -0
|
@@ -0,0 +1,908 @@
|
|
|
1
|
+
<% url_helper = QuickSearch::Engine.routes.url_helpers %>
|
|
2
|
+
|
|
3
|
+
(function() {
|
|
4
|
+
var Globals = {};
|
|
5
|
+
|
|
6
|
+
$(document).on("turbolinks:load", function() {
|
|
7
|
+
if ($("#graph_general_statistics").length) {
|
|
8
|
+
var from = $("#from").datepicker("getDate");
|
|
9
|
+
var to = new Date($("#to").datepicker("getDate").getTime() + 1000*60*60*24);
|
|
10
|
+
Globals.Days_In_Sample = parseInt((to-from)/(1000*60*60*24));
|
|
11
|
+
d3.select("#graphIconContainer").append("i")
|
|
12
|
+
.attr("class", "fa fa-spinner fa-spin fa-5x fa-fw big-icon")
|
|
13
|
+
.attr("id", "graphIcon");
|
|
14
|
+
d3.select("#tableIconContainer").append("i")
|
|
15
|
+
.attr("class", "fa fa-spinner fa-spin fa-5x fa-fw big-icon")
|
|
16
|
+
.attr("id", "tableIcon");
|
|
17
|
+
// Redraw graph if the date range is changed
|
|
18
|
+
document.getElementById("dateButton").addEventListener("click", function() {
|
|
19
|
+
var from = $("#from").datepicker("getDate");
|
|
20
|
+
var to = new Date($("#to").datepicker("getDate").getTime() + 1000*60*60*24);
|
|
21
|
+
Globals.Days_In_Sample = parseInt((to-from)/(1000*60*60*24));
|
|
22
|
+
document.getElementById("numDays").innerHTML = "" + Globals.Days_In_Sample;
|
|
23
|
+
$.ajax({
|
|
24
|
+
type: "GET",
|
|
25
|
+
contentType: "application/json; charset=utf-8",
|
|
26
|
+
url: '<%= url_helper.data_general_statistics_path %>',
|
|
27
|
+
dataType: "json",
|
|
28
|
+
data: {
|
|
29
|
+
"start_date": from,
|
|
30
|
+
"end_date": to
|
|
31
|
+
},
|
|
32
|
+
success: function(generalStatisticsDataSet) {
|
|
33
|
+
Globals.Data = _.cloneDeep(generalStatisticsDataSet)
|
|
34
|
+
var dataMain = _.cloneDeep(Globals.Data);
|
|
35
|
+
var dataMini = _.cloneDeep(Globals.Data);
|
|
36
|
+
|
|
37
|
+
draw_graph_general_statistics(dataMain, false, Globals.Index, true);
|
|
38
|
+
|
|
39
|
+
draw_graph_mini(dataMini[0], "#mini0");
|
|
40
|
+
draw_graph_mini(dataMini[1], "#mini1");
|
|
41
|
+
draw_graph_mini(dataMini[2], "#mini2");
|
|
42
|
+
},
|
|
43
|
+
error: function(result) {
|
|
44
|
+
error();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
$.ajax({
|
|
48
|
+
type: "GET",
|
|
49
|
+
contentType: "application/json; charset=utf-8",
|
|
50
|
+
url: '<%= url_helper.data_general_table_path %>',
|
|
51
|
+
dataType: "json",
|
|
52
|
+
data: {
|
|
53
|
+
"start_date": from,
|
|
54
|
+
"end_date": to
|
|
55
|
+
},
|
|
56
|
+
success: function(tableDataSet) {
|
|
57
|
+
var dataTable = _.cloneDeep(tableDataSet);
|
|
58
|
+
draw_table(dataTable);
|
|
59
|
+
},
|
|
60
|
+
error: function(result) {
|
|
61
|
+
error();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
$.ajax({
|
|
66
|
+
type: "GET",
|
|
67
|
+
contentType: "application/json; charset=utf-8",
|
|
68
|
+
url: '<%= url_helper.data_general_statistics_path %>',
|
|
69
|
+
dataType: "json",
|
|
70
|
+
success: function(generalStatisticsDataSet) {
|
|
71
|
+
d3.select("#graphIcon").transition().duration(250)
|
|
72
|
+
.style("opacity", .000001)
|
|
73
|
+
.remove();
|
|
74
|
+
Globals.Data = _.cloneDeep(generalStatisticsDataSet)
|
|
75
|
+
var dataMain = _.cloneDeep(Globals.Data);
|
|
76
|
+
var dataMini = _.cloneDeep(Globals.Data);
|
|
77
|
+
|
|
78
|
+
draw_graph_general_statistics(dataMain, false, 0, false);
|
|
79
|
+
|
|
80
|
+
draw_graph_mini(dataMini[0], "#mini0");
|
|
81
|
+
draw_graph_mini(dataMini[1], "#mini1");
|
|
82
|
+
draw_graph_mini(dataMini[2], "#mini2");
|
|
83
|
+
|
|
84
|
+
if ($("#graph_general_statistics").length) {
|
|
85
|
+
document.getElementById("mini0").addEventListener("click", function() {
|
|
86
|
+
load_new_data(0);
|
|
87
|
+
})
|
|
88
|
+
document.getElementById("mini1").addEventListener("click", function() {
|
|
89
|
+
load_new_data(1);
|
|
90
|
+
})
|
|
91
|
+
document.getElementById("mini2").addEventListener("click", function() {
|
|
92
|
+
load_new_data(2);
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
error: function(result) {
|
|
97
|
+
error();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
$.ajax({
|
|
101
|
+
type: "GET",
|
|
102
|
+
contentType: "application/json; charset=utf-8",
|
|
103
|
+
url: '<%= url_helper.data_general_table_path %>',
|
|
104
|
+
dataType: "json",
|
|
105
|
+
success: function(tableDataSet) {
|
|
106
|
+
d3.select("#tableIcon").remove();
|
|
107
|
+
var dataTable = _.cloneDeep(tableDataSet);
|
|
108
|
+
draw_table(dataTable);
|
|
109
|
+
},
|
|
110
|
+
error: function(result) {
|
|
111
|
+
error();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
function error() {
|
|
118
|
+
console.log("Error retrieving data");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function draw_graph_general_statistics(dataShared, transitioning, index, dateUpdated) {
|
|
122
|
+
if ($("#graph_general_statistics").length) {
|
|
123
|
+
// General Variables
|
|
124
|
+
var svg; // SVG to contain graph
|
|
125
|
+
var dataInt; // Internal reference to graph dataset
|
|
126
|
+
var titles; // Array of possible titles for graph
|
|
127
|
+
var title; // Title as determined by index passed in
|
|
128
|
+
// Dimension Variables
|
|
129
|
+
var margin; // Blank space around top graph (focus)
|
|
130
|
+
var margin2; // Blank space around bottom graph (context)
|
|
131
|
+
var width; // Drawable width of focus/context (not including margins)
|
|
132
|
+
var height; // Drawable height of focus (not including margins)
|
|
133
|
+
var height2; // Drawable height of context (not including margins)
|
|
134
|
+
// Date Variables
|
|
135
|
+
var parseDate; // Function to parse dates into proper format
|
|
136
|
+
var dateRange; // Range of dates in data set
|
|
137
|
+
var numDays; // Number of days in range
|
|
138
|
+
// Scale Variables
|
|
139
|
+
var x; // X-scale for focus graph
|
|
140
|
+
var x2; // X-scale for context graph
|
|
141
|
+
var y; // Y-scale for focus graph
|
|
142
|
+
var y2; // Y-scale for context graph
|
|
143
|
+
// Brush and Zoom Variables
|
|
144
|
+
var brush; // Object that allows domain selection by brush movement
|
|
145
|
+
var zoom; // Object that allows domain selection by zooming
|
|
146
|
+
// Axis Variables
|
|
147
|
+
var xAxis; // X-axis for focus graph
|
|
148
|
+
var xAxis2; // X-axis for context graph
|
|
149
|
+
var yAxis; // Y-axis for focus graph
|
|
150
|
+
// Area Variables
|
|
151
|
+
var area; // Area for focus graph
|
|
152
|
+
var area2; // Area for context graph
|
|
153
|
+
// Selection Variables
|
|
154
|
+
var gAllSelection; // Selection for overarching group
|
|
155
|
+
var gAll; // Group containing all elements
|
|
156
|
+
var focusSelection; // Selection for focus group
|
|
157
|
+
var focus; // Group containing all focus elements
|
|
158
|
+
var contextSelection; // Selection for context group
|
|
159
|
+
var context; // Group containing all context elements
|
|
160
|
+
var clipSelection; // Selection for clip path
|
|
161
|
+
var xAxisSelection; // Selection for xAxis
|
|
162
|
+
var yAxisSelection; // Selection for yAxis
|
|
163
|
+
var titleSelection; // Selection for title
|
|
164
|
+
var focusPathSelection; // Selection for focus path (area)
|
|
165
|
+
var xAxis2Selection; // Selection for xAxis2
|
|
166
|
+
var contextPathSelection; // Selection for context path (area)
|
|
167
|
+
var brushSelection; // Selection for brush
|
|
168
|
+
var zoomSelection; // Selection for zoom
|
|
169
|
+
// Update global index
|
|
170
|
+
Globals.Index = index;
|
|
171
|
+
|
|
172
|
+
// Initialize General Variables ///////////////////////////////////////////////////////////
|
|
173
|
+
svg = d3.select("#graph_general_statistics");
|
|
174
|
+
|
|
175
|
+
dataInt = dataShared[index];
|
|
176
|
+
|
|
177
|
+
titles = ["Clicks", "Sessions", "Searches"];
|
|
178
|
+
|
|
179
|
+
title = titles[index];
|
|
180
|
+
|
|
181
|
+
// Initialize Dimension Variables /////////////////////////////////////////////////////////
|
|
182
|
+
margin = {
|
|
183
|
+
top: 40,
|
|
184
|
+
right: 20,
|
|
185
|
+
bottom: 110,
|
|
186
|
+
left: 40
|
|
187
|
+
};
|
|
188
|
+
margin2 = {
|
|
189
|
+
top: 430,
|
|
190
|
+
right: 20,
|
|
191
|
+
bottom: 30,
|
|
192
|
+
left: 40
|
|
193
|
+
};
|
|
194
|
+
width = +svg.attr("width") - margin.left - margin.right;
|
|
195
|
+
height = +svg.attr("height") - margin.top - margin.bottom;
|
|
196
|
+
height2 = +svg.attr("height") - margin2.top - margin2.bottom;
|
|
197
|
+
|
|
198
|
+
// Initialize Date Variables and Parse Dates //////////////////////////////////////////////
|
|
199
|
+
parseDate = d3.timeParse("%Y-%m-%d");
|
|
200
|
+
|
|
201
|
+
dataInt.forEach(function(d) {
|
|
202
|
+
d.date = parseDate(d.date);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
dateRange = d3.extent(dataInt, function(d) {
|
|
206
|
+
return d.date;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
numDays = parseInt((dateRange[1]-dateRange[0])/(1000*60*60*24));
|
|
210
|
+
|
|
211
|
+
// Initialize Scale Variables /////////////////////////////////////////////////////////////
|
|
212
|
+
x = d3.scaleTime().range([0, width]);
|
|
213
|
+
x2 = d3.scaleTime().range([0, width]);
|
|
214
|
+
y = d3.scaleLinear().range([height, 0]);
|
|
215
|
+
y2 = d3.scaleLinear().range([height2, 0]);
|
|
216
|
+
|
|
217
|
+
// Set domains
|
|
218
|
+
x2.domain(d3.extent(dataInt, function(d) {
|
|
219
|
+
return d.date;
|
|
220
|
+
}));
|
|
221
|
+
if (_.isEqual(undefined, Globals.Domain)) {
|
|
222
|
+
x.domain(d3.extent(dataInt, function(d) {
|
|
223
|
+
return d.date;
|
|
224
|
+
}));
|
|
225
|
+
} else {
|
|
226
|
+
var lb, ub;
|
|
227
|
+
if (Globals.Domain[0] < x2.domain()[0]) {
|
|
228
|
+
lb = x2.domain()[0];
|
|
229
|
+
} else {
|
|
230
|
+
lb = Globals.Domain[0];
|
|
231
|
+
}
|
|
232
|
+
if (Globals.Domain[1] > x2.domain()[1]) {
|
|
233
|
+
ub = x2.domain()[1];
|
|
234
|
+
} else {
|
|
235
|
+
ub = Globals.Domain[1];
|
|
236
|
+
}
|
|
237
|
+
if(Globals.Domain[0]>x2.domain()[1] || Globals.Domain[1]<x2.domain()[0]) {
|
|
238
|
+
lb = x2.domain()[0];
|
|
239
|
+
ub = x2.domain()[1];
|
|
240
|
+
}
|
|
241
|
+
x.domain([lb, ub]);
|
|
242
|
+
}
|
|
243
|
+
y.domain([0, d3.max(dataInt, function(d) {
|
|
244
|
+
return d.count;
|
|
245
|
+
})]);
|
|
246
|
+
y2.domain(y.domain());
|
|
247
|
+
|
|
248
|
+
// Initialize Brush and Zoom Variables ////////////////////////////////////////////////////
|
|
249
|
+
brush = d3.brushX()
|
|
250
|
+
.extent([
|
|
251
|
+
[0, 0],
|
|
252
|
+
[width, height2]
|
|
253
|
+
])
|
|
254
|
+
.on("brush end", brushed);
|
|
255
|
+
|
|
256
|
+
zoom = d3.zoom()
|
|
257
|
+
.scaleExtent([1, 1000])
|
|
258
|
+
.translateExtent([
|
|
259
|
+
[0, 0],
|
|
260
|
+
[width, height]
|
|
261
|
+
])
|
|
262
|
+
.extent([
|
|
263
|
+
[0, 0],
|
|
264
|
+
[width, height]
|
|
265
|
+
])
|
|
266
|
+
.on("zoom", zoomed);
|
|
267
|
+
|
|
268
|
+
// Initialize Axis Variables //////////////////////////////////////////////////////////////
|
|
269
|
+
xAxis = d3.axisBottom(x);
|
|
270
|
+
xAxis2 = d3.axisBottom(x2);
|
|
271
|
+
yAxis = d3.axisLeft(y);
|
|
272
|
+
|
|
273
|
+
// Initialize Area Variables //////////////////////////////////////////////////////////////
|
|
274
|
+
area = d3.area()
|
|
275
|
+
.curve(d3.curveMonotoneX)
|
|
276
|
+
.x(function(d) {
|
|
277
|
+
return x(d.date);
|
|
278
|
+
})
|
|
279
|
+
.y0(height)
|
|
280
|
+
.y1(function(d) {
|
|
281
|
+
return y(d.count);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
area2 = d3.area()
|
|
285
|
+
.curve(d3.curveMonotoneX)
|
|
286
|
+
.x(function(d) {
|
|
287
|
+
return x2(d.date);
|
|
288
|
+
})
|
|
289
|
+
.y0(height2)
|
|
290
|
+
.y1(function(d) {
|
|
291
|
+
return y2(d.count);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Make overarching group /////////////////////////////////////////////////////////////////
|
|
295
|
+
gAllSelection = svg.selectAll(".gAll").data([dataInt]);
|
|
296
|
+
|
|
297
|
+
gAllSelection.exit().transition().duration(500)
|
|
298
|
+
.style("opacity", .000001)
|
|
299
|
+
.remove();
|
|
300
|
+
gAllSelection.enter().append("g")
|
|
301
|
+
.attr("class", "gAll")
|
|
302
|
+
.attr("transform", "translate(0,0)");
|
|
303
|
+
|
|
304
|
+
gAll = svg.select(".gAll");
|
|
305
|
+
|
|
306
|
+
// Make focus
|
|
307
|
+
focusSelection = gAll.selectAll(".focus").data([dataInt]);
|
|
308
|
+
|
|
309
|
+
focusSelection.exit().transition().duration(500)
|
|
310
|
+
.style("opacity", .000001)
|
|
311
|
+
.remove();
|
|
312
|
+
focusSelection.enter().append("g")
|
|
313
|
+
.attr("class", "focus")
|
|
314
|
+
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
315
|
+
|
|
316
|
+
focus = gAll.select(".focus");
|
|
317
|
+
|
|
318
|
+
// Make context
|
|
319
|
+
contextSelection = gAll.selectAll(".context").data([dataInt]);
|
|
320
|
+
|
|
321
|
+
contextSelection.exit().transition().duration(500)
|
|
322
|
+
.style("opacity", .000001)
|
|
323
|
+
.remove();
|
|
324
|
+
contextSelection.enter().append("g")
|
|
325
|
+
.attr("class", "context")
|
|
326
|
+
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
|
|
327
|
+
|
|
328
|
+
context = gAll.select(".context");
|
|
329
|
+
|
|
330
|
+
// Make clip path
|
|
331
|
+
clipSelection = gAll.selectAll("defs").data([dataInt]);
|
|
332
|
+
|
|
333
|
+
clipSelection.exit().transition().duration(500)
|
|
334
|
+
.style("opacity", .000001)
|
|
335
|
+
.remove();
|
|
336
|
+
clipSelection.enter().append("defs").append("clipPath")
|
|
337
|
+
.attr("id", "clip")
|
|
338
|
+
.append("rect")
|
|
339
|
+
.attr("width", width)
|
|
340
|
+
.attr("height", height);
|
|
341
|
+
|
|
342
|
+
// Make focus x axis
|
|
343
|
+
xAxisSelection = focus.selectAll(".xAxis").data([dataInt]);
|
|
344
|
+
|
|
345
|
+
xAxisSelection.transition().duration(750)
|
|
346
|
+
.call(xAxis);
|
|
347
|
+
xAxisSelection.exit().transition().duration(500)
|
|
348
|
+
.style("opacity", .000001)
|
|
349
|
+
.remove();
|
|
350
|
+
xAxisSelection.enter().append("g")
|
|
351
|
+
.style("opacity", .000001)
|
|
352
|
+
.attr("class", "xAxis")
|
|
353
|
+
.attr("transform", "translate(0," + height + ")")
|
|
354
|
+
.call(xAxis)
|
|
355
|
+
.transition().duration(500)
|
|
356
|
+
.style("opacity", 1);
|
|
357
|
+
|
|
358
|
+
// Make focus y axis
|
|
359
|
+
yAxisSelection = focus.selectAll(".yAxis").data([dataInt]);
|
|
360
|
+
|
|
361
|
+
yAxisSelection.transition().duration(750)
|
|
362
|
+
.call(yAxis);
|
|
363
|
+
yAxisSelection.exit().transition().duration(500)
|
|
364
|
+
.style("opacity", .000001)
|
|
365
|
+
.remove();
|
|
366
|
+
yAxisSelection.enter().append("g")
|
|
367
|
+
.style("opacity", .000001)
|
|
368
|
+
.attr("class", "yAxis")
|
|
369
|
+
.attr("transform", "translate(0,0)")
|
|
370
|
+
.call(yAxis)
|
|
371
|
+
.transition().duration(500)
|
|
372
|
+
.style("opacity", 1);
|
|
373
|
+
|
|
374
|
+
// Make chart title
|
|
375
|
+
titleSelection = svg.selectAll(".chartTitle").data([dataInt]);
|
|
376
|
+
|
|
377
|
+
titleSelection.transition().duration(325)
|
|
378
|
+
.style("opacity", .00001)
|
|
379
|
+
.transition()
|
|
380
|
+
.text(title)
|
|
381
|
+
.transition().duration(325)
|
|
382
|
+
.style("opacity", 1);
|
|
383
|
+
titleSelection.exit().transition().duration(500)
|
|
384
|
+
.style("opacity", .000001)
|
|
385
|
+
.remove();
|
|
386
|
+
titleSelection.enter().append("text")
|
|
387
|
+
.style("opacity", .000001)
|
|
388
|
+
.text(title)
|
|
389
|
+
.attr("class", "chartTitle")
|
|
390
|
+
.attr("transform", "translate(" + (width / 2) + "," + 30 + ")")
|
|
391
|
+
.transition().duration(500)
|
|
392
|
+
.style("opacity", 1);
|
|
393
|
+
|
|
394
|
+
// Make focus path
|
|
395
|
+
focusPathSelection = focus.selectAll(".area").data([dataInt]);
|
|
396
|
+
|
|
397
|
+
focusPathSelection.datum(dataInt).transition().duration(750)
|
|
398
|
+
.attr("d", area);
|
|
399
|
+
focusPathSelection.exit().transition().duration(500)
|
|
400
|
+
.style("opacity", .000001)
|
|
401
|
+
.remove();
|
|
402
|
+
focusPathSelection.enter().append("path")
|
|
403
|
+
.style("opacity", .000001)
|
|
404
|
+
.datum(dataInt)
|
|
405
|
+
.attr("class", "area")
|
|
406
|
+
.transition().duration(500)
|
|
407
|
+
.style("opacity", 1);;
|
|
408
|
+
|
|
409
|
+
// Make context x axis
|
|
410
|
+
xAxis2Selection = context.selectAll(".xAxis").data([dataInt]);
|
|
411
|
+
|
|
412
|
+
xAxis2Selection.transition().duration(500)
|
|
413
|
+
.call(xAxis2);
|
|
414
|
+
xAxis2Selection.exit().transition().duration(500)
|
|
415
|
+
.style("opacity", .000001)
|
|
416
|
+
.remove();
|
|
417
|
+
xAxis2Selection.enter().append("g")
|
|
418
|
+
.style("opacity", .000001)
|
|
419
|
+
.attr("class", "xAxis")
|
|
420
|
+
.attr("transform", "translate(0," + height2 + ")")
|
|
421
|
+
.call(xAxis2)
|
|
422
|
+
.transition().duration(500)
|
|
423
|
+
.style("opacity", 1);
|
|
424
|
+
|
|
425
|
+
// Make context path
|
|
426
|
+
contextPathSelection = context.selectAll(".area").data([dataInt]);
|
|
427
|
+
|
|
428
|
+
contextPathSelection.datum(dataInt).transition().duration(750)
|
|
429
|
+
.attr("d", area2);
|
|
430
|
+
contextPathSelection.exit().transition().duration(500)
|
|
431
|
+
.style("opacity", .000001)
|
|
432
|
+
.remove();
|
|
433
|
+
contextPathSelection.enter().append("path")
|
|
434
|
+
.style("opacity", .000001)
|
|
435
|
+
.datum(dataInt)
|
|
436
|
+
.attr("class", "area")
|
|
437
|
+
.attr("d", area2)
|
|
438
|
+
.transition().duration(500)
|
|
439
|
+
.style("opacity", 1);
|
|
440
|
+
|
|
441
|
+
// Make brush container
|
|
442
|
+
brushSelection = context.selectAll(".brush").data([dataInt]);
|
|
443
|
+
|
|
444
|
+
brushSelection.exit().transition().duration(500)
|
|
445
|
+
.style("opacity", .000001)
|
|
446
|
+
.remove();
|
|
447
|
+
brushSelection.enter().append("g")
|
|
448
|
+
.attr("class", "brush")
|
|
449
|
+
.call(brush)
|
|
450
|
+
.call(brush.move, x.range())
|
|
451
|
+
.merge(brushSelection)
|
|
452
|
+
.style("opacity", 1)
|
|
453
|
+
.call(brush);
|
|
454
|
+
|
|
455
|
+
// Misc ///////////////////////////////////////////////////////////////////////////////////
|
|
456
|
+
// Have to prevent zoom or brush temporarily for transitions to execute
|
|
457
|
+
if (transitioning) {
|
|
458
|
+
setTimeout(function() {
|
|
459
|
+
transitioning = false;
|
|
460
|
+
}, 50);
|
|
461
|
+
} // If not on transition, fade in brush
|
|
462
|
+
else {
|
|
463
|
+
svg.selectAll(".brush")
|
|
464
|
+
.style("opacity", .000001)
|
|
465
|
+
.transition().duration(500)
|
|
466
|
+
.style("opacity", 1);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// Before updating domains, move brush to domain it was previously set to
|
|
470
|
+
if (dateUpdated) {
|
|
471
|
+
var lb, ub;
|
|
472
|
+
if (x2(Globals.Domain[0]) < 0) {
|
|
473
|
+
lb = 0;
|
|
474
|
+
} else {
|
|
475
|
+
lb = x2(Globals.Domain[0]);
|
|
476
|
+
}
|
|
477
|
+
if (x2(Globals.Domain[1]) > width) {
|
|
478
|
+
ub = width;
|
|
479
|
+
} else {
|
|
480
|
+
ub = x2(Globals.Domain[1]);
|
|
481
|
+
}
|
|
482
|
+
if(Globals.Domain[0]>x2.domain()[1] || Globals.Domain[1]<x2.domain()[0]) {
|
|
483
|
+
lb = 0;
|
|
484
|
+
ub = width;
|
|
485
|
+
}
|
|
486
|
+
context.select(".brush").call(brush.move, [lb, ub]);
|
|
487
|
+
context.select(".brush").transition().duration(500)
|
|
488
|
+
.style("opacity", 1);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Make zoom container
|
|
492
|
+
zoomSelection = gAll.selectAll(".zoom").data([dataInt]);
|
|
493
|
+
|
|
494
|
+
zoomSelection.exit().transition().duration(500)
|
|
495
|
+
.style("opacity", .000001)
|
|
496
|
+
.remove();
|
|
497
|
+
zoomSelection.enter().append("rect")
|
|
498
|
+
.attr("class", "zoom")
|
|
499
|
+
.attr("width", width)
|
|
500
|
+
.attr("height", height)
|
|
501
|
+
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
|
|
502
|
+
.merge(zoomSelection)
|
|
503
|
+
.call(zoom);
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
function brushed() {
|
|
507
|
+
if (!transitioning) {
|
|
508
|
+
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return;
|
|
509
|
+
var s = d3.event.selection || x2.range();
|
|
510
|
+
x.domain(s.map(x2.invert, x2));
|
|
511
|
+
Globals.Domain = x.domain();
|
|
512
|
+
focus.select(".area").attr("d", area);
|
|
513
|
+
focus.select(".xAxis").call(xAxis);
|
|
514
|
+
svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
|
|
515
|
+
.scale(width / (s[1] - s[0]))
|
|
516
|
+
.translate(-s[0], 0));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function zoomed() {
|
|
521
|
+
if (!transitioning) {
|
|
522
|
+
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return;
|
|
523
|
+
var t = d3.event.transform;
|
|
524
|
+
x.domain(t.rescaleX(x2).domain());
|
|
525
|
+
Globals.Domain = x.domain();
|
|
526
|
+
focus.select(".area").attr("d", area);
|
|
527
|
+
focus.select(".xAxis").call(xAxis);
|
|
528
|
+
context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function load_new_data(index) {
|
|
535
|
+
var updateData = _.cloneDeep(Globals.Data);
|
|
536
|
+
draw_graph_general_statistics(updateData, true, index, false);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function draw_graph_mini(dataShared, id) {
|
|
540
|
+
if ($("#graph_general_statistics").length) {
|
|
541
|
+
// General Variables
|
|
542
|
+
var svg; // SVG to contain graph
|
|
543
|
+
var dataInt; // Internal reference to graph dataset
|
|
544
|
+
var title; // Title as determined by id passed in
|
|
545
|
+
// Dimension Variables
|
|
546
|
+
var margin; // Blank space around graph
|
|
547
|
+
var width; // Drawable width of graph (not including margins)
|
|
548
|
+
var height; // Drawable height of graph (not including margins)
|
|
549
|
+
// Date Variables
|
|
550
|
+
var parseDate; // Function to parse dates into proper format
|
|
551
|
+
// Scale Variables
|
|
552
|
+
var x; // X-scale for graph
|
|
553
|
+
var y; // Y-scale for graph
|
|
554
|
+
// Axis Variables
|
|
555
|
+
var xAxis; // X-axis for graph
|
|
556
|
+
var yAxis; // Y-axis for graph
|
|
557
|
+
// Area Variables
|
|
558
|
+
var area; // Area for graph
|
|
559
|
+
// Selection Variables
|
|
560
|
+
var gAllSelection; // Selection for overarching group
|
|
561
|
+
var gAll; // Group containing all elements
|
|
562
|
+
var xAxisSelection; // Selection for xAxis
|
|
563
|
+
var yAxisSelection; // Selection for yAxis
|
|
564
|
+
var pathSelection; // Selection for path
|
|
565
|
+
var textSelection; // Selection for title
|
|
566
|
+
|
|
567
|
+
// Initialize General Variables ///////////////////////////////////////////////////////////
|
|
568
|
+
svg = d3.select(id);
|
|
569
|
+
|
|
570
|
+
dataInt = dataShared;
|
|
571
|
+
|
|
572
|
+
title = "";
|
|
573
|
+
if (id == "#mini0") {
|
|
574
|
+
title = "Clicks";
|
|
575
|
+
} else if (id == "#mini1") {
|
|
576
|
+
title = "Sessions";
|
|
577
|
+
} else {
|
|
578
|
+
title = "Searches";
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// Initialize Dimension Variables /////////////////////////////////////////////////////////
|
|
582
|
+
margin = {
|
|
583
|
+
top: 5,
|
|
584
|
+
right: 5,
|
|
585
|
+
bottom: 5,
|
|
586
|
+
left: 5
|
|
587
|
+
};
|
|
588
|
+
width = +svg.attr("width") - margin.left - margin.right;
|
|
589
|
+
height = +svg.attr("height") - margin.top - margin.bottom;
|
|
590
|
+
|
|
591
|
+
// Initialize Date Variables and Parse Dates //////////////////////////////////////////////
|
|
592
|
+
parseDate = d3.timeParse("%Y-%m-%d");
|
|
593
|
+
|
|
594
|
+
dataInt.forEach(function(d) {
|
|
595
|
+
d.date = parseDate(d.date);
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
// Initialize Scale Variables /////////////////////////////////////////////////////////////
|
|
599
|
+
x = d3.scaleTime().range([0, width]);
|
|
600
|
+
y = d3.scaleLinear().range([height, 0]);
|
|
601
|
+
|
|
602
|
+
// Set domains
|
|
603
|
+
x.domain(d3.extent(dataInt, function(d) {
|
|
604
|
+
return d.date;
|
|
605
|
+
}));
|
|
606
|
+
y.domain([0, d3.max(dataInt, function(d) {
|
|
607
|
+
return d.count;
|
|
608
|
+
})]);
|
|
609
|
+
|
|
610
|
+
// Initialize Axis Variables //////////////////////////////////////////////////////////////
|
|
611
|
+
xAxis = d3.axisBottom(x);
|
|
612
|
+
yAxis = d3.axisLeft(y);
|
|
613
|
+
|
|
614
|
+
// Remove ticks from axes
|
|
615
|
+
xAxis.tickSizeOuter(0);
|
|
616
|
+
yAxis.tickSizeOuter(0);
|
|
617
|
+
|
|
618
|
+
// Initialize Area Variables //////////////////////////////////////////////////////////////
|
|
619
|
+
area = d3.area()
|
|
620
|
+
.curve(d3.curveMonotoneX)
|
|
621
|
+
.x(function(d) {
|
|
622
|
+
return x(d.date);
|
|
623
|
+
})
|
|
624
|
+
.y0(height)
|
|
625
|
+
.y1(function(d) {
|
|
626
|
+
return y(d.count);
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
// Make overarching group /////////////////////////////////////////////////////////////////
|
|
630
|
+
gAllSelection = svg.selectAll(".gAll").data([dataInt]);
|
|
631
|
+
|
|
632
|
+
gAllSelection.exit().transition().duration(500)
|
|
633
|
+
.style("opacity", .000001)
|
|
634
|
+
.remove();
|
|
635
|
+
gAllSelection.enter().append("g")
|
|
636
|
+
.attr("class", "gAll")
|
|
637
|
+
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
638
|
+
|
|
639
|
+
gAll = svg.select(".gAll");
|
|
640
|
+
|
|
641
|
+
// Append clip path
|
|
642
|
+
svg.append("defs").append("clipPath")
|
|
643
|
+
.attr("id", "clipMini")
|
|
644
|
+
.append("rect")
|
|
645
|
+
.attr("width", width)
|
|
646
|
+
.attr("height", height);
|
|
647
|
+
|
|
648
|
+
// Make xAxis
|
|
649
|
+
xAxisSelection = gAll.selectAll(".xAxis").data([dataInt]);
|
|
650
|
+
|
|
651
|
+
xAxisSelection.exit().transition().duration(500)
|
|
652
|
+
.style("opacity", .000001)
|
|
653
|
+
.remove();
|
|
654
|
+
xAxisSelection.enter().append("g")
|
|
655
|
+
.style("opacity", .000001)
|
|
656
|
+
.attr("class", "xAxis")
|
|
657
|
+
.attr("transform", "translate(0," + height + ")")
|
|
658
|
+
.call(xAxis.ticks(0))
|
|
659
|
+
.transition().duration(500)
|
|
660
|
+
.style("opacity", 1);
|
|
661
|
+
|
|
662
|
+
// Make yAxis
|
|
663
|
+
yAxisSelection = gAll.selectAll(".yAxis").data([dataInt]);
|
|
664
|
+
|
|
665
|
+
yAxisSelection.exit().transition().duration(500)
|
|
666
|
+
.style("opacity", .000001)
|
|
667
|
+
.remove();
|
|
668
|
+
yAxisSelection.enter().append("g")
|
|
669
|
+
.style("opacity", .000001)
|
|
670
|
+
.attr("class", "yAxis")
|
|
671
|
+
.call(yAxis.ticks(0))
|
|
672
|
+
.transition().duration(500)
|
|
673
|
+
.style("opacity", 1);
|
|
674
|
+
|
|
675
|
+
// Make path
|
|
676
|
+
pathSelection = gAll.selectAll(".areaMini").data([dataInt]);
|
|
677
|
+
|
|
678
|
+
pathSelection.datum(dataInt).transition().duration(750)
|
|
679
|
+
.attr("d", area);
|
|
680
|
+
pathSelection.exit().transition().duration(500)
|
|
681
|
+
.style("opacity", .000001)
|
|
682
|
+
.remove();
|
|
683
|
+
pathSelection.enter().append("path")
|
|
684
|
+
.style("opacity", .000001)
|
|
685
|
+
.datum(dataInt)
|
|
686
|
+
.attr("class", "areaMini")
|
|
687
|
+
.attr("d", area)
|
|
688
|
+
.transition().duration(500)
|
|
689
|
+
.style("opacity", 1);
|
|
690
|
+
|
|
691
|
+
// Make title
|
|
692
|
+
textSelection = gAll.selectAll(".chartTitle").data([dataInt]);
|
|
693
|
+
|
|
694
|
+
textSelection.exit().transition().duration(500)
|
|
695
|
+
.style("opacity", .000001)
|
|
696
|
+
.remove();
|
|
697
|
+
textSelection.enter().append("text")
|
|
698
|
+
.style("opacity", .000001)
|
|
699
|
+
.text(title)
|
|
700
|
+
.attr("class", "chartTitle")
|
|
701
|
+
.attr("transform", "translate(" + (width / 2) + "," + (height - margin.bottom) + ")")
|
|
702
|
+
.transition().duration(500)
|
|
703
|
+
.style("opacity", 1);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function draw_table(dataShared) {
|
|
708
|
+
if ($("#graph_general_statistics").length) {
|
|
709
|
+
// General Variables
|
|
710
|
+
var svg; // SVG to contain graph
|
|
711
|
+
var dataInt; // Internal reference to graph dataset
|
|
712
|
+
// Dimension Variables
|
|
713
|
+
var margin; // Blank space around graph
|
|
714
|
+
var width; // Drawable width of graph (not including margins)
|
|
715
|
+
var height; // Drawable height of graph (not including margins)
|
|
716
|
+
var horizontalTextOffset; // Horizontal text padding
|
|
717
|
+
var verticalTextOffset; // Vertical text padding
|
|
718
|
+
// Scale Variables
|
|
719
|
+
var x; // X-scale for graph
|
|
720
|
+
var y; // Y-scale for graph
|
|
721
|
+
// Additional Data Variables
|
|
722
|
+
var lineData; // Data for line construction (two x,y pairs)
|
|
723
|
+
var headingData; // Data for heading construction (text, x, and y values)
|
|
724
|
+
var keys; // Keys used to traverse dataset
|
|
725
|
+
// Selection Variables
|
|
726
|
+
var groupEnter; // Entry selection for overarching group
|
|
727
|
+
var gAll; // Group containing all elements
|
|
728
|
+
var lineGroup; // Group containing all lines
|
|
729
|
+
var headingGroup; // Group containing all headings
|
|
730
|
+
var dataGroup; // Group containing all data elements
|
|
731
|
+
|
|
732
|
+
// Initialize General Variables ///////////////////////////////////////////////////////////
|
|
733
|
+
svg = d3.select("#graph_general_table");
|
|
734
|
+
|
|
735
|
+
dataInt = dataShared;
|
|
736
|
+
|
|
737
|
+
// Initialize Dimension Variables /////////////////////////////////////////////////////////
|
|
738
|
+
margin = {
|
|
739
|
+
top: 20,
|
|
740
|
+
right: 20,
|
|
741
|
+
bottom: 20,
|
|
742
|
+
left: 20
|
|
743
|
+
};
|
|
744
|
+
width = +svg.attr("width") - margin.left - margin.right;
|
|
745
|
+
height = +svg.attr("height") - margin.top - margin.bottom;
|
|
746
|
+
horizontalTextOffset = 10;
|
|
747
|
+
verticalTextOffset = 30;
|
|
748
|
+
|
|
749
|
+
// Initialize Scale Variables /////////////////////////////////////////////////////////////
|
|
750
|
+
x = d3.scaleLinear().rangeRound([0, width]);
|
|
751
|
+
y = d3.scaleLinear().rangeRound([0, height]);
|
|
752
|
+
|
|
753
|
+
// Set domains
|
|
754
|
+
x.domain([0, 100]);
|
|
755
|
+
y.domain([0, 100]);
|
|
756
|
+
|
|
757
|
+
// Initialize Additional Data Variables ///////////////////////////////////////////////////
|
|
758
|
+
lineData = [ {x1: x(0 ), y1: y(25 ), x2: x(100), y2: y(25 )}
|
|
759
|
+
,{x1: x(20 ), y1: y(0 ), x2: x(20 ), y2: y(100)}
|
|
760
|
+
,{x1: x(36 ), y1: y(0 ), x2: x(36 ), y2: y(100)}
|
|
761
|
+
,{x1: x(52 ), y1: y(0 ), x2: x(52 ), y2: y(100)}
|
|
762
|
+
,{x1: x(68 ), y1: y(0 ), x2: x(68 ), y2: y(100)}
|
|
763
|
+
,{x1: x(84 ), y1: y(0 ), x2: x(84 ), y2: y(100)}];
|
|
764
|
+
|
|
765
|
+
headingData = [ {txt: "Clicks", x1: x(2 ), y1: y(37.5)}
|
|
766
|
+
,{txt: "Searches", x1: x(2 ), y1: y(62.5)}
|
|
767
|
+
,{txt: "Sessions", x1: x(2 ), y1: y(87.5)}
|
|
768
|
+
,{txt: "Total", x1: x(22), y1: y(12.5)}
|
|
769
|
+
,{txt: "Per Day", x1: x(38), y1: y(12.5)}
|
|
770
|
+
,{txt: "Per Click", x1: x(54), y1: y(12.5)}
|
|
771
|
+
,{txt: "Per Search", x1: x(70), y1: y(12.5)}
|
|
772
|
+
,{txt: "Per Session", x1: x(86), y1: y(12.5)}];
|
|
773
|
+
|
|
774
|
+
keys = ["clicks", "searches", "sessions"];
|
|
775
|
+
|
|
776
|
+
// Make overarching group /////////////////////////////////////////////////////////////////
|
|
777
|
+
groupEnter = svg.selectAll("g").data([dataInt]).enter();
|
|
778
|
+
|
|
779
|
+
groupEnter.append("g")
|
|
780
|
+
.attr("class", "gAll");
|
|
781
|
+
|
|
782
|
+
gAll = svg.select(".gAll")
|
|
783
|
+
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
// Add Lines For Grid
|
|
788
|
+
gAll.selectAll(".lineGroup").data([dataInt]).enter().append("g")
|
|
789
|
+
.attr("class", "lineGroup");
|
|
790
|
+
|
|
791
|
+
lineGroup = gAll.select(".lineGroup")
|
|
792
|
+
.attr("transform", "translate(0,0)");
|
|
793
|
+
|
|
794
|
+
lineGroup.selectAll(".gridLine").data(lineData).enter().append("line")
|
|
795
|
+
.style("opacity", .000001)
|
|
796
|
+
.attr("class", "gridLine")
|
|
797
|
+
.attr("x1", function(d) { return d.x1; })
|
|
798
|
+
.attr("x2", function(d) { return d.x2; })
|
|
799
|
+
.attr("y1", function(d) { return d.y1; })
|
|
800
|
+
.attr("y2", function(d) { return d.y2; })
|
|
801
|
+
.transition().duration(500)
|
|
802
|
+
.style("opacity", 1);;
|
|
803
|
+
|
|
804
|
+
// Add row/column headings headings
|
|
805
|
+
gAll.selectAll(".headingGroup").data([dataInt]).enter().append("g")
|
|
806
|
+
.attr("class", "headingGroup");
|
|
807
|
+
|
|
808
|
+
headingGroup = gAll.select(".headingGroup")
|
|
809
|
+
.attr("transform", "translate(0,0)");
|
|
810
|
+
|
|
811
|
+
headingGroup.selectAll(".headText").data(headingData).enter().append("text")
|
|
812
|
+
.style("opacity", .000001)
|
|
813
|
+
.attr("class", "headText")
|
|
814
|
+
.text(function (d) { return d.txt; })
|
|
815
|
+
.attr("transform", function(d) { return "translate(" + d.x1 + "," + d.y1 + ")"; })
|
|
816
|
+
.transition().duration(500)
|
|
817
|
+
.style("opacity", 1);;
|
|
818
|
+
|
|
819
|
+
// Add data text
|
|
820
|
+
gAll.selectAll(".dataGroup").data([dataInt]).enter().append("g")
|
|
821
|
+
.attr("class", "dataGroup");
|
|
822
|
+
|
|
823
|
+
dataGroup = gAll.select(".dataGroup")
|
|
824
|
+
.attr("transform", "translate(0,0)");
|
|
825
|
+
|
|
826
|
+
// Totals column
|
|
827
|
+
dataGroup.selectAll(".totalText").data(dataInt)
|
|
828
|
+
.transition().duration(325)
|
|
829
|
+
.style("opacity", .000001)
|
|
830
|
+
.transition()
|
|
831
|
+
.text(function (d,i) { return d[keys[i]]; })
|
|
832
|
+
.transition().duration(325)
|
|
833
|
+
.style("opacity", 1);
|
|
834
|
+
dataGroup.selectAll(".totalText").data(dataInt).enter().append("text")
|
|
835
|
+
.style("opacity", .000001)
|
|
836
|
+
.attr("class", "totalText")
|
|
837
|
+
.text(function (d,i) { return d[keys[i]]; })
|
|
838
|
+
.attr("transform", function(d, i) { return "translate(" + x(22) + "," + y(37.5+25*i) + ")"; })
|
|
839
|
+
.transition().duration(500)
|
|
840
|
+
.style("opacity", 1);
|
|
841
|
+
|
|
842
|
+
// Per Day column
|
|
843
|
+
dataGroup.selectAll(".perDayText").data(dataInt)
|
|
844
|
+
.transition().duration(325)
|
|
845
|
+
.style("opacity", .000001)
|
|
846
|
+
.transition()
|
|
847
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/Globals.Days_In_Sample * 10000)/10000; })
|
|
848
|
+
.transition().duration(325)
|
|
849
|
+
.style("opacity", 1);
|
|
850
|
+
dataGroup.selectAll(".perDayText").data(dataInt).enter().append("text")
|
|
851
|
+
.style("opacity", .000001)
|
|
852
|
+
.attr("class", "perDayText")
|
|
853
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/Globals.Days_In_Sample * 10000)/10000; })
|
|
854
|
+
.attr("transform", function(d, i) { return "translate(" + x(38) + "," + y(37.5+25*i) + ")"; })
|
|
855
|
+
.transition().duration(500)
|
|
856
|
+
.style("opacity", 1);
|
|
857
|
+
|
|
858
|
+
// Per Click column
|
|
859
|
+
dataGroup.selectAll(".perClickText").data(dataInt)
|
|
860
|
+
.transition().duration(325)
|
|
861
|
+
.style("opacity", .000001)
|
|
862
|
+
.transition()
|
|
863
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/parseInt(dataInt[0]["clicks"]) * 10000)/10000; })
|
|
864
|
+
.transition().duration(325)
|
|
865
|
+
.style("opacity", 1);
|
|
866
|
+
dataGroup.selectAll(".perClickText").data(dataInt).enter().append("text")
|
|
867
|
+
.style("opacity", .000001)
|
|
868
|
+
.attr("class", "perClickText")
|
|
869
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/parseInt(dataInt[0]["clicks"]) * 10000)/10000; })
|
|
870
|
+
.attr("transform", function(d, i) { return "translate(" + x(54) + "," + y(37.5+25*i) + ")"; })
|
|
871
|
+
.transition().duration(500)
|
|
872
|
+
.style("opacity", 1);
|
|
873
|
+
|
|
874
|
+
// Per Search column
|
|
875
|
+
dataGroup.selectAll(".perSearchText").data(dataInt)
|
|
876
|
+
.transition().duration(325)
|
|
877
|
+
.style("opacity", .000001)
|
|
878
|
+
.transition()
|
|
879
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/parseInt(dataInt[1]["searches"]) * 10000)/10000; })
|
|
880
|
+
.transition().duration(325)
|
|
881
|
+
.style("opacity", 1);
|
|
882
|
+
dataGroup.selectAll(".perSearchText").data(dataInt).enter().append("text")
|
|
883
|
+
.style("opacity", .000001)
|
|
884
|
+
.attr("class", "perSearchText")
|
|
885
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/parseInt(dataInt[1]["searches"]) * 10000)/10000; })
|
|
886
|
+
.attr("transform", function(d, i) { return "translate(" + x(70) + "," + y(37.5+25*i) + ")"; })
|
|
887
|
+
.transition().duration(500)
|
|
888
|
+
.style("opacity", 1);
|
|
889
|
+
|
|
890
|
+
// Per Session column
|
|
891
|
+
dataGroup.selectAll(".perSessionText").data(dataInt)
|
|
892
|
+
.transition().duration(325)
|
|
893
|
+
.style("opacity", .000001)
|
|
894
|
+
.transition()
|
|
895
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/parseInt(dataInt[2]["sessions"]) * 10000)/10000; })
|
|
896
|
+
.transition().duration(325)
|
|
897
|
+
.style("opacity", 1);
|
|
898
|
+
dataGroup.selectAll(".perSessionText").data(dataInt).enter().append("text")
|
|
899
|
+
.style("opacity", .000001)
|
|
900
|
+
.attr("class", "perSessionText")
|
|
901
|
+
.text(function (d,i) { return Math.round(parseInt(d[keys[i]])/parseInt(dataInt[2]["sessions"]) * 10000)/10000; })
|
|
902
|
+
.attr("transform", function(d, i) { return "translate(" + x(86) + "," + y(37.5+25*i) + ")"; })
|
|
903
|
+
.transition().duration(500)
|
|
904
|
+
.style("opacity", 1);
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
})();
|