Retorna os recursos de javascript
@param chart Chart
@return lista de com os javascripts dos gráficos
428116
public static List<String> retriveJavaScriptResources(Chart<?> chart) {
        List<String> resources = new ArrayList<String>();

        Class<?> clazz = chart.getClass();
        if (clazz.isAnnotationPresent(JqPlotPlugin.class)) {
            JqPlotResources[] jqPlotResourceses = clazz.getAnnotation(
                    JqPlotPlugin.class).values();
            for (JqPlotResources jqPlotResources : jqPlotResourceses) {
                resources.add(jqPlotResources.getResource());
            }
        }

        //can it/should we make this more generic?
        if(chart.getChartConfiguration().getHighlighter() != null) {
            resources.add(JqPlotResources.Highlighter.getResource());
        }

        return resources;
    }
579103
function drawBoxes() {
            boxes = svg.select('.chart-group').selectAll('.box').data(data);

            boxes.enter()
              .append('rect')
                .classed('box', true)
                .attr('width', boxSize)
                .attr('height', boxSize)
                .attr('x', ({hour}) => hour * boxSize)
                .attr('y', ({day}) => day * boxSize)
                .style('opacity', boxInitialOpacity)
                .style('fill', boxInitialColor)
                .style('stroke', boxBorderColor)
                .style('stroke-width', boxBorderSize)
                .transition()
                    .duration(animationDuration)
                    .style('fill', ({value}) => colorScale(value))
                    .style('opacity', boxFinalOpacity);

            boxes.exit().remove();
        }
1345281
function () {
		var options = this.options,
			chart = this.chart,
			group = this.group,
			title = this.title,
			shape = this.shape,
			linkedTo = this.linkedObject,
			xAxis = chart.xAxis[options.xAxis],
			yAxis = chart.yAxis[options.yAxis],
			width = options.width,
			height = options.height,
			anchorY = ALIGN_FACTOR[options.anchorY],
			anchorX = ALIGN_FACTOR[options.anchorX],
			resetBBox = false,
			shapeParams,
			linkType,
			series,
			param,
			bbox,
			x,
			y;

		if (linkedTo) {
			linkType = (linkedTo instanceof Highcharts.Point) ? 'point' :
						(linkedTo instanceof Highcharts.Series) ? 'series' : null;

			if (linkType === 'point') {
				options.xValue = linkedTo.x;
				options.yValue = linkedTo.y;
				series = linkedTo.series;
			} else if (linkType === 'series') {
				series = linkedTo;
			}

			if (group.visibility !== series.group.visibility) {
				group.attr({
					visibility: series.group.visibility
				});
			}
		}


		// Based on given options find annotation pixel position
		x = (defined(options.xValue) ? xAxis.toPixels(options.xValue + xAxis.minPointOffset) - xAxis.minPixelPadding : options.x);
		y = defined(options.yValue) ? yAxis.toPixels(options.yValue) : options.y;

		if (isNaN(x) || isNaN(y) || !isNumber(x) || !isNumber(y)) {
			return;
		}


		if (title) {
			title.attr(options.title);
			title.css(options.title.style);
			resetBBox = true;
		}

		if (shape) {
			shapeParams = extend({}, options.shape.params);

			if (options.units === 'values') {
				for (param in shapeParams) {
					if (inArray(param, ['width', 'x']) > -1) {
						shapeParams[param] = xAxis.translate(shapeParams[param]);
					} else if (inArray(param, ['height', 'y']) > -1) {
						shapeParams[param] = yAxis.translate(shapeParams[param]);
					}
				}

				if (shapeParams.width) {
					shapeParams.width -= xAxis.toPixels(0) - xAxis.left;
				}

				if (shapeParams.x) {
					shapeParams.x += xAxis.minPixelPadding;
				}

				if (options.shape.type === 'path') {
					translatePath(shapeParams.d, xAxis, yAxis, x, y);
				}
			}

			// move the center of the circle to shape x/y
			if (options.shape.type === 'circle') {
				shapeParams.x += shapeParams.r;
				shapeParams.y += shapeParams.r;
			}

			resetBBox = true;
			shape.attr(shapeParams);
		}

		group.bBox = null;

		// If annotation width or height is not defined in options use bounding box size
		if (!isNumber(width)) {
			bbox = group.getBBox();
			width = bbox.width;
		}

		if (!isNumber(height)) {
			// get bbox only if it wasn't set before
			if (!bbox) {
				bbox = group.getBBox();
			}

			height = bbox.height;
		}

		// Calculate anchor point
		if (!isNumber(anchorX)) {
			anchorX = ALIGN_FACTOR.center;
		}

		if (!isNumber(anchorY)) {
			anchorY = ALIGN_FACTOR.center;
		}

		// Translate group according to its dimension and anchor point
		x = x - width * anchorX;
		y = y - height * anchorY;

		if (chart.animation && defined(group.translateX) && defined(group.translateY)) {
			group.animate({
				translateX: x,
				translateY: y
			});
		} else {
			group.translate(x, y);
		}
	}
817733
function (chart, options) {
		var shapeType = options.shape && options.shape.type;

		this.chart = chart;
		this.options = merge({}, defaultOptions(shapeType), options);
	}
671258
@Override protected void layoutPlotChildren() {
        super.layoutPlotChildren();

        double height = getLayoutBounds().getHeight();
        getData().forEach(series -> {
            final Path[] paths = getPaths(series);
            if (null == paths) { return; }
            if (isSmoothed()) { smooth(paths[1].getElements(), paths[0].getElements(), height); }
            paths[0].setVisible(ChartType.AREA == getChartType());
            paths[0].setManaged(ChartType.AREA == getChartType());
        });
    }
465235
function Chart(options) {

	this.__proto__ = new Control();

	this.init = function(options) {
		this.type = options.type = 'Chart';
		this.parent = options.parent;
		this.defaults = {
			x:48, y:48, w:288, h:144,
			text: '',
			script: undefined,
			onload: undefined,
			fill: this.parent.fill,
			fill_highlight: this.parent.lighter(this.parent.stroke), 	// ??
			stroke: this.parent.stroke,
			'stroke-width': this.parent.control_stroke,
			fontsize: this.parent.fontsize,
			repeat: 0,
			running: 0,
			corner: this.parent.button_corner,
			subtype: undefined,
			r: this.w/2,		//?? chart??
			autorun: undefined,
			interpolate: 'step-after',	// vs. 'basis'
			ticks: 5,
			target: undefined,
			refresh: 0,
			ymax: undefined,
			ymin: undefined
		};
		//console.log('Chart defaults:', this.defaults);
		this.setoptions(options);
		this.render();		// render D3 chart
		var self = this;
		if (this.refresh) setInterval(function() { self.redraw.call(self); }, this.refresh);
		return this;
	};

	this.attr = function(attrs) {
		this.__proto__.attr.call(this);
		this.svg.attr(attrs);
	};

	this.render = function() {

		var margin = {top: 0, right: 0, bottom: 0, left: 0};
		var width = this.w - margin.left - margin.right;
		var height = this.h - margin.top - margin.bottom;

		var x = d3.scale.linear().range([0, width]);
		var y = d3.scale.linear().range([height, 0]);
		var color = d3.scale.category10();
		var xAxis = d3.svg.axis().scale(x).ticks(this.ticks).orient('bottom');
		var yAxis = d3.svg.axis().scale(y).ticks(this.ticks).orient('left');

		var line = d3.svg.line().interpolate(this.interpolate)
				.x(function(d) { return x(d.time); })
				.y(function(d) { return y(d.value); });

		var self = this;
		this.outerrect = this.parent.paper.rect(this.x, this.y, this.w, this.h, this.parent.button_corner)
			.attr({fill: this.fill, stroke: this.stroke, 'stroke-width':this.parent.control_stroke});
		this.elts.push(this.outerrect);

		this.label = this.parent.paper.text(this.x + (this.w/2), this.y + this.h + this.fontsize*2, this.text)
			.attr({fill:this.stroke, stroke:this.stroke, 'font-size': this.fontsize});
		this.textelts.push(this.label);

		this.sethandlers();

		this.svg = d3.select(this.parent.paper.canvas).append('g')
				.attr('width', width + margin.left + margin.right)
				.attr('height', height + margin.top + margin.bottom)
			.append('g')
				//.attr('transform', 'translate(' + (this.x+margin.left) + ',' + (this.y+margin.top) + ')');
				.attr('transform', 'translate(' + (this.x) + ',' + (this.y) + ')');

		d3.json('/d3/' + this.target, function(data) {

			// console.log('d3:', typeof data, data);

			color.domain(d3.keys(data[0]).filter(function(key) { return key !== 'time'; }));
			var values = color.domain().map(function(name) {
				return {
					name: name,
					values: data.map(function(d) {
						return {time: d.time, value: +d[name]};
					})
				};
			});

			x.domain(d3.extent(data, function(d) { return d.time; }));
			if (self.ymax !== undefined) y.domain([self.ymin, self.ymax]);
			else y.domain([
				d3.min(values, function(c) { return d3.min(c.values, function(v) { return v.value; }); }),
				d3.max(values, function(c) { return d3.max(c.values, function(v) { return v.value; }); })
			]);

			self.svgx = self.svg.append('g')
					.attr('class', 'x axis')
					.attr('transform', 'translate(0,' + height + ')')
					.attr('stroke', self.stroke)
					.attr('fill', self.stroke)
					.call(xAxis);

			self.svgy = self.svg.append('g')
					.attr('class', 'y axis')
					.attr('stroke', self.stroke)
					.attr('fill', self.stroke)
					.call(yAxis);
/* y axis label
				.append('text')
					.attr('transform', 'rotate(-90)')
					.attr('y', 6)
					.attr('dy', '.71em')
					.style('text-anchor', 'end')
					.attr('stroke', self.stroke)
					.attr('fill', self.stroke)
					.text(' ');
*/
			self.svgvalue = self.svg.selectAll('.value')
					.data(values)
				.enter().append('g')
					.attr('class', 'value');

			self.svgvalue.append('path')
					.attr('class', 'line')
					.attr('d', function(d) { return line(d.values); })
					.style('stroke', function(d) { return color(d.name); })
					.style('fill', self.fill)
					.style('stroke-width', self['stroke-width']);

			self.svgvalue.append('text')
					.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
					.attr('transform', function(d) { return 'translate(' + x(d.value.time) + ',' + y(d.value.value) + ')'; })
					.attr('x', 3)
					.attr('dy', '.35em')
					.attr('stroke', self.stroke)
					.attr('fill', self.stroke)
					.text(function(d) { return d.name; });
		});
	};

	this.redraw = function() {
		if (this.svg) {
			var doomed_svg = this.svg;
			delete this.svg;
			this.render();
			doomed_svg.remove();
		}
	};

	this.remove = function() {
		this.__proto__.remove.call(this);
		this.svg.remove();
	};

	this.move = function(x, y) {
		this.x = x;
		this.y = y;
		this.outerrect.attr({x:this.x, y:this.y, width:this.w, height:this.h});
		this.label.attr({x:this.x + this.w/2, y:this.y + this.h + this.fontsize*2});

		var translation = ['translate(', this.x, ',', this.y,')'].join('');
		//console.log('translation:', translation)
		this.svg.attr('transform', translation);
	};

	this.handleClick = function(e) {
		if (this.repeat) {
			if (this.running) {
				this.running = false;
				clearInterval(this.intervalid);
				delete this.intervalid;
			} else {
				this.running = true;
				this.exec();
			}
		}
		else this.redraw();

		if (e) {
			e.preventDefault();
			e.stopPropagation();
		}
		return false;
	};

	this.setValue = function(value) {
		this.value = value;
		//this.label.attr({text: this.text + ': ' + this.value});
		var update = {id: this.id, value: this.value};
		this.fire('update', update);
	};

	return this.init(options || {});
}
862766
protected function chartStyles(): array
    {
        return [
            /* I18N: layout option for the fan chart */
            self::STYLE_HALF_CIRCLE          => I18N::translate('half circle'),
            /* I18N: layout option for the fan chart */
            self::STYLE_THREE_QUARTER_CIRCLE => I18N::translate('three-quarter circle'),
            /* I18N: layout option for the fan chart */
            self::STYLE_FULL_CIRCLE          => I18N::translate('full circle'),
        ];
    }
1332854
function getWeeksOnChartFromChartItem(chartItem) {
	var weeksOnChart;
	try {
		if (chartItem.children[3].children.length > 5) {
			weeksOnChart = chartItem.children[3].children[5].children[7].children[3].children[0].data;
		} else {
			weeksOnChart = chartItem.children[3].children[3].children[5].children[3].children[0].data;
		}
	} catch (e) {
		weeksOnChart = '1';
	}
	return parseInt(weeksOnChart);
}
19559
function charToVal(char) {
  if (typeof char != 'string' || char.length != 1) throw new Error('in charToVal, invalid argument');

  if (consts.caseSensitive) return consts.alphabet.indexOf(char);

  let code = char.charCodeAt(0);
  let val = -1;
  for (let i = 0; i < consts.alphabet.length; i++) {
    let okCode = consts.alphabet[i].charCodeAt(0);
    if (code == okCode || code == changeCase(okCode)) {
      val = i;
      break;
    }
  }
  return val;
}
20309
function () {
            var chart = charts[hoverChartIndex];
            if (chart) {
                chart.pointer.reset();
                chart.pointer.chartPosition = null; // also reset the chart position, used in #149 fix
            }
        }
1260248
function(chartInstance) {
			var index = helpers.findNextWhere(this.animations, function(animationWrapper) {
				return animationWrapper.chartInstance === chartInstance;
			});

			if (index)
			{
				this.animations.splice(index, 1);
			}
		}
1097638
public String getJsonData(Chart chart)
            throws ReportRunnerException, NoDataFoundException, TimeoutException {
        return getJsonData(chart, null, null);
	}
487406
function (itemOptions) {
		var plotOptions = this.chart.options.plotOptions,
			options = merge(
				plotOptions[this.type],
				plotOptions.series,
				itemOptions
			);

		return options;

	}
32991
private List<Chart> getChartFromParams(final PageParameters params) {
        String chartString;
        List<Chart> config = new ArrayList<>();

        //If the showcase is started without any parameters
        //set the parameters to lineBasic and give us a line Chart
        final String chartComponentID = "chart";
        if(params.getAllNamed().isEmpty()){
            PageParameters temp = new PageParameters();
            temp.add("chart", "lineBasic");
            setResponsePage(HomepageChartJs.class, temp);
            config.add(new Chart(chartComponentID, new LineChartBasicConfiguration()));
            return config;
        }

        chartString = params.getAllNamed().get(0).getValue();
        if(chartString == null) {
    		config.add(new Chart(chartComponentID, new LineChartBasicConfiguration()));
    		return config;
    	}

        switch(chartString) {

            case "barVertical":
                config.add(new Chart(chartComponentID, new BarChartVerticalConfiguration()));
                break;

            case "barHorizontal":
                config.add(new Chart(chartComponentID, new BarChartHorizontalConfiguration()));
                break;

            case "barMultiAxis":
                config.add(new Chart(chartComponentID, new BarChartMultiAxisConfiguration()));
                break;

            case "barStacked":
                config.add(new Chart(chartComponentID, new BarChartStackedConfiguration()));
                break;

            case "barStackedGroup":
                config.add(new Chart(chartComponentID, new BarChartStackedGroupConfiguration()));
                break;

            case "lineBasic":
                config.add(new Chart(chartComponentID, new LineChartBasicConfiguration()));
                break;

            case "lineMultiAxis":
                config.add(new Chart(chartComponentID, new LineChartMultiAxisConfiguration()));
                break;

            case "lineStepped":
                config.add(new Chart(chartComponentID, new LineChartSteppedBeforeConfiguration()));
                config.add(new Chart(chartComponentID, new LineChartSteppedAfterConfiguration()));
                break;

            case "lineInterpolated":
                config.add(new Chart(chartComponentID, new LineChartInterpolatedConfiguration()));
                break;

            case "lineStyles":
                config.add(new Chart(chartComponentID, new LineStylesConfiguration()));
                break;

            case "pointStyles":
                config.add(new Chart(chartComponentID, new PointStylesConfiguration()));
                break;

            case "pointSizes":
                config.add(new Chart(chartComponentID, new LineChartWithDifferentPointSizesConfiguration()));
                break;

            case "areaLineBoundaries":
                config.add(new Chart(chartComponentID, new AreaLineBoundariesChartStartConfiguration()));
                config.add(new Chart(chartComponentID, new AreaLineBoundariesChartEndConfiguration()));
                config.add(new Chart(chartComponentID, new AreaLineBoundariesChartOriginConfiguration()));
                config.add(new Chart(chartComponentID, new AreaLineBoundariesChartFalseConfiguration()));
                break;

            case "lineDataset":
                config.add(new Chart(chartComponentID, new LineChartAreaDatasetConfiguration()));
                break;

            case "lineStacked":
                config.add(new Chart(chartComponentID, new LineChartStackedConfiguration()));
                break;

            case "radar":
                config.add(new Chart(chartComponentID, new RadarChartConfiguration()));
                break;

            case "scatter":
                config.add(new Chart(chartComponentID, new ScatterChartConfiguration()));
                break;

            case "scatterMultiAxis":
                config.add(new Chart(chartComponentID, new ScatterChartMultiAxisConfiguration()));
                break;

            case "doughnut":
                config.add(new Chart(chartComponentID, new DoughnutChartConfiguration()));
                break;

            case "pie":
                config.add(new Chart(chartComponentID, new PieChartConfiguration()));
                break;

            case "polarArea":
                config.add(new Chart(chartComponentID, new PolarAreaChartConfiguration()));
                break;

            case "radar2":
                config.add(new Chart(chartComponentID, new OtherRadarChartConfiguration()));
                break;

            case "comboBarLine":
                config.add(new Chart(chartComponentID, new ComboBarLineChartConfiguration()));
                break;

            case "stepSize":
                config.add(new Chart(chartComponentID, new LinearStepSizeConfiguration()));
                break;

            case "minMax":
                config.add(new Chart(chartComponentID, new MinMaxConfiguration()));
                config.add(new Chart(chartComponentID, new MinMaxSuggestedConfiguration()));
                break;

            case "lineLogarithmic":
                config.add(new Chart(chartComponentID, new LogarithmicLineChartConfiguration()));
                break;

            case "scatterLogarithmic":
                config.add(new Chart(chartComponentID, new LogarithmicScatterChartConfiguration()));
                break;

            case "timeLine":
                config.add(new Chart(chartComponentID, new TimeLineConfiguration()));
                break;

            case "timePoint":
                config.add(new Chart(chartComponentID, new TimePointConfiguration()));
                break;

            case "timeSeries":
                config.add(new Chart(chartComponentID, new TimeSeriesConfiguration()));
                break;

            case "timeCombo":
                config.add(new Chart(chartComponentID, new TimeComboConfigurationWicket8()));
                break;

            case "gridLines":
                config.add(new Chart(chartComponentID, new GridLinesBasicConfiguration()));
                config.add(new Chart(chartComponentID, new GridLinesDisplayFalseConfiguration()));
                config.add(new Chart(chartComponentID, new GridLinesDisplayFalseNoBorderConfiguration()));
                config.add(new Chart(chartComponentID, new GridLinesChartAreaConfiguration()));
                config.add(new Chart(chartComponentID, new GridLinesTicksConfiguration()));
                config.add(new Chart(chartComponentID, new GridLineStylesConfiguration()));
                break;

            case "multiLineLabels":
                config.add(new Chart(chartComponentID, new MultilineLabelsConfiguration()));
                break;

            case "filteringLabels":
                config.add(new Chart(chartComponentID, new FilteringLabelsConfiguration()));
                break;

            case "nonNumeric":
                config.add(new Chart(chartComponentID, new NonNumericConfiguration()));
                break;

            case "legendPosition":
                config.add(new Chart(chartComponentID, new LegendPositionTopConfiguration()));
                config.add(new Chart(chartComponentID, new LegendPositionRightConfiguration()));
                config.add(new Chart(chartComponentID, new LegendPositionBottomConfiguration()));
                config.add(new Chart(chartComponentID, new LegendPositionLeftConfiguration()));
                break;

            case "legendPointStyle":
                config.add(new Chart(chartComponentID, new LegendPointStyleConfiguration()));
                break;

            case "tooltip":
                config.add(new Chart(chartComponentID, new TooltipBorderConfiguration()));
                config.add(new Chart(chartComponentID, new TooltipCallbacksConfiguration()));
                config.add(new Chart(chartComponentID, new TooltipAverageConfiguration()));
                config.add(new Chart(chartComponentID, new TooltipNearestConfiguration()));
                break;

            case "tooltipHtml":
                config.add(new Chart(chartComponentID, new TooltipHtmlLineConfiguration()));
                config.add(new Chart(chartComponentID, new TooltipHtmlPieConfigurationWicket8()));
                config.add(new Chart(chartComponentID, new TooltipHtmlPointsConfigurationWicket8()));
                break;

            case "bubble":
                config.add(new Chart(chartComponentID, new BubbleChartConfiguration()));
                break;

            case "lineProgressBar":
                config.add(new Chart(chartComponentID, new LineChartProgressBarConfigurationWicket8()));
                break;

            case "dataLabelling":
                config.add(new Chart(chartComponentID, new DataLabellingChartConfiguration()));
                break;

            case "tooltipInteractions":
                config.add(new Chart(chartComponentID, new DatasetIntersectFalseConfiguration()));
                config.add(new Chart(chartComponentID, new DatasetIntersectTrueConfiguration()));
                config.add(new Chart(chartComponentID, new IndexIntersectFalseConfiguration()));
                config.add(new Chart(chartComponentID, new IndexIntersectTrueConfiguration()));
                config.add(new Chart(chartComponentID, new NearestIntersectFalseConfiguration()));
                config.add(new Chart(chartComponentID, new NearestIntersectTrueConfiguration()));
                config.add(new Chart(chartComponentID, new PointIntersectFalseConfiguration()));
                config.add(new Chart(chartComponentID, new PointIntersectTrueConfiguration()));
                config.add(new Chart(chartComponentID, new xIntersectFalseConfiguration()));
                config.add(new Chart(chartComponentID, new xIntersectTrueConfiguration()));
                config.add(new Chart(chartComponentID, new yIntersectFalseConfiguration()));
                config.add(new Chart(chartComponentID, new yIntersectTrueConfiguration()));
                break;

            default:
                config.add(new Chart(chartComponentID, new LineChartBasicConfiguration()));
                break;
        }
        return config;
    }
711558
function(chartArea) {
			var me = this;
			var options = me.options;
			if (!options.display) {
				return;
			}

			var context = me.ctx;
			var globalDefaults = Chart.defaults.global;
			var optionTicks = options.ticks;
			var gridLines = options.gridLines;
			var scaleLabel = options.scaleLabel;

			var isRotated = me.labelRotation !== 0;
			var skipRatio;
			var useAutoskipper = optionTicks.autoSkip;
			var isHorizontal = me.isHorizontal();

			// figure out the maximum number of gridlines to show
			var maxTicks;
			if (optionTicks.maxTicksLimit) {
				maxTicks = optionTicks.maxTicksLimit;
			}

			var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor);
			var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize);
			var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle);
			var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily);
			var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
			var tl = gridLines.tickMarkLength;
			var borderDash = helpers.getValueOrDefault(gridLines.borderDash, globalDefaults.borderDash);
			var borderDashOffset = helpers.getValueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset);

			var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor);
			var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize);
			var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle);
			var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily);
			var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);

			var labelRotationRadians = helpers.toRadians(me.labelRotation);
			var cosRotation = Math.cos(labelRotationRadians);
			var longestRotatedLabel = me.longestLabelWidth * cosRotation;

			// Make sure we draw text in the correct color and font
			context.fillStyle = tickFontColor;

			var itemsToDraw = [];

			if (isHorizontal) {
				skipRatio = false;

				// Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation
				// See #2584
				if (isRotated) {
					longestRotatedLabel /= 2;
				}

				if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {
					skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));
				}

				// if they defined a max number of optionTicks,
				// increase skipRatio until that number is met
				if (maxTicks && me.ticks.length > maxTicks) {
					while (!skipRatio || me.ticks.length / (skipRatio || 1) > maxTicks) {
						if (!skipRatio) {
							skipRatio = 1;
						}
						skipRatio += 1;
					}
				}

				if (!useAutoskipper) {
					skipRatio = false;
				}
			}


			var xTickStart = options.position === 'right' ? me.left : me.right - tl;
			var xTickEnd = options.position === 'right' ? me.left + tl : me.right;
			var yTickStart = options.position === 'bottom' ? me.top : me.bottom - tl;
			var yTickEnd = options.position === 'bottom' ? me.top + tl : me.bottom;

			helpers.each(me.ticks, function(label, index) {
				// If the callback returned a null or undefined value, do not draw this line
				if (label === undefined || label === null) {
					return;
				}

				var isLastTick = me.ticks.length === index + 1;

				// Since we always show the last tick,we need may need to hide the last shown one before
				var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio >= me.ticks.length);
				if (shouldSkip && !isLastTick || (label === undefined || label === null)) {
					return;
				}

				var lineWidth, lineColor;
				if (index === (typeof me.zeroLineIndex !== 'undefined' ? me.zeroLineIndex : 0)) {
					// Draw the first index specially
					lineWidth = gridLines.zeroLineWidth;
					lineColor = gridLines.zeroLineColor;
				} else {
					lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, index);
					lineColor = helpers.getValueAtIndexOrDefault(gridLines.color, index);
				}

				// Common properties
				var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY;
				var textAlign = 'middle';
				var textBaseline = 'middle';

				if (isHorizontal) {
					if (!isRotated) {
						textBaseline = options.position === 'top' ? 'bottom' : 'top';
					}

					textAlign = isRotated ? 'right' : 'center';

					var xLineValue = me.getPixelForTick(index) + helpers.aliasPixel(lineWidth); // xvalues for grid lines
					labelX = me.getPixelForTick(index, gridLines.offsetGridLines) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option)
					labelY = (isRotated) ? me.top + 12 : options.position === 'top' ? me.bottom - tl : me.top + tl;

					tx1 = tx2 = x1 = x2 = xLineValue;
					ty1 = yTickStart;
					ty2 = yTickEnd;
					y1 = chartArea.top;
					y2 = chartArea.bottom;
				} else {
					if (options.position === 'left') {
						if (optionTicks.mirror) {
							labelX = me.right + optionTicks.padding;
							textAlign = 'left';
						} else {
							labelX = me.right - optionTicks.padding;
							textAlign = 'right';
						}
					// right side
					} else if (optionTicks.mirror) {
						labelX = me.left - optionTicks.padding;
						textAlign = 'right';
					} else {
						labelX = me.left + optionTicks.padding;
						textAlign = 'left';
					}

					var yLineValue = me.getPixelForTick(index); // xvalues for grid lines
					yLineValue += helpers.aliasPixel(lineWidth);
					labelY = me.getPixelForTick(index, gridLines.offsetGridLines);

					tx1 = xTickStart;
					tx2 = xTickEnd;
					x1 = chartArea.left;
					x2 = chartArea.right;
					ty1 = ty2 = y1 = y2 = yLineValue;
				}

				itemsToDraw.push({
					tx1: tx1,
					ty1: ty1,
					tx2: tx2,
					ty2: ty2,
					x1: x1,
					y1: y1,
					x2: x2,
					y2: y2,
					labelX: labelX,
					labelY: labelY,
					glWidth: lineWidth,
					glColor: lineColor,
					glBorderDash: borderDash,
					glBorderDashOffset: borderDashOffset,
					rotation: -1 * labelRotationRadians,
					label: label,
					textBaseline: textBaseline,
					textAlign: textAlign
				});
			});

			// Draw all of the tick labels, tick marks, and grid lines at the correct places
			helpers.each(itemsToDraw, function(itemToDraw) {
				if (gridLines.display) {
					context.save();
					context.lineWidth = itemToDraw.glWidth;
					context.strokeStyle = itemToDraw.glColor;
					if (context.setLineDash) {
						context.setLineDash(itemToDraw.glBorderDash);
						context.lineDashOffset = itemToDraw.glBorderDashOffset;
					}

					context.beginPath();

					if (gridLines.drawTicks) {
						context.moveTo(itemToDraw.tx1, itemToDraw.ty1);
						context.lineTo(itemToDraw.tx2, itemToDraw.ty2);
					}

					if (gridLines.drawOnChartArea) {
						context.moveTo(itemToDraw.x1, itemToDraw.y1);
						context.lineTo(itemToDraw.x2, itemToDraw.y2);
					}

					context.stroke();
					context.restore();
				}

				if (optionTicks.display) {
					context.save();
					context.translate(itemToDraw.labelX, itemToDraw.labelY);
					context.rotate(itemToDraw.rotation);
					context.font = tickLabelFont;
					context.textBaseline = itemToDraw.textBaseline;
					context.textAlign = itemToDraw.textAlign;

					var label = itemToDraw.label;
					if (helpers.isArray(label)) {
						for (var i = 0, y = -(label.length - 1)*tickFontSize*0.75; i < label.length; ++i) {
							// We just make sure the multiline element is a string here..
							context.fillText('' + label[i], 0, y);
							// apply same lineSpacing as calculated @ L#320
							y += (tickFontSize * 1.5);
						}
					} else {
						context.fillText(label, 0, 0);
					}
					context.restore();
				}
			});

			if (scaleLabel.display) {
				// Draw the scale label
				var scaleLabelX;
				var scaleLabelY;
				var rotation = 0;

				if (isHorizontal) {
					scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width
					scaleLabelY = options.position === 'bottom' ? me.bottom - (scaleLabelFontSize / 2) : me.top + (scaleLabelFontSize / 2);
				} else {
					var isLeft = options.position === 'left';
					scaleLabelX = isLeft ? me.left + (scaleLabelFontSize / 2) : me.right - (scaleLabelFontSize / 2);
					scaleLabelY = me.top + ((me.bottom - me.top) / 2);
					rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;
				}

				context.save();
				context.translate(scaleLabelX, scaleLabelY);
				context.rotate(rotation);
				context.textAlign = 'center';
				context.textBaseline = 'middle';
				context.fillStyle = scaleLabelFontColor; // render in correct colour
				context.font = scaleLabelFont;
				context.fillText(scaleLabel.labelString, 0, 0);
				context.restore();
			}

			if (gridLines.drawBorder) {
				// Draw the line at the edge of the axis
				context.lineWidth = helpers.getValueAtIndexOrDefault(gridLines.lineWidth, 0);
				context.strokeStyle = helpers.getValueAtIndexOrDefault(gridLines.color, 0);
				var x1 = me.left,
					x2 = me.right,
					y1 = me.top,
					y2 = me.bottom;

				var aliasPixel = helpers.aliasPixel(context.lineWidth);
				if (isHorizontal) {
					y1 = y2 = options.position === 'top' ? me.bottom : me.top;
					y1 += aliasPixel;
					y2 += aliasPixel;
				} else {
					x1 = x2 = options.position === 'left' ? me.right : me.left;
					x1 += aliasPixel;
					x2 += aliasPixel;
				}

				context.beginPath();
				context.moveTo(x1, y1);
				context.lineTo(x2, y2);
				context.stroke();
			}
		}
151735
function drawChart(chart) {
	var streaming = chart.streaming;
	var frameRate = chart.options.plugins.streaming.frameRate;
	var frameDuration = 1000 / (Math.max(frameRate, 0) || 30);
	var next = streaming.lastDrawn + frameDuration || 0;
	var now = Date.now();
	var lastMouseEvent = streaming.lastMouseEvent;

	if (next <= now) {
		// Draw only when animation is inactive
		if (!chart.animating && !chart.tooltip._start) {
			chart.draw();
		}
		if (lastMouseEvent) {
			chart.eventHandler(lastMouseEvent);
		}
		streaming.lastDrawn = (next + frameDuration > now) ? next : now;
	}
}
643365
public function readChartLegend($chartIndex)
    {
        //check whether workshett name is set or not
        if ($this->worksheetName == '')
            throw new Exception('Worksheet name not specified');
        $strURI = Product::$baseProductUri . '/cells/' . $this->getFileName() . '/worksheets/' . $this->worksheetName . '/charts/' . $chartIndex . '/legend';
        $signedURI = Utils::sign($strURI);
        $responseStream = Utils::processCommand($signedURI, 'GET', 'json', '');
        $json = json_decode($responseStream);
        return $json->Legend;
    }