Adds meter with dimensions to the registry
192558
def meter(self, key, **dims):
        """"""
        return super(RegexRegistry, self).meter(self._get_key(key), **dims)
1300816
public void addRegistry(Registry... registries){
		for (Registry registry: registries){
			registryList.add(registryList.size()-1, registry);
		}
	}
111353
public MetricNameBuilder addDimension(Dimension dimension, boolean permute) throws MetricsNameSyntaxException {
        return addDimension(dimension.getName(), dimension.getValue(), false);
    }
1210074
function updateMetrics() {
		var dprM;

		isVwDirty = false;
		DPR = window.devicePixelRatio;
		cssCache = {};
		sizeLengthCache = {};

		dprM = (DPR || 1) * cfg.xQuant;

		if(!cfg.uT){
			cfg.maxX = Math.max(1.3, cfg.maxX);
			dprM = Math.min( dprM, cfg.maxX );

			ri.DPR = dprM;
		}

		units.width = Math.max(window.innerWidth || 0, docElem.clientWidth);
		units.height = Math.max(window.innerHeight || 0, docElem.clientHeight);

		units.vw = units.width / 100;
		units.vh = units.height / 100;

		units.em = ri.getEmValue();
		units.rem = units.em;

		lazyFactor = cfg.lazyFactor / 2;

		lazyFactor = (lazyFactor * dprM) + lazyFactor;

		substractCurRes = 0.4 + (0.1 * dprM);

		lowTreshHold = 0.5 + (0.2 * dprM);

		partialLowTreshHold = 0.5 + (0.25 * dprM);

		tMemory = dprM + 1.3;

		if(!(isLandscape = units.width > units.height)){
			lazyFactor *= 0.9;
		}
		if(supportAbort){
			lazyFactor *= 0.9;
		}

		evalID = [units.width, units.height, dprM].join('-');
	}
264161
function setMeasures(data, config, ctx, canvasheight, canvaswidth, ylabels, ylabels2, reverseLegend, reverseAxis, drawAxis, legendBox, typegraph) {
		var height = canvasheight;
		var width = canvaswidth;
		if (window.devicePixelRatio > 1) {
			height = height / window.devicePixelRatio;
			width = width / window.devicePixelRatio;
		}
		if (config.canvasBackgroundColor != "none") ctx.canvas.style.background = config.canvasBackgroundColor;
		var i, j, k;
		var borderHeight = 0;
		var borderTHeight = 0;
		var borderBHeight = 0;
		var borderRHeight = 0;
		var borderLHeight = 0;
		var graphTitleHeight = 0;
		var graphTitlePosY = 0;
		var graphSubTitleHeight = 0;
		var graphSubTitlePosY = 0;
		var footNoteHeight = 0;
		var footNotePosY = 0;
		//		ctx.widthAtSetMeasures=width;
		//		ctx.heightAtSetMeasures=height;
		var currentPosition, topNotUsableHeight, bottomNotUsableHeight, leftNotUsableWidth, rightNotUsableWidth, availableWidth, availableHeight;
		availableWidth = width;
		availableHeight = height;
		//// Step 0 : border height;
		// Borders height (and width);
		if (config.canvasBorders && config.canvasBordersSelection > 0) {
			borderHeight = Math.ceil(ctx.chartLineScale * config.canvasBordersWidth);
			if (isBorder(config.canvasBordersSelection, "TOP")) borderTHeight = borderHeight;
			if (isBorder(config.canvasBordersSelection, "BOTTOM")) borderBHeight = borderHeight;
			if (isBorder(config.canvasBordersSelection, "RIGHT")) borderRHeight = borderHeight;
			if (isBorder(config.canvasBordersSelection, "LEFT")) borderLHeight = borderHeight;
		}
		//// Step 1 : compute height/width and position of top elements;
		currentPosition = 0 + borderTHeight + Math.ceil(ctx.chartSpaceScale * config.spaceTop);
		// Title height - Title Position;
		if (config.graphTitle.trim() != "") {
			graphTitleHeight = (Math.ceil(ctx.chartTextScale * config.graphTitleFontSize)) * (config.graphTitle.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.graphTitleSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.graphTitleSpaceAfter);
			graphTitlePosY = currentPosition + Math.ceil(ctx.chartSpaceScale * config.graphTitleSpaceBefore)
			if (config.graphTitleBackgroundColor != "none" || config.graphTitleBorders) {
				graphTitleHeight += (isBorder(config.graphTitleBordersSelection, "TOP") + isBorder(config.graphTitleBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartSpaceScale * config.graphTitleBordersYSpace));
				graphTitlePosY += isBorder(config.graphTitleBordersSelection, "TOP") * Math.ceil(ctx.chartSpaceScale * config.graphTitleBordersYSpace);
			}
			if (config.graphTitleBorders) {
				graphTitleHeight += (isBorder(config.graphTitleBordersSelection, "TOP") + isBorder(config.graphTitleBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.graphTitleBordersWidth));
				graphTitlePosY += isBorder(config.graphTitleBordersSelection, "TOP") * Math.ceil(ctx.chartLineScale * config.graphTitleBordersWidth);
			}
			currentPosition += graphTitleHeight;
		}
		// subTitle height - position;
		if (config.graphSubTitle.trim() != "") {
			graphSubTitleHeight = (Math.ceil(ctx.chartTextScale * config.graphSubTitleFontSize)) * (config.graphSubTitle.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.graphSubTitleSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.graphSubTitleSpaceAfter);
			graphSubTitlePosY = currentPosition + Math.ceil(ctx.chartSpaceScale * config.graphSubTitleSpaceBefore);
			if (config.graphSubTitleBackgroundColor != "none" || config.graphSubTitleBorders) {
				graphSubTitleHeight += 2 * (Math.ceil(ctx.chartSpaceScale * config.graphSubTitleBordersYSpace));
				graphSubTitlePosY += Math.ceil(ctx.chartSpaceScale * config.graphSubTitleBordersYSpace);
			}
			if (config.graphSubTitleBorders) {
				graphSubTitleHeight += (isBorder(config.graphTitleBordersSelection, "TOP") + isBorder(config.graphTitleBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.graphSubTitleBordersWidth));
				graphSubTitlePosY += isBorder(config.graphTitleBordersSelection, "TOP") * Math.ceil(ctx.chartLineScale * config.graphSubTitleBordersWidth);
			}
			currentPosition += graphSubTitleHeight;
		}
		topNotUsableHeight = currentPosition;
		availableHeight -= topNotUsableHeight;
		//// Step 2 : compute height/width and position of bottom elements;
		currentPosition = height - borderBHeight - Math.ceil(ctx.chartSpaceScale * config.spaceBottom);
		// footNote
		if (typeof(config.footNote) != "undefined") {
			if (config.footNote.trim() != "") {
				footNoteHeight = (Math.ceil(ctx.chartTextScale * config.footNoteFontSize)) * (config.footNote.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.footNoteSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.footNoteSpaceAfter);
				footNotePosY = currentPosition - Math.ceil(ctx.chartSpaceScale * config.footNoteSpaceAfter);
				if (config.footNoteBackgroundColor != "none" || config.footNoteBorders) {
					footNoteHeight += 2 * (Math.ceil(ctx.chartSpaceScale * config.footNoteBordersYSpace));
					footNotePosY -= Math.ceil(ctx.chartSpaceScale * config.footNoteBordersYSpace);
				}
				if (config.footNoteBorders) {
					footNoteHeight += (isBorder(config.footNoteBordersSelection, "TOP") + isBorder(config.footNoteBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.footNoteBordersWidth));
					footNotePosY -= isBorder(config.footNoteBordersSelection, "BOTTOM") * Math.ceil(ctx.chartLineScale * config.footNoteBordersWidth);
				}
				currentPosition -= footNoteHeight;
			}
		}
		bottomNotUsableHeight = height - currentPosition;
		availableHeight -= bottomNotUsableHeight;
		//// Step 3 : compute height/width and position of left elements;
		currentPosition = 0 + borderLHeight + Math.ceil(ctx.chartSpaceScale * config.spaceLeft);
		// No left element to be drawn;
		leftNotUsableWidth = currentPosition;
		availableWidth -= leftNotUsableWidth;
		//// Step 4 : compute height/width and position of right elements;
		currentPosition = width - borderRHeight - Math.ceil(ctx.chartSpaceScale * config.spaceRight);
		// No right element to be drawn;
		rightNotUsableWidth = width - currentPosition;
		availableWidth -= rightNotUsableWidth;
		topNotUsableHeight += Math.ceil(ctx.chartSpaceScale * config.graphSpaceBefore);
		bottomNotUsableHeight += Math.ceil(ctx.chartSpaceScale * config.graphSpaceAfter);
		availableHeight -= (Math.ceil(ctx.chartSpaceScale * config.graphSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.graphSpaceAfter));
		//// Step 5  : compute widest text legend;
		var nbeltLegend = 0;
		var widestLegend = -99999999;
		var highestLegend = 0;
		var drawLegendData;
		if (typeof(config.legend) != "undefined") {
			if (config.legend == true) {
				ctx.font = (Math.ceil(ctx.chartTextScale * config.legendFontSize)).toString() + "px " + config.legendFontFamily;
				//				ctx.font = config.legendFontStyle + " " + (Math.ceil(ctx.chartTextScale*config.legendFontSize)).toString() + "px " + config.legendFontFamily;
				var textLength;
				for (i = 0; i < data.datasets.length; i++) {
					if (!config.legendDrawEmptyData) {
						drawLegendData = false;
						for (j = 0; j < data.datasets[i].data.length; j++) {
							if (typeof(1 * data.datasets[i].data[j]) == "number") {
								if (1 * data.datasets[i].data[j] != 0) drawLegendData = true;
							}
						}
					} else drawLegendData = true;
					if (drawLegendData && typeof(data.datasets[i].title) == "string") {
						if (data.datasets[i].title.trim() != "") {
							nbeltLegend++;
							textLength = ctx.measureTextMultiLine(fmtChartJS(config, data.datasets[i].title, config.fmtLegend), Math.ceil(ctx.chartTextScale * config.legendFontSize));
							widestLegend = Math.max(textLength.textWidth, widestLegend);
							highestLegend = Math.max(Math.ceil(ctx.chartTextScale * config.legendFontSize), highestLegend);
						}
					}
				}
				widestLegend += Math.ceil(ctx.chartTextScale * config.legendBlockSize) + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenBoxAndText);
				if (nbeltLegend == 0 || (nbeltLegend == 1 && !config.showSingleLegend)) widestLegend = 0;
			}
		}
		//// Step 6  : compute legend heights and width if legendPosY = 0 or 4 or if legendPosX = 0 or 4; 
		var legendBorderHeight = 0;
		var legendBorderWidth = 0;
		var spaceLegendHeight = 0;
		var xLegendPos = 0;
		var yLegendPos = 0;
		var nbLegendLines = 0;
		var nbLegendCols = 0;
		var legendHeight = 0;
		var legendWidth = 0;
		var msrLegend;
		if (widestLegend > -99999998) {
			if (config.legendPosY == 0 || config.legendPosY == 4) {
				var availableLegendWidth, maxLegendOnLine;
				if (config.legendPosX == 1 || config.legendPosX == 2 || config.legendPosX == 3) {
					availableLegendWidth = availableWidth - Math.ceil(ctx.chartSpaceScale * Math.ceil(ctx.chartSpaceScale * config.legendSpaceLeftText)) - Math.ceil(ctx.chartSpaceScale * config.legendSpaceRightText);
				} else {
					availableLegendWidth = width - borderRHeight - borderLHeight - Math.ceil(ctx.chartSpaceScale * config.spaceLeft) - Math.ceil(ctx.chartSpaceScale * config.spaceRight) - Math.ceil(ctx.chartSpaceScale * Math.ceil(ctx.chartSpaceScale * config.legendSpaceLeftText)) - Math.ceil(ctx.chartSpaceScale * config.legendSpaceRightText);
				}
				if (config.legendBorders == true || config.legendFillColor != "rgba(0,0,0,0)") availableLegendWidth -= (config.legendBorders * (isBorder(config.legendBordersSelection, "RIGHT") + isBorder(config.legendBordersSelection, "LEFT")) * (Math.ceil(ctx.chartLineScale * config.legendBordersWidth)) + Math.ceil(ctx.chartSpaceScale * config.legendBordersSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.legendBordersSpaceRight));
				maxLegendOnLine = Min([Math.floor((availableLegendWidth + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenTextHorizontal)) / (widestLegend + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenTextHorizontal))), config.maxLegendCols]);
				nbLegendLines = Math.ceil(nbeltLegend / maxLegendOnLine);
				nbLegendCols = Math.ceil(nbeltLegend / nbLegendLines);
				msrLegend = measureLegend(data, ctx, config, widestLegend, highestLegend, nbLegendLines, nbLegendCols, availableLegendWidth);
				legendHeight = msrLegend.legendHeight;
				if (config.legendPosY == 0) {
					yLegendPos = topNotUsableHeight - Math.ceil(ctx.chartSpaceScale * config.graphSpaceBefore);
					topNotUsableHeight += legendHeight;
				} else {
					yLegendPos = height - bottomNotUsableHeight - legendHeight;
					bottomNotUsableHeight += legendHeight;
				}
				availableHeight -= legendHeight;
			} else if (config.legendPosX == 0 || config.legendPosX == 4) {
				var availableLegendHeight, maxLegendOnCols;
				availableLegendHeight = availableHeight - Math.ceil(ctx.chartSpaceScale * Math.ceil(ctx.chartSpaceScale * config.legendSpaceBeforeText)) - Math.ceil(ctx.chartSpaceScale * config.legendSpaceAfterText);
				availableLegendWidth = availableWidth - Math.ceil(ctx.chartSpaceScale * Math.ceil(ctx.chartSpaceScale * config.legendSpaceLeftText)) - Math.ceil(ctx.chartSpaceScale * config.legendSpaceRightText);
				if (config.legendBorders == true || config.legendFillColor != "rgba(0,0,0,0)") availableLegendHeight -= (config.legendBorders * (isBorder(config.legendBordersSelection, "BOTTOM") + isBorder(config.legendBordersSelection, "TOP")) * (Math.ceil(ctx.chartLineScale * config.legendBordersWidth)) + Math.ceil(ctx.chartSpaceScale * config.legendBordersSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.legendBordersSpaceAfter));
				maxLegendOnCols = Min([Math.floor((availableLegendHeight + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenTextVertical)) / (highestLegend + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenTextVertical))), config.maxLegendLines]);
				nbLegendCols = Math.ceil(nbeltLegend / maxLegendOnCols);
				nbLegendLines = Math.ceil(nbeltLegend / nbLegendCols);
				msrLegend = measureLegend(data, ctx, config, widestLegend, highestLegend, nbLegendLines, nbLegendCols, availableLegendWidth);
				legendWidth = msrLegend.legendWidth;
				if (config.legendPosX == 0) {
					xLegendPos = leftNotUsableWidth;
					leftNotUsableWidth += legendWidth;
				} else {
					xLegendPos = width - rightNotUsableWidth - legendWidth;
					rightNotUsableWidth += legendWidth;
				}
				availableWidth -= legendWidth;
			}
		}
		//// Step 7 - Compute Y Unit height and position;
		var yAxisUnit2 = "";
		if (config.yAxisRight) {
			yAxisUnit2 = config.yAxisUnit2;
			if (yAxisUnit2 == '') yAxisUnit2 = config.yAxisUnit;
		}
		var yAxisUnitPosY = 0;
		var yAxisUnitHeight = 0;
		var yAxisUnitWidth = 0;
		var yAxisUnit2Width = 0;
		if (drawAxis && ((config.yAxisUnit.trim() != "" && config.yAxisLeft) || (yAxisUnit2.trim() != "" && config.yAxisRight))) {
			yAxisUnitHeight = (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)) * (config.yAxisUnit.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.yAxisUnitSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.yAxisUnitSpaceAfter);
			ctx.font = config.yAxisUnitFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)).toString() + "px " + config.yAxisUnitFontFamily;
			var yAxisUnitSize;
			yAxisUnitSize = ctx.measureTextMultiLine(config.yAxisUnit, (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)));
			yAxisUnitWidth = yAxisUnitSize.textWidth;
			yAxisUnitSize = ctx.measureTextMultiLine(yAxisUnit2, (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)));
			yAxisUnit2Width = yAxisUnitSize.textWidth;
			yAxisUnitPosY = topNotUsableHeight + Math.ceil(ctx.chartSpaceScale * config.yAxisUnitSpaceBefore) + yAxisUnitSize.textHeight;
			if (config.yAxisUnitBackgroundColor != "none" || config.yAxisUnitBorders) {
				yAxisUnitHeight += 2 * (Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersYSpace));
				yAxisUnitPosY += Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersYSpace);
			}
			if (config.yAxisUnitBorders) {
				yAxisUnitHeight += (isBorder(config.yAxisUnitBordersSelection, "TOP") + isBorder(config.yAxisUnitBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.yAxisUnitBordersWidth));
				yAxisUnitPosY += isBorder(config.yAxisUnitBordersSelection, "TOP") * Math.ceil(ctx.chartLineScale * config.yAxisUnitBordersWidth);
			}
			topNotUsableHeight += yAxisUnitHeight;
			availableHeight -= yAxisUnitHeight;
		}
		//// Step 8 - compute Labels width;
		var widestXLabel = 0;
		var highestXLabel = 1;
		var widestTXLabel = 0;
		var highestTXLabel = 1;
		var xAxisLabelHeight = 0;
		var xTAxisLabelHeight = 0;
		var xAxisLabelPos = 0;
		var xTAxisLabelPos = 0;
		var widestYLabel = 0;
		var highestYLabel = 1;
		var widestYLabel2 = 0;
		var highestYLabel2 = 1;
		var yAxisLabelWidth = 0;
		var yAxisLabelPosLeft = 0;
		var yAxisLabelPosRight = 0;
		if (drawAxis) {
			var textMsr;
			// compute widest X label
			ctx.font = config.scaleFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.scaleFontSize)).toString() + "px " + config.scaleFontFamily;
			widestXLabel = Math.max(1, Math.ceil(ctx.chartTextScale * config.xScaleLabelsMinimumWidth));
			widestTXLabel = widestXLabel;
			for (i = 0; i < data.labels.length; i++) {
				if (showLabels(ctx, data, config, i) === true) {
					textMsr = ctx.measureTextMultiLine(fmtChartJS(config, data.labels[i], config.fmtXLabel), (Math.ceil(ctx.chartTextScale * config.scaleFontSize)));
					//If the text length is longer - make that equal to longest text!
					widestXLabel = Math.max(textMsr.textWidth, widestXLabel);
					highestXLabel = Math.max(textMsr.textHeight, highestXLabel);
				}
			}
			if (typeof data.Labels2 == "object" && config.xAxisBottom && config.xAxisTop) {
				ctx.font = config.scaleFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.scaleFontSize)).toString() + "px " + config.scaleFontFamily;
				for (i = 0; i < data.Labels2.length; i++) {
					if (showLabels(ctx, data, config, i) === true) {
						textMsr = ctx.measureTextMultiLine(fmtChartJS(config, data.Labels2[i], config.fmtTopXLabel), (Math.ceil(ctx.chartTextScale * config.scaleFontSize)));
						//If the text length is longer - make that equal to longest text!
						widestTXLabel = Math.max(textMsr.textWidth, widestTXLabel);
						highestTXLabel = Math.max(textMsr.textHeight, highestTXLabel);
					}
				}
			} else {
				widestTXLabel = widestXLabel;
				highestTXLabel = highestXLabel;
			}
			// xAxisLabel height;
			if (typeof(config.xAxisLabel) != "undefined" && config.xAxisBottom) {
				if (config.xAxisLabel.trim() != "") {
					xAxisLabelHeight = (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)) * (config.xAxisLabel.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.xAxisLabelSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.xAxisLabelSpaceAfter);
					xAxisLabelPos = (height - bottomNotUsableHeight) - Math.ceil(ctx.chartSpaceScale * config.xAxisLabelSpaceAfter);
					if (config.xAxisLabelBackgroundColor != "none" || config.footNoteBorders) {
						xAxisLabelHeight += 2 * (Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersYSpace));
						xAxisLabelPos -= Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersYSpace);
					}
					if (config.xAxisLabelBorders) {
						xAxisLabelHeight += (isBorder(config.xAxisLabelBordersSelection, "TOP") + isBorder(config.xAxisLabelBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.xAxisLabelBordersWidth));
						xAxisLabelPos -= isBorder(config.xAxisLabelBordersSelection, "BOTTOM") * Math.ceil(ctx.chartLineScale * config.xAxisLabelBordersWidth);
					}
				}
			}
			var tLabelT;
			tLabelT = config.xAxisLabel;
			if (typeof(config.xTAxisLabel) != "undefined" && config.xAxisTop) {
				if (config.xTAxisLabel.trim() != "") tLabelT = config.xTAxisLabel;
			}
			if (typeof(tLabelT) != "undefined" && config.xAxisTop) {
				if (tLabelT.trim() != "") {
					xTAxisLabelHeight = (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)) * (tLabelT.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.xAxisLabelSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.xAxisLabelSpaceAfter);
					xTAxisLabelPos = topNotUsableHeight + Math.ceil(ctx.chartSpaceScale * config.xAxisLabelSpaceBefore);
					if (config.xAxisLabelBackgroundColor != "none") {
						xTAxisLabelHeight += 2 * (Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersYSpace));
						xTAxisLabelPos += Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersYSpace);
					}
					if (config.xAxisLabelBorders) {
						xTAxisLabelHeight += (isBorder(config.xAxisLabelBordersSelection, "TOP") + isBorder(config.xAxisLabelBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.xAxisLabelBordersWidth));
						xTAxisLabelPos += isBorder(config.xAxisLabelBordersSelection, "TOP") * Math.ceil(ctx.chartLineScale * config.xAxisLabelBordersWidth);
					}
				}
			}
			// compute widest Y Label Width
			widestYLabel = Math.max(1, Math.ceil(ctx.chartTextScale * config.yScaleLabelsMinimumWidth));
			widestYLabel2 = widestYLabel;
			if (ylabels != null && ylabels != "nihil") {
				ctx.font = config.scaleFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.scaleFontSize)).toString() + "px " + config.scaleFontFamily;
				for (i = ylabels.length - 1; i >= 0; i--) {
					if (typeof(ylabels[i]) == "string") {
						if (showYLabels(ctx, data, config, i, ylabels[i])) {
							if (ylabels[i].trim() != "") {
								//								textMsr = ctx.measureTextMultiLine(fmtChartJS(config, ylabels[i], config.fmtYLabel), (Math.ceil(ctx.chartTextScale*config.scaleFontSize)));
								textMsr = ctx.measureTextMultiLine(ylabels[i], (Math.ceil(ctx.chartTextScale * config.scaleFontSize)));
								widestYLabel = Math.max(widestYLabel, textMsr.textWidth);
								highestYLabel = Math.max(highestYLabel, textMsr.textHeight);
							}
						}
					}
				}
			}
			if (ylabels2 != null && config.yAxisRight) {
				ctx.font = config.scaleFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.scaleFontSize)).toString() + "px " + config.scaleFontFamily;
				for (i = ylabels2.length - 1; i >= 0; i--) {
					if (typeof(ylabels2[i]) == "string") {
						if (showYLabels(ctx, data, config, i, ylabels2[i])) {
							//							textMsr = ctx.measureTextMultiLine(fmtChartJS(config, ylabels2[i], config.fmtYLabel2), (Math.ceil(ctx.chartTextScale*config.scaleFontSize)));
							textMsr = ctx.measureTextMultiLine(ylabels2[i], (Math.ceil(ctx.chartTextScale * config.scaleFontSize)));
							widestYLabel2 = Math.max(textMsr.textWidth, widestYLabel2);
							highestYLabel2 = Math.max(textMsr.textHeight, highestYLabel2);
						}
					}
				}
			} else {
				widestYLabel2 = widestYLabel;
				highestYLabel2 = highestYLabel;
			}
			// yAxisLabel width;
			if (typeof(config.yAxisLabel) != "undefined" && (config.yAxisRight || config.yAxisLeft)) {
				if (config.yAxisLabel.trim() != "") {
          yAxisFontSize=config.yAxisFontSize;
          if (config.yAxisRight) {
            if (config.yAxisFontSize2 > config.yAxisFontSize)yAxisFontSize=config.yAxisFontSize2;
          }
					yAxisLabelWidth = (Math.ceil(ctx.chartTextScale * yAxisFontSize)) * (config.yAxisLabel.split("\n").length || 1) + Math.ceil(ctx.chartSpaceScale * config.yAxisLabelSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisLabelSpaceRight);
					yAxisLabelPosLeft = leftNotUsableWidth + Math.ceil(ctx.chartSpaceScale * config.yAxisLabelSpaceLeft) + (Math.ceil(ctx.chartTextScale * yAxisFontSize));
					yAxisLabelPosRight = (width - rightNotUsableWidth) - Math.ceil(ctx.chartSpaceScale * config.yAxisLabelSpaceLeft) - (Math.ceil(ctx.chartTextScale * yAxisFontSize));
					if (config.yAxisLabelBackgroundColor != "none" || config.yAxisLabelBorders) {
						yAxisLabelWidth += 2 * (Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersYSpace));
						yAxisLabelPosLeft += Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersYSpace);
						yAxisLabelPosRight -= Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersYSpace);
					}
					if (config.yAxisLabelBorders) {
						yAxisLabelWidth += (isBorder(config.yAxisLabelBordersSelection, "TOP") + isBorder(config.yAxisLabelBordersSelection, "BOTTOM")) * (Math.ceil(ctx.chartLineScale * config.yAxisLabelBordersWidth));
						yAxisLabelPosLeft += isBorder(config.yAxisLabelBordersSelection, "TOP") * Math.ceil(ctx.chartLineScale * config.yAxisLabelBordersWidth);
						yAxisLabelPosRight -= isBorder(config.yAxisLabelBordersSelection, "TOP") * Math.ceil(ctx.chartLineScale * config.yAxisLabelBordersWidth);
					}
				}
			}
		}
		//// Step 9 - Compute x Label rotation;
		var rotateLabels = 0;
		var rotateTLabels = 0;
		var xLabelWidth = 0;
		var xTLabelWidth = 0;
		var xLabelHeight = 0;
		var xTLabelHeight = 0;
		var xLabelPos = 0;
		var xTLabelPos = 0;
		var widestLabel, highestLabel, nblab, labelAvailableWidth;
		if (drawAxis && config.xAxisBottom) {
			labelAvailableWidth = availableWidth;
			if (reverseAxis == false) {
				widestLabel = widestXLabel;
				highestLabel = highestXLabel;
				nblab = data.labels.length;
				if (config.yAxisLeft == true) labelAvailableWidth -= (widestYLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
				if (config.yAxisRight == true) labelAvailableWidth -= (widestYLabel2 + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
			} else {
				widestLabel = widestYLabel;
				highestLabel = highestYLabel;
				nblab = ylabels.length;
				if (config.yAxisLeft == true) labelAvailableWidth -= (widestXLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
				if (config.yAxisRight == true) labelAvailableWidth -= (widestTXLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
			}
			if (typeof(config.yAxisLabel) != "undefined") {
				if (config.yAxisLabel.trim() != "") {
					if (config.yAxisRight) labelAvailableWidth -= yAxisLabelWidth;
					if (config.yAxisLeft) labelAvailableWidth -= yAxisLabelWidth;
				}
			}
			if (config.rotateLabels == "smart") {
				rotateLabels = 0;
				if ((labelAvailableWidth + Math.ceil(ctx.chartTextScale * config.xAxisSpaceBetweenLabels)) / nblab < (widestLabel + Math.ceil(ctx.chartTextScale * config.xAxisSpaceBetweenLabels))) {
					rotateLabels = 45;
					if (labelAvailableWidth / nblab < Math.abs(Math.cos(rotateLabels * Math.PI / 180) * widestLabel)) {
						rotateLabels = 90;
					}
				}
			} else {
				rotateLabels = config.rotateLabels;
				if (rotateLabels < 0) rotateLabels = 0;
				if (rotateLabels > 180) rotateLabels = 180;
			}
			if (rotateLabels > 90) rotateLabels += 180;
			xLabelHeight = Math.abs(Math.sin(rotateLabels * Math.PI / 180) * widestLabel) + Math.abs(Math.sin((rotateLabels + 90) * Math.PI / 180) * highestLabel);
			xLabelWidth = Math.abs(Math.cos(rotateLabels * Math.PI / 180) * widestLabel) + Math.abs(Math.cos((rotateLabels + 90) * Math.PI / 180) * highestLabel);
			xLabelPos = height - bottomNotUsableHeight - xAxisLabelHeight - xLabelHeight - Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceAfter);
		}
		if (drawAxis && config.xAxisTop) {
			labelAvailableWidth = availableWidth;
			if (reverseAxis == false) {
				widestLabel = widestTXLabel;
				highestLabel = highestTXLabel;
				nblab = data.labels.length;
				if (config.yAxisLeft == true) labelAvailableWidth -= (widestYLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
				if (config.yAxisRight == true) labelAvailableWidth -= (widestYLabel2 + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
			} else {
				widestLabel = widestYLabel2;
				highestLabel = highestYLabel2;
				nblab = ylabels2.length;
				if (config.yAxisLeft == true) labelAvailableWidth -= (widestXLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
				if (config.yAxisRight == true) labelAvailableWidth -= (widestTXLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight));
			}
			if (typeof(config.yAxisLabel) != "undefined") {
				if (config.yAxisLabel.trim() != "") {
					if (config.yAxisRight) labelAvailableWidth -= yAxisLabelWidth;
					if (config.yAxisLeft) labelAvailableWidth -= yAxisLabelWidth;
				}
			}
			if (config.rotateTLabels == "smart") {
				rotateTLabels = 0;
				if ((labelAvailableWidth + Math.ceil(ctx.chartTextScale * config.xAxisSpaceBetweenLabels)) / nblab < (widestLabel + Math.ceil(ctx.chartTextScale * config.xAxisSpaceBetweenLabels))) {
					rotateTLabels = 45;
					if (labelAvailableWidth / nblab < Math.abs(Math.cos(rotateTLabels * Math.PI / 180) * widestLabel)) {
						rotateTLabels = 90;
					}
				}
			} else {
				rotateTLabels = config.rotateTLabels;
				if (rotateTLabels < 0) rotateTLabels = 0;
				if (rotateTLabels > 180) rotateTLabels = 180;
			}
			if (rotateLabels > 90) rotateLabels += 180;
			xTLabelHeight = Math.abs(Math.sin(rotateTLabels * Math.PI / 180) * widestLabel) + Math.abs(Math.sin((rotateTLabels + 90) * Math.PI / 180) * highestLabel);
			xTLabelWidth = Math.abs(Math.cos(rotateTLabels * Math.PI / 180) * widestLabel) + Math.abs(Math.cos((rotateTLabels + 90) * Math.PI / 180) * highestLabel);
			xTLabelPos = topNotUsableHeight + xTAxisLabelHeight + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceBefore);
		}
		// recompute availableWidth/Height with axis label width/height and label width/height;
		var prevLeftNotUsableWidth = leftNotUsableWidth;
		var prevRightNotUsableWidth = rightNotUsableWidth;
		if (drawAxis && config.yAxisLeft) {
			if (reverseAxis == false) leftNotUsableWidth += yAxisLabelWidth + widestYLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight);
			else leftNotUsableWidth += yAxisLabelWidth + widestXLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight);
		}
		if (drawAxis && config.yAxisRight) {
			if (reverseAxis == false) rightNotUsableWidth += yAxisLabelWidth + widestYLabel2 + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight);
			else rightNotUsableWidth += yAxisLabelWidth + widestTXLabel + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceLeft) + Math.ceil(ctx.chartSpaceScale * config.yAxisSpaceRight);
		}
		availableWidth = width - leftNotUsableWidth - rightNotUsableWidth;
		if (drawAxis && config.xAxisTop) {
			if (reverseAxis == false) topNotUsableHeight += xTAxisLabelHeight + xTLabelHeight + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceAfter);
			else {
				var yTLabelHeight = Math.abs(Math.sin(rotateTLabels * Math.PI / 180) * widestYLabel2) + Math.abs(Math.sin((rotateTLabels + 90) * Math.PI / 180) * highestYLabel2);
				topNotUsableHeight += xAxisLabelHeight + yTLabelHeight + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceAfter);
			}
		}
		if (drawAxis && config.xAxisBottom) {
			if (reverseAxis == false) bottomNotUsableHeight += xAxisLabelHeight + xLabelHeight + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceAfter);
			else {
				var yTLabelHeight = Math.abs(Math.sin(rotateLabels * Math.PI / 180) * widestYLabel) + Math.abs(Math.sin((rotateLabels + 90) * Math.PI / 180) * highestYLabel);
				bottomNotUsableHeight += xAxisLabelHeight + yTLabelHeight + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceBefore) + Math.ceil(ctx.chartSpaceScale * config.xAxisSpaceAfter);
			}
		}
		availableHeight = height - topNotUsableHeight - bottomNotUsableHeight;
		// compute space for Legend
		if (widestLegend > -99999998) {
			if (nbLegendLines == 0) { // compute nbLegendLines/nbLegendCols if not yet done;
				availableLegendWidth = availableWidth - Math.ceil(ctx.chartSpaceScale * Math.ceil(ctx.chartSpaceScale * config.legendSpaceLeftText)) - Math.ceil(ctx.chartSpaceScale * config.legendSpaceRightText);
				maxLegendOnLine = Min([Math.floor((availableLegendWidth + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenTextHorizontal)) / (widestLegend + Math.ceil(ctx.chartSpaceScale * config.legendSpaceBetweenTextHorizontal))), config.maxLegendCols]);
				nbLegendLines = Math.ceil(nbeltLegend / maxLegendOnLine);
				nbLegendCols = Math.ceil(nbeltLegend / nbLegendLines);
				msrLegend = measureLegend(data, ctx, config, widestLegend, highestLegend, nbLegendLines, nbLegendCols, availableLegendWidth);
			}
			legendHeight = msrLegend.legendHeight;
			legendWidth = msrLegend.legendWidth;
			switch (config.legendPosY) {
				case 0: // already computed;
					break;
				case 1:
					yLegendPos = topNotUsableHeight;
					break;
				case 2:
					yLegendPos = topNotUsableHeight + (availableHeight / 2) - legendHeight / 2;
					break;
				case -2:
					yLegendPos = height / 2 - legendHeight / 2;
					break;
				case 3:
					yLegendPos = height - bottomNotUsableHeight - legendHeight;
					break;
				case 4: // already Computed;
					break;
				default:
					yLegendPos = topNotUsableHeight;
					break;
			}
			switch (config.legendPosX) {
				case 0:
					if (config.legendPosY == 0 || config.legendPosY == 4) xLegendPos = prevLeftNotUsableWidth;
					break;
				case 1:
					xLegendPos = leftNotUsableWidth;
					break;
				case 2:
					xLegendPos = leftNotUsableWidth + (availableWidth) / 2 - legendWidth / 2;
					break;
				case -2:
					xLegendPos = width / 2 - (legendWidth / 2);
					break;
				case 3:
					xLegendPos = width - rightNotUsableWidth - legendWidth;
					break;
				case 4:
					if (config.legendPosY == 0 || config.legendPosY == 4) xLegendPos = width - prevRightNotUsableWidth - legendWidth;
					break;
				default:
					xLegendPos = width - rightNotUsableWidth;
					break;
			}
		}
		// correct space;
		if (drawAxis && config.yAxisLeft && yAxisUnitWidth > 0) leftNotUsableWidth = Math.max(leftNotUsableWidth, borderLHeight + config.spaceLeft + (config.yAxisUnitBorders && isBorder(config.yAxisUnitBordersSelection, "LEFT")) * (config.yAxisUnitBordersWidth) + (config.yAxisUnitBackgroundColor != "none" || config.yAxisUnitBorders) * Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersYSpace) + 1 + yAxisUnitWidth / 2);
		if (drawAxis && config.yAxisRight && yAxisUnit2Width > 0) rightNotUsableWidth = Math.max(rightNotUsableWidth, borderRHeight + config.spaceRight + (config.yAxisUnitBorders && isBorder(config.yAxisUnitBordersSelection, "RIGHT")) * (config.yAxisUnitBordersWidth) + (config.yAxisUnitBackgroundColor != "none" || config.yAxisUnitBorders) * Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersYSpace) + 1 + yAxisUnit2Width / 2);
		if (config.inGraphDataShow && (typegraph == "Line" || typegraph == "HorizontalBar" || typegraph == "HorizontalStackedBar")) {
			rightNotUsableWidth = Math.max(rightNotUsableWidth, Math.max(widestYLabel, widestYLabel2) + 1 + borderRHeight);
			leftNotUsableWidth = Math.max(leftNotUsableWidth, Math.max(widestYLabel, widestYLabel2) + 1 + borderLHeight);
		}
		if (typegraph == "Line" && (config.xAxisTop || config.xAxisBottom)) {
			rightNotUsableWidth = Math.max(rightNotUsableWidth, Math.max(config.xAxisBottom * Math.cos(rotateLabels) * widestXLabel / 2, config.xAxisTop * Math.cos(rotateTLabels) * widestTXLabel / 2) + 1 + borderRHeight);
			leftNotUsableWidth = Math.max(leftNotUsableWidth, Math.max(config.xAxisBottom * Math.cos(rotateLabels) * widestXLabel / 2, config.xAxisTop * Math.cos(rotateTLabels) * widestTXLabel / 2) + 1 + borderLHeight);
		}
		if ((typegraph == "HorizontalBar" || typegraph == "HorizontalStackedBar") && (config.xAxisTop || config.xAxisBottom)) {
			rightNotUsableWidth = Math.max(rightNotUsableWidth, config.xAxisBottom * Math.cos(rotateLabels) * widestYLabel / 2 + 1 + borderRHeight);
			leftNotUsableWidth = Math.max(leftNotUsableWidth, config.xAxisBottom * Math.cos(rotateLabels) * widestYLabel / 2 + 1 + borderLHeight);
		}
		if (typegraph == "Line" && config.inGraphDataShow) {
			topNotUsableHeight = Math.max(topNotUsableHeight, Math.max(highestYLabel, highestYLabel2) + 1 + borderTHeight);
		}
		if (typegraph == "Line" && ctx.tpchartSub == "Bubble") {
			rightNotUsableWidth = Math.max(rightNotUsableWidth, availableWidth * config.bubbleMaxRadius / 2 + 1 + borderRHeight);
			leftNotUsableWidth = Math.max(leftNotUsableWidth, availableWidth * config.bubbleMaxRadius / 2 + 1 + borderLHeight);
			topNotUsableHeight += availableHeight * config.bubbleMaxRadius / 2;
		}
		availableWidth = width - rightNotUsableWidth - leftNotUsableWidth;
		availableHeight = height - topNotUsableHeight - bottomNotUsableHeight;
		// ----------------------- DRAW EXTERNAL ELEMENTS -------------------------------------------------
		dispCrossImage(ctx, config, width / 2, height / 2, width / 2, height / 2, false, data, -1, -1);
		if (typeof config.initFunction == "function") config.initFunction("INITFUNCTION", ctx, data, null, -1, -1, {
			animationValue: 0,
			cntiter: 0,
			config: config,
			borderX: 0,
			borderY: 0,
			midPosX: 0,
			midPosY: 0
		});
		if (ylabels != "nihil") {
			// Draw Borders
			if (borderHeight > 0) {
				ctx.save();
				ctx.beginPath();
				ctx.setLineDash(lineStyleFn(config.canvasBordersStyle));
				ctx.strokeStyle = config.canvasBordersColor;
				ctx.lineWidth = borderHeight;
				ctx.setLineDash(lineStyleFn(config.canvasBordersStyle));
				ctx.strokeStyle = config.canvasBordersColor;
				ctx.fillStyle = "rgba(0,0,0,0)";
				ctx.drawRectangle({
					x: 0 + borderLHeight / 2,
					y: 0 + borderTHeight / 2,
					width: width - borderRHeight / 2 - borderLHeight / 2,
					height: height - borderTHeight / 2 - borderBHeight / 2,
					borders: true,
					bordersWidth: borderHeight,
					borderSelection: config.canvasBordersSelection,
					borderRadius: config.canvasBordersRadius,
					fill: false,
					stroke: true
				});
				ctx.setLineDash([]);
				ctx.restore();
			}
			// Draw Graph Title
			if (graphTitleHeight > 0) {
				ctx.save();
				ctx.beginPath();
				ctx.font = config.graphTitleFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.graphTitleFontSize)).toString() + "px " + config.graphTitleFontFamily;
				ctx.fillStyle = config.graphTitleFontColor;
				ctx.textBaseline = "top";
				var textPos;
				switch (config.graphTitleAlign) {
					case "right":
						ctx.textAlign = "right";
						textPos = Math.ceil(ctx.chartSpaceScale * config.spaceLeft) + (width - Math.ceil(ctx.chartSpaceScale * config.spaceLeft) - Math.ceil(ctx.chartSpaceScale * config.spaceRight)) / 2;
						textPos = width - Math.ceil(ctx.chartSpaceScale * (config.spaceRight + config.graphTitleShift)) - borderRHeight;
						break;
					case "left":
						ctx.textAlign = "left";
						textPos = borderLHeight + Math.ceil(ctx.chartSpaceScale * (config.spaceLeft + config.graphTitleShift));
						break;
					default:
						ctx.textAlign = "center";
						textPos = borderLHeight + Math.ceil(ctx.chartSpaceScale * config.spaceLeft) + (width - borderRHeight - borderLHeight - Math.ceil(ctx.chartSpaceScale * config.spaceLeft) - Math.ceil(ctx.chartSpaceScale * config.spaceRight)) / 2;
						break;
				}
				setTextBordersAndBackground(ctx, config.graphTitle, (Math.ceil(ctx.chartTextScale * config.graphTitleFontSize)), textPos, graphTitlePosY, config.graphTitleBorders, config.graphTitleBordersSelection, config.graphTitleBordersColor, Math.ceil(ctx.chartLineScale * config.graphTitleBordersWidth), Math.ceil(ctx.chartSpaceScale * config.graphTitleBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.graphTitleBordersYSpace), config.graphTitleBordersStyle, config.graphTitleBackgroundColor, "GRAPHTITLE", config.graphTitleBordersRadius);
				ctx.translate(textPos, graphTitlePosY);
				ctx.fillTextMultiLine(config.graphTitle, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.graphTitleFontSize)), true, config.detectMouseOnText, ctx, "TITLE_TEXTMOUSE", 0, textPos, graphTitlePosY, -1, -1);
				ctx.stroke();
				ctx.restore();
			}
			// Draw Graph Sub-Title
			if (graphSubTitleHeight > 0) {
				ctx.save();
				ctx.beginPath();
				ctx.font = config.graphSubTitleFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.graphSubTitleFontSize)).toString() + "px " + config.graphSubTitleFontFamily;
				ctx.fillStyle = config.graphSubTitleFontColor;
				switch (config.graphSubTitleAlign) {
					case "right":
						ctx.textAlign = "right";
						textPos = width - Math.ceil(ctx.chartSpaceScale * (config.spaceRight + config.graphSubTitleShift)) - borderRHeight;
						break;
					case "left":
						ctx.textAlign = "left";
						textPos = borderLHeight + Math.ceil(ctx.chartSpaceScale * (config.spaceLeft + config.graphSubTitleShift));
						break;
					default:
						ctx.textAlign = "center";
						textPos = borderLHeight + Math.ceil(ctx.chartSpaceScale * config.spaceLeft) + (width - borderRHeight - borderLHeight - Math.ceil(ctx.chartSpaceScale * config.spaceLeft) - Math.ceil(ctx.chartSpaceScale * config.spaceRight)) / 2;
						break;
				}
				ctx.textBaseline = "top";
				setTextBordersAndBackground(ctx, config.graphSubTitle, (Math.ceil(ctx.chartTextScale * config.graphSubTitleFontSize)), textPos, graphSubTitlePosY, config.graphSubTitleBorders, config.graphSubTitleBordersSelection, config.graphSubTitleBordersColor, Math.ceil(ctx.chartLineScale * config.graphSubTitleBordersWidth), Math.ceil(ctx.chartSpaceScale * config.graphSubTitleBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.graphSubTitleBordersYSpace), config.graphSubTitleBordersStyle, config.graphSubTitleBackgroundColor, "GRAPHSUBTITLE", config.graphSubTitleBordersRadius);
				ctx.translate(textPos, graphSubTitlePosY);
				ctx.fillTextMultiLine(config.graphSubTitle, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.graphSubTitleFontSize)), true, config.detectMouseOnText, ctx, "SUBTITLE_TEXTMOUSE", 0, textPos, graphSubTitlePosY, -1, -1);
				ctx.stroke();
				ctx.restore();
			}
			// Draw FootNote
			if (config.footNote.trim() != "") {
				ctx.save();
				ctx.font = config.footNoteFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.footNoteFontSize)).toString() + "px " + config.footNoteFontFamily;
				ctx.fillStyle = config.footNoteFontColor;
				switch (config.footNoteAlign) {
					case "right":
						ctx.textAlign = "right";
						textPos = width - Math.ceil(ctx.chartSpaceScale * (config.spaceRight + config.footNoteShift)) - borderRHeight;
						break;
					case "left":
						ctx.textAlign = "left";
						textPos = borderLHeight + Math.ceil(ctx.chartSpaceScale * (config.spaceLeft + config.footNoteShift));
						break;
					default:
						ctx.textAlign = "center";
						textPos = leftNotUsableWidth + (availableWidth / 2);
						break;
				}
				ctx.textBaseline = "bottom";
				setTextBordersAndBackground(ctx, config.footNote, (Math.ceil(ctx.chartTextScale * config.footNoteFontSize)), textPos, footNotePosY, config.footNoteBorders, config.footNoteBordersSelection, config.footNoteBordersColor, Math.ceil(ctx.chartLineScale * config.footNoteBordersWidth), Math.ceil(ctx.chartSpaceScale * config.footNoteBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.footNoteBordersYSpace), config.footNoteBordersStyle, config.footNoteBackgroundColor, "FOOTNOTE", config.footNoteBordersRadius);
				ctx.translate(textPos, footNotePosY);
				ctx.fillTextMultiLine(config.footNote, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.footNoteFontSize)), true, config.detectMouseOnText, ctx, "FOOTNOTE_TEXTMOUSE", 0, textPos, footNotePosY, -1, -1);
				ctx.stroke();
				ctx.restore();
			}
			// Draw Y Axis Unit
			if (yAxisUnitHeight > 0) {
				if (config.yAxisLeft) {
					ctx.save();
					ctx.beginPath();
					ctx.font = config.yAxisUnitFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)).toString() + "px " + config.yAxisUnitFontFamily;
					ctx.fillStyle = config.yAxisUnitFontColor;
					ctx.textAlign = "center";
					ctx.textBaseline = "bottom";
					setTextBordersAndBackground(ctx, config.yAxisUnit, (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)), leftNotUsableWidth, yAxisUnitPosY, config.yAxisUnitBorders, config.yAxisUnitBordersSelection, config.yAxisUnitBordersColor, Math.ceil(ctx.chartLineScale * config.yAxisUnitBordersWidth), Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersYSpace), config.yAxisUnitBordersStyle, config.yAxisUnitBackgroundColor, "YAXISUNIT", config.yAxisUnitBordersRadius);
					ctx.translate(leftNotUsableWidth, yAxisUnitPosY);
					ctx.fillTextMultiLine(config.yAxisUnit, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)), true, config.detectMouseOnText, ctx, "YLEFTAXISUNIT_TEXTMOUSE", 0, leftNotUsableWidth, yAxisUnitPosY, -1, -1);
					ctx.stroke();
					ctx.restore();
				}
				if (config.yAxisRight && yAxisUnit2 != "") {
					ctx.save();
					ctx.beginPath();
					ctx.font = config.yAxisUnitFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)).toString() + "px " + config.yAxisUnitFontFamily;
					ctx.fillStyle = config.yAxisUnitFontColor;
					ctx.textAlign = "center";
					ctx.textBaseline = "bottom";
					setTextBordersAndBackground(ctx, yAxisUnit2, (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)), width - rightNotUsableWidth, yAxisUnitPosY, config.yAxisUnitBorders, config.yAxisUnitBordersSelection, config.yAxisUnitBordersColor, Math.ceil(ctx.chartLineScale * config.yAxisUnitBordersWidth), Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.yAxisUnitBordersYSpace), config.yAxisUnitBordersStyle, config.yAxisUnitBackgroundColor, "YAXISUNIT", config.yAxisUnitBordersRadius);
					ctx.translate(width - rightNotUsableWidth, yAxisUnitPosY);
					ctx.fillTextMultiLine(yAxisUnit2, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.yAxisUnitFontSize)), true, config.detectMouseOnText, ctx, "YRIGHTAXISUNIT_TEXTMOUSE", 0, width - rightNotUsableWidth, yAxisUnitPosY, -1, -1);
					ctx.stroke();
					ctx.restore();
				}
			}
			// Draw Y Axis Label
			if (yAxisLabelWidth > 0) {
				if (config.yAxisLeft) {
					ctx.save();
					ctx.beginPath();
					ctx.font = config.yAxisFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.yAxisFontSize)).toString() + "px " + config.yAxisFontFamily;
					ctx.fillStyle = config.yAxisFontColor;
					ctx.textAlign = "center";
					ctx.textBaseline = "bottom";
					ctx.translate(yAxisLabelPosLeft, topNotUsableHeight + (availableHeight / 2));
					ctx.rotate(-(90 * (Math.PI / 180)));
					setTextBordersAndBackground(ctx, config.yAxisLabel, (Math.ceil(ctx.chartTextScale * config.yAxisFontSize)), 0, 0, config.yAxisLabelBorders, config.yAxisLabelBordersSelection, config.yAxisLabelBordersColor, Math.ceil(ctx.chartLineScale * config.yAxisLabelBordersWidth), Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersYSpace), config.yAxisLabelBordersStyle, config.yAxisLabelBackgroundColor, "YAXISLABELLEFT", config.yAxisLabelBordersRadius);
					ctx.fillTextMultiLine(config.yAxisLabel, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.yAxisFontSize)), false, config.detectMouseOnText, ctx, "YLEFTAXISLABEL_TEXTMOUSE", -(90 * (Math.PI / 180)), yAxisLabelPosLeft, topNotUsableHeight + (availableHeight / 2), -1, -1);
					ctx.stroke();
					ctx.restore();
				}
				if (config.yAxisRight) {
					var yAxisLabel2 = config.yAxisLabel2;
					if (yAxisLabel2 == '') yAxisLabel2 = config.yAxisLabel;
					ctx.save();
					ctx.beginPath();
          if (config.yAxisFontSize2==0) {
            yAxisFontSize=config.yAxisFontSize;
          } else {
            yAxisFontSize=config.yAxisFontSize2;
          }
					ctx.font = config.yAxisFontStyle + " " + (Math.ceil(ctx.chartTextScale * yAxisFontSize)).toString() + "px " + config.yAxisFontFamily;
					if (config.yAxisFontColor2 == ""){
            ctx.fillStyle = config.yAxisFontColor;
          } else {
            ctx.fillStyle = config.yAxisFontColor2;
          }
					ctx.textAlign = "center";
					ctx.textBaseline = "bottom";
					ctx.translate(yAxisLabelPosRight, topNotUsableHeight + (availableHeight / 2));
					ctx.rotate(+(90 * (Math.PI / 180)));
					setTextBordersAndBackground(ctx, yAxisLabel2, (Math.ceil(ctx.chartTextScale * yAxisFontSize)), 0, 0, config.yAxisLabelBorders, config.yAxisLabelBordersSelection, config.yAxisLabelBordersColor, Math.ceil(ctx.chartLineScale * config.yAxisLabelBordersWidth), Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.yAxisLabelBordersYSpace), config.yAxisLabelBordersStyle, config.yAxisLabelBackgroundColor, "YAXISLABELLEFT", config.yAxisLabelBordersRadius);
					ctx.fillTextMultiLine(yAxisLabel2, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * yAxisFontSize)), false, config.detectMouseOnText, ctx, "YRIGHTAXISLABEL_TEXTMOUSE", +(90 * (Math.PI / 180)), yAxisLabelPosRight, topNotUsableHeight + (availableHeight / 2), -1, -1);
					ctx.stroke();
					ctx.restore();
				}
			}
			// Draw bottom X Axis Label
			if (xAxisLabelHeight > 0) {
				if (config.xAxisBottom) {
					ctx.save();
					ctx.beginPath();
					ctx.font = config.xAxisFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)).toString() + "px " + config.xAxisFontFamily;
					ctx.fillStyle = config.xAxisFontColor;
					ctx.textAlign = "center";
					ctx.textBaseline = "bottom";
					setTextBordersAndBackground(ctx, config.xAxisLabel, (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)), leftNotUsableWidth + (availableWidth / 2), xAxisLabelPos, config.xAxisLabelBorders, config.xAxisLabelBordersSelection, config.xAxisLabelBordersColor, Math.ceil(ctx.chartLineScale * config.xAxisLabelBordersWidth), Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersYSpace), config.xAxisLabelBordersStyle, config.xAxisLabelBackgroundColor, "XAXISLABEL", config.xAxisLabelBordersRadius);
					ctx.translate(leftNotUsableWidth + (availableWidth / 2), xAxisLabelPos);
					ctx.fillTextMultiLine(config.xAxisLabel, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)), true, config.detectMouseOnText, ctx, "XAXISLABEL_TEXTMOUSE", 0, leftNotUsableWidth + (availableWidth / 2), xAxisLabelPos, -1, -1);
					ctx.stroke();
					ctx.restore();
				}
				if (config.xAxisTop) {
					var xAxisLabel2 = config.xAxisLabel2;
					if (xAxisLabel2 == '') xAxisLabel2 = config.xAxisLabel;
					ctx.save();
					ctx.beginPath();
					ctx.font = config.xAxisFontStyle + " " + (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)).toString() + "px " + config.xAxisFontFamily;
					ctx.fillStyle = config.xAxisFontColor;
					ctx.textAlign = "center";
					ctx.textBaseline = "top";
					setTextBordersAndBackground(ctx, xAxisLabel2, (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)), leftNotUsableWidth + (availableWidth / 2), xTAxisLabelPos, config.xAxisLabelBorders, config.xAxisLabelBordersSelection, config.xAxisLabelBordersColor, Math.ceil(ctx.chartLineScale * config.xAxisLabelBordersWidth), Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersXSpace), Math.ceil(ctx.chartSpaceScale * config.xAxisLabelBordersYSpace), config.xAxisLabelBordersStyle, config.xAxisLabelBackgroundColor, "XAXISLABEL", config.xAxisLabelBordersRadius);
					ctx.translate(leftNotUsableWidth + (availableWidth / 2), xTAxisLabelPos);
					ctx.fillTextMultiLine(xAxisLabel2, 0, 0, ctx.textBaseline, (Math.ceil(ctx.chartTextScale * config.xAxisFontSize)), true, config.detectMouseOnText, ctx, "XAXISLABEL_TEXTMOUSE", 0, leftNotUsableWidth + (availableWidth / 2), xAxisLabelPos, -1, -1);
					ctx.stroke();
					ctx.restore();
				}
			}
			// Draw Legend
			var legendMsr;
			if (nbeltLegend > 1 || (nbeltLegend == 1 && config.showSingleLegend)) {
				legendMsr = {
					dispLegend: true,
					xLegendPos: xLegendPos,
					yLegendPos: yLegendPos,
					nbLegendLines: nbLegendLines,
					nbLegendCols: nbLegendCols,
					reverseLegend: reverseLegend,
					legendBox: legendBox,
					widestLegend: widestLegend,
					highestLegend: highestLegend,
					legendWidth: msrLegend.legendWidth,
					legendHeight: msrLegend.legendHeight,
					legendBackgroundColorWidth: msrLegend.legendBackgroundColorWidth,
					legendBackgroundColorHeight: msrLegend.legendBackgroundColorHeight,
					legendBorderWidth: msrLegend.legendBorderWidth,
					legendBorderHeight: msrLegend.legendBorderHeight,
					legendFirstTextXPos: msrLegend.legendFirstTextXPos,
					legendFirstTextYPos: msrLegend.legendFirstTextYPos,
					legendBackgroundColorXPos: msrLegend.legendBackgroundColorXPos,
					legendBackgroundColorYPos: msrLegend.legendBackgroundColorYPos,
					legendBorderXPos: msrLegend.legendBorderXPos,
					legendBorderYPos: msrLegend.legendBorderYPos,
					elementMsr: msrLegend.elementMsr
				};
				if (config.legendPosY == 0 || config.legendPosY == 4 || config.legendPosX == 0 || config.legendPosX == 4) {
					drawLegend(legendMsr, data, config, ctx, typegraph, -1);
					legendMsr = {
						dispLegend: false
					};
				}
			} else {
				legendMsr = {
					dispLegend: false
				};
			}
		}
		clrx = leftNotUsableWidth;
		clrwidth = availableWidth;
		clry = topNotUsableHeight;
		clrheight = availableHeight;
		return {
			leftNotUsableWidth: leftNotUsableWidth,
			rightNotUsableWidth: rightNotUsableWidth,
			availableWidth: availableWidth,
			topNotUsableHeight: topNotUsableHeight,
			bottomNotUsableHeight: bottomNotUsableHeight,
			availableHeight: availableHeight,
			widestXLabel: widestXLabel,
			widestTXLabel: widestTXLabel,
			highestXLabel: highestXLabel,
			highestTXLabel: highestTXLabel,
			widestYLabel: widestYLabel,
			widestYLabel2: widestYLabel2,
			highestYLabel: highestYLabel,
			rotateLabels: rotateLabels,
			rotateTLabels: rotateTLabels,
			xLabelPos: xLabelPos,
			xTLabelPos: xTLabelPos,
			clrx: clrx,
			clry: clry,
			clrwidth: clrwidth,
			clrheight: clrheight,
			legendMsr: legendMsr
		};
	}
535365
def add_namespace_statistics(self, namespace, offset, data_points,
                                 byte_count):
        """"""
        query = 'UPDATE gauged_statistics ' \
            'SET data_points = data_points + %s,' \
            'byte_count = byte_count + %s WHERE namespace = %s ' \
            'AND "offset" = %s; INSERT INTO gauged_statistics ' \
            'SELECT %s, %s, %s, %s WHERE NOT EXISTS (' \
            'SELECT 1 FROM gauged_statistics WHERE namespace = %s' \
            'AND "offset" = %s)'
        self.cursor.execute(query, (data_points, byte_count, namespace,
                                    offset, namespace, offset, data_points,
                                    byte_count, namespace, offset))
1097376
void measure(Registry registry, JmxData data, List<Measurement> ms) {
    Map<String, String> tags = tagMappings.entrySet().stream().collect(Collectors.toMap(
        Map.Entry::getKey,
        e -> MappingExpr.substitute(e.getValue(), data.getStringAttrs())
    ));
    Id id = registry
        .createId(MappingExpr.substitute(nameMapping, data.getStringAttrs()))
        .withTags(tags);

    Map<String, Number> numberAttrs = new HashMap<>(data.getNumberAttrs());
    JmxData previous = previousData.put(data.getName(), data);
    if (previous != null) {
      previous.getNumberAttrs().forEach((key, value) -> numberAttrs.put("previous:" + key, value));
    }

    Double v = MappingExpr.eval(valueMapping, numberAttrs);

    if (v != null && !v.isNaN()) {
      if (counter) {
        updateCounter(registry, id, v.longValue());
      } else {
        ms.add(new Measurement(id, registry.clock().wallTime(), v));
      }
    }
  }
1290437
def register_default_dimensions(cube, slvr_cfg):
    

    import montblanc.src_types as mbs

    # Pull out the configuration options for the basics
    autocor = slvr_cfg['auto_correlations']

    ntime = 10
    na = 7
    nbands = 1
    nchan = 16
    npol = 4

    # Infer number of baselines from number of antenna,
    nbl = nr_of_baselines(na, autocor)

    if not npol == 4:
        raise ValueError("npol set to {}, but only 4 polarisations "
                         "are currently supported.")

    # Register these dimensions on this solver.
    cube.register_dimension('ntime', ntime,
        description="Timesteps")
    cube.register_dimension('na', na,
        description="Antenna")
    cube.register_dimension('nbands', nbands,
        description="Bands")
    cube.register_dimension('nchan', nchan,
        description="Channels")
    cube.register_dimension('npol', npol,
        description="Polarisations")
    cube.register_dimension('nbl', nbl,
        description="Baselines")

    # Register dependent dimensions
    cube.register_dimension('npolchan', nchan*npol,
        description='Polarised channels')
    cube.register_dimension('nvis', ntime*nbl*nchan,
        description='Visibilities')

    # Convert the source types, and their numbers
    # to their number variables and numbers
    # { 'point':10 } => { 'npsrc':10 }
    src_cfg = default_sources()
    src_nr_vars = sources_to_nr_vars(src_cfg)
    # Sum to get the total number of sources
    cube.register_dimension('nsrc', sum(src_nr_vars.itervalues()),
        description="Sources (Total)")

    # Register the individual source types
    for nr_var, nr_of_src in src_nr_vars.iteritems():
        cube.register_dimension(nr_var, nr_of_src,
            description='{} sources'.format(mbs.SOURCE_DIM_TYPES[nr_var]))
1302018
def make_measurement(name,
                     channels,
                     lumi=1.0, lumi_rel_error=0.1,
                     output_prefix='./histfactory',
                     POI=None,
                     const_params=None,
                     verbose=False):
    
    if verbose:
        llog = log['make_measurement']
        llog.info("creating measurement {0}".format(name))

    if not isinstance(channels, (list, tuple)):
        channels = [channels]

    # Create the measurement
    meas = Measurement('measurement_{0}'.format(name), '')
    meas.SetOutputFilePrefix(output_prefix)
    if POI is not None:
        if isinstance(POI, string_types):
            if verbose:
                llog.info("setting POI {0}".format(POI))
            meas.SetPOI(POI)
        else:
            if verbose:
                llog.info("adding POIs {0}".format(', '.join(POI)))
            for p in POI:
                meas.AddPOI(p)

    if verbose:
        llog.info("setting lumi={0:f} +/- {1:f}".format(lumi, lumi_rel_error))
    meas.lumi = lumi
    meas.lumi_rel_error = lumi_rel_error

    for channel in channels:
        if verbose:
            llog.info("adding channel {0}".format(channel.GetName()))
        meas.AddChannel(channel)

    if const_params is not None:
        if verbose:
            llog.info("adding constant parameters {0}".format(
                ', '.join(const_params)))
        for param in const_params:
            meas.AddConstantParam(param)

    return meas
1244247
def submit_statsd_measurements(self):
        """"""
        for key, value in self.measurement.counters.items():
            self.statsd.incr(key, value)
        for key, values in self.measurement.durations.items():
            for value in values:
                self.statsd.add_timing(key, value)
        for key, value in self.measurement.values.items():
            self.statsd.set_gauge(key, value)
        for key, value in self.measurement.tags.items():
            if isinstance(value, bool):
                if value:
                    self.statsd.incr(key)
            elif isinstance(value, str):
                if value:
                    self.statsd.incr('{}.{}'.format(key, value))
            elif isinstance(value, int):
                self.statsd.incr(key, value)
            else:
                LOGGER.warning('The %s value type of %s is unsupported',
                               key, type(value))
120905
public void registerMetrics() {
        if (metricsAreRegistered) {
            return;
        }
        getMetricRegistry().register("jvm.attribute", new JvmAttributeGaugeSet());
        getMetricRegistry().register("jvm.buffers", new BufferPoolMetricSet(ManagementFactory
                                                                               .getPlatformMBeanServer()));
        getMetricRegistry().register("jvm.classloader", new ClassLoadingGaugeSet());
        getMetricRegistry().register("jvm.filedescriptor", new FileDescriptorRatioGauge());
        getMetricRegistry().register("jvm.gc", new GarbageCollectorMetricSet());
        getMetricRegistry().register("jvm.memory", new MemoryUsageGaugeSet());
        getMetricRegistry().register("jvm.threads", new ThreadStatesGaugeSet());

        JmxReporter.forRegistry(metricRegistry).build().start();
        metricsAreRegistered = true;
    }
1065429
Optional<String> writeMeter(Meter meter) {
        Iterable<Measurement> measurements = meter.measure();
        List<String> names = new ArrayList<>();
        // Snapshot values should be used throughout this method as there are chances for values to be changed in-between.
        List<Double> values = new ArrayList<>();
        for (Measurement measurement : measurements) {
            double value = measurement.getValue();
            if (!Double.isFinite(value)) {
                continue;
            }
            names.add(measurement.getStatistic().getTagValueRepresentation());
            values.add(value);
        }
        if (names.isEmpty()) {
            return Optional.empty();
        }
        return Optional.of(writeDocument(meter, builder -> {
            for (int i = 0; i < names.size(); i++) {
                builder.append(",\"").append(names.get(i)).append("\":\"").append(values.get(i)).append("\"");
            }
        }));
    }
411533
def add(self, key, metric, **dims):
        
        return super(MetricsRegistry, self).add(
            self.metadata.register(key, **dims), metric)
1092496
def gauge(self, key, gauge=None, default=float("nan"), **dims):
        """"""
        return super(RegexRegistry, self).gauge(
            self._get_key(key), gauge=gauge, default=default, **dims)
1049479
protected void configureMetrics() {
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS, ESMetrics.class.getName());
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.type", "jest");
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.protocol", "${apiman.es.protocol}");
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.host", "${apiman.es.host}");
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.port", "${apiman.es.port}");
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.username", "${apiman.es.username}");
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.password", "${apiman.es.password}");
        setConfigProperty(GatewayConfigProperties.METRICS_CLASS + ".client.index", "apiman_metrics");
    }
1261269
Counter counter(Meter.Id id) {
        return registerMeterIfNecessary(Counter.class, id, this::newCounter, NoopCounter::new);
    }
757416
public void addMeasurement(long durationInMillis) {
    count.addAndGet(1);
    timerSum.addAndGet(durationInMillis);
    timerSumOfSquares.addAndGet(durationInMillis * durationInMillis);
  }