function addYAxis() { let ticks = Math.ceil(chartHeight / DEFAULT_Y_TICK_SIZE_PX); let tick_interval = tickStep(data.heatmapStats.min, data.heatmapStats.max, ticks); let {y_min, y_max} = wideYAxisRange(data.heatmapStats.min, data.heatmapStats.max, tick_interval); // Rewrite min and max if it have been set explicitly y_min = panel.yAxis.min !== null ? panel.yAxis.min : y_min; y_max = panel.yAxis.max !== null ? panel.yAxis.max : y_max; // Adjust ticks after Y range widening tick_interval = tickStep(y_min, y_max, ticks); ticks = Math.ceil((y_max - y_min) / tick_interval); let decimalsAuto = getPrecision(tick_interval); let decimals = panel.yAxis.decimals === null ? decimalsAuto : panel.yAxis.decimals; // Calculate scaledDecimals for log scales using tick size (as in jquery.flot.js) let flot_tick_size = getFlotTickSize(y_min, y_max, ticks, decimalsAuto); let scaledDecimals = getScaledDecimals(decimals, flot_tick_size); ctrl.decimals = decimals; ctrl.scaledDecimals = scaledDecimals; // Set default Y min and max if no data if (_.isEmpty(data.buckets)) { y_max = 1; y_min = -1; ticks = 3; decimals = 1; } data.yAxis = { min: y_min, max: y_max, ticks: ticks }; scope.yScale = yScale = d3.scaleLinear() .domain([y_min, y_max]) .range([chartHeight, 0]); let yAxis = d3.axisLeft(yScale) .ticks(ticks) .tickFormat(tickValueFormatter(decimals, scaledDecimals)) .tickSizeInner(0 - width) .tickSizeOuter(0) .tickPadding(Y_AXIS_TICK_PADDING); heatmap.append("g") .attr("class", "axis axis-y") .call(yAxis); // Calculate Y axis width first, then move axis into visible area let posY = margin.top; let posX = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING; heatmap.select(".axis-y").attr("transform", "translate(" + posX + "," + posY + ")"); // Remove vertical line in the right of axis labels (called domain in d3) heatmap.select(".axis-y").select(".domain").remove(); }
prepareXAxis(options, panel) { switch (panel.xaxis.mode) { case 'series': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; for (let i = 0; i < this.data.length; i++) { const series = this.data[i]; series.data = [[i + 1, series.stats[panel.xaxis.values[0]]]]; } this.addXSeriesAxis(options); break; } case 'histogram': { let bucketSize: number; if (this.data.length) { let histMin = _.min(_.map(this.data, s => s.stats.min)); let histMax = _.max(_.map(this.data, s => s.stats.max)); const ticks = panel.xaxis.buckets || this.panelWidth / 50; if (panel.xaxis.min != null) { const isInvalidXaxisMin = tickStep(panel.xaxis.min, histMax, ticks) <= 0; histMin = isInvalidXaxisMin ? histMin : panel.xaxis.min; } if (panel.xaxis.max != null) { const isInvalidXaxisMax = tickStep(histMin, panel.xaxis.max, ticks) <= 0; histMax = isInvalidXaxisMax ? histMax : panel.xaxis.max; } bucketSize = tickStep(histMin, histMax, ticks); options.series.bars.barWidth = bucketSize * 0.8; this.data = convertToHistogramData(this.data, bucketSize, this.ctrl.hiddenSeries, histMin, histMax); } else { bucketSize = 0; } this.addXHistogramAxis(options, bucketSize); break; } case 'table': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; this.addXTableAxis(options); break; } default: { options.series.bars.barWidth = this.getMinTimeStepOfSeries(this.data) / 1.5; this.addTimeAxis(options); break; } } }
function buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) { const range = rangeTo - rangeFrom; const tickStepSize = tickStep(rangeFrom, rangeTo, 3); const ticksNum = Math.round(range / tickStepSize); let ticks = []; for (let i = 0; i < ticksNum; i++) { const current = tickStepSize * i; // Add user-defined min and max if it had been set if (isValueCloseTo(minValue, current, tickStepSize)) { ticks.push(minValue); continue; } else if (minValue < current) { ticks.push(minValue); } if (isValueCloseTo(maxValue, current, tickStepSize)) { ticks.push(maxValue); continue; } else if (maxValue < current) { ticks.push(maxValue); } ticks.push(tickStepSize * i); } if (!isValueCloseTo(maxValue, rangeTo, tickStepSize)) { ticks.push(maxValue); } ticks.push(rangeTo); ticks = _.sortBy(_.uniq(ticks)); return ticks; }
function prepareXAxis(options, panel) { switch (panel.xaxis.mode) { case 'series': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; for (let i = 0; i < data.length; i++) { let series = data[i]; series.data = [[i + 1, series.stats[panel.xaxis.values[0]]]]; } addXSeriesAxis(options); break; } case 'histogram': { let bucketSize: number; let values = getSeriesValues(data); if (data.length && values.length) { let histMin = _.min(_.map(data, s => s.stats.min)); let histMax = _.max(_.map(data, s => s.stats.max)); let ticks = panel.xaxis.buckets || panelWidth / 50; bucketSize = tickStep(histMin, histMax, ticks); let histogram = convertValuesToHistogram(values, bucketSize); data[0].data = histogram; options.series.bars.barWidth = bucketSize * 0.8; } else { bucketSize = 0; } addXHistogramAxis(options, bucketSize); break; } case 'table': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; addXTableAxis(options); break; } default: { options.series.bars.barWidth = getMinTimeStepOfSeries(data) / 1.5; addTimeAxis(options); break; } } }
// Function for rendering panel function render_panel() { panelWidth = elem.width(); if (shouldAbortRender()) { return; } // give space to alert editing thresholdManager.prepare(elem, data); // un-check dashes if lines are unchecked panel.dashes = panel.lines ? panel.dashes : false; var stack = panel.stack ? true : null; // Populate element var options: any = { hooks: { draw: [drawHook], processOffset: [processOffsetHook], }, legend: { show: false }, series: { stackpercent: panel.stack ? panel.percentage : false, stack: panel.percentage ? null : stack, lines: { show: panel.lines, zero: false, fill: translateFillOption(panel.fill), lineWidth: panel.dashes ? 0 : panel.linewidth, steps: panel.steppedLine }, dashes: { show: panel.dashes, lineWidth: panel.linewidth, dashLength: [panel.dashLength, panel.spaceLength] }, bars: { show: panel.bars, fill: 1, barWidth: 1, zero: false, lineWidth: 0 }, points: { show: panel.points, fill: 1, fillColor: false, radius: panel.points ? panel.pointradius : 2 }, shadowSize: 0 }, yaxes: [], xaxis: {}, grid: { minBorderMargin: 0, markings: [], backgroundColor: null, borderWidth: 0, hoverable: true, clickable: true, color: '#c8c8c8', margin: { left: 0, right: 0 }, }, selection: { mode: "x", color: '#666' }, crosshair: { mode: 'x' } }; for (let i = 0; i < data.length; i++) { let series = data[i]; series.data = series.getFlotPairs(series.nullPointMode || panel.nullPointMode); // if hidden remove points and disable stack if (ctrl.hiddenSeries[series.alias]) { series.data = []; series.stack = false; } } switch (panel.xaxis.mode) { case 'series': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; for (let i = 0; i < data.length; i++) { let series = data[i]; series.data = [[i + 1, series.stats[panel.xaxis.values[0]]]]; } addXSeriesAxis(options); break; } case 'histogram': { let bucketSize: number; let values = getSeriesValues(data); if (data.length && values.length) { let histMin = _.min(_.map(data, s => s.stats.min)); let histMax = _.max(_.map(data, s => s.stats.max)); let ticks = panel.xaxis.buckets || panelWidth / 50; bucketSize = tickStep(histMin, histMax, ticks); let histogram = convertValuesToHistogram(values, bucketSize); data[0].data = histogram; data[0].alias = data[0].label = data[0].id = "count"; data = [data[0]]; options.series.bars.barWidth = bucketSize * 0.8; } else { bucketSize = 0; } addXHistogramAxis(options, bucketSize); break; } case 'table': { options.series.bars.barWidth = 0.7; options.series.bars.align = 'center'; addXTableAxis(options); break; } default: { options.series.bars.barWidth = getMinTimeStepOfSeries(data) / 1.5; addTimeAxis(options); break; } } thresholdManager.addFlotOptions(options, panel); eventManager.addFlotEvents(annotations, options); configureAxisOptions(data, options); sortedSeries = _.sortBy(data, function(series) { return series.zindex; }); function callPlot(incrementRenderCounter) { try { plot = $.plot(elem, sortedSeries, options); if (ctrl.renderError) { delete ctrl.error; delete ctrl.inspector; } } catch (e) { console.log('flotcharts error', e); ctrl.error = e.message || "Render Error"; ctrl.renderError = true; ctrl.inspector = {error: e}; } if (incrementRenderCounter) { ctrl.renderingCompleted(); } } if (shouldDelayDraw(panel)) { // temp fix for legends on the side, need to render twice to get dimensions right callPlot(false); setTimeout(function() { callPlot(true); }, 50); legendSideLastValue = panel.legend.rightSide; } else { callPlot(true); } }
addYAxis() { let ticks = Math.ceil(this.chartHeight / DEFAULT_Y_TICK_SIZE_PX); let tick_interval = ticksUtils.tickStep(this.data.heatmapStats.min, this.data.heatmapStats.max, ticks); let { y_min, y_max } = this.wideYAxisRange(this.data.heatmapStats.min, this.data.heatmapStats.max, tick_interval); // Rewrite min and max if it have been set explicitly y_min = this.panel.yAxis.min !== null ? this.panel.yAxis.min : y_min; y_max = this.panel.yAxis.max !== null ? this.panel.yAxis.max : y_max; // Adjust ticks after Y range widening tick_interval = ticksUtils.tickStep(y_min, y_max, ticks); ticks = Math.ceil((y_max - y_min) / tick_interval); const decimalsAuto = ticksUtils.getPrecision(tick_interval); let decimals = this.panel.yAxis.decimals === null ? decimalsAuto : this.panel.yAxis.decimals; // Calculate scaledDecimals for log scales using tick size (as in jquery.flot.js) const flot_tick_size = ticksUtils.getFlotTickSize(y_min, y_max, ticks, decimalsAuto); const scaledDecimals = ticksUtils.getScaledDecimals(decimals, flot_tick_size); this.ctrl.decimals = decimals; this.ctrl.scaledDecimals = scaledDecimals; // Set default Y min and max if no data if (_.isEmpty(this.data.buckets)) { y_max = 1; y_min = -1; ticks = 3; decimals = 1; } this.data.yAxis = { min: y_min, max: y_max, ticks: ticks, }; this.scope.yScale = this.yScale = d3 .scaleLinear() .domain([y_min, y_max]) .range([this.chartHeight, 0]); const yAxis = d3 .axisLeft(this.yScale) .ticks(ticks) .tickFormat(this.tickValueFormatter(decimals, scaledDecimals)) .tickSizeInner(0 - this.width) .tickSizeOuter(0) .tickPadding(Y_AXIS_TICK_PADDING); this.heatmap .append('g') .attr('class', 'axis axis-y') .call(yAxis); // Calculate Y axis width first, then move axis into visible area const posY = this.margin.top; const posX = this.getYAxisWidth(this.heatmap) + Y_AXIS_TICK_PADDING; this.heatmap.select('.axis-y').attr('transform', 'translate(' + posX + ',' + posY + ')'); // Remove vertical line in the right of axis labels (called domain in d3) this.heatmap .select('.axis-y') .select('.domain') .remove(); }