(function () { var D = Flotr.DOM, _ = Flotr._; Flotr.addPlugin('legend', { options: { show: true, // => setting to true will show the legend, hide otherwise noColumns: 1, // => number of colums in legend table // @todo: doesn't work for HtmlText = false labelFormatter: function(v){return v;}, // => fn: string -> string labelBoxBorderColor: '#CCCCCC', // => border color for the little label boxes labelBoxWidth: 14, labelBoxHeight: 10, labelBoxMargin: 5, container: null, // => container (as jQuery object) to put legend in, null means default on top of graph position: 'nw', // => position of default legend container within plot margin: 5, // => distance from grid edge to default legend container within plot backgroundColor: '#F0F0F0', // => Legend background color. backgroundOpacity: 0.85// => set to 0 to avoid background, set to 1 for a solid background }, callbacks: { 'flotr:afterinit': function() { this.legend.insertLegend(); }, 'flotr:destroy': function() { var markup = this.legend.markup; if (markup) { this.legend.markup = null; D.remove(markup); } } }, /** * Adds a legend div to the canvas container or draws it on the canvas. */ insertLegend: function(){ if(!this.options.legend.show) return; var series = this.series, plotOffset = this.plotOffset, options = this.options, legend = options.legend, fragments = [], rowStarted = false, ctx = this.ctx, itemCount = _.filter(series, function(s) {return (s.label && !s.hide);}).length, p = legend.position, m = legend.margin, opacity = legend.backgroundOpacity, i, label, color; if (itemCount) { var lbw = legend.labelBoxWidth, lbh = legend.labelBoxHeight, lbm = legend.labelBoxMargin, offsetX = plotOffset.left + m, offsetY = plotOffset.top + m, labelMaxWidth = 0, style = { size: options.fontSize*1.1, color: options.grid.color }; // We calculate the labels' max width for(i = series.length - 1; i > -1; --i){ if(!series[i].label || series[i].hide) continue; label = legend.labelFormatter(series[i].label); labelMaxWidth = Math.max(labelMaxWidth, this._text.measureText(label, style).width); } var legendWidth = Math.round(lbw + lbm*3 + labelMaxWidth), legendHeight = Math.round(itemCount*(lbm+lbh) + lbm); // Default Opacity if (!opacity && opacity !== 0) { opacity = 0.1; } if (!options.HtmlText && this.textEnabled && !legend.container) { if(p.charAt(0) == 's') offsetY = plotOffset.top + this.plotHeight - (m + legendHeight); if(p.charAt(0) == 'c') offsetY = plotOffset.top + (this.plotHeight/2) - (m + (legendHeight/2)); if(p.charAt(1) == 'e') offsetX = plotOffset.left + this.plotWidth - (m + legendWidth); // Legend box color = this.processColor(legend.backgroundColor, { opacity : opacity }); ctx.fillStyle = color; ctx.fillRect(offsetX, offsetY, legendWidth, legendHeight); ctx.strokeStyle = legend.labelBoxBorderColor; ctx.strokeRect(Flotr.toPixel(offsetX), Flotr.toPixel(offsetY), legendWidth, legendHeight); // Legend labels var x = offsetX + lbm; var y = offsetY + lbm; for(i = 0; i < series.length; i++){ if(!series[i].label || series[i].hide) continue; label = legend.labelFormatter(series[i].label); ctx.fillStyle = series[i].color; ctx.fillRect(x, y, lbw-1, lbh-1); ctx.strokeStyle = legend.labelBoxBorderColor; ctx.lineWidth = 1; ctx.strokeRect(Math.ceil(x)-1.5, Math.ceil(y)-1.5, lbw+2, lbh+2); // Legend text Flotr.drawText(ctx, label, x + lbw + lbm, y + lbh, style); y += lbh + lbm; } } else { for(i = 0; i < series.length; ++i){ if(!series[i].label || series[i].hide) continue; if(i % legend.noColumns === 0){ fragments.push(rowStarted ? '