I am rendering an Graph with CanvasJS.
It´s generated dynamically.
After I stop the generation (or after an specified time) I generate from that an image.
Now I want to load that image AND take the generation of the Graph. So... I am again generating the same data, but this time with the complete (mostly scaled) picture of the data. - This shall work as an fast Overview.
That´s how I am doing it basiclly: (the dynamic data)
<script type="text/javascript">
window.onload = function ()
{
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer",{
zoomEnabled:true,
title :{
text: "Live Random Data"
},
data: [{
type: "stackedColumn",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 100;
var dataLength = 500; // number of dataPoints visible at any point
var arr = [];
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
arr.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
var d= setInterval(function(){updateChart()}, updateInterval);
$("#test").click(function () {
console.log("baa");
clearInterval(d);
});
$("#show").click(function () {
console.log("baa");
dps=[];
dps.push(arr);
chart.render();
});
}
</script>
http://canvasjs.com/editor/?id=http://canvasjs.com/example/gallery/dynamic/realtime_line/
Now, if I am zooming or panning the "Live Data" or on the Image:
I want an synchronization between those two. If I am zooming or panning on the Image I only want to see an opaque rect and the dynamic data has to be really zoomed.
An sync. Example is here http://jsfiddle.net/canvasjs/m5jgk5sg/, but how do I do that with an Image?
Does anyone of you has an idea or how to make an workaround?
Related
The below code doesn't work correctly when I click the button more than once. I found the temporary solution is to call chart.destroy() and chart = Highcharts.chart(...) to reset the internal states. But I want to know the right solution because that's just a temporary measure and it won't solve the actual cause of the problem. Please anyone can help me?
var chart = Highcharts.chart('container', options);
var update = function () {
var points = chart.series[0].points;
chart.series[0].setData([points[0].y, points[1].y + 200]);
};
var rotate = function () {
var points = chart.series[0].points,
ticks = chart.xAxis[0].ticks;
var sortedPoints = points.slice();
sortedPoints.sort(function(a,b){
return b.y - a.y;
});
points.forEach(function(point, i){
sortedPoints.forEach(function(sPoint, j){
if (point === sPoint){
points[i].graphic.animate({
x: points[j].shapeArgs.x
});
points[i].dataLabel.animate({
y: points[j].dataLabel.y
});
ticks[i].label.animate({
y: ticks[j].label.xy.y
});
}
});
});
};
document.getElementById("button").addEventListener("click", function() {
update();
rotate();
}, false);
Live demo: https://jsfiddle.net/Shinohara/dscvwrxu/22/
You do not need to reset the internal states. You can relay on current and initial values:
var rotate = function() {
var points = chart.series[0].points,
index,
ticks = chart.xAxis[0].ticks;
var sortedPoints = points.slice();
sortedPoints.sort(function(a, b) {
return b.y - a.y;
});
points.forEach(function(point, i) {
sortedPoints.forEach(function(sPoint, j) {
if (point === sPoint) {
index = j;
if (points[i].animated) {
points[i].animated = false;
j = i;
} else {
points[i].animated = true;
}
points[i].graphic.animate({
x: points[j].shapeArgs.x
});
points[i].dataLabel.animate({
y: points[index].dataLabel.y
});
ticks[i].label.animate({
y: ticks[j].label.xy.y
});
}
});
});
};
Live demo: https://jsfiddle.net/BlackLabel/jfd0vuy8/
#ppotaczek Your live demo rotates bars infinitely when I click the button more than once. In this case, what I want is the code which rotates bars for the first time only. The below is my intention.
State1: Cat1=1000, Cat2=900 # Current rank is 1st:Cat1 and 2nd:Cat2
Interval1: Cat2+=200 and rotate bars between state1 and state2
State2: Cat1=1000, Cat2=1100 # Current rank is 1st:Cat2 and 2nd:Cat1
Interval2: Cat2+=200 and don't rotate bars between state2 and state3
State3: Cat1=1000, Cat2=1300 # Current rank is 1st:Cat2 and 2nd:Cat1
I think the reason why your live demo rotates bars between state2 and state3 is update() also rotates bars.
// This function unintentionally rotates bars for the second time.
var update = function() {
var points = chart.series[0].points;
chart.series[0].setData([points[0].y, points[1].y + 200]);
};
I want to put bars from largest to smallest. And I don't want to rotate bars when the rank is not changed. Do you have any good solution?
I have a area chart which is having a dynamic point that will be added to chart.I got this http://jsfiddle.net/rjpjwve0/
but it looks like the point gets displayed first and then after a delay the chart draws back. Now i want to display the last point which will be a animated point and it should travel with chart without delay in rendering.
Could any one help me to achieve this.
I put together a test, and it seems to work well.
I updated the load event to add a second series, using the same series.data[len -1] values; then in the setInterval portion, we update that new point at each iteration.
That way, by updating the existing marker rather than destroying one marker and creating another, the animation works as desired.
Code:
events: {
load: function () {
var series = this.series[0],
len = series.data.length;
//-------------------------------------
//added this part ->
this.addSeries({
id: 'end point',
type: 'scatter',
marker: {
enabled:true,
symbol:'circle',
radius:5,
fillColor:'white',
lineColor: 'black',
lineWidth:2
},
data: [[
series.data[len - 1].x,
series.data[len - 1].y
]]
});
var series2 = this.get('end point');
//-------------------------------------
setInterval(function () {
var x = (new Date()).getTime(),
y = Math.random();
len = series.data.length;
series.addPoint([x,y], true, true);
//and added this line -->
series2.data[0].update([x,y]);
}, 1000);
}
}
Fiddle:
http://jsfiddle.net/jlbriggs/a6pshutt/
You can try this :
series: [{
name: 'Random data',
marker : {
enabled : false,
lineWidth: 0,
radius: 0
},
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -19; i <= 0; i += 1) {
data.push({
x: time + i * 1000,
y: Math.random()
});
}
return data;
}())
}]
Its works.
Greg.
i need to highlight y value example 20 to -10 and -30 to -45 in y axis. permanently with some color with opacity 50%, how to do.,
in this example how to add external csv file to this following code. Pls Guide me
var orig_range;
window.onload = function(){ var r = [];
var arr = ["7/13/2015 0:15:45",45,"7/13/2015 0:30",5,"7/13/2015 0:45",100,"7/13/2015 1:00",95,"7/13/2015 1:15",88,"7/13/2015 1:30",78];
for (var i = 0; i < arr.length; i++) {
r.push([ new Date(arr[i]),arr[i+1]
]);
i++;
}
orig_range = [ r[0][0].valueOf(), r[r.length - 1][0].valueOf() ];
g2 = new Dygraph(
document.getElementById("div_g"),
r, {
rollPeriod: 7,
animatedZooms: true,
// errorBars: true,
width: 1000,
height: 500,
xlabel: 'date',
ylabel: 'Pressure',
}
);
var desired_range = null;};
function approach_range() {
if (!desired_range) return;
// go halfway there
var range = g2.xAxisRange();
if (Math.abs(desired_range[0] - range[0]) < 60 &&
Math.abs(desired_range[1] - range[1]) < 60) {
g2.updateOptions({dateWindow: desired_range});
// (do not set another timeout.)
} else {
var new_range;
new_range = [0.5 * (desired_range[0] + range[0]),
0.5 * (desired_range[1] + range[1])];
g2.updateOptions({dateWindow: new_range});
animate();
}
}
function animate() {
setTimeout(approach_range, 50);
}
function zoom(res) {
var w = g2.xAxisRange();
desired_range = [ w[0], w[0] + res * 1000 ];
animate();
}
function reset() {
desired_range = orig_range;
animate();
}
function pan(dir) {
var w = g2.xAxisRange();
var scale = w[1] - w[0];
var amount = scale * 0.25 * dir;
desired_range = [ w[0] + amount, w[1] + amount ];
animate();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/1.1.0/dygraph-combined-dev.js"></script>
<div id="div_g"></div>
<div id="output"></div>
<b>Zoom:</b>
hour
day
week
month
full
<b>Pan:</b>
left
right
i'm trying to convert graph to dynamic graph data from csv file
var data = ["te1.csv"];
g2 = new Dygraph(document.getElementById("div_g"), data,
{
drawPoints: true,
showRoller: true,
labels:['date','depth'],
});
setInterval(function() {
data.push([data]);
g2.updateOptions( { 'file': data } );
}, 1000);
i have seen example but i dont know how to link my csv file with dynamic dygraph pls guide me
This example does something extremely similar to what you want: it highlights a specific range on the x-axis. To adapt it, you'd do something like this:
new Dygraph(data, div, {
underlayCallback: function (canvas, area, g) {
var bottom = g.toDomYCoord(highlight_start);
var top = g.toDomYCoord(highlight_end);
canvas.fillStyle = "rgba(255, 255, 102, 1.0)";
canvas.fillRect(area.x, top, area.w, bottom - top);
}
})
I have this code I have made out of a composition of my own code and the template code of Canvasjs which uses API of Canvasjs to make the chart.
Everything is good, I debugged it nicely and the chart shows with my database data as a source. My database data reads the data from a textfile which has data from a Arduino-based Pulse Sensor.
This is my code:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"> </script>
<script type="text/javascript">
$().ready(function () {
var dataPoints = [];
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
function updateChart( result ) { // move it here!!!
$.getJSON("arduino_data.php", function( result ){
var dataLength = 40; // number of dataPoints visible at any point
var updateInterval = 20;
var chart = new CanvasJS.Chart("chartContainer",{ // new chart Object
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dataPoints
}]
});
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
}
if (dataPoints.length > dataLength){
dataPoints.shift();
}
chart.render();
});
}
// First read - Start
updateChart();
// Update chart after specified time.
setInterval(updateChart, updateInterval);
});
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width:100%;">
</div>
</body>
</html>
Why do dataLength = 40; and updateInterval=20 and the last line: updateChart();
do not work? Should there be something in updateChart() like updateChart(dataPoints) ??
Why is my chart not live, though I have the right code parts?
EDIT
This is the template code that works without database data. And this is a Live Chart. It updates every second or so.
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"> </script>
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer2",{
title :{
text: "Patient #01"
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
</script>
<script type="text/javascript" src="canvasjs.min.js"></script>
As you can see, it is just like my code. However this uses math.randomize data instead of real data from database.
My Question: Why won't my chart keep updating (live) so it will show changes? My chart remains static. I have to refresh it manually to show new data transmission.
I'm working with Nvd3 charts from the examples from their official website. Now I want a line chart to update periodically based on data sent from server but I couldn't found any useful Example for this on internet.
I have created a function which re-draws the chart when new data is arrived but i want to append every new point to the existing chart (like we can do in highcharts) but i'm stuck.
Here is the code I'm using for Updating the chart.
var data = [{
"key" : "Long",
"values" : getData()
}];
var chart;
function redraw() {
nv.addGraph(function() {
var chart = nv.models.lineChart().margin({
left : 100
})
//Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true);
//Show the x-axis
chart.xAxis.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d))
});
chart.yAxis.tickFormat(d3.format(',.1%'));
d3.select('#chart svg').datum(data)
//.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
}
function getData() {
var arr = [];
var theDate = new Date(2012, 01, 01, 0, 0, 0, 0);
for (var x = 0; x < 30; x++) {
arr.push({
x : new Date(theDate.getTime()),
y : Math.random() * 100
});
theDate.setDate(theDate.getDate() + 1);
}
return arr;
}
setInterval(function() {
var long = data[0].values;
var next = new Date(long[long.length - 1].x);
next.setDate(next.getDate() + 1)
long.shift();
long.push({
x : next.getTime(),
y : Math.random() * 100
});
redraw();
}, 1500);