@cryptotaxi247 / netdata-1 / commits / 5230d2268

dynamic highlight of time-frames using the ALT key

Costa Tsaousis (ktsaou) committed Nov 18, 2017 at 03:12 UTC 5230d22688f3960f8e7097a4aef78c338980fd60
2 files changed +171 -10
web/dashboard.js
+81 -4
@@ -151,6 +151,7 @@ var NETDATA = window.NETDATA || {};
151 foreground: '#000000',
152 grid: '#F0F0F0',
153 axis: '#F0F0F0',
154 + highlight: '#F5F5F5',
155 colors: [ '#3366CC', '#DC3912', '#109618', '#FF9900', '#990099', '#DD4477',
156 '#3B3EAC', '#66AA00', '#0099C6', '#B82E2E', '#AAAA11', '#5574A6',
157 '#994499', '#22AA99', '#6633CC', '#E67300', '#316395', '#8B0707',
@@ -168,6 +169,7 @@ var NETDATA = window.NETDATA || {};
169 foreground: '#C8C8C8',
170 grid: '#283236',
171 axis: '#283236',
172 + highlight: '#383838',
173 /* colors: [ '#55bb33', '#ff2222', '#0099C6', '#faa11b', '#adbce0', '#DDDD00',
174 '#4178ba', '#f58122', '#a5cc39', '#f58667', '#f5ef89', '#cf93c0',
175 '#a5d18a', '#b8539d', '#3954a3', '#c8a9cf', '#c7de8a', '#fad20a',
@@ -304,6 +306,10 @@ var NETDATA = window.NETDATA || {};
306 force_data_points: 0, // force the number of points to be returned for charts
307 fake_chart_rendering: false, // when set to true, the dashboard will download data but will not render the charts
308
309 + highlightCallback: null, // what to call when a highlighted range is setup
310 + highlight_after: null, // highlight after this time
311 + highlight_before: null, // highlight before this time
312 +
313 // the current profile
314 // we may have many...
315 current: {
@@ -5626,6 +5632,29 @@ var NETDATA = window.NETDATA || {};
5632 state.unpauseChart();
5633 NETDATA.globalSelectionSync.stop();
5634 },
5635 + underlayCallback: function(canvas, area, g) {
5636 + if(NETDATA.options.highlight_after !== null && NETDATA.options.highlight_before !== null) {
5637 + var after = NETDATA.options.highlight_after;
5638 + var before = NETDATA.options.highlight_before;
5639 +
5640 + if(after < state.view_after)
5641 + after = state.view_after;
5642 +
5643 + if(before > state.view_before)
5644 + before = state.view_before;
5645 +
5646 + if(after < before) {
5647 + var bottom_left = g.toDomCoords(after, -20);
5648 + var top_right = g.toDomCoords(before, +20);
5649 +
5650 + var left = bottom_left[0];
5651 + var right = top_right[0];
5652 +
5653 + canvas.fillStyle = NETDATA.themes.current.highlight;
5654 + canvas.fillRect(left, area.y, right - left, area.h);
5655 + }
5656 + }
5657 + },
5658 interactionModel : {
5659 mousedown: function(event, dygraph, context) {
5660 if(NETDATA.options.debug.dygraph === true || state.debug === true)
@@ -5646,26 +5675,52 @@ var NETDATA = window.NETDATA || {};
5675 context.initializeMouseDown(event, dygraph, context);
5676
5677 if(event.button && event.button === 1) {
5649 - if (event.altKey || event.shiftKey) {
5678 + if (event.shiftKey) {
5679 + // middle mouse button dragging (PAN)
5680 state.setMode('pan');
5681 // NETDATA.globalSelectionSync.delay();
5682 + state.tmp.dygraph_highlight_after = undefined;
5683 Dygraph.startPan(event, dygraph, context);
5684 }
5685 + else if(event.altKey) {
5686 + // middle mouse button highlight
5687 + if (!(event.offsetX && event.offsetY)) {
5688 + event.offsetX = event.layerX - event.target.offsetLeft;
5689 + event.offsetY = event.layerY - event.target.offsetTop;
5690 + }
5691 + state.tmp.dygraph_highlight_after = dygraph.toDataXCoord(event.offsetX);
5692 + Dygraph.startZoom(event, dygraph, context);
5693 + }
5694 else {
5695 + // middle mouse button selection for zoom (ZOOM)
5696 state.setMode('zoom');
5697 // NETDATA.globalSelectionSync.delay();
5698 + state.tmp.dygraph_highlight_after = undefined;
5699 Dygraph.startZoom(event, dygraph, context);
5700 }
5701 }
5702 else {
5661 - if (event.altKey || event.shiftKey) {
5703 + if (event.shiftKey) {
5704 + // left mouse button selection for zoom (ZOOM)
5705 state.setMode('zoom');
5706 // NETDATA.globalSelectionSync.delay();
5707 + state.tmp.dygraph_highlight_after = undefined;
5708 + Dygraph.startZoom(event, dygraph, context);
5709 + }
5710 + else if(event.altKey) {
5711 + // left mouse button highlight
5712 + if (!(event.offsetX && event.offsetY)) {
5713 + event.offsetX = event.layerX - event.target.offsetLeft;
5714 + event.offsetY = event.layerY - event.target.offsetTop;
5715 + }
5716 + state.tmp.dygraph_highlight_after = dygraph.toDataXCoord(event.offsetX);
5717 Dygraph.startZoom(event, dygraph, context);
5718 }
5719 else {
5720 + // left mouse button dragging (PAN)
5721 state.setMode('pan');
5722 // NETDATA.globalSelectionSync.delay();
5723 + state.tmp.dygraph_highlight_after = undefined;
5724 Dygraph.startPan(event, dygraph, context);
5725 }
5726 }
@@ -5674,7 +5729,12 @@ var NETDATA = window.NETDATA || {};
5729 if(NETDATA.options.debug.dygraph === true || state.debug === true)
5730 state.log('interactionModel.mousemove()');
5731
5677 - if(context.isPanning) {
5732 + if(typeof state.tmp.dygraph_highlight_after !== 'undefined') {
5733 + state.tmp.dygraph_user_action = true;
5734 + Dygraph.moveZoom(event, dygraph, context);
5735 + event.preventDefault();
5736 + }
5737 + else if(context.isPanning) {
5738 state.tmp.dygraph_user_action = true;
5739 //NETDATA.globalSelectionSync.stop();
5740 //NETDATA.globalSelectionSync.delay();
@@ -5696,7 +5756,24 @@ var NETDATA = window.NETDATA || {};
5756 if(NETDATA.options.debug.dygraph === true || state.debug === true)
5757 state.log('interactionModel.mouseup()');
5758
5699 - if (context.isPanning) {
5759 + if(typeof state.tmp.dygraph_highlight_after !== 'undefined') {
5760 + if (!(event.offsetX && event.offsetY)){
5761 + event.offsetX = event.layerX - event.target.offsetLeft;
5762 + event.offsetY = event.layerY - event.target.offsetTop;
5763 + }
5764 +
5765 + context.isZooming = false;
5766 + NETDATA.options.highlight_after = state.tmp.dygraph_highlight_after;
5767 + NETDATA.options.highlight_before = dygraph.toDataXCoord(event.offsetX);
5768 + state.tmp.dygraph_highlight_after = undefined;
5769 + dygraph.clearZoomRect_();
5770 + dygraph.drawGraph_(false);
5771 + NETDATA.globalPanAndZoom.setMaster(state, state.view_after, state.view_before);
5772 +
5773 + if(typeof NETDATA.options.highlightCallback === 'function')
5774 + NETDATA.options.highlightCallback(true, NETDATA.options.highlight_after, NETDATA.options.highlight_before);
5775 + }
5776 + else if (context.isPanning) {
5777 state.tmp.dygraph_user_action = true;
5778 //NETDATA.globalSelectionSync.delay();
5779 Dygraph.endPan(event, dygraph, context);
web/index.html
+90 -6
@@ -65,6 +65,32 @@
65 text-align: center;
66 }
67
68 + .navbar-highlight {
69 + display: none;
70 + position: fixed;
71 + margin-top: 5px;
72 + height: 26px;
73 + width: 100%;
74 + text-align: center;
75 + overflow: hidden;
76 + z-index: 30;
77 + }
78 +
79 + .navbar-highlight-content {
80 + position: relative;
81 + display: inline-block;
82 + margin: 0 auto;
83 + height: 26px;
84 + min-width: 500px;
85 + background-color:rgba(0, 0, 0, 0.7);
86 + padding-top: 2px;
87 + padding-bottom: 2px;
88 + padding-left: 15px;
89 + padding-right: 15px;
90 + border-radius:10px;
91 + color: lightgrey;
92 + }
93 +
94 .modal-wide .modal-dialog {
95 width: 80%;
96 }
@@ -496,6 +522,9 @@
522 server: null,
523 after: 0,
524 before: 0,
525 + highlight: false,
526 + highlight_after: 0,
527 + highlight_before: 0,
528 nowelcome: false,
529 show_alarms: false,
530 chart: null,
@@ -515,7 +544,12 @@
544
545 if(urlOptions.pan_and_zoom === true) {
546 hash += ';after=' + urlOptions.after.toString() +
518 - ';before=' + urlOptions.before.toString();
547 + ';before=' + urlOptions.before.toString();
548 + }
549 +
550 + if(urlOptions.highlight === true) {
551 + hash += ';highlight_after=' + urlOptions.highlight_after.toString() +
552 + ';highlight_before=' + urlOptions.highlight_before.toString();
553 }
554
555 if(urlOptions.theme !== null)
@@ -551,7 +585,7 @@
585 }
586 }
587
554 - var booleans = [ 'nowelcome', 'show_alarms', 'pan_and_zoom', 'update_always' ];
588 + var booleans = [ 'nowelcome', 'show_alarms', 'update_always' ];
589 len = booleans.length;
590 while(len--) {
591 if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1)
@@ -578,6 +612,12 @@
612 else
613 urlOptions.pan_and_zoom = false;
614
615 + if(urlOptions.highlight_before > 0 && urlOptions.highlight_after > 0) {
616 + urlOptions.highlight = true;
617 + }
618 + else
619 + urlOptions.highlight = false
620 +
621 switch(urlOptions.mode) {
622 case 'print':
623 urlOptions.theme = 'white';
@@ -616,6 +656,33 @@
656 urlOptions.before = before;
657 urlOptions.hashUpdate();
658 }
659 + },
660 +
661 + netdataHighlightCallback: function(status, after, before) {
662 + urlOptions.highlight = status;
663 + urlOptions.highlight_after = Math.round(after);
664 + urlOptions.highlight_before = Math.round(before);
665 + urlOptions.hashUpdate();
666 +
667 + if(status === true) {
668 + var d1 = NETDATA.dateTime.localeDateString(urlOptions.highlight_after);
669 + var d2 = NETDATA.dateTime.localeDateString(urlOptions.highlight_before);
670 + if(d1 === d2) d2 = '';
671 + document.getElementById('navbar-highlight-content').innerHTML = 'Highlighted timeframe <b>' + d1 + ' <code>' + NETDATA.dateTime.localeTimeString(urlOptions.highlight_after) + '</code></b> to <b>' + d2 + ' <code>' + NETDATA.dateTime.localeTimeString(urlOptions.highlight_before) + '</code></b>, duration <b>' + NETDATA.seconds4human(Math.round((urlOptions.highlight_before - urlOptions.highlight_after) / 1000)) + '</b> <span onclick="urlOptions.clearHighlight();" style="padding-left: 10px;"><i class="fa fa-times" aria-hidden="true"></i></span>';
672 + $('.navbar-highlight').show();
673 + }
674 + else
675 + $('.navbar-highlight').hide();
676 + },
677 +
678 + clearHighlight: function() {
679 + NETDATA.options.highlight_after = null;
680 + NETDATA.options.highlight_before = null;
681 +
682 + if(NETDATA.globalPanAndZoom.isActive() === true)
683 + NETDATA.globalPanAndZoom.clearMaster();
684 +
685 + urlOptions.netdataHighlightCallback(false, 0, 0);
686 }
687
688 };
@@ -3569,6 +3636,13 @@
3636
3637 // callback for us to track PanAndZoom operations
3638 NETDATA.globalPanAndZoom.callback = urlOptions.netdataPanAndZoomCallback;
3639 + NETDATA.options.highlightCallback = urlOptions.netdataHighlightCallback;
3640 +
3641 + if(urlOptions.highlight === true) {
3642 + NETDATA.options.highlight_after = urlOptions.highlight_after;
3643 + NETDATA.options.highlight_before = urlOptions.highlight_before;
3644 + urlOptions.netdataHighlightCallback(urlOptions.highlight, urlOptions.highlight_after, urlOptions.highlight_before);
3645 + }
3646
3647 // let it run (update the charts)
3648 NETDATA.unpause();
@@ -4030,6 +4104,11 @@
4104 </nav>
4105 </div>
4106 </nav>
4107 + <div class="navbar-highlight">
4108 + <div id="navbar-highlight-content" class="navbar-highlight-content">
4109 + hello world
4110 + </div>
4111 + </div>
4112
4113 <div id="masthead" style="display: none;">
4114 <div class="container">
@@ -4374,7 +4453,7 @@
4453 <hr/>
4454 <div class="p">
4455 <h4>Drag Chart Contents</h4>
4377 - Drag the contents of a chart to pan it horizontally.
4456 + Drag the contents of a chart, by pressing the left mouse button and moving the mouse, to pan it horizontally.
4457 <br/>
4458 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
4459 <br/>
@@ -4388,7 +4467,7 @@
4467 <hr/>
4468 <div class="p">
4469 <h4>SHIFT + Drag</h4>
4391 - While pressing the shift key, click on the contents of a chart and move the mouse to select an area, to zoom in. The other charts will follow too. Zooming is performed in two phases:
4470 + While pressing the <code>SHIFT</code> key, press the left mouse button on the contents of a chart and move the mouse to select an area, to zoom in. The other charts will follow too. Zooming is performed in two phases:
4471 <ul>
4472 <li>The already loaded chart contents are zoomed (low resolution)</li>
4473 <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
@@ -4396,9 +4475,14 @@
4475 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
4476 </div>
4477 <hr/>
4478 + <div class="p">
4479 + <h4>Highlight Timeframe</h4>
4480 + While pressing the <code>ALT</code> key, press the left mouse button on the contents of a chart and move the mouse to select an area. The selected are will be highlighted on all charts.
4481 + </div>
4482 + <hr/>
4483 <div class="p">
4484 <h4>SHIFT + Mouse Wheel</h4>
4401 - While pressing the shift key and the mouse pointer is over the contents of a chart, scroll the mouse wheel to zoom in or out. This kind of zooming is aligned to center below the mouse pointer. The other charts will follow too.
4485 + While pressing the <code>SHIFT</code> key and the mouse pointer is over the contents of a chart, scroll the mouse wheel to zoom in or out. This kind of zooming is aligned to center below the mouse pointer. The other charts will follow too.
4486 <br/>
4487 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
4488 </div>
@@ -5165,6 +5249,6 @@
5249 </div>
5250 </div>
5251 <div id="hiddenDownloadLinks" style="display: none;" hidden></div>
5168 - <script type="text/javascript" src="dashboard.js?v20171117-1"></script>
5252 + <script type="text/javascript" src="dashboard.js?v20171118-1"></script>
5253 </body>
5254 </html>