@cryptotaxi247 / netdata-1 / commits / 5043adb6f

allow printing netdata dashboards

Costa Tsaousis (ktsaou) committed Nov 11, 2017 at 19:16 UTC 5043adb6f125cd9ee7bd5faaab42612b317192b1
4 files changed +353 -62
web/dashboard.css
+1
@@ -286,6 +286,7 @@ body {
286 white-space: nowrap;
287 display: inline-block;
288 cursor: pointer;
289 + -webkit-print-color-adjust: exact;
290 }
291
292 .netdata-legend-value {
web/dashboard.js
+74 -46
@@ -144,7 +144,7 @@ var NETDATA = window.NETDATA || {};
144 NETDATA.themes = {
145 white: {
146 bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-3.3.7.css',
147 - dashboard_css: NETDATA.serverDefault + 'dashboard.css?v20170725-1',
147 + dashboard_css: NETDATA.serverDefault + 'dashboard.css?v20171111-5',
148 background: '#FFFFFF',
149 foreground: '#000000',
150 grid: '#F0F0F0',
@@ -161,7 +161,7 @@ var NETDATA = window.NETDATA || {};
161 },
162 slate: {
163 bootstrap_css: NETDATA.serverDefault + 'css/bootstrap-slate-flat-3.3.7.css?v20161229-1',
164 - dashboard_css: NETDATA.serverDefault + 'dashboard.slate.css?v20170725-1',
164 + dashboard_css: NETDATA.serverDefault + 'dashboard.slate.css?v20171111-5',
165 background: '#272b30',
166 foreground: '#C8C8C8',
167 grid: '#283236',
@@ -306,6 +306,9 @@ var NETDATA = window.NETDATA || {};
306 timezone: 'default', // the timezone to use, or 'default'
307 user_set_server_timezone: 'default', // as set by the user on the dashboard
308
309 + legend_toolbox: true, // show the legend toolbox on charts
310 + resize_charts: true, // show the resize handler on charts
311 +
312 pixels_per_point: isSlowDevice()?5:1, // the minimum pixels per point for all charts
313 // increase this to speed javascript up
314 // each chart library has its own limit too
@@ -1313,7 +1316,7 @@ var NETDATA = window.NETDATA || {};
1316 if(this.name_div !== name_div) {
1317 this.name_div = name_div;
1318 this.name_div.title = this.label;
1316 - this.name_div.style.color = this.color;
1319 + this.name_div.style.setProperty('color', this.color, 'important');
1320 if(this.selected === false)
1321 this.name_div.className = 'netdata-legend-name not-selected';
1322 else
@@ -1323,7 +1326,7 @@ var NETDATA = window.NETDATA || {};
1326 if(this.value_div !== value_div) {
1327 this.value_div = value_div;
1328 this.value_div.title = this.label;
1326 - this.value_div.style.color = this.color;
1329 + this.value_div.style.setProperty('color', this.color, 'important');
1330 if(this.selected === false)
1331 this.value_div.className = 'netdata-legend-value not-selected';
1332 else
@@ -2598,6 +2601,21 @@ var NETDATA = window.NETDATA || {};
2601 resizeChart();
2602 };
2603
2604 + this.resizeForPrint = function() {
2605 + if(typeof this.element_legend_childs !== 'undefined' && this.element_legend_childs.perfect_scroller !== null) {
2606 + var current = this.element.clientHeight;
2607 + var optimal = current
2608 + + this.element_legend_childs.perfect_scroller.scrollHeight
2609 + - this.element_legend_childs.perfect_scroller.clientHeight;
2610 +
2611 + if(optimal > current) {
2612 + // this.log('resized');
2613 + this.element.style.height = optimal + 'px';
2614 + this.library.resize(this);
2615 + }
2616 + }
2617 + };
2618 +
2619 this.resizeHandler = function(e) {
2620 e.preventDefault();
2621
@@ -3479,7 +3497,7 @@ var NETDATA = window.NETDATA || {};
3497 label.name.innerHTML = '<table class="netdata-legend-name-table-'
3498 + state.chart.chart_type
3499 + '" style="background-color: '
3482 - + 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + NETDATA.options.current['color_fill_opacity_' + state.chart.chart_type] + ')'
3500 + + 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + NETDATA.options.current['color_fill_opacity_' + state.chart.chart_type] + ') !important'
3501 + '"><tr class="netdata-legend-name-tr"><td class="netdata-legend-name-td"></td></tr></table>';
3502
3503 var text = document.createTextNode(' ' + name);
@@ -3516,14 +3534,14 @@ var NETDATA = window.NETDATA || {};
3534
3535 this.element_legend_childs = {
3536 content: content,
3519 - resize_handler: document.createElement('div'),
3520 - toolbox: document.createElement('div'),
3521 - toolbox_left: document.createElement('div'),
3522 - toolbox_right: document.createElement('div'),
3523 - toolbox_reset: document.createElement('div'),
3524 - toolbox_zoomin: document.createElement('div'),
3525 - toolbox_zoomout: document.createElement('div'),
3526 - toolbox_volume: document.createElement('div'),
3537 + resize_handler: null,
3538 + toolbox: null,
3539 + toolbox_left: null,
3540 + toolbox_right: null,
3541 + toolbox_reset: null,
3542 + toolbox_zoomin: null,
3543 + toolbox_zoomout: null,
3544 + toolbox_volume: null,
3545 title_date: document.createElement('span'),
3546 title_time: document.createElement('span'),
3547 title_units: document.createElement('span'),
@@ -3531,7 +3549,15 @@ var NETDATA = window.NETDATA || {};
3549 series: {}
3550 };
3551
3534 - if(this.library.toolboxPanAndZoom !== null) {
3552 + if(NETDATA.options.current.legend_toolbox === true && this.library.toolboxPanAndZoom !== null) {
3553 + this.element_legend_childs.toolbox = document.createElement('div');
3554 + this.element_legend_childs.toolbox_left = document.createElement('div');
3555 + this.element_legend_childs.toolbox_right = document.createElement('div');
3556 + this.element_legend_childs.toolbox_reset = document.createElement('div');
3557 + this.element_legend_childs.toolbox_zoomin = document.createElement('div');
3558 + this.element_legend_childs.toolbox_zoomout = document.createElement('div');
3559 + this.element_legend_childs.toolbox_volume = document.createElement('div');
3560 +
3561 var get_pan_and_zoom_step = function(event) {
3562 if (event.ctrlKey)
3563 return NETDATA.options.current.pan_and_zoom_factor * NETDATA.options.current.pan_and_zoom_factor_multiplier_control;
@@ -3671,41 +3697,39 @@ var NETDATA = window.NETDATA || {};
3697 //alert('clicked toolbox_volume on ' + that.id);
3698 //}
3699 }
3674 - else {
3675 - this.element_legend_childs.toolbox = null;
3676 - this.element_legend_childs.toolbox_left = null;
3677 - this.element_legend_childs.toolbox_reset = null;
3678 - this.element_legend_childs.toolbox_right = null;
3679 - this.element_legend_childs.toolbox_zoomin = null;
3680 - this.element_legend_childs.toolbox_zoomout = null;
3681 - this.element_legend_childs.toolbox_volume = null;
3682 - }
3700
3684 - this.element_legend_childs.resize_handler.className += " netdata-legend-resize-handler";
3685 - this.element_legend_childs.resize_handler.innerHTML = '<i class="fa fa-chevron-up"></i><i class="fa fa-chevron-down"></i>';
3686 - this.element.appendChild(this.element_legend_childs.resize_handler);
3687 - if(NETDATA.options.current.show_help === true)
3688 - $(this.element_legend_childs.resize_handler).popover({
3689 - container: "body",
3690 - animation: false,
3691 - html: true,
3692 - trigger: 'hover',
3693 - placement: 'bottom',
3694 - delay: { show: NETDATA.options.current.show_help_delay_show_ms, hide: NETDATA.options.current.show_help_delay_hide_ms },
3695 - title: 'Chart Resize',
3696 - content: 'Drag this point with your mouse or your finger (on touch devices), to resize the chart vertically. You can also <b>double click it</b> or <b>double tap it</b> to reset between 2 states: the default and the one that fits all the values.<br/><small>Help, can be disabled from the settings.</small>'
3697 - });
3701 + if(NETDATA.options.current.resize_charts === true) {
3702 + this.element_legend_childs.resize_handler = document.createElement('div');
3703 +
3704 + this.element_legend_childs.resize_handler.className += " netdata-legend-resize-handler";
3705 + this.element_legend_childs.resize_handler.innerHTML = '<i class="fa fa-chevron-up"></i><i class="fa fa-chevron-down"></i>';
3706 + this.element.appendChild(this.element_legend_childs.resize_handler);
3707 + if (NETDATA.options.current.show_help === true)
3708 + $(this.element_legend_childs.resize_handler).popover({
3709 + container: "body",
3710 + animation: false,
3711 + html: true,
3712 + trigger: 'hover',
3713 + placement: 'bottom',
3714 + delay: {
3715 + show: NETDATA.options.current.show_help_delay_show_ms,
3716 + hide: NETDATA.options.current.show_help_delay_hide_ms
3717 + },
3718 + title: 'Chart Resize',
3719 + content: 'Drag this point with your mouse or your finger (on touch devices), to resize the chart vertically. You can also <b>double click it</b> or <b>double tap it</b> to reset between 2 states: the default and the one that fits all the values.<br/><small>Help, can be disabled from the settings.</small>'
3720 + });
3721
3699 - // mousedown event
3700 - this.element_legend_childs.resize_handler.onmousedown =
3701 - function(e) {
3702 - that.resizeHandler(e);
3703 - };
3722 + // mousedown event
3723 + this.element_legend_childs.resize_handler.onmousedown =
3724 + function (e) {
3725 + that.resizeHandler(e);
3726 + };
3727
3705 - // touchstart event
3706 - this.element_legend_childs.resize_handler.addEventListener('touchstart', function(e) {
3707 - that.resizeHandler(e);
3708 - }, false);
3728 + // touchstart event
3729 + this.element_legend_childs.resize_handler.addEventListener('touchstart', function (e) {
3730 + that.resizeHandler(e);
3731 + }, false);
3732 + }
3733
3734 if(this.chart) {
3735 this.element_legend_childs.title_date.title = this.legendPluginModuleString(true);
@@ -3725,6 +3749,7 @@ var NETDATA = window.NETDATA || {};
3749 this.element_legend.appendChild(document.createElement('br'));
3750
3751 this.element_legend_childs.title_units.className += " netdata-legend-title-units";
3752 + this.element_legend_childs.title_units.innerText = this.units_current;
3753 this.element_legend.appendChild(this.element_legend_childs.title_units);
3754 this.tmp.__last_shown_legend_units = undefined;
3755
@@ -4198,6 +4223,9 @@ var NETDATA = window.NETDATA || {};
4223 };
4224
4225 var __isVisible = function() {
4226 + if(NETDATA.options.current.update_only_visible === false)
4227 + return true;
4228 +
4229 // tolerance is the number of pixels a chart can be off-screen
4230 // to consider it as visible and refresh it as if was visible
4231 var tolerance = 0;
web/dashboard.slate.css
+1
@@ -300,6 +300,7 @@ code {
300 white-space: nowrap;
301 display: inline-block;
302 cursor: pointer;
303 + -webkit-print-color-adjust: exact;
304 }
305
306 .netdata-legend-value {
web/index.html
+277 -16
@@ -105,7 +105,12 @@
105 padding: 10px;
106 }
107
108 - .chart-message {
108 + .dashboard-submenu-info {
109 + display: block;
110 + margin-top: 10px;
111 + }
112 +
113 + .dashboard-context-info {
114 display: block;
115 margin-top: 10px;
116 }
@@ -305,6 +310,62 @@
310 display: none;
311 }
312
313 + .dashboard-section-container {
314 + display: block;
315 + width: 100%;
316 + page-break-before: auto;
317 + page-break-after: auto;
318 + page-break-inside: auto;
319 + }
320 +
321 + .dashboard-print-row {
322 + display: block;
323 + width: 100%;
324 + page-break-before: auto;
325 + page-break-after: auto;
326 + page-break-inside: avoid;
327 + }
328 +
329 + .netdata-chartblock-container {
330 + display: inline-block;
331 + }
332 +
333 + @media print {
334 + body {
335 + overflow: visible !important;
336 + -webkit-print-color-adjust: exact;
337 + page-break-inside: auto;
338 + page-break-before: auto;
339 + page-break-after: auto;
340 + }
341 +
342 + .dashboard-section {
343 + page-break-inside: auto;
344 + page-break-before: auto;
345 + page-break-after: auto;
346 + }
347 +
348 + .dashboard-subsection {
349 + page-break-before: avoid;
350 + page-break-after: auto;
351 + page-break-inside: auto;
352 + }
353 +
354 + .charts-body {
355 + padding-left: 0%;
356 + padding-right: 0%;
357 + display: block;
358 + page-break-inside: auto;
359 + page-break-before: auto;
360 + page-break-after: auto;
361 + }
362 +
363 + .back-to-top,
364 + .dashboard-theme-toggle {
365 + display: block;
366 + }
367 + }
368 +
369 @media (min-width: 768px) {
370 .charts-body {
371 padding-left: 0%;
@@ -416,6 +477,9 @@
477 // enable registry updates
478 var netdataRegistry = true;
479
480 + // control the welcome modal and analytics
481 + var this_is_demo = null;
482 +
483 // --------------------------------------------------------------------
484 // urlOptions
485
@@ -423,6 +487,7 @@
487 hash: '#',
488 theme: null,
489 help: null,
490 + mode: 'live', // 'live', 'print', 'save', 'load'
491 update_always: false,
492 pan_and_zoom: false,
493 after: 0,
@@ -458,6 +523,9 @@
523 if(urlOptions.update_always === true)
524 hash += ';update_always=true';
525
526 + if(urlOptions.mode !== 'live')
527 + hash += ';mode=' + urlOptions.mode;
528 +
529 return hash;
530 },
531
@@ -492,6 +560,35 @@
560 else
561 urlOptions.pan_and_zoom = false;
562
563 + switch(urlOptions.mode) {
564 + case 'live':
565 + case 'print':
566 + case 'load':
567 + case 'save':
568 + break;
569 +
570 + default:
571 + urlOptions.mode = 'live';
572 + break;
573 + }
574 +
575 + if(urlOptions.mode === 'print') {
576 + urlOptions.theme = 'white';
577 + urlOptions.welcome = false;
578 + urlOptions.help = false;
579 + urlOptions.show_alarms = false;
580 +
581 + if(urlOptions.pan_and_zoom === false) {
582 + urlOptions.pan_and_zoom = true;
583 + urlOptions.before = Date.now();
584 + urlOptions.after = urlOptions.before - 600000;
585 + }
586 +
587 + netdataShowAlarms = false;
588 + netdataRegistry = false;
589 + this_is_demo = false;
590 + }
591 +
592 // console.log(urlOptions);
593 },
594
@@ -566,6 +663,9 @@
663 }
664
665 function getTheme(def) {
666 + if(urlOptions.mode === 'print')
667 + return 'white';
668 +
669 var ret = loadLocalStorage('netdataTheme');
670 if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
671 return def;
@@ -574,6 +674,8 @@
674 }
675
676 function setTheme(theme) {
677 + if(urlOptions.mode === 'print') return false;
678 +
679 if(theme === netdataTheme) return false;
680 return saveLocalStorage('netdataTheme', theme);
681 }
@@ -605,7 +707,7 @@
707 var x = 0, y = -1, n = 0, i, j;
708
709 while (i = (j = t.charAt(x++)).charCodeAt(0)) {
608 - var m = (i === 46 || (i >= 48 && i <= 57));
710 + var m = (i >= 48 && i <= 57);
711 if (m !== n) {
712 tz[++y] = "";
713 n = m;
@@ -750,7 +852,6 @@
852 gotoServerInit();
853 };
854
753 - var this_is_demo = null; // FIXME
855 function isdemo() {
856 if(this_is_demo !== null) return this_is_demo;
857 this_is_demo = false;
@@ -1170,7 +1271,7 @@
1271 var x = this.anyAttribute(this.context, 'info', id, null);
1272
1273 if(x !== null)
1173 - return '<div class="chart-message netdata-chart-alignment" role="document">' + x + '</div>';
1274 + return '<div class="shorten dashboard-context-info netdata-chart-alignment" role="document">' + x + '</div>';
1275 else
1276 return '';
1277 },
@@ -1312,6 +1413,9 @@
1413 function headMain(os, charts, duration) {
1414 void(os);
1415
1416 + if(urlOptions.mode === 'print')
1417 + return '';
1418 +
1419 var head = '';
1420
1421 if(typeof charts['system.swap'] !== 'undefined')
@@ -1478,6 +1582,9 @@
1582 }
1583
1584 function generateHeadCharts(type, chart, duration) {
1585 + if(urlOptions.mode === 'print')
1586 + return '';
1587 +
1588 var head = '';
1589 var hcharts = netdataDashboard.anyAttribute(netdataDashboard.context, type, chart.context, []);
1590 if(hcharts.length > 0) {
@@ -1513,7 +1620,7 @@
1620
1621 var menuid = NETDATA.name2id('menu_' + menu);
1622 sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
1516 - html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="document">';
1623 + html += '<div role="section" class="dashboard-section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="section" class="dashboard-subsection">';
1624
1625 if(menus[menu].info !== null)
1626 html += menus[menu].info;
@@ -1533,10 +1640,10 @@
1640 // generate an entry at the submenu
1641 var submenuid = NETDATA.name2id('menu_' + menu + '_submenu_' + submenu);
1642 sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
1536 - shtml += '<div class="netdata-group-container" id="' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
1643 + shtml += '<div role="section" class="dashboard-section-container" id="' + submenuid + '"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
1644
1645 if(menus[menu].submenus[submenu].info !== null)
1539 - shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
1646 + shtml += '<div class="dashboard-submenu-info netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
1647
1648 var head = '<div class="netdata-chart-row">';
1649 var chtml = '';
@@ -1570,8 +1677,11 @@
1677 }
1678
1679 // generate the chart
1573 - chtml += netdataDashboard.contextInfo(chart.context) + '<div class="netdata-container" id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"'
1574 - + ' data-width="' + pcent_width.toString() + '%"'
1680 + if(urlOptions.mode === 'print')
1681 + chtml += '<div role="row" class="dashboard-print-row">';
1682 +
1683 + chtml += '<div class="netdata-chartblock-container" style="width: ' + pcent_width.toString() + '%;">' + netdataDashboard.contextInfo(chart.context) + '<div class="netdata-container" id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"'
1684 + + ' data-width="100%"'
1685 + ' data-height="' + netdataDashboard.contextHeight(chart.context, options.chartsHeight).toString() + 'px"'
1686 + ' data-dygraph-valuerange="' + netdataDashboard.contextValueRange(chart.context) + '"'
1687 + ' data-before="0"'
@@ -1581,7 +1691,10 @@
1691 + ' data-decimal-digits="' + netdataDashboard.contextDecimalDigits(chart.context, -1) + '"'
1692 + chartCommonMin(chart.family, chart.context, chart.units)
1693 + chartCommonMax(chart.family, chart.context, chart.units)
1584 - + ' role="application"></div>';
1694 + + ' role="application"></div></div>';
1695 +
1696 + if(urlOptions.mode === 'print')
1697 + chtml += '</div>';
1698
1699 // console.log(' \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context + ' height: ' + menus[menu].submenus[submenu].height);
1700 }
@@ -1601,7 +1714,11 @@
1714 sidebar += '</ul>';
1715 div.innerHTML = html;
1716 document.getElementById('sidebar').innerHTML = sidebar;
1604 - finalizePage();
1717 +
1718 + if(urlOptions.mode === 'print')
1719 + printPage();
1720 + else
1721 + finalizePage();
1722 }
1723
1724 function renderChartsAndMenu(data) {
@@ -2553,6 +2670,92 @@
2670
2671 // ----------------------------------------------------------------------------
2672
2673 + function showPageFooter() {
2674 + document.getElementById('footer').style.display = 'block';
2675 + }
2676 +
2677 +
2678 + function exportPreflight(mode) {
2679 + var url = document.location.origin + document.location.search + '#' + urlOptions.genHash() + ';mode=print';
2680 + var width = 990;
2681 + var height = screen.height * 90 / 100;
2682 + console.log(url);
2683 + console.log(document.location);
2684 + window.open(url, '', 'width=' + width.toString() + ',height=' + height.toString() + ',menubar=no,location=no,resizable=no,scrollbars=yes,status=no');
2685 + }
2686 +
2687 + function printPage() {
2688 + var print_is_rendering = true;
2689 +
2690 + $('#exportModal').on('hide.bs.modal', function(e) {
2691 + if(print_is_rendering === true) {
2692 + e.preventDefault();
2693 + return false;
2694 + }
2695 +
2696 + return true;
2697 + });
2698 +
2699 + $('#exportModal').on('show.bs.modal', function() {
2700 + var print_options = {
2701 + stop_updates_when_focus_is_lost: false,
2702 + update_only_visible: false,
2703 + sync_selection: false,
2704 + eliminate_zero_dimensions: false,
2705 + pan_and_zoom_data_padding: false,
2706 + show_help: false,
2707 + legend_toolbox: false,
2708 + resize_charts: false,
2709 + pixels_per_point: 1
2710 + };
2711 +
2712 + var x;
2713 + for(x in print_options) {
2714 + if (print_options.hasOwnProperty(x))
2715 + NETDATA.options.current[x] = print_options[x];
2716 + }
2717 +
2718 + NETDATA.parseDom();
2719 + showPageFooter();
2720 +
2721 + NETDATA.globalSelectionSync.stop();
2722 + NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
2723 + // NETDATA.onresize();
2724 +
2725 + var el = document.getElementById('exportModalProgressBar');
2726 + var eltxt = document.getElementById('exportModalProgressBarText');
2727 +
2728 + function update_chart(idx) {
2729 + var state = NETDATA.options.targets[--idx];
2730 +
2731 + var pcent = (NETDATA.options.targets.length - idx) * 100 / NETDATA.options.targets.length;
2732 + $(el).css('width', pcent+'%').attr('aria-valuenow', pcent);
2733 + eltxt.innerText = Math.round(pcent).toString() + '%, ' + state.id;
2734 +
2735 + setTimeout(function() {
2736 + state.updateChart(function () {
2737 + NETDATA.options.targets[idx].resizeForPrint();
2738 +
2739 + if (idx > 0) {
2740 + update_chart(idx);
2741 + }
2742 + else {
2743 + print_is_rendering = false;
2744 + $('#exportModal').modal('hide');
2745 + window.print();
2746 + // window.close();
2747 + }
2748 + })
2749 + }, 0);
2750 + }
2751 +
2752 + print_is_rendering = true;
2753 + update_chart(NETDATA.options.targets.length);
2754 + });
2755 +
2756 + $('#exportModal').modal('show');
2757 + }
2758 +
2759 function finalizePage() {
2760 // resize all charts - without starting the background thread
2761 // this has to be done while NETDATA is paused
@@ -2560,7 +2763,7 @@
2763 // the Dom elements are initially zero-sized
2764 NETDATA.parseDom();
2765
2563 - if(urlOptions.pan_and_zoom === true)
2766 + if(urlOptions.pan_and_zoom === true && NETDATA.options.targets.length > 0)
2767 NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
2768
2769 // ------------------------------------------------------------------------
@@ -2695,7 +2898,7 @@
2898 });
2899
2900 };
2698 - $(".chart-message").shorten();
2901 + $(".shorten").shorten();
2902 // ------------------------------------------------------------------------
2903
2904 // callback for us to track PanAndZoom operations
@@ -2756,7 +2959,7 @@
2959 //else console.log('el.find(): not found');
2960 });
2961
2759 - document.getElementById('footer').style.display = 'block';
2962 + showPageFooter();
2963
2964 var update_options_modal = function() {
2965 // console.log('update_options_modal');
@@ -3126,6 +3329,8 @@
3329 <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata on github"><i class="fa fa-github"></i></a></li>
3330 <li><a href="https://twitter.com/linuxnetdata" class="btn" target="_blank" title="netdata on twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a></li>
3331 <li><a href="https://www.facebook.com/linuxnetdata/" class="btn" target="_blank" title="netdata on facebook"><i class="fa fa-facebook-official" aria-hidden="true"></i></a></li>
3332 + <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#importPreflightModal" title="import a saved dashboard"><i class="fa fa-upload"></i>&nbsp;<span class="hidden-sm hidden-md">Load</span></a></li>
3333 + <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#exportPreflightModal" title="export this dashboard"><i class="fa fa-download"></i>&nbsp;<span class="hidden-sm hidden-md">Save</span></a></li>
3334 <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i>&nbsp;<span class="hidden-sm hidden-md">Help</span></a></li>
3335 <li class="dropdown hidden-sm hidden-md hidden-lg">
3336 <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a>
@@ -3170,7 +3375,7 @@
3375 <div class="charts-body" role="main">
3376 <div id="charts_div"></div>
3377 </div>
3173 - <div class="sidebar-body hidden-xs hidden-sm" id="sidebar-body" role="complementary">
3378 + <div class="sidebar-body hidden-xs hidden-sm hidden-print" id="sidebar-body" role="complementary">
3379 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
3380 </div>
3381 </div>
@@ -3226,6 +3431,62 @@
3431 </div>
3432 </div>
3433
3434 + <div class="modal fade" id="exportPreflightModal" tabindex="-1" role="dialog" aria-labelledby="exportPreflightModalLabel">
3435 + <div class="modal-dialog modal-lg" role="document">
3436 + <div class="modal-content">
3437 + <div class="modal-header">
3438 + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
3439 + <h4 class="modal-title" id="exportPreflightModalLabel">Export this dashboard?</h4>
3440 + </div>
3441 + <div class="modal-body">
3442 + <p>
3443 + <b>Print to printer (i.e. PDF) or save data (i.e. JSON)?</b>
3444 + </p>
3445 + <p>
3446 + netdata dashboards cannot be captured, since we are lazy loading and hiding all but the visible charts.
3447 + <br/>
3448 + To capture the whole page with the charts rendered, a new browser window will pop-up that will render all the charts at once.
3449 + The new browser window will maintain the current pan and zoom settings of the charts. So, align the charts before proceeding.
3450 + </p>
3451 + <p>
3452 + <small>
3453 + This process will put some CPU and memory pressure on your browser.<br/>
3454 + For the netdata server, we will sequencially download all the charts, to avoid congesting network and server resources.<br/>
3455 + <b>Please, do not print netdata dashboards on paper!</b>
3456 + </small>
3457 + </p>
3458 + </div>
3459 + <div class="modal-footer">
3460 + <a href="#" onclick="exportPreflight('print'); return false;" type="button" class="btn btn-default">Print (PDF)</a>
3461 + <a href="#" onclick="exportPreflight('save'); return false;" type="button" class="btn btn-default">Save (JSON)</a>
3462 + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
3463 + </div>
3464 + </div>
3465 + </div>
3466 + </div>
3467 +
3468 + <div class="modal fade" id="exportModal" tabindex="-1" role="dialog" aria-labelledby="exportModalLabel" data-keyboard="false" data-backdrop="static">
3469 + <div class="modal-dialog modal-lg" role="document">
3470 + <div class="modal-content">
3471 + <div class="modal-header">
3472 + <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
3473 + <h4 class="modal-title" id="exportModalLabel">Preparing dashboard for printing...</h4>
3474 + </div>
3475 + <div class="modal-body">
3476 + Please wait while we initialize and render all the charts on the dashboard.
3477 + <div class="progress progress-striped active" style="height: 2em !important;">
3478 + <div id="exportModalProgressBar" class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="min-width: 2em;">
3479 + <span id="exportModalProgressBarText" style="padding-top: 4px; font-size: 1.2em; text-align: center; width: 100%; position: absolute; display: block; color: black;"></span>
3480 + </div>
3481 + </div>
3482 + The print dialog will appear as soon as we finish rendering the page.
3483 + </div>
3484 + <div class="modal-footer">
3485 + </div>
3486 + </div>
3487 + </div>
3488 + </div>
3489 +
3490 <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
3491 <div class="modal-dialog modal-lg" role="document">
3492 <div class="modal-content">
@@ -4095,6 +4356,6 @@
4356 </div>
4357 </div>
4358 </div>
4098 - <script type="text/javascript" src="dashboard.js?v20171031-1"></script>
4359 + <script type="text/javascript" src="dashboard.js?v20171111-12"></script>
4360 </body>
4361 </html>