I have a problem with a jQuery flot and jquery.flot.symbol usage. I render a flot using jquery.flot and using an additional plugin (jquery.flot.symbol to make some rectangles over the graph).
The problem is when I reverse the axes (ox starting from right to left and oy position right). The part that is generated with the help of jquery.flot.symbol exceeds the grid and the zero values is somehow outside the graph (with other words all the values are moved to right)
http://jsfiddle.net/5L3eyafn/2/
and a relevant part of the code
var data1 = [
{
data: graphData,
bars: {
show: true,
lineWidth: 3,
horizontal: false,
fillColor: "#f8e7b3"
},
color: "#ffffff"
},
{
data: trendData,
points: {
show: true,
lineWidth: 3,
radius: 10,
fill: true,
fillColor: "#000000",
symbol: "rectangleGraph"
},
color: "#000000"
}
];
$.plot($(".graph"), data1, {
grid:{
tickColor: "#eee",
borderColor: "#eee",
borderWidth: 1,
hoverable: true,
clickable: true
},
xaxis:{
show: true,
transform: function (v) { return -v; },
inverseTransform: function (v) { return -v; }
},
yaxis: {
show: true,
position: "right"
}
});
The problem here is that the bars are aligned left by default which switches to alignment right by your transformation to the reverse. This does not happen automatically with the symbols. Here you have to do it by hand.
1) Changing symbol alignment to right like the bars (fiddle):
Change
ctx.rect(x + 3, y - 8, 12, 1); //12 - width, 1 - height
to
ctx.rect(x - 15, y - 8, 12, 1); //12 - width, 1 - height
If you want to be able to switch between normal and reverse axis you have to use a variable for the x offset.
2) Using center alignment (fiddle):
Change the above line to
ctx.rect(x - 6, y - 8, 12, 1); //12 - width, 1 - height
and add this to the bars
options:
align: "center"
With center alignment you can switch between normal and reverse without need to change the symbol code. (And it better shows which bar belongs to which x value.)
3) Correction for symbol y values (fiddle):
As you can see in the fiddles for both 1) and 2), the symbol for the value x = 0
is above the bar, but it should not be (symbol y = 41.6
, bar y = 42.0
).
To correct this you can also change the y offset in the code line from above to
ctx.rect(x - 6, y + 1, 12, 1); //12 - width, 1 - height
Here is the result from 2) plus 3) as a code snippet:
/*
Flot plugin that adds some extra symbols for plotting points.
The symbols are accessed as strings through the standard symbol
choice:
series: {
points: {
symbol: "square" // or "diamond", "triangle", "cross"
}
}
*/
(function ($) {
function processRawData(plot, series, datapoints) {
// we normalize the area of each symbol so it is approximately the
// same as a circle of the given radius
var handlers = {
square: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x - size, y - size, size + size, size + size);
},
diamond: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
var size = radius * Math.sqrt(Math.PI / 2);
ctx.moveTo(x - size, y);
ctx.lineTo(x, y - size);
ctx.lineTo(x + size, y);
ctx.lineTo(x, y + size);
ctx.lineTo(x - size, y);
},
triangle: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
var height = size * Math.sin(Math.PI / 3);
ctx.moveTo(x - size / 2, y + height / 2);
ctx.lineTo(x + size / 2, y + height / 2);
if (!shadow) {
ctx.lineTo(x, y - height / 2);
ctx.lineTo(x - size / 2, y + height / 2);
}
},
cross: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.moveTo(x - size, y + size);
ctx.lineTo(x + size, y - size);
},
rectangle: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x + 2, y - 8, 5, 8); //5 - width, 9 - height
},
rectangleGraph: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
//ctx.rect(x + 3, y - 8, 12, 1); //12 - width, 1 - height
ctx.rect(x - 6, y + 1, 12, 1); //12 - width, 1 - height
}
};
var s = series.points.symbol;
if (handlers[s]) series.points.symbol = handlers[s];
}
function init(plot) {
plot.hooks.processDatapoints.push(processRawData);
}
$.plot.plugins.push({
init: init,
name: 'symbols',
version: '1.0'
});
})(jQuery);
// end of symbol plugin
$(document).ready(function () {
var graphData = [
[0, "42.00"],
[1, "42.00"],
[2, "42.00"],
[3, "42.00"],
[4, "42.00"],
[5, "42.00"],
[6, "42.00"],
[7, "42.00"],
[8, "42.00"],
[9, "42.00"],
[10, "42.00"],
[11, "42.00"],
[12, "43.00"],
[13, "43.00"],
[14, "43.00"],
[15, "43.00"],
[16, "43.00"],
[17, "43.00"],
[18, "43.00"],
[19, "43.00"],
[20, "43.00"],
[21, "43.00"],
[22, "43.00"],
[23, "42.00"],
[24, "42.00"],
[25, "42.00"],
[26, "41.00"],
[27, "41.00"],
[28, "41.00"],
[29, "41.00"],
[30, "41.00"],
[31, "41.00"],
[32, "41.00"],
[33, "41.00"],
[34, "41.00"],
[35, "41.00"],
[36, "41.00"],
[37, "40.00"],
[38, "40.00"],
[39, "41.00"],
[40, "41.00"],
[41, "40.00"]
];
var trendData = [
[0, "41.60"],
[1, "39.93"],
[2, "39.13"],
[3, "38.87"],
[4, "38.20"],
[5, "37.93"],
[6, "37.13"],
[7, "36.73"],
[8, "36.27"],
[9, "36.07"],
[10, "34.60"],
[11, "35.20"],
[12, "35.00"],
[13, "33.53"],
[14, "34.07"],
[15, "33.47"],
[16, "32.93"],
[17, "31.40"],
[18, "32.07"],
[19, "30.07"],
[20, "28.80"],
[21, "29.00"],
[22, "28.67"],
[23, "29.20"],
[24, "26.13"],
[25, "28.40"],
[26, "26.27"],
[27, "25.07"],
[28, "25.07"],
[29, "24.53"],
[30, "25.80"],
[31, "20.40"],
[32, "25.07"],
[33, "23.27"],
[34, "22.13"],
[35, "22.07"],
[36, "20.27"],
[37, "22.07"],
[38, "18.67"],
[39, "19.13"],
[40, "18.87"],
[41, "18.67"]
];
var data1 = [{
data: graphData,
bars: {
show: true,
lineWidth: 3,
horizontal: false,
fillColor: "#f8e7b3",
align: "center"
},
color: "#ffffff"
}, {
data: trendData,
points: {
show: true,
lineWidth: 3,
radius: 10,
fill: true,
fillColor: "#000000",
symbol: "rectangleGraph"
},
color: "#000000"
}];
$.plot($(".graph"), data1, {
grid: {
tickColor: "#eee",
borderColor: "#eee",
borderWidth: 1,
hoverable: true,
clickable: true
},
xaxis: {
show: true,
//*
transform: function (v) {
return -v;
},
inverseTransform: function (v) {
return -v;
}
//*/
},
yaxis: {
show: true,
position: "right"
}
});
});
.graph {
width: 800x;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/flot/0.8.2/jquery.flot.min.js"></script>
<div class="graph bar"></div>