Adding data points to existing graph with Dygraphs - javascript

I have an existing graph created with Dygraphs based on a JavaScript array. I also have a process that generates new values, say once per second, as JavaScript array.
Is it possible to add the new values to the existing graph? I'd like to avoid redrawing the whole graph each time a new value is created.
var data = [[1,99,42],[2,98,52]]
var graph = new Dygraph(element, data, {});
// now graph is created and visible
// how to add newPoint to existing graph?
var newPoint = [3,100,20];

You can use option file for all kinds of data, not just for CSV files.
data.push(newPoint);
graph.updateOptions({file: data});

Related

How to set dynamic positions to the node axis in visjs?

I have bulk of nodes around 500 and I want to place nodes together. To achieve this I need to set the X-axis and Y-axis positions to these nodes dynamically. How do I do that in vis.js?
You can set nodes' coordinates using VisData and update if you set them like this:
// data is your data in form of { nodes:nodes, edges:edges }
window.testNodes = new vis.DataSet(data.nodes); // make it globally available for this demo
window.testEdges = new vis.DataSet(data.edges); // if you need to change something about edges too
data = { nodes: window.testNodes, edges: window.testEdges };
network = new vis.Network(container, data, options);
and then use
window.testNodes.update({id:5,label:'wow',x:100,y:-200})
to update the node with id == 5. The x:100,y:-200 updates coordinates, of'course.
As for putting nodes together, you should clarify what does "together" mean. For instance, you can create a simple grid and put nodes into it (by setting their coordinates like shown above). What distances do you expect from "together"? What else do you need? I'd say this deserves a separate question if you have problems not only with applying coordinates dynamically.

How to use scatter chart with complex data?

I trying to implement scatter chart by example.
In example we can see creating dimension:
runDimension = ndx.dimension(function(d) {return [+d.Expt, +d.Run]; });
Example's data:
Expt Run Speed
1 1 850
1 2 740
1 3 900
I want to use same chart, but I have my data in next format:
[
{
"Timestamp":"2016-12-15T17:29:53Z",
"idgame":"euro",
"users":{
"Jo": {
"energy":200,
"jump_height":0.5
},
"Bob": {
"energy":220,
"jump_height":0.35
}
}
},
{
"Timestamp":"2016-12-15T17:29:55Z",
"idgame":"euro",
"users":{
"Jo": {
"energy":120,
"jump_height":0.15
},
"Bob": {
"energy":240,
"jump_height":0.75
}
}
}
]
I need to build next chart, where x-axis is timestamp and y-axis is jump_height:
My data is allready in crossfilter, so I can't change it.
How can I create good dimension with current format?
I'm still not convinced this is worth the effort, versus biting the bullet and flattening your data and fixing up the other charts. If your data isn't flat you will be fighting crossfilter and dc.js every step of the way.
That said, as usual, it's possible!
We can't use the series chart, because that requires all the data to be present in one group. But since you want to produce multiple symbols from each row of data, an ordinary crossfilter group can't produce the data you need.
Maybe we could use a fake group, but that would be complicated. Instead, let's produce a dimension and group for each user, and then sew them together using a composite chart.
First, we need to parse those timestamps:
data.forEach(function(d) {
d.Timestamp = new Date(d.Timestamp);
});
Next, we'll retrieve a list of all users, by pulling the user keys from each event (timestamp), concatenating them, and then using a d3.set to unique them:
// retrieve all users from all events
var users = data.reduce(function(p, event) {
return p.concat(Object.keys(event.users));
}, []);
users = d3.set(users).values();
In the rest of the code, we'll assume there are the same users for each event. It's possible for them to be different, but it adds extra complexity, and this answer is complicated enough. Just ping me me if you need that feature!
We'll create the chart, crossfilter, and a scale which will assign symbols to users:
var chart = dc.compositeChart("#test");
var ndx = crossfilter(data);
var symbolScale = d3.scale.ordinal().range(d3.svg.symbolTypes);
Now we can create the composite chart. (We'll add the scatter subcharts in the next step.)
chart
.width(768)
.height(480)
.x(d3.time.scale())
.xUnits(d3.time.seconds)
.elasticX(true)
.elasticY(true)
.brushOn(false)
.clipPadding(10)
.shareTitle(false) // allow default scatter title to work
.shareColors(true) // but use different colors for subcharts
.legend(dc.legend().x(350).y(350).itemHeight(13)
.gap(5).horizontal(1).legendWidth(140).itemWidth(70));
We set up the X axis with a time scale, with a resolution of seconds. Both axes have elastic. We need to share colors so that each subchart will be assigned its own color. (The legend is perhaps overspecified - I copied this from another example.)
Finally we get to the meat of it. For each user, we'll create a subchart, and we'll tell the composite chart to compose all of them:
chart.compose(users.map(function(user) {
var userDimension = ndx.dimension(function(d) {
return [d.Timestamp, d.users[user].jump_height];
})
var jumpGroup = userDimension.group();
console.log(user, jumpGroup.all());
var scatter = dc.scatterPlot(chart)
.symbol(symbolScale(user))
.dimension(userDimension)
.group(jumpGroup)
.colorAccessor(function() { return user; })
.symbolSize(8)
.highlightedSize(10);
return scatter;
}))
We're creating a new dimension for each chart. This is because the dc.js scatter plot expects the keys to include both X and Y coordinates, and we can only access the Y coordinate (jump_height) once we know the user. Once we get past that, the group is simple.
The chart will assign the symbol and color based on the user key. These both work the same; an ordinal scale will assign a new value from the range for each new value it encounters in the domain. The only difference is that we're using the default color scale, whereas we had to specify our own symbol scale.
Here's a fiddle: https://jsfiddle.net/gordonwoodhull/3m4mv3xf/19/

Canvas.js chart not updating with new data

I'm using CanvasJS to create a line graph based on some numbers coming in from my Myo. When new data comes in, the graph doesn't update. Since I don't populate the graph with initial data points, it stays empty forever.
My code: Here
Try this way.
Lets say:
var myChart = new CanvasJS.Chart(...);
Then to update chart data use:
myChart.options.data[0].dataPoints = YOUR_DATA_ARRAY;
myChart.render();
Worked for me, as I didn't find any 'update' method in documentation.

Google Annotation Chart Duplicates Itself

I haven't seen this problem with other Google charts before but I am using the Annotation Chart and every time the data is updated the following lines are called which duplicates the chart object in the DOM as a sibling of the parent:
var chart = new google.visualization.AnnotationChart(document.getElementById('chart_' + this.display.displayDivId));
chart.draw(data, options);
This more or less makes sense based on the code but how can I prevent the new method from firing and instead create a chart object out of the existing DOM element and then call the .draw() method on that object?
Is this possible? The only other thing I can think of would be to clear the existing one from the DOM first, and then proceed w/ the logic I illustrated above.
Any thoughts/suggestions would be much appreciated.

Dynamically pass series in jqplot line chart

I have used jqplot line chart.
I have get data from php page using ajax.In some condition I will display specific series.So
How to pass series dynamically in jqplot line chart and also set legend of series ?
I have manually write code for above requirement.I have apply click event on legend series and draw graph as per click on legend.
I have also change y-axis value as per select/deselect series legend.
I originally tried the answer posted by #sdespont, but due to additional properties that need to be in place for the series, it wasn't working properly. I was able to get this working by doing the following:
plot1.data = data;
plot1.replot( data );
data is a 3D array of the same makeup as you would pass in when creating the plot. If I did either part without doing the other, it wouldn't refresh properly, but the combination of the two seems to do the trick. Refreshing the plot in this fashion would dynamically add or remove any series I added to the data array.
Hope that helps.
You could add or remove series by playing with plot1.series array.
Here is a good jsfiddle : jsfiddle.net/fracu/HrZcj
The idea is to create an array with data
myNewSerie = Array();
x = (new Date()).getTime();
y = Math.floor(Math.random() * 100);
myNewSerie.push([x, y]);
Then add it to the graph using the next available slot
plot1.series[plot1.series.length] = myNewSerie
And finally redraw using plot1.replot();
Check out the updateSeries function in the end of the fiddle
Not tested, but should work
I had the same problem recently. "replot" works but is veeerrryyy slow. I used "jQPlot.drawSeries" which is blazingly fast. Just give your new series data to jQPlot as usual and call jQPlot.drawSeries({}, <nr of your series from 0...xxx)
My realtime chart with 800 values runs with >> 60 FPS on my PC and also very fast on my mobiles.

Categories