@cryptotaxi247 / netdata-1 / commits / 14f580429

new chart resize functionality; removed dependency on CSS-Element-Queries; added option to enable or disable smooth lines plotter

Costa Tsaousis (ktsaou) committed Dec 23, 2015 at 03:04 UTC 14f580429703aae4d2433dbf0717f71c1fe1026a
3 files changed +150 -81
web/dashboard.css
+17 -30
@@ -19,37 +19,24 @@ html {
19 /* width and height is given per chart with data-width and data-height */
20 }
21
22 -.netdata-container-resizable {
23 - display: -webkit-flex; /* Safari */
24 - -webkit-flex-wrap: wrap; /* Safari 6.1+ */
25 - display: inline-block;
26 - flex-wrap: wrap;
22 +.netdata-legend-resize-handler {
23 + display: block;
24 + position: absolute;
25 + bottom: 0px;
26 + right: 0px;
27 + height: 15px;
28 + width: 30px;
29 + background-color: White;
30 + font-size: 12px;
31 + vertical-align: middle;
32 + line-height: 15px;
33 + cursor: ns-resize;
34 + color: #DDDDDD;
35 + text-align: center;
36 overflow: hidden;
28 -
29 - /* enable CSS3 resizing */
30 - resize: vertical;
31 -
32 - /* required for child elements to have absolute position */
33 - position: relative;
34 -
35 - /* width and height is given per chart with data-width and data-height */
36 -}
37 -
38 -.netdata-container-resizable::after {
39 - /* pointer-events: none; */
40 - font-family: FontAwesome;
41 - color: #999999;
42 - content: "\f078";
43 - font-size: 12px;
44 - position: absolute;
45 - height: 15px;
46 - width: 18px;
47 - text-align: center;
48 - bottom: 0px;
49 - right: -2px;
50 - z-index: 2;
51 - cursor: ns-resize;
52 - background-color: #ffffff;
37 + z-index: 11;
38 + padding: 0px;
39 + margin: 0px;
40 }
41
42 .netdata-message {
web/dashboard.js
+124 -50
@@ -203,7 +203,11 @@
203
204 stop_updates_when_focus_is_lost: true,
205
206 - color_fill_opacity: {
206 + double_click_speed: 500,
207 +
208 + smooth_plot: true, // enable smooth plot, where possible
209 +
210 + color_fill_opacity: {
211 line: 1.0,
212 area: 0.2,
213 stacked: 0.8
@@ -691,6 +695,85 @@
695 this.init();
696 }
697
698 + // ----------------------------------------------------------------------------------------------------------------
699 + // Chart Resize
700 +
701 + chartState.prototype.resizeHandler = function(e) {
702 + e.preventDefault();
703 +
704 + if(typeof this.event_resize === 'undefined'
705 + || this.event_resize.chart_original_w === 'undefined'
706 + || this.event_resize.chart_original_h === 'undefined')
707 + this.event_resize = {
708 + chart_original_w: this.element.clientWidth,
709 + chart_original_h: this.element.clientHeight,
710 + last: 0
711 + };
712 +
713 + this.event_resize.mouse_start_x = e.clientX;
714 + this.event_resize.mouse_start_y = e.clientY;
715 + this.event_resize.chart_start_w = this.element.clientWidth;
716 + this.event_resize.chart_start_h = this.element.clientHeight;
717 + this.event_resize.chart_last_w = this.element.clientWidth;
718 + this.event_resize.chart_last_h = this.element.clientHeight;
719 +
720 + var resize_height_and_update_chart = function(state, h) {
721 + state.element.style.height = h.toString() + 'px';
722 +
723 + NETDATA.options.last_page_scroll = new Date().getTime();
724 +
725 + if(typeof state.library.resize === 'function')
726 + state.library.resize(state);
727 +
728 + if(state.element_legend_childs.nano !== null && state.element_legend_childs.nano_options !== null)
729 + $(state.element_legend_childs.nano).nanoScroller();
730 + };
731 +
732 + var now = new Date().getTime();
733 + if(now - this.event_resize.last <= NETDATA.options.current.double_click_speed) {
734 + // double click event
735 +
736 + var optimal = this.event_resize.chart_last_h
737 + + this.element_legend_childs.content.scrollHeight
738 + - this.element_legend_childs.content.clientHeight;
739 +
740 + if(this.event_resize.chart_last_h != optimal)
741 + resize_height_and_update_chart(this, optimal);
742 +
743 + else if(this.event_resize.chart_last_h != this.event_resize.chart_original_h)
744 + resize_height_and_update_chart(this, this.event_resize.chart_original_h);
745 + }
746 + else {
747 + this.event_resize.last = now;
748 +
749 + var self = this;
750 +
751 + document.onmousemove =
752 + this.element_legend_childs.resize_handler.onmousemove =
753 + this.element_legend_childs.resize_handler.onmouseout =
754 + function(e) {
755 + var newH = self.event_resize.chart_start_h + e.clientY - self.event_resize.mouse_start_y;
756 +
757 + if(newH >= 70 && newH !== self.event_resize.chart_last_h) {
758 + resize_height_and_update_chart(self, newH);
759 + self.event_resize.chart_last_h = newH;
760 + }
761 + };
762 +
763 + document.onmouseup =
764 + this.element_legend_childs.resize_handler.onmouseup =
765 + function(e) {
766 + document.onmouseup =
767 + document.onmousemove =
768 + self.element_legend_childs.resize_handler.onmousemove =
769 + self.element_legend_childs.resize_handler.onmouseout =
770 + self.element_legend_childs.resize_handler.onmouseup =
771 + null;
772 + };
773 + }
774 + }
775 +
776 +
777 // ----------------------------------------------------------------------------------------------------------------
778 // global selection sync
779
@@ -1275,6 +1358,8 @@
1358
1359 if(this.hasLegend()) {
1360 this.element_legend_childs = {
1361 + content: content,
1362 + resize_handler: document.createElement('div'),
1363 title_date: document.createElement('span'),
1364 title_time: document.createElement('span'),
1365 title_units: document.createElement('span'),
@@ -1294,6 +1379,14 @@
1379
1380 this.element_legend.innerHTML = '';
1381
1382 + this.element_legend_childs.resize_handler.className += " netdata-legend-resize-handler";
1383 + this.element_legend_childs.resize_handler.innerHTML = '<i class="fa fa-chevron-up"></i><i class="fa fa-chevron-down"></i>';
1384 + this.element.appendChild(this.element_legend_childs.resize_handler);
1385 + var self2 = this;
1386 + this.element_legend_childs.resize_handler.onmousedown = function(e) {
1387 + self2.resizeHandler(e);
1388 + };
1389 +
1390 this.element_legend_childs.title_date.className += " netdata-legend-title-date";
1391 this.element_legend.appendChild(this.element_legend_childs.title_date);
1392
@@ -1317,6 +1410,8 @@
1410 }
1411 else {
1412 this.element_legend_childs = {
1413 + content: content,
1414 + resize_handler: null,
1415 title_date: null,
1416 title_time: null,
1417 title_units: null,
@@ -1382,26 +1477,9 @@
1477
1478 if(this.hasLegend() === false)
1479 this.element_legend.style.display = 'none';
1385 - else {
1480 + else
1481 this.element.appendChild(this.element_legend);
1482
1388 - if(typeof this.___addedContainerResizable___ === 'undefined') {
1389 - this.element.className += " netdata-container-resizable";
1390 - this.___addedContainerResizable___ = true;
1391 -
1392 - var state = this;
1393 - this.resize_sensor = ResizeSensor(this.element, function() {
1394 - NETDATA.options.last_updated = new Date().getTime();
1395 -
1396 - if(typeof state.library.resize === 'function')
1397 - state.library.resize(state);
1398 -
1399 - if(state.element_legend_childs.nano !== null && state.element_legend_childs.nano_options !== null)
1400 - $(state.element_legend_childs.nano).nanoScroller();
1401 - });
1402 - }
1403 - }
1404 -
1483 this.element_legend_childs.series = null;
1484 this.legendUpdateDOM();
1485
@@ -2408,8 +2486,6 @@
2486 }
2487
2488 NETDATA.parseDom = function(callback) {
2411 - ElementQueries.update();
2412 -
2489 NETDATA.options.last_page_scroll = new Date().getTime();
2490 NETDATA.options.updated_dom = false;
2491
@@ -2722,7 +2798,7 @@
2798 NETDATA.error(100, NETDATA.dygraph_js);
2799 })
2800 .always(function() {
2725 - if(NETDATA.chartLibraries.dygraph.enabled === true)
2801 + if(NETDATA.chartLibraries.dygraph.enabled === true && NETDATA.options.current.smooth_plot === true)
2802 NETDATA.dygraphSmoothInitialize(callback);
2803 else if(typeof callback === "function")
2804 callback();
@@ -2749,31 +2825,34 @@
2825 if(state.tm.last_unhidden > state.dygraph_last_rendered)
2826 dygraph.resize();
2827
2752 - if(state.current.name === 'pan') {
2753 - if(NETDATA.options.debug.dygraph === true || state.debug === true)
2754 - state.log('dygraphChartUpdate() loose update');
2755 -
2756 - dygraph.updateOptions({
2828 + var options = {
2829 file: data.result.data,
2830 colors: state.chartColors(),
2831 labels: data.result.labels,
2832 labelsDivWidth: state.chartWidth() - 70
2761 - });
2833 + }
2834 +
2835 + if(state.current.name === 'pan') {
2836 + if(NETDATA.options.debug.dygraph === true || state.debug === true)
2837 + state.log('dygraphChartUpdate() loose update');
2838 }
2839 else {
2840 if(NETDATA.options.debug.dygraph === true || state.debug === true)
2841 state.log('dygraphChartUpdate() strict update');
2842 +
2843 + options.dateWindow = null;
2844 + options.valueRange = null;
2845 + }
2846
2767 - dygraph.updateOptions({
2768 - file: data.result.data,
2769 - colors: state.chartColors(),
2770 - labels: data.result.labels,
2771 - labelsDivWidth: state.chartWidth() - 70,
2772 - dateWindow: null,
2773 - valueRange: null
2774 - });
2847 + if(state.dygraph_smooth_eligible === true) {
2848 + if((NETDATA.options.current.smooth_plot === true && state.dygraph_options.plotter !== smoothPlotter)
2849 + || (NETDATA.options.current.smooth_plot === false && state.dygraph_options.plotter === smoothPlotter)) {
2850 + NETDATA.dygraphChartCreate(state, data);
2851 + return;
2852 + }
2853 }
2854
2855 + dygraph.updateOptions(options);
2856 state.dygraph_last_rendered = new Date().getTime();
2857 };
2858
@@ -2796,7 +2875,6 @@
2875 var strokeWidth = (chart_type === 'stacked')?0.0:((smooth)?1.5:1.0)
2876 var highlightCircleSize = (NETDATA.chartLibraries.dygraph.isSparkline(state))?3:4;
2877
2799 -
2878 state.dygraph_options = {
2879 colors: self.data('dygraph-colors') || state.chartColors(),
2880
@@ -3209,12 +3287,12 @@
3287 state.globalSelectionSync(t);
3288 }
3289
3212 - // if it was double tap within 250ms, reset the charts
3290 + // if it was double tap within double click time, reset the charts
3291 var now = new Date().getTime();
3292 if(typeof state.dygraph_last_touch_end !== 'undefined') {
3293 if(state.dygraph_last_touch_move === 0) {
3294 var dt = now - state.dygraph_last_touch_end;
3217 - if(dt <= 250) {
3295 + if(dt <= NETDATA.options.current.double_click_speed) {
3296 state.globalSelectionSyncStop();
3297 NETDATA.globalPanAndZoom.clearMaster();
3298 state.resetChart();
@@ -3241,7 +3319,13 @@
3319 state.dygraph_options.rightGap = 0;
3320 }
3321
3244 - if(smooth === true) state.dygraph_options.plotter = smoothPlotter;
3322 + if(smooth === true) {
3323 + state.dygraph_smooth_eligible = true;
3324 +
3325 + if(NETDATA.options.current.smooth_plot === true)
3326 + state.dygraph_options.plotter = smoothPlotter;
3327 + }
3328 + else state.dygraph_smooth_eligible = false;
3329
3330 state.dygraph_instance = new Dygraph(state.element_chart,
3331 data.result.data, state.dygraph_options);
@@ -3725,14 +3809,6 @@
3809 url: NETDATA.serverDefault + 'lib/jquery.nanoscroller.min.js',
3810 isAlreadyLoaded: function() { return false; }
3811 },
3728 - {
3729 - url: NETDATA.serverDefault + 'lib/ResizeSensor.js',
3730 - isAlreadyLoaded: function() { return false; }
3731 - },
3732 - {
3733 - url: NETDATA.serverDefault + 'lib/ElementQueries.js',
3734 - isAlreadyLoaded: function() { return false; }
3735 - },
3812 {
3813 url: NETDATA.serverDefault + 'lib/bootstrap-toggle.min.js',
3814 isAlreadyLoaded: function() { return false; }
@@ -3815,8 +3891,6 @@
3891
3892 NETDATA._loadjQuery(function() {
3893 NETDATA.loadRequiredJs(0, function() {
3818 - ElementQueries.init();
3819 -
3894 // keep a copy of the default settings
3895 NETDATA.options.defaults = $.extend({}, NETDATA.options.current);
3896
web/index.html
+9 -1
@@ -253,7 +253,7 @@
253 <!-- <script> netdataServer = "http://box:19999"; </script> -->
254
255 <!-- load the dashboard manager - it will do the rest -->
256 - <script type="text/javascript" src="dashboard.js?v4"></script>
256 + <script type="text/javascript" src="dashboard.js?v5"></script>
257 </head>
258
259 <body data-spy="scroll" data-target="#sidebar">
@@ -479,6 +479,12 @@
479 <small>When enabled, pan and zoom operations on a chart will be replicated to all charts (even the ones that are not currently visible - of course only when they will become visible). When disabled, pan and zoom operations will not be propagated to other charts.</small>
480 </td>
481 </tr>
482 + <tr class="option-row">
483 + <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle" data-on="Smooth" data-off="Rough" data-width="110px"></td>
484 + <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
485 + <small>When set to <b>Smooth</b> the charts libraries that support it, will plot smooth curves instead of simple straight lines to connect the points.</small>
486 + </td>
487 + </tr>
488 </table>
489 </div>
490 </form>
@@ -1015,6 +1021,7 @@ function prepareScreen(data) {
1021 sync_option('sync_selection');
1022 sync_option('sync_pan_and_zoom');
1023 sync_option('stop_updates_when_focus_is_lost');
1024 + sync_option('smooth_plot');
1025
1026 if(NETDATA.getOption('parallel_refresher') === false) {
1027 $('#concurrent_refreshes_row').hide();
@@ -1033,6 +1040,7 @@ function prepareScreen(data) {
1040 $('#sync_selection').change(function() { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
1041 $('#sync_pan_and_zoom').change(function() { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
1042 $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
1043 + $('#smooth_plot').change(function() { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
1044
1045 if(document.location.hostname === demo_hostname)
1046 setTimeout(function() {