I've included in my HTML page a stacked bar graphic (with the Chart.js library) that makes user visualize some data. These data change on selection of the user, the Javascript function that enables this onclick feature is:
function aggLav(){
[...]
for(i=2; i<src.rows.length-1; i++){
cells[i]=row.insertCell(j);
cells[i].onclick = function () {//load graphic
dati=createData();
makeGrafico(dati, this.innerHTML);
var gr=document.getElementById("canvas");
if($(gr).is(':hidden')) $(gr).slideToggle();
};
}
where the function createData creates the JSON object (with labels and datasets) to pass to the graphic (works fine), and the function makeGrafico():
function makeGrafico(dati, titolo){
var d=getFirstMonday();
var mondays=[];
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: dati,
options: {
title:{
display:true,
text:titolo//change to name of procedure
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
}
takes the name of the parameter in order to display it, and the JSON object of the previous function.
When i first click on one procedure (the cell with the onclick feature rapresents an industrial procedure, not relevant), everything goes just fine, the graphic slides up and show the correct result. But when i click on another procedure, i expect to see the graphic related to that procedure: this is true, but when i move the mouse over the image, the graphic suddenly changes, making me see for a while the data of the first procedure i clicked.
In general, if i click 10 different procedures, and i hover the mouse on the graphic, i see all the 10 graphics alterning each other. If i manage to find the spot on where the graphic changes, it rests changed for all the time i leave the pointer on that position.
I'd surely like to make the data (and the graphic) be persistent, and relative to the last procedure i clicked.
How to solve this weird issue? Am i missing something? I'm new to this library.
You might be interested by this post. You need to clear the canvas at the beginning of your makeGrafico function.
In a first time, you should try adding window.myBar.destroy(). If it does not work, you should consider deleting the canvas element and then creating it again :
var $parent = $('#canvas').parent();
$('#canvas').remove();
$parent.append('<canvas id="canvas"></canvas>');
Related
How to show tooltip only when data available in chart js?
callbacks: {
title: (item, data) => this.projectNumberArray[item[0].index],
label: (item, data) => this.projectNameArray[item.index]
},
And I want disable tooltip, when I don't have needed data.
I have been faced same problem several days ago. I checked documentation and github both but i couldn't find the solution for disabling tooltip when data is not available.
Then i found a solution.
Then i checkced data on runtime and set a variable. When i draw chart then i check variable which i have been set on runtime and disable the tooltip accordingly.
tooltips: {
enabled: false
}
You can use above piece of code for disabling tooltip while drawing chart on canvas.
I am plotting a point graph and the graph should get update with new data for every 5 secs. Here min and max range are always fixed
Currently, when I get new data from server, I do merge the new data to the existing source.data and plotting the complete graph.
So, I dont want to redraw the complete data again and again. As the length of the source.data is increasing, performance is going down . So instead of redraw complete data, can I add only the new data to the existing graph
Please find the source code here
var source = [
{
data: [],
show: true,
label: "Constellation",
name: "Constellation",
color: "#0000FF",
points: {
show: true,
radius: 2,
fillColor: '#0000FF'
},
lines: {
show: false
}
}
]
var options = {...}
$.getJSON(URL , function(data) {
...
$.merge(source[0].data, new_data);
plotObj = $.plot("#placeholder", source, options);
}
Follow this steps:
plotObj.setData(newData);
plotObj.setupGrid(); //if you also need to update axis.
plotObj.draw(); //to redraw data
Another usefull method is getData(). With this method you can get the current data.
var data = plotObj.getData();
Your method of calling $.plot over and over should be avoided. It used to leak memory (not sure if it still does).
That said, #Luis is close, but let's put it all together. To add data to an existing plot do this:
var allData = plotObj.getData(); // allData is an array of series objects
allData[seriesIndex].data.push([newXPoint,newYPoint]);
plotObj.setData(allData);
plotObj.setupGrid(); // if axis have changed
plotObj.draw();
It should be noted that this does redraw the entire plot. This is unavoidable with HTML5 canvas. BUT flot draws extremely fast, you'll barely notice it.
I am looking at a simple Rickshaw chart with data from a JSON file.
d3.json(data, function(error, json) {
var graph = new Rickshaw.Graph( {
element: document.getElementById(chart_id),
renderer: 'line',
series: [
{name: 'myseries',
data: json[0].data}
]
})
graph.render();
});
I would like to access the graph after it has been rendered. Since the graph is created within a callback function I cannot simply return the handle. Also document.getElementById(chart_id) does not have a chart attribute.
My goal is to, for example, allow users to specify a certain range for multiple charts at the same time (e.g. last 5 years) without having to adjust the RangeSlider for each one of them. With access to the chart I could then do
new_rng = [new_min,new_max]
graph.window.xMin = new_rng[0]
graph.window.xMax = new_rng[1]
$('#' + slider_id).slider('option', 'values',new_rng)
Any ideas?
I think this is a similar problem to the one I encountered with a xively feed where the data is not returned when the graph is rendered. Here's my post.
Multiple calls to xively.feed.history()
I'm trying to create a data vs time graph which allows the user to zoom in/out to large/smaller time periods. You can see an example of one such graph here:
http://people.iola.dk/olau/flot/examples/visitors.html
While the API has been a breeze for setting up that level of functionality, I've gotten stock when trying to figure out how to create a default "zoom" value - to, for instance, set the default zoom to the past 30 days (while retaining the ability for the user to zoom out and view an entire year of data).
Does anyone have any experience or know a way of doing this? Or is it a matter of digging into the source code and customizing it?
Thanks!
Walker
If you look at the code in, for example, flot zooming example, and you modify the definitions of the variable "options" thusly:
var options = {
legend: {
show: false
},
series: {
lines: {
show: true
},
points: {
show: true
}
},
yaxis: {
ticks: 10,
min: -0.8,
max: 0.4
},
selection: {
mode: "xy"
}
};
... you'll find that the graph starts out with this level of y-axis zoom, but the smaller graph still retains the full range that you can zoom out to if you want. The lines added are in the "yaxis" definition, "min" and "max". You would do something similar for "xaxis" if you want to pre-zoom the x-axis.
Any sample code for chart with multiple bars using flot ??
similar to this example . The given patched files are not working for me. Anywhere I can download the latest files for multi bar graph.
Update
I am sure Flot is a very good library but plugins/add-ons are not available easily and the examples given on the website are very basic, so I decided to use jqPlot instead
Updated Info: AndiĆ³n's answer makes reference to this library. Bars-side-by-side
You can download the code here:
http://www.benjaminbuffet.com/public/js/jquery.flot.orderBars.js
The result is :
Have you tried the orderBars plugin?
You can download the code here
You have to treat each bar as its own data series, so if you see 11 bars you need to create 11 data series.
Here's sample code for 2 bars.
<script id="source" language="javascript" type="text/javascript">
$(function () {
var d1 =[0, 2];
var d2 =[1,3];
var startData = [
{ //first series
label:"d1",
data: [d1],
bars:{
show: true,
fill: true,
fillColor: "red"
}
},
{ //second series
label:"d2",
data: [d2],
bars:{
show: true,
fill: true,
fillColor: "blue"
}
}
];
var option={
series: {
bars:{
show: true,
fill: true
}
},
grid: {
hoverable: true,
clickable: true
},
yaxis: { ticks: 5 }
};
$.plot($("#placeholder"),startData,option );
});
Double-check the values that you're passing in on the X-axis (of your bar series).
You don't need a different series for each bar, that would be.... excessive.
What you do need is a different series for each colour of bar (or more accurately, each different set of rendering settings that you'd like to have in your chart).
I realize you've moved on, but if you want to post the code that was giving you issues, it might help other people. The examples on the flot site are pretty straight-forward, so it may have just been something simple (like your X-axis value if they weren't defined) that was tripping you up.
I'm using flot in a production system to render three different bar series (red, yellow and green bars) so it sounds like a very similar solution what you're trying to do.