(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, labelBoxOpacity: 0.4, 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: null, // => null means auto-detect backgroundOpacity: 0.85// => set to 0 to avoid background, set to 1 for a solid background }, callbacks: { 'flotr:afterinit': function() { this.legend.insertLegend(); } }, /** * 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, i, label, color; if (itemCount) { if (!options.HtmlText && this.textEnabled && !legend.container) { var style = { size: options.fontSize*1.1, color: options.grid.color }; var lbw = legend.labelBoxWidth, lbh = legend.labelBoxHeight, lbm = legend.labelBoxMargin, offsetX = plotOffset.left + m, offsetY = plotOffset.top + m; // We calculate the labels' max width var labelMaxWidth = 0; 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); if(p.charAt(0) == 's') offsetY = plotOffset.top + this.plotHeight - (m + legendHeight); if(p.charAt(1) == 'e') offsetX = plotOffset.left + this.plotWidth - (m + legendWidth); // Legend box color = this.processColor(legend.backgroundColor || 'rgb(240,240,240)', {opacity: legend.backgroundOpacity || 0.1}); 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 ? '' : ''); rowStarted = true; } // @TODO remove requirement on bars var s = series[i], boxWidth = legend.labelBoxWidth, boxHeight = legend.labelBoxHeight, opacityValue = (s.bars ? s.bars.fillOpacity : legend.labelBoxOpacity), opacity = 'opacity:' + opacityValue + ';filter:alpha(opacity=' + opacityValue*100 + ');'; label = legend.labelFormatter(s.label); color = 'background-color:' + ((s.bars && s.bars.show && s.bars.fillColor && s.bars.fill) ? s.bars.fillColor : s.color) + ';'; fragments.push( '', '
', '
', // Border '
', // Background '
', '
', '', '', label, '' ); } if(rowStarted) fragments.push(''); if(fragments.length > 0){ var table = '' + fragments.join('') + '
'; if(legend.container){ D.insert(legend.container, table); } else { var styles = {position: 'absolute', 'z-index': 2}; if(p.charAt(0) == 'n') { styles.top = (m + plotOffset.top) + 'px'; styles.bottom = 'auto'; } else if(p.charAt(0) == 's') { styles.bottom = (m + plotOffset.bottom) + 'px'; styles.top = 'auto'; } if(p.charAt(1) == 'e') { styles.right = (m + plotOffset.right) + 'px'; styles.left = 'auto'; } else if(p.charAt(1) == 'w') { styles.left = (m + plotOffset.left) + 'px'; styles.right = 'auto'; } var div = D.create('div'), size; div.className = 'flotr-legend'; D.setStyles(div, styles); D.insert(div, table); D.insert(this.el, div); if(!legend.backgroundOpacity) return; var c = legend.backgroundColor || options.grid.backgroundColor || '#ffffff'; _.extend(styles, D.size(div), { 'backgroundColor': c, 'z-index': 1 }); styles.width += 'px'; styles.height += 'px'; // Put in the transparent background separately to avoid blended labels and div = D.create('div'); div.className = 'flotr-legend-bg'; D.setStyles(div, styles); D.opacity(div, legend.backgroundOpacity); D.insert(div, ' '); D.insert(this.el, div); } } } } } }); })();