leonardoeloy / flot-valuelabels Goto Github PK
View Code? Open in Web Editor NEWImprovement of Flot Value Labels plugin
Home Page: http://wiki.github.com/leonardoeloy/flot-valuelabels/
Improvement of Flot Value Labels plugin
Home Page: http://wiki.github.com/leonardoeloy/flot-valuelabels/
Please update with "plot.getPlaceholder().find("#valueLabels"+series.seriesIndex).remove();" after line 22 to deal with this issue
Hi,
i am using this plugin and works great.
Now i would like to rotate the values to 90 degrees, so that the label values do not overlap each other.
Any ideas ?
Please note that i am using Canvas and not HTML mode.
Thanks.
I make some improvments to this plugin, so now u can change labels color, font and setup offset for it:
/**
Value Labels Plugin for flot.
Using canvas.fillText instead of divs, which is better for printing - by Leonardo Eloy, March 2010.
Tested with Flot 0.6 and JQuery 1.3.2.
*
Original homepage: http://sites.google.com/site/petrsstuff/projects/flotvallab
Released under the MIT license by Petr Blahos, December 2009.
*/
(function ($) {
var options = {
valueLabels: {
show: false,
showAsHtml: false, // Set to true if you wanna switch back to DIV usage (you need plot.css for this)
showLastValue: false // Use this to show the label only for the last value in the series
}
};
function init(plot) {
plot.hooks.draw.push(function (plot, ctx) {
if (!plot.getOptions().valueLabels.show) return;
var showLastValue = plot.getOptions().valueLabels.showLastValue;
var showAsHtml = plot.getOptions().valueLabels.showAsHtml;
var fontcolor = plot.getOptions().valueLabels.fontcolor;
var xoffset = plot.getOptions().valueLabels.xoffset;
var yoffset = plot.getOptions().valueLabels.yoffset;
var font = plot.getOptions().valueLabels.font;
var ctx = plot.getCanvas().getContext("2d");
$.each(plot.getData(), function(ii, series) {
// Workaround, since Flot doesn't set this value anymore
series.seriesIndex = ii;
if (showAsHtml) plot.getPlaceholder().find("#valueLabels"+ii).remove();
var html = '<div id="valueLabels' + series.seriesIndex + '" class="valueLabels">';
var last_val = null;
var last_x = -1000;
var last_y = -1000;
for (var i = 0; i < series.data.length; ++i) {
if (series.data[i] == null || (showLastValue && i != series.data.length-1)) continue;
var x = series.data[i][0], y = series.data[i][1];
if (x < series.xaxis.min || x > series.xaxis.max || y < series.yaxis.min || y > series.yaxis.max) continue;
var val = y;
if (series.valueLabelFunc) val = series.valueLabelFunc({ series: series, seriesIndex: ii, index: i });
val = ""+val;
if (val!=last_val || i==series.data.length-1) {
var xx = series.xaxis.p2c(x)+plot.getPlotOffset().left;
var yy = series.yaxis.p2c(y)-12+plot.getPlotOffset().top;
if (Math.abs(yy-last_y)>20 || last_x<xx) {
last_val = val;
last_x = xx + val.length*8;
last_y = yy;
if (!showAsHtml) {
// Little 5 px padding here helps the number to get
// closer to points
x_pos = xx;
y_pos = yy+6;
// If the value is on the top of the canvas, we need
// to push it down a little
if (yy <= 0) y_pos = 18;
// The same happens with the x axis
if (xx >= plot.width()) x_pos = plot.width();
if (font) { ctx.font = font; }
ctx.fillStyle = fontcolor;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 1.5;
ctx.shadowColor = fontcolor;
ctx.fillText(val, x_pos+xoffset, y_pos+yoffset);
} else {
var head = '<div style="left:' + xx + 'px;top:' + yy + 'px;" class="valueLabel';
var tail = '">' + val + '</div>';
html+= head + "Light" + tail + head + tail;
}
}
}
}
if (showAsHtml) {
html+= "</div>";
plot.getPlaceholder().append(html);
}
});
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'valueLabels',
version: '1.1'
});
})(jQuery);
And here how u can use it:
var options = {
bars: { show: true, autoScale: true, fillOpacity: 1},
xaxis: { autoscaleMargin:0.3, ticks: [[1.5,"2008"], [3.5,"2010"], [5.5,"2011"]] },
yaxis: { autoscaleMargin:0.2 },
valueLabels: { show: true, font : "17px Arial", yoffset : 0, xoffset : 14, fontcolor : "#FF0000" }
};
For stacked graphs, using the "stack" plugin that is included with Flot, the labels are placed in the location that the value would be if it weren't stacked, which is wrong for the stacked graph. Example:
<html>
<head>
<script language="javascript" type="text/javascript" src="jquery.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.stack.js"></script>
<script language="javascript" type="text/javascript" src="jquery.flot.valuelabels.js"></script>
</head>
<body>
<div id="placeholder" style="width:800px;height:500px"></div>
<script id="source" language="javascript" type="text/javascript">
$(function () {
$.plot($("#placeholder"),
[ [ [ 1, 3 ], [ 2, 4 ], [ 3, 5 ] ],
[ [ 1, 6 ], [ 2, 7 ], [ 3, 8 ] ] ],
{
series: { stack: 0 },
valueLabels: { show: true }
}
);
});
</script>
</body>
</html>
var data = [["Mar3", 3], ["Mar4", 5], ["Mar5", 8], ["Apr1", 5], ["Apr2", 5], ["Apr3", 3], ["Apr4", 8], ["May1", 2], ["May2", 3], ["May3", 1]];
$.plot("#b-flot-container_placeholder", [ data ], {
series: {
bars: {
show: true,
barWidth: 0.6,
align: "center"
},
valueLabels: {
show: true,
align: "center"
},
},
xaxis: {
mode: "categories",
tickLength: 0
}
});
Images on this page are broken:
I had an issue where some of my numbers did not show
It turned out to be the line
if (val!=last_val || i==series.data.length-1) {
which appears to skip number that have the same number as the previous processed value. However the numbers are not presented in graph order, so I'm not sure what it is trying to achieve.
anyway I replaced this line with
if(true) {
and it worked for my use case..
<head>
<script type="text/javascript" src="scripts/jquery-1.4.2.js"></script>
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="script/excanvas.min.js"></script><![endif]-->
<script src="script/jquery.flot.min.js" type="text/javascript"></script>
<script src="script/jquery.flot.axislabels.js" type="text/javascript"></script>
<script src="script/jquery.flot.valuelabels.js" type="text/javascript"></script>
</head>
<body>
<div id="flotChartPlaceHolder" style="width: 500px; height: 400px; margin: 8px 20px 20px; padding: 0px; position: relative;">
<script type="text/javascript">
$(document).ready(function() {$.plot($('#flotChartPlaceHolder'), [
{ data: [[0,5]], bars: { show: true, align: 'center', barWidth: .75 }},
{ data: [[1,0]], bars: { show: true, align: 'center', barWidth: .75 }},
{ data: [[2,3]], bars: { show: true, align: 'center', barWidth: .75 }},
{ data: [[3,0]], bars: { show: true, align: 'center', barWidth: .75 }},
{ data: [[4,0]], bars: { show: true, align: 'center', barWidth: .75 }}
],{
colors: ['#8B0000','#006400','#00008B','#9400D3','#FF8C00'],
xaxis: { autoscaleMargin: .05, tickLength: 0, ticks: [[0,'Unopened'], [1,'Bounced'], [2,'Opened'], [3,'Clicked'], [4,'Unsubscribed']] },
yaxis: { axisLabel: 'Count', axisLabelUseCanvas: true, axisLabelFontFamily: 'Arial' },
valueLabels: { show: true }
})});
</script>
</body>
</html>
Original version doesnt support the fallback to the yaxis custom tickFormatter(), for example, if value ticks across the Y axis are defined to be percentages, lets say, 50% instead of 50 as a value using tickFormatter, the valueLabels should have default support for that.
...if (series.valueLabelFunc) val = series.valueLabelFunc({ series: series, seriesIndex: ii, index: i });
val = ""+val;
// enable custom formatting on valueLabels
if (plot.getOptions().yaxis.tickFormatter) val = series.yaxis.tickFormatter(Number(val), series);
if (val!=last_val || i==series.data.length-1) {...
For bar graphs, is it possible to display the value label centered above the bar? Currently, there are two options: if the bar's align option is "left" (the default), the value label appears on top of the bar to the left side; or, if the bar's align option is "center", the value label appears on top of the bar to the right of center. Neither is visually appealing.
There are currently no options for formatting the value labels. Ticks on flot's axes can be formatted using the "tickDecimals" and "tickFormatter" options. It would be nice if we can use these or similar options for value labels.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.