I have a dynamic LineChart. I am setting the zoom to false but I want to be able to trigger an Ajax Event when selecting an area in the Chart (like the zoom functionnality when selecting the area you want to zoom), I want to call a server method and getting the max and min x axis values of the selected area.
Can anyone help with this?
Else if I set the zoom to true, is there any way to get the values from the zoomed area ?
PrimeFaces and JSF is in this context nothing more than an html/javascript/css generator. If you look at the source of the generated page in your browser developer tool, you'll see a lot of javascript, including all datapoints.
<script id="j_idt87_s" type="text/javascript">
$(function(){PrimeFaces.cw('Chart','chart'{
id:'j_idt87',
type:'line',
data:[[[1,2],[2,1],[3,3],[4,6],[5,8]],[[1,6],[2,3],[3,2],[4,7],[5,9]]],
title:"Zoom",
legendPosition:"e",
axes:{
xaxis:{
label:"",
renderer:$.jqplot.LinearAxisRenderer,
tickOptions:{angle:0}},
yaxis: {
label:"",
min:0,
max:10,
renderer:$.jqplot.LinearAxisRenderer,
tickOptions:{angle:0}}
},
series:[{label:'Series 1',renderer: $.jqplot.LineRenderer,showLine:true,markerOptions:{show:true, style:'filledCircle'}},{label:'Series 2',renderer: $.jqplot.LineRenderer,showLine:true,markerOptions:{show:true, style:'filledCircle'}}],zoom:true,datatip:true},'charts');});
</script>
So the answer to this question is valid for the PrimeFaces charts as well.
Running the following code (from the link above) in your browser developer tool on the zoom examples will show you the data points that fall in your zoom region
chart = PF('chart').plot;
PF('chart').plot.target.bind('jqplotZoom', function(ev, gridpos, datapos, plot, cursor){
var plotData = plot.series[0].data;
for (var i=0; i< plotData.length; i++) {
if(plotData[i][0] >= chart.axes.xaxis.min && plotData[i][0] <= chart.axes.xaxis.max ) {
//this dataset from the original is within the zoomed region
//You can save these datapoints in a new array
//This new array will contain your zoom dataset
//for ex: zoomDataset.push(plotData[i]);
console.log(plotData[i]);
}
}
});
Replacing PF(çhart') with PF('myLineChartWV') will make it work for your example to
Once you have gathered the data, you can use this in e.g. a PrimeFaces remoteCommand to pass it to the server.
Notice that this only takes the x-axis value of the zoom into account. If you want the y-axis taken into account to (so the real zoom area), add
plotData[i][1] >= chart.axes.yaxis.min && plotData[i][1] <= chart.axes.yaxis.max
to the if-statement in the loop.
Also notice it just takes the first series. If you have multiple, you have some simple homework to do.
Related
I have a noUiSlider with several handles to allow specifying several contiguous date periods (example = Feb to Apr, May to July, and Aug to Sept). Ideally I would like to have labels that appear centered on the connect divisions to describe what each period relates to (ex. "Current Period", "Next Period"). I was thinking I could do this by setting a centered background image on the noUi-connect divisions.
However, the noUi-connect divisions use transform (translate/scale) styling which results in my background images being scaled which I do not want.
I also thought maybe I could revise the javascript to generate an outer division around each nonUi-connect division, and I would apply the background onto the outer division instead - but I was unable to get the background from the outer division to appear.
Any other ways I could accomplish this? The only other thing I can think of it to have floating divisions defined outside of the noUiSlider object which I would need to reposition whenever I detect changes in the handle positions.
You can add an element outside of the connects and absolutely position it.
A quick version for a slider with two handles (showing the value for the first handle):
var origin = slider.querySelector('.noUi-connects');
var node = document.createElement('div');
node.style.textAlign = 'center';
node.style.position = 'absolute';
node.style.zIndex = '10';
node.style.fontSize = '10px';
origin.appendChild(node);
slider.noUiSlider.on('update', function(values, handle, unencoded, tap, positions) {
node.style.left = positions[0] + '%';
node.style.right = (100 - positions[1]) + '%';
node.innerText = values[0];
});
Just realized another approach is to set the innerHtml of the specific noUi-connect divisions to my label values. Simpler than playing with background images.
But the transform styling still affects the labels, so the end result is not better. Maybe I can load the innerHtml with an inner division that somehow ignores the transform settings but I haven't figure out how to do that yet. transform: none does not make any difference.
I Need 10 different Colors in Pie chart Using the Library of pykcharts.
Is it possible Because As per the Documentation they Provide only one shade_color.
Go through this link http://pykcharts.com/tour/pie
#Tkingovr chart_color is for all charts but One dimensional. You can use shade_color for One dimensional charts https://github.com/pykih/PykCharts.js/wiki/Colors#shade-color
#KIRANJOSHI
var selector = "pieContainer", // selector of your chart
colors = ["red","blue","green","yellow","orange"];
setTimeout(function() {
d3.selectAll("#" + selector + "_svg path.pie")
.attr("fill",function(d, i) {
return colors[i];
});
},1000);
setTimeout is required since the chart may take time to render and there is no provision in the current version to run a piece of code on chart render complete.
According to the documentation you should be able to pass in values like this:
{
"chart_color": ["blue","green","Yellow"]
}
The chart also accepts any of the following:
Color Names (Eg: "red")
Hex values (Eg: "#B0171F")
RGB values (Eg: "rgb(176,23,31)" )
I'm using Flot Charts with mouse scroll to zoom in and out. I created a button to call zoomOut() and it works well, but I can't find any solution to how I can zoom out all the way so that it Looks just like when it was first loaded. I don't want to reload that who container because it using ajax to pull data from mysql on refresh.
I Googled but couldn't find anything.
You can also set a double click to reset the zoom function of the Flot chart. It redraws the Flot chart to its original state and can be used with dynamic data.
$("#placeholder").dblclick(function () {
plot = $.plot(placeholder, dataset, options);
});
You can set the ranges of the axes to null. By setting this, the zoom level will be set so every data point is visible, just like the default zoom level.
Unlike the other solutions, this solution will not construct a whole new plot.
var axes = plot.getAxes(),
xaxis = axes.xaxis.options,
yaxis = axes.yaxis.options;
xaxis.min = null;
xaxis.max = null;
yaxis.min = null;
yaxis.max = null;
// Don't forget to redraw the plot
plot.setupGrid();
plot.draw();
You can save your initial ranges of axes and redraw your plot like in example for navigating. But your code will be look like these:
// do the zooming
plotObjectPointer = $.plot(placeholder, plotData,
$.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
}));
where ranges will be your initial ranges. To prevent repeated Ajax loading you can use window.localStorage or just another var for storing plotData.
For example I have plotted a line chart based on the date and number of students registered on a particular day on x and y axis respectively. When i mouse over to a particular point in the line chart i can view the tool tip displaying the x and y axis values. Instead I want to display the names of the students registered on that day when I mouse over to a particular point. Is there any solution for this problem? If there is no work around with Jqplot, please suggest me any other charts.. Please help me out. Thanks in advance.
Here's a little example I put together for you.
It uses the largely undocumented tooltipContentEditor property of the highlighter plugin:
highlighter: {
show: true,
sizeAdjust: 7.5,
tooltipContentEditor:tooltipContentEditor
}
Where your data is predefined like:
var students = [
['Bob','Mark','Dave'],
['Tim','Mike']
];
var data = [students[0].length,students[1].length];
function tooltipContentEditor(str, seriesIndex, pointIndex, plot) {
// display series_label, x-axis_tick, y-axis value
return students[pointIndex].join(", ");
}
I found this solution.
If type of chart is pie, how specify parameters (x,y) of highlight(x, y)?
Thanks
Sorry for my bad English.
Unfortunately, flot doesn't expose the pie highlighting code to the user. So we are pretty much out of luck, but what may work for you is synthesizing a click event at the appropriate place on the page:
$("#highligher").click(function () {
var e = jQuery.Event('click');
e.pageX = 250; //add a made up x/y coordinate to the click event
e.pageY = 250;
$('#plot canvas:first').trigger(e); //trigger the click event on the canvas
});
Here it is in action: http://jsfiddle.net/ryleyb/mHJm5/
The problem is you have to know where the slice you want to highlight is already. This would be easy enough to set if the graph is static. If it's a dynamic graph, you'd have to dig into the source of the pie code to figure out how to calculate where the pie slice is. It might be easier in that case to just have a copy of all the pie functions and manually draw on the pie overlay.
Just got this working by altering a few things...
I changed highlight and unhighlight in jquery.flot.pie.js to pieHighlight and pieUnhighlight.
Then, after these two lines in jquery.flot.pie.js...
plot.hooks.processOptions.push(function(plot, options) {
if (options.series.pie.show) {
I added...
plot.highlight = pieHighlight;
plot.unhighlight = pieUnhighlight;
We're maintaining selection state outside of the chart (as a backbone model). When a selection event (click) occurs, we set the selected slice in the model. When selection changes, we refresh the chart using a selection color for the pie slices that are selected.
var data = [];
var color = slice.index == selected ? '#FF0000' : '#0000FF';
data.push({label:slice.Label,data:slice.Value,color:color});
The snippet above uses blue for all non-selected slices, red for the selected slice. Your color logic will be more sophisticated.
NOTE: You can also use rgba CSS for the colors, which gives a really nice effect. For example:
var color = slice.index == selected ? 'rgba(0,0,255,1)' : 'rgba(0,0,255,0.5)';