// dygraph // Codacy declarations /* global smoothPlotter */ /* global Dygraph */ NETDATA.dygraph = { smooth: false }; NETDATA.dygraphToolboxPanAndZoom = function (state, after, before) { if (after < state.netdata_first) { after = state.netdata_first; } if (before > state.netdata_last) { before = state.netdata_last; } state.setMode('zoom'); NETDATA.globalSelectionSync.stop(); NETDATA.globalSelectionSync.delay(); state.tmp.dygraph_user_action = true; state.tmp.dygraph_force_zoom = true; // state.log('toolboxPanAndZoom'); state.updateChartPanOrZoom(after, before); NETDATA.globalPanAndZoom.setMaster(state, after, before); }; NETDATA.dygraphSetSelection = function (state, t) { if (typeof state.tmp.dygraph_instance !== 'undefined') { let r = state.calculateRowForTime(t); if (r !== -1) { state.tmp.dygraph_instance.setSelection(r); return true; } else { state.tmp.dygraph_instance.clearSelection(); state.legendShowUndefined(); } } return false; }; NETDATA.dygraphClearSelection = function (state) { if (typeof state.tmp.dygraph_instance !== 'undefined') { state.tmp.dygraph_instance.clearSelection(); } return true; }; NETDATA.dygraphSmoothInitialize = function (callback) { $.ajax({ url: NETDATA.dygraph_smooth_js, cache: true, dataType: "script", xhrFields: {withCredentials: true} // required for the cookie }) .done(function () { NETDATA.dygraph.smooth = true; smoothPlotter.smoothing = 0.3; }) .fail(function () { NETDATA.dygraph.smooth = false; }) .always(function () { if (typeof callback === "function") { return callback(); } }); }; NETDATA.dygraphInitialize = function (callback) { if (typeof netdataNoDygraphs === 'undefined' || !netdataNoDygraphs) { $.ajax({ url: NETDATA.dygraph_js, cache: true, dataType: "script", xhrFields: {withCredentials: true} // required for the cookie }) .done(function () { NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js); }) .fail(function () { NETDATA.chartLibraries.dygraph.enabled = false; NETDATA.error(100, NETDATA.dygraph_js); }) .always(function () { if (NETDATA.chartLibraries.dygraph.enabled && NETDATA.options.current.smooth_plot) { NETDATA.dygraphSmoothInitialize(callback); } else if (typeof callback === "function") { return callback(); } }); } else { NETDATA.chartLibraries.dygraph.enabled = false; if (typeof callback === "function") { return callback(); } } }; NETDATA.dygraphChartUpdate = function (state, data) { let dygraph = state.tmp.dygraph_instance; if (typeof dygraph === 'undefined') { return NETDATA.dygraphChartCreate(state, data); } // when the chart is not visible, and hidden // if there is a window resize, dygraph detects // its element size as 0x0. // this will make it re-appear properly if (state.tm.last_unhidden > state.tmp.dygraph_last_rendered) { dygraph.resize(); } let options = { file: data.result.data, colors: state.chartColors(), labels: data.result.labels, //labelsDivWidth: state.chartWidth() - 70, includeZero: state.tmp.dygraph_include_zero, visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names) }; if (state.tmp.dygraph_chart_type === 'stacked') { if (options.includeZero && state.dimensions_visibility.countSelected() < options.visibility.length) { options.includeZero = 0; } } if (!NETDATA.chartLibraries.dygraph.isSparkline(state)) { options.ylabel = state.units_current; // (state.units_desired === 'auto')?"":state.units_current; } if (state.tmp.dygraph_force_zoom) { if (NETDATA.options.debug.dygraph || state.debug) { state.log('dygraphChartUpdate() forced zoom update'); } options.dateWindow = (state.requested_padding !== null) ? [state.view_after, state.view_before] : null; //options.isZoomedIgnoreProgrammaticZoom = true; state.tmp.dygraph_force_zoom = false; } else if (state.current.name !== 'auto') { if (NETDATA.options.debug.dygraph || state.debug) { state.log('dygraphChartUpdate() loose update'); } } else { if (NETDATA.options.debug.dygraph || state.debug) { state.log('dygraphChartUpdate() strict update'); } options.dateWindow = (state.requested_padding !== null) ? [state.view_after, state.view_before] : null; //options.isZoomedIgnoreProgrammaticZoom = true; } options.valueRange = state.tmp.dygraph_options.valueRange; let oldMax = null, oldMin = null; if (state.tmp.__commonMin !== null) { state.data.min = state.tmp.dygraph_instance.axes_[0].extremeRange[0]; oldMin = options.valueRange[0] = NETDATA.commonMin.get(state); } if (state.tmp.__commonMax !== null) { state.data.max = state.tmp.dygraph_instance.axes_[0].extremeRange[1]; oldMax = options.valueRange[1] = NETDATA.commonMax.get(state); } if (state.tmp.dygraph_smooth_eligible) { if ((NETDATA.options.current.smooth_plot && state.tmp.dygraph_options.plotter !== smoothPlotter) || (NETDATA.options.current.smooth_plot === false && state.tmp.dygraph_options.plotter === smoothPlotter)) { NETDATA.dygraphChartCreate(state, data); return; } } if (netdataSnapshotData !== null && NETDATA.globalPanAndZoom.isActive() && NETDATA.globalPanAndZoom.isMaster(state) === false) { // pan and zoom on snapshots options.dateWindow = [NETDATA.globalPanAndZoom.force_after_ms, NETDATA.globalPanAndZoom.force_before_ms]; //options.isZoomedIgnoreProgrammaticZoom = true; } if (NETDATA.chartLibraries.dygraph.isLogScale(state)) { if (Array.isArray(options.valueRange) && options.valueRange[0] <= 0) { options.valueRange[0] = null; } } dygraph.updateOptions(options); let redraw = false; if (oldMin !== null && oldMin > state.tmp.dygraph_instance.axes_[0].extremeRange[0]) { state.data.min = state.tmp.dygraph_instance.axes_[0].extremeRange[0]; options.valueRange[0] = NETDATA.commonMin.get(state); redraw = true; } if (oldMax !== null && oldMax < state.tmp.dygraph_instance.axes_[0].extremeRange[1]) { state.data.max = state.tmp.dygraph_instance.axes_[0].extremeRange[1]; options.valueRange[1] = NETDATA.commonMax.get(state); redraw = true; } if (redraw) { // state.log('forcing redraw to adapt to common- min/max'); dygraph.updateOptions(options); } state.tmp.dygraph_last_rendered = Date.now(); return true; }; NETDATA.dygraphChartCreate = function (state, data) { if (NETDATA.options.debug.dygraph || state.debug) { state.log('dygraphChartCreate()'); } state.tmp.dygraph_chart_type = NETDATA.dataAttribute(state.element, 'dygraph-type', state.chart.chart_type); if (state.tmp.dygraph_chart_type === 'stacked' && data.dimensions === 1) { state.tmp.dygraph_chart_type = 'area'; } if (state.tmp.dygraph_chart_type === 'stacked' && NETDATA.chartLibraries.dygraph.isLogScale(state)) { state.tmp.dygraph_chart_type = 'area'; } let highlightCircleSize = NETDATA.chartLibraries.dygraph.isSparkline(state) ? 3 : 4; let smooth = NETDATA.dygraph.smooth ? (NETDATA.dataAttributeBoolean(state.element, 'dygraph-smooth', (state.tmp.dygraph_chart_type === 'line' && NETDATA.chartLibraries.dygraph.isSparkline(state) === false))) : false; state.tmp.dygraph_include_zero = NETDATA.dataAttribute(state.element, 'dygraph-includezero', (state.tmp.dygraph_chart_type === 'stacked')); let drawAxis = NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawaxis', true); state.tmp.dygraph_options = { colors: NETDATA.dataAttribute(state.element, 'dygraph-colors', state.chartColors()), // leave a few pixels empty on the right of the chart rightGap: NETDATA.dataAttribute(state.element, 'dygraph-rightgap', 5), showRangeSelector: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showrangeselector', false), showRoller: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showroller', false), title: NETDATA.dataAttribute(state.element, 'dygraph-title', state.title), titleHeight: NETDATA.dataAttribute(state.element, 'dygraph-titleheight', 19), legend: NETDATA.dataAttribute(state.element, 'dygraph-legend', 'always'), // we need this to get selection events labels: data.result.labels, labelsDiv: NETDATA.dataAttribute(state.element, 'dygraph-labelsdiv', state.element_legend_childs.hidden), //labelsDivStyles: NETDATA.dataAttribute(state.element, 'dygraph-labelsdivstyles', { 'fontSize':'1px' }), //labelsDivWidth: NETDATA.dataAttribute(state.element, 'dygraph-labelsdivwidth', state.chartWidth() - 70), labelsSeparateLines: NETDATA.dataAttributeBoolean(state.element, 'dygraph-labelsseparatelines', true), labelsShowZeroValues: NETDATA.chartLibraries.dygraph.isLogScale(state) ? false : NETDATA.dataAttributeBoolean(state.element, 'dygraph-labelsshowzerovalues', true), labelsKMB: false, labelsKMG2: false, showLabelsOnHighlight: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showlabelsonhighlight', true), hideOverlayOnMouseOut: NETDATA.dataAttributeBoolean(state.element, 'dygraph-hideoverlayonmouseout', true), includeZero: state.tmp.dygraph_include_zero, xRangePad: NETDATA.dataAttribute(state.element, 'dygraph-xrangepad', 0), yRangePad: NETDATA.dataAttribute(state.element, 'dygraph-yrangepad', 1), valueRange: NETDATA.dataAttribute(state.element, 'dygraph-valuerange', [null, null]), ylabel: state.units_current, // (state.units_desired === 'auto')?"":state.units_current, yLabelWidth: NETDATA.dataAttribute(state.element, 'dygraph-ylabelwidth', 12), // the function to plot the chart plotter: null, // The width of the lines connecting data points. // This can be used to increase the contrast or some graphs. strokeWidth: NETDATA.dataAttribute(state.element, 'dygraph-strokewidth', ((state.tmp.dygraph_chart_type === 'stacked') ? 0.1 : ((smooth === true) ? 1.5 : 0.7))), strokePattern: NETDATA.dataAttribute(state.element, 'dygraph-strokepattern', undefined), // The size of the dot to draw on each point in pixels (see drawPoints). // A dot is always drawn when a point is "isolated", // i.e. there is a missing point on either side of it. // This also controls the size of those dots. drawPoints: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawpoints', false), // Draw points at the edges of gaps in the data. // This improves visibility of small data segments or other data irregularities. drawGapEdgePoints: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawgapedgepoints', true), connectSeparatedPoints: NETDATA.chartLibraries.dygraph.isLogScale(state) ? false : NETDATA.dataAttributeBoolean(state.element, 'dygraph-connectseparatedpoints', false), pointSize: NETDATA.dataAttribute(state.element, 'dygraph-pointsize', 1), // enabling this makes the chart with little square lines stepPlot: NETDATA.dataAttributeBoolean(state.element, 'dygraph-stepplot', false), // Draw a border around graph lines to make crossing lines more easily // distinguishable. Useful for graphs with many lines. strokeBorderColor: NETDATA.dataAttribute(state.element, 'dygraph-strokebordercolor', NETDATA.themes.current.background), strokeBorderWidth: NETDATA.dataAttribute(state.element, 'dygraph-strokeborderwidth', (state.tmp.dygraph_chart_type === 'stacked') ? 0.0 : 0.0), fillGraph: NETDATA.dataAttribute(state.element, 'dygraph-fillgraph', (state.tmp.dygraph_chart_type === 'area' || state.tmp.dygraph_chart_type === 'stacked')), fillAlpha: NETDATA.dataAttribute(state.element, 'dygraph-fillalpha', ((state.tmp.dygraph_chart_type === 'stacked') ? NETDATA.options.current.color_fill_opacity_stacked : NETDATA.options.current.color_fill_opacity_area) ), stackedGraph: NETDATA.dataAttribute(state.element, 'dygraph-stackedgraph', (state.tmp.dygraph_chart_type === 'stacked')), stackedGraphNaNFill: NETDATA.dataAttribute(state.element, 'dygraph-stackedgraphnanfill', 'none'), drawAxis: drawAxis, axisLabelFontSize: NETDATA.dataAttribute(state.element, 'dygraph-axislabelfontsize', 10), axisLineColor: NETDATA.dataAttribute(state.element, 'dygraph-axislinecolor', NETDATA.themes.current.axis), axisLineWidth: NETDATA.dataAttribute(state.element, 'dygraph-axislinewidth', 1.0), drawGrid: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawgrid', true), gridLinePattern: NETDATA.dataAttribute(state.element, 'dygraph-gridlinepattern', null), gridLineWidth: NETDATA.dataAttribute(state.element, 'dygraph-gridlinewidth', 1.0), gridLineColor: NETDATA.dataAttribute(state.element, 'dygraph-gridlinecolor', NETDATA.themes.current.grid), maxNumberWidth: NETDATA.dataAttribute(state.element, 'dygraph-maxnumberwidth', 8), sigFigs: NETDATA.dataAttribute(state.element, 'dygraph-sigfigs', null), digitsAfterDecimal: NETDATA.dataAttribute(state.element, 'dygraph-digitsafterdecimal', 2), valueFormatter: NETDATA.dataAttribute(state.element, 'dygraph-valueformatter', undefined), highlightCircleSize: NETDATA.dataAttribute(state.element, 'dygraph-highlightcirclesize', highlightCircleSize), highlightSeriesOpts: NETDATA.dataAttribute(state.element, 'dygraph-highlightseriesopts', null), // TOO SLOW: { strokeWidth: 1.5 }, highlightSeriesBackgroundAlpha: NETDATA.dataAttribute(state.element, 'dygraph-highlightseriesbackgroundalpha', null), // TOO SLOW: (state.tmp.dygraph_chart_type === 'stacked')?0.7:0.5, pointClickCallback: NETDATA.dataAttribute(state.element, 'dygraph-pointclickcallback', undefined), visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names), logscale: NETDATA.chartLibraries.dygraph.isLogScale(state) ? 'y' : undefined, // Expects a string in the format ":