brilliant_cms 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/images/brilliant_cms/bootstrap-colorpicker/alpha-horizontal.png +0 -0
  6. data/app/assets/images/brilliant_cms/bootstrap-colorpicker/alpha.png +0 -0
  7. data/app/assets/images/brilliant_cms/bootstrap-colorpicker/hue-horizontal.png +0 -0
  8. data/app/assets/images/brilliant_cms/bootstrap-colorpicker/hue.png +0 -0
  9. data/app/assets/images/brilliant_cms/bootstrap-colorpicker/saturation.png +0 -0
  10. data/app/assets/images/brilliant_cms/light-bulb.svg +38 -0
  11. data/app/assets/images/brilliant_cms/user.png +0 -0
  12. data/app/assets/javascripts/brilliant_cms/application.js +6 -0
  13. data/app/assets/javascripts/brilliant_cms/dashboard.js +2 -0
  14. data/app/assets/javascripts/brilliant_cms/data/flot.js +58 -0
  15. data/app/assets/javascripts/brilliant_cms/data/gauge.js +21 -0
  16. data/app/assets/javascripts/brilliant_cms/data/linegraphs.coffee +23 -0
  17. data/app/assets/javascripts/brilliant_cms/data/load.js +1 -0
  18. data/app/assets/javascripts/brilliant_cms/data/map.coffee +17 -0
  19. data/app/assets/javascripts/brilliant_cms/datepicker.coffee +107 -0
  20. data/app/assets/javascripts/brilliant_cms/entries.js +2 -0
  21. data/app/assets/javascripts/brilliant_cms/skycons.coffee +18 -0
  22. data/app/assets/javascripts/brilliant_cms/vendor/bootstrap-progressbar.min.js +2 -0
  23. data/app/assets/javascripts/brilliant_cms/vendor/chart.min.js +11 -0
  24. data/app/assets/javascripts/brilliant_cms/vendor/daterangepicker.js +1 -0
  25. data/app/assets/javascripts/brilliant_cms/vendor/flot/a.jquery.flot.js +2 -0
  26. data/app/assets/javascripts/brilliant_cms/vendor/flot/b.jquery.flot.pie.js +820 -0
  27. data/app/assets/javascripts/brilliant_cms/vendor/flot/c.jquery.flot.orderBars.js +187 -0
  28. data/app/assets/javascripts/brilliant_cms/vendor/flot/d.jquery.flot.time.min.js +1 -0
  29. data/app/assets/javascripts/brilliant_cms/vendor/flot/e.date.js +104 -0
  30. data/app/assets/javascripts/brilliant_cms/vendor/flot/f.jquery.flot.spline.js +212 -0
  31. data/app/assets/javascripts/brilliant_cms/vendor/flot/g.jquery.flot.stack.js +188 -0
  32. data/app/assets/javascripts/brilliant_cms/vendor/flot/h.curvedLines.js +483 -0
  33. data/app/assets/javascripts/brilliant_cms/vendor/flot/i.jquery.flot.resize.js +57 -0
  34. data/app/assets/javascripts/brilliant_cms/vendor/flot/jquery.flot.tooltip.min.js +12 -0
  35. data/app/assets/javascripts/brilliant_cms/vendor/gauge.min.js +61 -0
  36. data/app/assets/javascripts/brilliant_cms/vendor/jquery.nicescroll.min.js +111 -0
  37. data/app/assets/javascripts/brilliant_cms/vendor/load.js +11 -0
  38. data/app/assets/javascripts/brilliant_cms/vendor/maps/jquery-jvectormap.js +2 -0
  39. data/app/assets/javascripts/brilliant_cms/vendor/maps/jvectormap-us-aea-en.js +1 -0
  40. data/app/assets/javascripts/brilliant_cms/vendor/maps/jvectormap-world-mill-en.js +1 -0
  41. data/app/assets/javascripts/brilliant_cms/vendor/maps/z.gdp-data.js +185 -0
  42. data/app/assets/javascripts/brilliant_cms/vendor/moment.js +3606 -0
  43. data/app/assets/javascripts/brilliant_cms/vendor/nprogress.js +491 -0
  44. data/app/assets/javascripts/brilliant_cms/vendor/skycons.js +730 -0
  45. data/app/assets/javascripts/brilliant_cms/vendor/template.js +317 -0
  46. data/app/assets/stylesheets/brilliant_cms/application.css +6 -0
  47. data/app/assets/stylesheets/brilliant_cms/dashboard.css +4 -0
  48. data/app/assets/stylesheets/brilliant_cms/entries.css +4 -0
  49. data/app/assets/stylesheets/brilliant_cms/layout.scss +6389 -0
  50. data/app/assets/stylesheets/brilliant_cms/vendor/animate.min.css +11 -0
  51. data/app/assets/stylesheets/brilliant_cms/vendor/maps/jquery-jvectormap-2.0.1.css +129 -0
  52. data/app/controllers/brilliant_cms/application_controller.rb +35 -0
  53. data/app/controllers/brilliant_cms/dashboard_controller.rb +12 -0
  54. data/app/controllers/brilliant_cms/entries_controller.rb +87 -0
  55. data/app/controllers/brilliant_cms/registrations_controller.rb +19 -0
  56. data/app/helpers/brilliant_cms/application_helper.rb +9 -0
  57. data/app/helpers/brilliant_cms/dashboard_helper.rb +4 -0
  58. data/app/helpers/brilliant_cms/entries_helper.rb +4 -0
  59. data/app/models/brilliant_cms/article.rb +9 -0
  60. data/app/models/brilliant_cms/blog_link.rb +10 -0
  61. data/app/models/brilliant_cms/blog_post.rb +9 -0
  62. data/app/models/brilliant_cms/concerns/searchable.rb +37 -0
  63. data/app/models/brilliant_cms/entry.rb +25 -0
  64. data/app/models/brilliant_cms/entry_search_data.rb +19 -0
  65. data/app/models/brilliant_cms/user.rb +8 -0
  66. data/app/views/brilliant_cms/dashboard/index.html.erb +0 -0
  67. data/app/views/brilliant_cms/entries/_form.html.erb +21 -0
  68. data/app/views/brilliant_cms/entries/edit.html.erb +6 -0
  69. data/app/views/brilliant_cms/entries/index.html.erb +38 -0
  70. data/app/views/brilliant_cms/entries/new.html.erb +3 -0
  71. data/app/views/brilliant_cms/entries/show.html.erb +28 -0
  72. data/app/views/layouts/brilliant_cms/_footer.html.erb +10 -0
  73. data/app/views/layouts/brilliant_cms/_notifications.html.erb +6 -0
  74. data/app/views/layouts/brilliant_cms/_sidemenu.html.erb +87 -0
  75. data/app/views/layouts/brilliant_cms/_topbar.html.erb +31 -0
  76. data/app/views/layouts/brilliant_cms/application.html.erb +40 -0
  77. data/config/initializers/assets.rb +1 -0
  78. data/config/initializers/devise.rb +267 -0
  79. data/config/initializers/simple_form.rb +165 -0
  80. data/config/initializers/simple_form_bootstrap.rb +149 -0
  81. data/config/locales/devise.en.yml +62 -0
  82. data/config/locales/simple_form.en.yml +31 -0
  83. data/config/routes.rb +27 -0
  84. data/db/migrate/20160218214729_create_brilliant_cms_entries.rb +15 -0
  85. data/db/migrate/20160219045419_create_brilliant_cms_entry_search_data.rb +14 -0
  86. data/db/migrate/20160219065450_devise_create_brilliant_cms_users.rb +42 -0
  87. data/lib/brilliant_cms.rb +6 -0
  88. data/lib/brilliant_cms/configuration.rb +17 -0
  89. data/lib/brilliant_cms/engine.rb +11 -0
  90. data/lib/brilliant_cms/version.rb +3 -0
  91. data/lib/tasks/brilliant_cms_tasks.rake +4 -0
  92. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  93. data/test/brilliant_cms_test.rb +7 -0
  94. data/test/controllers/brilliant_cms/dashboard_controller_test.rb +13 -0
  95. data/test/controllers/brilliant_cms/entries_controller_test.rb +13 -0
  96. data/test/dummy/README.rdoc +28 -0
  97. data/test/dummy/Rakefile +6 -0
  98. data/test/dummy/app/assets/javascripts/application.js +13 -0
  99. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  100. data/test/dummy/app/controllers/application_controller.rb +5 -0
  101. data/test/dummy/app/helpers/application_helper.rb +2 -0
  102. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  103. data/test/dummy/bin/bundle +3 -0
  104. data/test/dummy/bin/rails +4 -0
  105. data/test/dummy/bin/rake +4 -0
  106. data/test/dummy/bin/setup +29 -0
  107. data/test/dummy/config.ru +4 -0
  108. data/test/dummy/config/application.rb +26 -0
  109. data/test/dummy/config/boot.rb +5 -0
  110. data/test/dummy/config/database.yml +85 -0
  111. data/test/dummy/config/environment.rb +5 -0
  112. data/test/dummy/config/environments/development.rb +41 -0
  113. data/test/dummy/config/environments/production.rb +79 -0
  114. data/test/dummy/config/environments/test.rb +42 -0
  115. data/test/dummy/config/initializers/assets.rb +11 -0
  116. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  117. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  118. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  119. data/test/dummy/config/initializers/inflections.rb +16 -0
  120. data/test/dummy/config/initializers/mime_types.rb +4 -0
  121. data/test/dummy/config/initializers/session_store.rb +3 -0
  122. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  123. data/test/dummy/config/locales/en.yml +23 -0
  124. data/test/dummy/config/routes.rb +4 -0
  125. data/test/dummy/config/secrets.yml +22 -0
  126. data/test/dummy/public/404.html +67 -0
  127. data/test/dummy/public/422.html +67 -0
  128. data/test/dummy/public/500.html +66 -0
  129. data/test/dummy/public/favicon.ico +0 -0
  130. data/test/fixtures/brilliant_cms/entries.yml +11 -0
  131. data/test/fixtures/brilliant_cms/entry_search_data.yml +13 -0
  132. data/test/fixtures/brilliant_cms/users.yml +11 -0
  133. data/test/integration/navigation_test.rb +8 -0
  134. data/test/models/brilliant_cms/entry_search_data_test.rb +9 -0
  135. data/test/models/brilliant_cms/entry_test.rb +9 -0
  136. data/test/models/brilliant_cms/user_test.rb +9 -0
  137. data/test/test_helper.rb +21 -0
  138. metadata +407 -0
@@ -0,0 +1,188 @@
1
+ /* Flot plugin for stacking data sets rather than overlyaing them.
2
+
3
+ Copyright (c) 2007-2014 IOLA and Ole Laursen.
4
+ Licensed under the MIT license.
5
+
6
+ The plugin assumes the data is sorted on x (or y if stacking horizontally).
7
+ For line charts, it is assumed that if a line has an undefined gap (from a
8
+ null point), then the line above it should have the same gap - insert zeros
9
+ instead of "null" if you want another behaviour. This also holds for the start
10
+ and end of the chart. Note that stacking a mix of positive and negative values
11
+ in most instances doesn't make sense (so it looks weird).
12
+
13
+ Two or more series are stacked when their "stack" attribute is set to the same
14
+ key (which can be any number or string or just "true"). To specify the default
15
+ stack, you can set the stack option like this:
16
+
17
+ series: {
18
+ stack: null/false, true, or a key (number/string)
19
+ }
20
+
21
+ You can also specify it for a single series, like this:
22
+
23
+ $.plot( $("#placeholder"), [{
24
+ data: [ ... ],
25
+ stack: true
26
+ }])
27
+
28
+ The stacking order is determined by the order of the data series in the array
29
+ (later series end up on top of the previous).
30
+
31
+ Internally, the plugin modifies the datapoints in each series, adding an
32
+ offset to the y value. For line series, extra data points are inserted through
33
+ interpolation. If there's a second y value, it's also adjusted (e.g for bar
34
+ charts or filled areas).
35
+
36
+ */
37
+
38
+ (function ($) {
39
+ var options = {
40
+ series: { stack: null } // or number/string
41
+ };
42
+
43
+ function init(plot) {
44
+ function findMatchingSeries(s, allseries) {
45
+ var res = null;
46
+ for (var i = 0; i < allseries.length; ++i) {
47
+ if (s == allseries[i])
48
+ break;
49
+
50
+ if (allseries[i].stack == s.stack)
51
+ res = allseries[i];
52
+ }
53
+
54
+ return res;
55
+ }
56
+
57
+ function stackData(plot, s, datapoints) {
58
+ if (s.stack == null || s.stack === false)
59
+ return;
60
+
61
+ var other = findMatchingSeries(s, plot.getData());
62
+ if (!other)
63
+ return;
64
+
65
+ var ps = datapoints.pointsize,
66
+ points = datapoints.points,
67
+ otherps = other.datapoints.pointsize,
68
+ otherpoints = other.datapoints.points,
69
+ newpoints = [],
70
+ px, py, intery, qx, qy, bottom,
71
+ withlines = s.lines.show,
72
+ horizontal = s.bars.horizontal,
73
+ withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
74
+ withsteps = withlines && s.lines.steps,
75
+ fromgap = true,
76
+ keyOffset = horizontal ? 1 : 0,
77
+ accumulateOffset = horizontal ? 0 : 1,
78
+ i = 0, j = 0, l, m;
79
+
80
+ while (true) {
81
+ if (i >= points.length)
82
+ break;
83
+
84
+ l = newpoints.length;
85
+
86
+ if (points[i] == null) {
87
+ // copy gaps
88
+ for (m = 0; m < ps; ++m)
89
+ newpoints.push(points[i + m]);
90
+ i += ps;
91
+ }
92
+ else if (j >= otherpoints.length) {
93
+ // for lines, we can't use the rest of the points
94
+ if (!withlines) {
95
+ for (m = 0; m < ps; ++m)
96
+ newpoints.push(points[i + m]);
97
+ }
98
+ i += ps;
99
+ }
100
+ else if (otherpoints[j] == null) {
101
+ // oops, got a gap
102
+ for (m = 0; m < ps; ++m)
103
+ newpoints.push(null);
104
+ fromgap = true;
105
+ j += otherps;
106
+ }
107
+ else {
108
+ // cases where we actually got two points
109
+ px = points[i + keyOffset];
110
+ py = points[i + accumulateOffset];
111
+ qx = otherpoints[j + keyOffset];
112
+ qy = otherpoints[j + accumulateOffset];
113
+ bottom = 0;
114
+
115
+ if (px == qx) {
116
+ for (m = 0; m < ps; ++m)
117
+ newpoints.push(points[i + m]);
118
+
119
+ newpoints[l + accumulateOffset] += qy;
120
+ bottom = qy;
121
+
122
+ i += ps;
123
+ j += otherps;
124
+ }
125
+ else if (px > qx) {
126
+ // we got past point below, might need to
127
+ // insert interpolated extra point
128
+ if (withlines && i > 0 && points[i - ps] != null) {
129
+ intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
130
+ newpoints.push(qx);
131
+ newpoints.push(intery + qy);
132
+ for (m = 2; m < ps; ++m)
133
+ newpoints.push(points[i + m]);
134
+ bottom = qy;
135
+ }
136
+
137
+ j += otherps;
138
+ }
139
+ else { // px < qx
140
+ if (fromgap && withlines) {
141
+ // if we come from a gap, we just skip this point
142
+ i += ps;
143
+ continue;
144
+ }
145
+
146
+ for (m = 0; m < ps; ++m)
147
+ newpoints.push(points[i + m]);
148
+
149
+ // we might be able to interpolate a point below,
150
+ // this can give us a better y
151
+ if (withlines && j > 0 && otherpoints[j - otherps] != null)
152
+ bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
153
+
154
+ newpoints[l + accumulateOffset] += bottom;
155
+
156
+ i += ps;
157
+ }
158
+
159
+ fromgap = false;
160
+
161
+ if (l != newpoints.length && withbottom)
162
+ newpoints[l + 2] += bottom;
163
+ }
164
+
165
+ // maintain the line steps invariant
166
+ if (withsteps && l != newpoints.length && l > 0
167
+ && newpoints[l] != null
168
+ && newpoints[l] != newpoints[l - ps]
169
+ && newpoints[l + 1] != newpoints[l - ps + 1]) {
170
+ for (m = 0; m < ps; ++m)
171
+ newpoints[l + ps + m] = newpoints[l + m];
172
+ newpoints[l + 1] = newpoints[l - ps + 1];
173
+ }
174
+ }
175
+
176
+ datapoints.points = newpoints;
177
+ }
178
+
179
+ plot.hooks.processDatapoints.push(stackData);
180
+ }
181
+
182
+ $.plot.plugins.push({
183
+ init: init,
184
+ options: options,
185
+ name: 'stack',
186
+ version: '1.2'
187
+ });
188
+ })(jQuery);
@@ -0,0 +1,483 @@
1
+ /* The MIT License
2
+
3
+ Copyright (c) 2011 by Michael Zinsmaier and nergal.dev
4
+ Copyright (c) 2012 by Thomas Ritou
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
+ */
24
+
25
+ /*
26
+ ____________________________________________________
27
+
28
+ what it is:
29
+ ____________________________________________________
30
+
31
+ curvedLines is a plugin for flot, that tries to display lines in a smoother way.
32
+ This is achieved through adding of more data points. The plugin is a data processor and can thus be used
33
+ in combination with standard line / point rendering options.
34
+
35
+ => 1) with large data sets you may get trouble
36
+ => 2) if you want to display the points too, you have to plot them as 2nd data series over the lines
37
+ => 3) consecutive x data points are not allowed to have the same value
38
+
39
+ Feel free to further improve the code
40
+
41
+ ____________________________________________________
42
+
43
+ how to use it:
44
+ ____________________________________________________
45
+
46
+ var d1 = [[5,5],[7,3],[9,12]];
47
+
48
+ var options = { series: { curvedLines: { active: true }}};
49
+
50
+ $.plot($("#placeholder"), [{data: d1, lines: { show: true}, curvedLines: {apply: true}}], options);
51
+
52
+ _____________________________________________________
53
+
54
+ options:
55
+ _____________________________________________________
56
+
57
+ active: bool true => plugin can be used
58
+ apply: bool true => series will be drawn as curved line
59
+ monotonicFit: bool true => uses monotone cubic interpolation (preserve monotonicity)
60
+ tension: int defines the tension parameter of the hermite spline interpolation (no effect if monotonicFit is set)
61
+ nrSplinePoints: int defines the number of sample points (of the spline) in between two consecutive points
62
+
63
+ deprecated options from flot prior to 1.0.0:
64
+ ------------------------------------------------
65
+ legacyOverride bool true => use old default
66
+ OR
67
+ legacyOverride optionArray
68
+ {
69
+ fit: bool true => forces the max,mins of the curve to be on the datapoints
70
+ curvePointFactor int defines how many "virtual" points are used per "real" data point to
71
+ emulate the curvedLines (points total = real points * curvePointFactor)
72
+ fitPointDist: int defines the x axis distance of the additional two points that are used
73
+ } to enforce the min max condition.
74
+ */
75
+
76
+ /*
77
+ * v0.1 initial commit
78
+ * v0.15 negative values should work now (outcommented a negative -> 0 hook hope it does no harm)
79
+ * v0.2 added fill option (thanks to monemihir) and multi axis support (thanks to soewono effendi)
80
+ * v0.3 improved saddle handling and added basic handling of Dates
81
+ * v0.4 rewritten fill option (thomas ritou) mostly from original flot code (now fill between points rather than to graph bottom), corrected fill Opacity bug
82
+ * v0.5 rewritten instead of implementing a own draw function CurvedLines is now based on the processDatapoints flot hook (credits go to thomas ritou).
83
+ * This change breakes existing code however CurvedLines are now just many tiny straight lines to flot and therefore all flot lines options (like gradient fill,
84
+ * shadow) are now supported out of the box
85
+ * v0.6 flot 0.8 compatibility and some bug fixes
86
+ * v0.6.x changed versioning schema
87
+ *
88
+ * v1.0.0 API Break marked existing implementation/options as deprecated
89
+ * v1.1.0 added the new curved line calculations based on hermite splines
90
+ * v1.1.1 added a rough parameter check to make sure the new options are used
91
+ */
92
+
93
+ (function($) {
94
+
95
+ var options = {
96
+ series : {
97
+ curvedLines : {
98
+ active : false,
99
+ apply : false,
100
+ monotonicFit : false,
101
+ tension : 0.5,
102
+ nrSplinePoints : 20,
103
+ legacyOverride : undefined
104
+ }
105
+ }
106
+ };
107
+
108
+ function init(plot) {
109
+
110
+ plot.hooks.processOptions.push(processOptions);
111
+
112
+ //if the plugin is active register processDatapoints method
113
+ function processOptions(plot, options) {
114
+ if (options.series.curvedLines.active) {
115
+ plot.hooks.processDatapoints.unshift(processDatapoints);
116
+ }
117
+ }
118
+
119
+ //only if the plugin is active
120
+ function processDatapoints(plot, series, datapoints) {
121
+ var nrPoints = datapoints.points.length / datapoints.pointsize;
122
+ var EPSILON = 0.005;
123
+
124
+ //detects missplaced legacy parameters (prior v1.x.x) in the options object
125
+ //this can happen if somebody upgrades to v1.x.x without adjusting the parameters or uses old examples
126
+ var invalidLegacyOptions = hasInvalidParameters(series.curvedLines);
127
+
128
+ if (!invalidLegacyOptions && series.curvedLines.apply == true && series.originSeries === undefined && nrPoints > (1 + EPSILON)) {
129
+ if (series.lines.fill) {
130
+
131
+ var pointsTop = calculateCurvePoints(datapoints, series.curvedLines, 1);
132
+ var pointsBottom = calculateCurvePoints(datapoints, series.curvedLines, 2);
133
+ //flot makes sure for us that we've got a second y point if fill is true !
134
+
135
+ //Merge top and bottom curve
136
+ datapoints.pointsize = 3;
137
+ datapoints.points = [];
138
+ var j = 0;
139
+ var k = 0;
140
+ var i = 0;
141
+ var ps = 2;
142
+ while (i < pointsTop.length || j < pointsBottom.length) {
143
+ if (pointsTop[i] == pointsBottom[j]) {
144
+ datapoints.points[k] = pointsTop[i];
145
+ datapoints.points[k + 1] = pointsTop[i + 1];
146
+ datapoints.points[k + 2] = pointsBottom[j + 1];
147
+ j += ps;
148
+ i += ps;
149
+
150
+ } else if (pointsTop[i] < pointsBottom[j]) {
151
+ datapoints.points[k] = pointsTop[i];
152
+ datapoints.points[k + 1] = pointsTop[i + 1];
153
+ datapoints.points[k + 2] = k > 0 ? datapoints.points[k - 1] : null;
154
+ i += ps;
155
+ } else {
156
+ datapoints.points[k] = pointsBottom[j];
157
+ datapoints.points[k + 1] = k > 1 ? datapoints.points[k - 2] : null;
158
+ datapoints.points[k + 2] = pointsBottom[j + 1];
159
+ j += ps;
160
+ }
161
+ k += 3;
162
+ }
163
+ } else if (series.lines.lineWidth > 0) {
164
+ datapoints.points = calculateCurvePoints(datapoints, series.curvedLines, 1);
165
+ datapoints.pointsize = 2;
166
+ }
167
+ }
168
+ }
169
+
170
+ function calculateCurvePoints(datapoints, curvedLinesOptions, yPos) {
171
+ if ( typeof curvedLinesOptions.legacyOverride != 'undefined' && curvedLinesOptions.legacyOverride != false) {
172
+ var defaultOptions = {
173
+ fit : false,
174
+ curvePointFactor : 20,
175
+ fitPointDist : undefined
176
+ };
177
+ var legacyOptions = jQuery.extend(defaultOptions, curvedLinesOptions.legacyOverride);
178
+ return calculateLegacyCurvePoints(datapoints, legacyOptions, yPos);
179
+ }
180
+
181
+ return calculateSplineCurvePoints(datapoints, curvedLinesOptions, yPos);
182
+ }
183
+
184
+ function calculateSplineCurvePoints(datapoints, curvedLinesOptions, yPos) {
185
+ var points = datapoints.points;
186
+ var ps = datapoints.pointsize;
187
+
188
+ //create interpolant fuction
189
+ var splines = createHermiteSplines(datapoints, curvedLinesOptions, yPos);
190
+ var result = [];
191
+
192
+ //sample the function
193
+ // (the result is intependent from the input data =>
194
+ // it is ok to alter the input after this method)
195
+ var j = 0;
196
+ for (var i = 0; i < points.length - ps; i += ps) {
197
+ var curX = i;
198
+ var curY = i + yPos;
199
+
200
+ var xStart = points[curX];
201
+ var xEnd = points[curX + ps];
202
+ var xStep = (xEnd - xStart) / Number(curvedLinesOptions.nrSplinePoints);
203
+
204
+ //add point
205
+ result.push(points[curX]);
206
+ result.push(points[curY]);
207
+
208
+ //add curve point
209
+ for (var x = (xStart += xStep); x < xEnd; x += xStep) {
210
+ result.push(x);
211
+ result.push(splines[j](x));
212
+ }
213
+
214
+ j++;
215
+ }
216
+
217
+ //add last point
218
+ result.push(points[points.length - ps]);
219
+ result.push(points[points.length - ps + yPos]);
220
+
221
+ return result;
222
+ }
223
+
224
+
225
+
226
+ // Creates an array of splines, one for each segment of the original curve. Algorithm based on the wikipedia articles:
227
+ //
228
+ // http://de.wikipedia.org/w/index.php?title=Kubisch_Hermitescher_Spline&oldid=130168003 and
229
+ // http://en.wikipedia.org/w/index.php?title=Monotone_cubic_interpolation&oldid=622341725 and the description of Fritsch-Carlson from
230
+ // http://math.stackexchange.com/questions/45218/implementation-of-monotone-cubic-interpolation
231
+ // for a detailed description see https://github.com/MichaelZinsmaier/CurvedLines/docu
232
+ function createHermiteSplines(datapoints, curvedLinesOptions, yPos) {
233
+ var points = datapoints.points;
234
+ var ps = datapoints.pointsize;
235
+
236
+ // preparation get length (x_{k+1} - x_k) and slope s=(p_{k+1} - p_k) / (x_{k+1} - x_k) of the segments
237
+ var segmentLengths = [];
238
+ var segmentSlopes = [];
239
+
240
+ for (var i = 0; i < points.length - ps; i += ps) {
241
+ var curX = i;
242
+ var curY = i + yPos;
243
+ var dx = points[curX + ps] - points[curX];
244
+ var dy = points[curY + ps] - points[curY];
245
+
246
+ segmentLengths.push(dx);
247
+ segmentSlopes.push(dy / dx);
248
+ }
249
+
250
+ //get the values for the desired gradients m_k for all points k
251
+ //depending on the used method the formula is different
252
+ var gradients = [segmentSlopes[0]];
253
+ if (curvedLinesOptions.monotonicFit) {
254
+ // Fritsch Carlson
255
+ for (var i = 1; i < segmentLengths.length; i++) {
256
+ var slope = segmentSlopes[i];
257
+ var prev_slope = segmentSlopes[i - 1];
258
+ if (slope * prev_slope <= 0) { // sign(prev_slope) != sign(slpe)
259
+ gradients.push(0);
260
+ } else {
261
+ var length = segmentLengths[i];
262
+ var prev_length = segmentLengths[i - 1];
263
+ var common = length + prev_length;
264
+ //m = 3 (prev_length + length) / ((2 length + prev_length) / prev_slope + (length + 2 prev_length) / slope)
265
+ gradients.push(3 * common / ((common + length) / prev_slope + (common + prev_length) / slope));
266
+ }
267
+ }
268
+ } else {
269
+ // Cardinal spline with t € [0,1]
270
+ // Catmull-Rom for t = 0
271
+ for (var i = ps; i < points.length - ps; i += ps) {
272
+ var curX = i;
273
+ var curY = i + yPos;
274
+ gradients.push(Number(curvedLinesOptions.tension) * (points[curY + ps] - points[curY - ps]) / (points[curX + ps] - points[curX - ps]));
275
+ }
276
+ }
277
+ gradients.push(segmentSlopes[segmentSlopes.length - 1]);
278
+
279
+ //get the two major coefficients (c'_{oef1} and c'_{oef2}) for each segment spline
280
+ var coefs1 = [];
281
+ var coefs2 = [];
282
+ for (i = 0; i < segmentLengths.length; i++) {
283
+ var m_k = gradients[i];
284
+ var m_k_plus = gradients[i + 1];
285
+ var slope = segmentSlopes[i];
286
+ var invLength = 1 / segmentLengths[i];
287
+ var common = m_k + m_k_plus - slope - slope;
288
+
289
+ coefs1.push(common * invLength * invLength);
290
+ coefs2.push((slope - common - m_k) * invLength);
291
+ }
292
+
293
+ //create functions with from the coefficients and capture the parameters
294
+ var ret = [];
295
+ for (var i = 0; i < segmentLengths.length; i ++) {
296
+ var spline = function (x_k, coef1, coef2, coef3, coef4) {
297
+ // spline for a segment
298
+ return function (x) {
299
+ var diff = x - x_k;
300
+ var diffSq = diff * diff;
301
+ return coef1 * diff * diffSq + coef2 * diffSq + coef3 * diff + coef4;
302
+ };
303
+ };
304
+
305
+ ret.push(spline(points[i * ps], coefs1[i], coefs2[i], gradients[i], points[i * ps + yPos]));
306
+ }
307
+
308
+ return ret;
309
+ };
310
+
311
+ //no real idea whats going on here code mainly from https://code.google.com/p/flot/issues/detail?id=226
312
+ //if fit option is selected additional datapoints get inserted before the curve calculations in nergal.dev s code.
313
+ function calculateLegacyCurvePoints(datapoints, curvedLinesOptions, yPos) {
314
+
315
+ var points = datapoints.points;
316
+ var ps = datapoints.pointsize;
317
+ var num = Number(curvedLinesOptions.curvePointFactor) * (points.length / ps);
318
+
319
+ var xdata = new Array;
320
+ var ydata = new Array;
321
+
322
+ var curX = -1;
323
+ var curY = -1;
324
+ var j = 0;
325
+
326
+ if (curvedLinesOptions.fit) {
327
+ //insert a point before and after the "real" data point to force the line
328
+ //to have a max,min at the data point.
329
+
330
+ var fpDist;
331
+ if ( typeof curvedLinesOptions.fitPointDist == 'undefined') {
332
+ //estimate it
333
+ var minX = points[0];
334
+ var maxX = points[points.length - ps];
335
+ fpDist = (maxX - minX) / (500 * 100);
336
+ //x range / (estimated pixel length of placeholder * factor)
337
+ } else {
338
+ //use user defined value
339
+ fpDist = Number(curvedLinesOptions.fitPointDist);
340
+ }
341
+
342
+ for (var i = 0; i < points.length; i += ps) {
343
+
344
+ var frontX;
345
+ var backX;
346
+ curX = i;
347
+ curY = i + yPos;
348
+
349
+ //add point X s
350
+ frontX = points[curX] - fpDist;
351
+ backX = points[curX] + fpDist;
352
+
353
+ var factor = 2;
354
+ while (frontX == points[curX] || backX == points[curX]) {
355
+ //inside the ulp
356
+ frontX = points[curX] - (fpDist * factor);
357
+ backX = points[curX] + (fpDist * factor);
358
+ factor++;
359
+ }
360
+
361
+ //add curve points
362
+ xdata[j] = frontX;
363
+ ydata[j] = points[curY];
364
+ j++;
365
+
366
+ xdata[j] = points[curX];
367
+ ydata[j] = points[curY];
368
+ j++;
369
+
370
+ xdata[j] = backX;
371
+ ydata[j] = points[curY];
372
+ j++;
373
+ }
374
+ } else {
375
+ //just use the datapoints
376
+ for (var i = 0; i < points.length; i += ps) {
377
+ curX = i;
378
+ curY = i + yPos;
379
+
380
+ xdata[j] = points[curX];
381
+ ydata[j] = points[curY];
382
+ j++;
383
+ }
384
+ }
385
+
386
+ var n = xdata.length;
387
+
388
+ var y2 = new Array();
389
+ var delta = new Array();
390
+ y2[0] = 0;
391
+ y2[n - 1] = 0;
392
+ delta[0] = 0;
393
+
394
+ for (var i = 1; i < n - 1; ++i) {
395
+ var d = (xdata[i + 1] - xdata[i - 1]);
396
+ if (d == 0) {
397
+ //point before current point and after current point need some space in between
398
+ return [];
399
+ }
400
+
401
+ var s = (xdata[i] - xdata[i - 1]) / d;
402
+ var p = s * y2[i - 1] + 2;
403
+ y2[i] = (s - 1) / p;
404
+ delta[i] = (ydata[i + 1] - ydata[i]) / (xdata[i + 1] - xdata[i]) - (ydata[i] - ydata[i - 1]) / (xdata[i] - xdata[i - 1]);
405
+ delta[i] = (6 * delta[i] / (xdata[i + 1] - xdata[i - 1]) - s * delta[i - 1]) / p;
406
+ }
407
+
408
+ for (var j = n - 2; j >= 0; --j) {
409
+ y2[j] = y2[j] * y2[j + 1] + delta[j];
410
+ }
411
+
412
+ // xmax - xmin / #points
413
+ var step = (xdata[n - 1] - xdata[0]) / (num - 1);
414
+
415
+ var xnew = new Array;
416
+ var ynew = new Array;
417
+ var result = new Array;
418
+
419
+ xnew[0] = xdata[0];
420
+ ynew[0] = ydata[0];
421
+
422
+ result.push(xnew[0]);
423
+ result.push(ynew[0]);
424
+
425
+ for ( j = 1; j < num; ++j) {
426
+ //new x point (sampling point for the created curve)
427
+ xnew[j] = xnew[0] + j * step;
428
+
429
+ var max = n - 1;
430
+ var min = 0;
431
+
432
+ while (max - min > 1) {
433
+ var k = Math.round((max + min) / 2);
434
+ if (xdata[k] > xnew[j]) {
435
+ max = k;
436
+ } else {
437
+ min = k;
438
+ }
439
+ }
440
+
441
+ //found point one to the left and one to the right of generated new point
442
+ var h = (xdata[max] - xdata[min]);
443
+
444
+ if (h == 0) {
445
+ //similar to above two points from original x data need some space between them
446
+ return [];
447
+ }
448
+
449
+ var a = (xdata[max] - xnew[j]) / h;
450
+ var b = (xnew[j] - xdata[min]) / h;
451
+
452
+ ynew[j] = a * ydata[min] + b * ydata[max] + ((a * a * a - a) * y2[min] + (b * b * b - b) * y2[max]) * (h * h) / 6;
453
+
454
+ result.push(xnew[j]);
455
+ result.push(ynew[j]);
456
+ }
457
+
458
+ return result;
459
+ }
460
+
461
+ function hasInvalidParameters(curvedLinesOptions) {
462
+ if (typeof curvedLinesOptions.fit != 'undefined' ||
463
+ typeof curvedLinesOptions.curvePointFactor != 'undefined' ||
464
+ typeof curvedLinesOptions.fitPointDist != 'undefined') {
465
+ throw new Error("CurvedLines detected illegal parameters. The CurvedLines API changed with version 1.0.0 please check the options object.");
466
+ return true;
467
+ }
468
+ return false;
469
+ }
470
+
471
+
472
+ }//end init
473
+
474
+
475
+ $.plot.plugins.push({
476
+ init : init,
477
+ options : options,
478
+ name : 'curvedLines',
479
+ version : '1.1.1'
480
+ });
481
+
482
+ })(jQuery);
483
+