I'm trying to set up a horizontal bar graph using jqplot as follows:
var plot1 = $.jqplot('graph', [gData], {
seriesDefaults: {
renderer:$.jqplot.BarRenderer,
rendererOptions: {
barDirection: 'horizontal'
}
},
axes: {
yaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: gTicks
}
}
});
This code works fine with vertical bars, like:
var plot1 = $.jqplot('graph', [gData], {
seriesDefaults: {
renderer:$.jqplot.BarRenderer
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: gTicks
}
}
});
But when I go to make it horizontal, suddenly the bars no longer line up with the ticks. For example, for some ticks, there may be two or more overlapping bars. And for some, there may be none at all. Finally, there is an additional 'undefined' tick that seems to have tons of bars overlapping.
gData and gTicks are both javascript arrays.
Any thoughts?
EDIT: The undefined category is actually my own creation, but the problem remains unchanged.
The reason it doesn't work for you is that, what I assume, you are not changing the data accordingly when changing your graph's orientation to horizontal. Therefore, assuming that this is the problem, the chart's data would have to be in the following form, as in the example at jqPlot's webpage:
[[[2,1], [4,2], [6,3], [3,4]],
[[5,1], [1,2], [3,3], [4,4]],
[[4,1], [7,2], [1,3], [2,4]]]
You could also use a value array notation (below), as oppose to the above (array of points) to express a series:
[[200, 600, 700, 1000],
[460, -210, 690, 820],
[-260, -440, 320, 200]]
This notation would allow you to change the orientation of the chart without worrying about the data format, as presented in the examples below, where data stay the same only appropriate graph's parameters change:
Vertical bar chart.
Horizontal bar chart.
Related
I am using Primefaces 6 for my companys charting needs, which relies on jQplot.
For a project, I am trying to overlay a line chart on a stacked bar chart with negative values, to obtain something like this:
The problem is that when I try to add a linechartseries to the same model as the two barchartseries , the linechart becomes a part of the stack when setting setStacked(true); on the model, because Primefaces seems to not allow individual disabling of stacking on series, only per model. So I end up with this when rendering the chart with
<p:chart type="bar" model="#{backingBean.cartesianChartModel}"/>
After some investigation I have notoced that jQplot is capable of disabling Stacking on individual series by passing disableStack : true in the JS options, so the question is if it's posssible to override this in some way on the rendered page,either via PF or via some JS hack? I feel that using the extender only apples to the entire model?
Related issues: Disable individual stacking
By pouring through the documentation I found a solution to the problem, if not the question:
It seems that Primefaces allows for individual series to be excempt from the stack in the series creation in this version, by passing
LineChartSeries.setDisableStack(true);
Simple as that.
I guess it may be possible. I used the extender functionality for some jqPlot hacks in the past.
In my case, for example, I had a Donut Chart defined with an extender function as follows:
private void createDonutModel() {
donutModel = new DonutChartModel();
donutModel.setLegendPosition("s");
donutModel.setLegendPlacement(LegendPlacement.OUTSIDE);
donutModel.setSliceMargin(4);
donutModel.setDataFormat("value");
donutModel.setShadow(false);
donutModel.setExtender("donutExtender");
donutModel.setSeriesColors("B81C40, FFA600, 79B54A");
}
The corresponding javascript was doing some changes to the jqPlot:
/**
* Customized jqPlot JQuery layout of the Donut Chart for Status Dashboard.
*/
function donutExtender() {
this.cfg.seriesDefaults = {
// make this a donut chart.
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
thickness: 26,
ringMargin: 0,
fill: true,
padding: 0,
sliceMargin: 4,
// Pies and donuts can start at any arbitrary angle.
startAngle: -90,
showDataLabels: false,
// By default, data labels show the percentage of the donut/pie.
// You can show the data 'value' or data 'label' instead, or 'percent'
dataLabels: 'value',
shadow: false
}
}
this.cfg.gridPadding = {
top: 0, right: 0, bottom: 0, left: 0
}
this.cfg.legend = {
show: false
}
this.cfg.grid = { drawBorder: false,
shadow: false,
background: "transparent"
};
}
So you may try something like this in your case ?
Leave the extension configuration of your series empty, except for the one you are interested in...
function chartExtender() {
this.cfg.series = [
{ //...
},
{ // ...
},
{
disableStack: true
}
]
}
Worth having a shot ...
My program is drawing a graph with the following (comparable) source code from the jqplot page. The goal is to draw a vertical line at position x in the graph. I followed up the guide an examples on the jqplot page, but it didn't draw the line, just the graph.
Is someone experienced with that? Or could tell me how the options/calls should be to get the line in the graph?
Example-code:
$(document).ready(function(){
var plot2 = $.jqplot ('chart2', [[3,7,9,1,4,6,8,2,5]], {
// Give the plot a title.
title: 'Plot With Options',
// You can specify options for all axes on the plot at once with
// the axesDefaults object. Here, we're using a canvas renderer
// to draw the axis label which allows rotated text.
axesDefaults: {
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
},
// An axes object holds options for all axes.
// Allowable axes are xaxis, x2axis, yaxis, y2axis, y3axis, ...
// Up to 9 y axes are supported.
axes: {
// options for each axis are specified in seperate option objects.
xaxis: {
label: "X Axis",
// Turn off "padding". This will allow data point to lie on the
// edges of the grid. Default padding is 1.2 and will keep all
// points inside the bounds of the grid.
pad: 0
},
yaxis: {
label: "Y Axis"
}
}
});
});
Adding this to your existing code should help you draw a vertical line.
CODE:
canvasOverlay: {
show: true,
objects: [
{verticalLine: {
name: 'stack-overflow',
x: 4, // x-axis position where you want to draw the vertical line.
lineWidth: 6,
color: 'rgb(100, 55, 124)',
shadow: false
}}
]
}
You can set the 'x' to a desired value of your choice.
IMP: In order for the canvasOverlay to work, you must include the jqplot.canvasOverlay.min.js file, else it will not work.
Here's a working fiddle: jqPlot - Draw vertical line on the graph
I included the following files in code above(JS Fiddle). You can also refer to the External Resources section on the left pane in JSFiddle.
jquery.jqplot.min.js
jquery.jqplot.min.css
jqplot.canvasOverlay.min.js
jqplot.canvasAxisLabelRenderer.min.js
jqplot.canvasTextRenderer.min.js
jqPlot Example here - jqPlot Canvas Overlay
Hope it helps :-)
I figured it out:
I was not including the jqplot.CategoryAxisRenderer. Once I included that, I was able to get it working.
Thanks, everyone!
UPDATE:
My code works in JSFiddle, so it's a CSS problem I'm having. Please disregard.
I'm trying to create a fairly simple bar chart in jQPlot. I'm expecting two horizontal bars, one on top of the other. Both are equal to 1 on the X axis. I want the Y axis to have the labels 'In Progress' for the top bar, and 'Apr 2014' for the bottom bar. I have tried numerous combinations. If I do not specify Ticks, then I see the two bars. Specifying Ticks, or using the desired labels as the Y axis data point just shows both labels overlapping with no bars. (ignore the setTimeout) Thanks in advance.
Here's the code:
var data = [[1,1],[1,2]];
var ticks = ['In Progress','Mar 2014'];
$(function () {
setTimeout(function(){
var plot1 = jQuery.jqplot ('chartdiv', [data],
{
seriesDefaults: {
renderer:$.jqplot.BarRenderer,
rendererOptions: {
barDirection: 'horizontal'
},
},
axes: {
yaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
}
}
});
},
100);
});
I have modified the JsFiddle given by Batu Zet previously adding following lines in order to label your bar chart here :
series: [
{
pointLabels:{
show:true,
labels:['Apr 2014', 'Apr 2014']
}
},
{
pointLabels:{
show:true,
labels:['In Progress', 'In Progress']
}
}
]
P.S : The labels are duplicated for each serie in order to display the same label for two points in a serie.
If the area is very small then the labels are getting overlapped in the donut chart.
How to place the data labels outside the donut chart with lines.
Currently I am able to draw the labels inside the chart. Find the sample code from here:
$(document).ready(function(){
var s1 = [['a',6], ['b',8], ['c',14], ['d',20]];
var plot3 = $.jqplot('chart4', [s1], {
seriesDefaults: {
// make this a donut chart.
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
// Donut's can be cut into slices like pies.
sliceMargin: 3,
// Pies and donuts can start at any arbitrary angle.
startAngle: -90,
showDataLabels: true,
// By default, data labels show the percentage of the donut/pie.
// You can show the data 'value' or data 'label' instead.
dataLabels: 'value'
}
}
});
});
fiddle
This is my expected output:
Helps much appreciated
Ok, what you need to set is:
dataLabelPositionFactor: 2
Please see jsFiddle here:
http://jsfiddle.net/9gXc3/1/
And further info here:
http://www.jqplot.com/docs/files/plugins/jqplot-donutRenderer-js.html
Update
I'd also set the padding too to avoid overlap i.e.
padding: 50
http://jsfiddle.net/9gXc3/3/
Use, dataLabelPositionFactor: 1.2, inside rendererOptions.
Below is an example I used in a project:
rendererOptions: {
padding: 8,
showDataLabels: true,
dataLabels: percentage,
dataLabelFormatString: '%s%%',
diameter: 300,
dataLabelPositionFactor: 1.1,
sliceMargin: 4,
startAngle: -90,
color: '#DCDCDC'
}
I have javascript code as:
var plot1 = jQuery.jqplot ('chartdiv', [data],
{
seriesDefaults: {
// Make this a pie chart.
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Put data labels on the pie slices.
// By default, labels show the percentage of the slice.
showDataLabels: true,
dataLabels: 'value'
}
},
legend: { show:true, location:'e'}
});
var handler = function(ev, gridpos, datapos, neighbor, plot) {
if (neighbor) {
alert('x:' + neighbor.data[0] + ' y:' + neighbor.data[1]);
}
};
$.jqplot.eventListenerHooks.push(['jqplotClick', handler]);
Now by using dataLabels: 'value' I am able to show values but shown value is 51 instead of 50.667.Value is rounded.But I need to show exact value.How to this??
My second question is that When I have mouse pointer on any region of the chart I want to show something.Is that would be done using jqplotDataMouseOver But how to use it?
Your first question can be solved with the dataLabelFormatString property:
seriesDefaults: {
// Make this a pie chart.
renderer: jQuery.jqplot.PieRenderer,
rendererOptions: {
// Put data labels on the pie slices.
// By default, labels show the percentage of the slice.
showDataLabels: true,
dataLabels: 'value',
dataLabelFormatString:'%.4f'
}
},
The '%.4f' would show 4 decimal places.
Your second question is more difficult. Apparently events on bar charts are not quite ironed out with jqplot. But the last suggestion in that link works for me:
$('#chartdiv').bind('jqplotDataMouseOver', function (ev, seriesIndex, pointIndex, data) { alert('series: '+seriesIndex+', point: '+pointIndex+', data: '+data)});
Here's a jsfiddle, remember to cache the JS files since jqplot does not allow hotlinking.