I have this problem using highcharts-ng: when I try to push a new data series over an existing data series already in a chart, the new series will be zoomed with the old zoom. My question is: is there any way to zoom to the default value of the new series after it's loaded?
$scope.datChart.series.pop();
$scope.datChart.series.push({data:dataArray, name:'Total'});
//$scope.datChart zoom out to default value of the new series
PS: the function zoomOut() doesn't work with highcharts-ng.
Thanks anyways
I faced the same problem. I found a way around by setting:
$scope.chart.xAxis.min = xMinValue;
$scope.chart.xAxis.max = xMaxValue;
$scope.chart.xAxis.currentMin = xMinValue;
$scope.chart.xAxis.currentMax = xMaxValue;
so every time you push new data, you do it by updating these $scopes as well
Related
I use node.js and javascript for creating a program.
I want to create a real time gauge using anychart, but the anychart gauge chart doesn't change although the data is coming from socket.io.
I want to access the anychart gauge chart object and change the data that was received from the socket.
How can I solve this problem?
anychartObj = new RealTimeAnyChart(elementId);
chartArrayList.push(anychartObj);
function RealTimeAnyChart(elemntId){
this.dataSet = anychart.data.set([15]);
this.gauge = anychart.gauges.circular();
this.gauge.data(this.dataSet);
this.gauge.container(elementId);
this.gauge.draw();
}
socket.on(' ',function(){
chartArrayList.gauge = value ?? this part is problem..
}
You can create new dataSet and apply it to you circular gauge like this:
socket.on(' ',function(){
var newData = anychart.data.set([20]);
chartArrayList.gauge.data(newData);
}
If you have an access to the existing dataSet object you can apply new data right to the old dataSet and do not create a new one. You can achieve that like this:
dataSet.data([20]);
I have the following error: TypeError: Cannot read property 'skip' of undefined.
I have a method which builds a chart in my app. That happens OnInit
var ctx = document.getElementById("myChart");
var chartInstance = new Chart(ctx);
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels :this.equity,
datasets: [{
data: this.equity
}]
}
});
}
this.equity is an array of values that I calculate on the client side using data from the server. That is the list that I filter later on.
Everything builds smoothly untill I start filtering. The chart is built upon values in a list. I have coded a filter that filters the list with various options. At the end of each filtering I call the method above again to rebuild the chart.
Now here is where strange things start to happen. The chart rebuilds smoothly. I filter many times with different options and then at some point boom I get this error! It doesn't occur at some particular moment when I'm pressing on the filter, it just occurs.
I think it is because every time I create a new chart object and supply it with new values. The variable for the values is the same as for the old object and that causes an error because at some point Angular checks out the old object and it has already got a new list of values which doesn't match the old list.
Has this hapened to anyone? Does anybody now how do I null out the old chart object at the point when I create a new chart object so this possibly solves? Thanks!
Try destroying the old chart instance before creating a new one, using the destroy() method.
...
if (myChart) myChart.destroy();
myChart = new Chart(ctx, {
type: 'line',
...
...
make sure the myChart variable is globally accessible
However, a better approach would be to update your chart using the update() method, when you add/update any data in your chart, instead of creating a new instance of chart everytime.
I'm working on a problem where I want to display data in a dashboard both as a chart (via perak:c3) and in a table (via aslagle:reactive-table). My issue is that the data is pulled from a collection in MongoDB, and it's format is instantly amenable to plotting via c3, but needs to be transformed into a local collection to be used by the reactive-table package, as suggested in this answer to a previous question.
When I change the dataset to be displayed I want the chart to be updated, and the table also. This requires changing the values in the local collection, however, which slows things down and so rather than the chart being smoothly redrawn, there is a freeze on the page, and then the new data is displayed.
I have created a sample project on GitHub here so the problem can be replicated easily. If you run the app and select a dataset in your browser you will see exactly what I mean
To see the reactive behaviour I want to preserve in the chart go to client/templates/dashboard/dashboard.html and simply comment out the table template {{> dashboardTable}}
and now change the dataset to see how the chart is smoothly redrawn. Essentially I am trying to ensure both templates dashboardChart and dashboardTable render independently of one another.
UPDATE
Following Michael Floyd's suggestion of using a timeout helped a bit
Meteor.setTimeout(function(){createLocalCollection(data)},200);
but although the chart gets smoothly drawn, when the table finishes being filled, the chart is drawn again. It looks like it jumps to some intermediate state that I can't understand. Here is a video showing what I mean.
I'm adding this as a separate answer because it's a completely different approach.
Use the onRendered callback in d3 to invoke the local collection update.
Where you have:
chart = c3.generate({
bindto: '#dataset-chart',
in dashboard_chart.js, add:
chart = c3.generate({
onrendered: createLocalCollection(),
bindto: '#dataset-chart',
Of course you need to remove createLocalCollection(data) from your event handler.
To avoid having to pass the data context through the onrendered handler in d3 also update your createLocalCollection function to use the reactive variable datasetID that you defined earlier to establish the current dataset:
var createLocalCollection = function() {
var values = My_First_Collection.find({datasetID: datasetID.get()}).fetch();
var tempDoc = {};
local.remove({});
tempDoc = {};
for (var i in values[0].value) {
tempDoc.value = values[0].value[i];
tempDoc.date = values[0].date[i];
local.insert(tempDoc);
}
};
Using this method you let D3 tell you when the chart rendering is done and then your table can start getting populated. The result is an instantaneous chart update followed by the table updating. No mucking with timeouts either.
Remember that js is single threaded. You have two things to and they are going to happen sequentially. What you can do is defer the code that is updating the local collection using Meteor.setTimeout(). This will allow the chart to update first and then your table can update second. I've seen this before where you run a function that updates the DOM (in your case d3 is updating the svg canvas) but the actual screen update gets stuck behind long running js.
I tried this specifically and chart performance was fine.
Meteor.setTimeout(function(){createLocalCollection(data)},500);
Cutting the interval down to 100 allowed the chart to update but then the menu didn't fade out completely until the local collection finished updating.
One thing that I've used with tables and local collections is to only update the local collection document when the corresponding non-local document is being rendered on screen (assuming there's a 1:1 relationship between the original data and the transformed version). This allows the reactive table to load lazily.
I'm using jqBarGraph to draw a graph on a page, but after the page loads, the graph updates with new values. How do I redraw the graph?
I'm updating the array I'm used to initialize the graph and then re-using it to initalize the graph (occurs within an each()).
Initial array:
array_msa_graph_1 = new Array(
[12300, 'MSA', '#88c100'],
[0, 'Gap', '#5e8500'],
[12300, 'ATB', '#74a400']
);
jQuery('#msa_graph_1').jqbargraph({
data: array_msa_graph_1
});
Updating array:
var graph_id = $(this).find('.msa_graph').attr('id');
var array_name = 'array_' + graph_id;
var graph_array = eval(array_name);
var msa_value = getMSA(graph_id);
graph_array[0][0] = msa_value;
$('#' + graph_id).jqbargraph({
data: graph_array
});
However, in the redraw process, it seems the array gets appended to the already existing graph and doesn't update the existing columns and labels.
What am I doing wrong?
Woah, this is quite an old post. I am also implementing bar graph using this plugin. I was having this trouble yesterday. I managed to solve this issue by taking a look at their page source. I found out that the person was able to clear the modification made on the graph. Hence, is this line of code that reset the values. $('#DivforGraph').html(''); //reset graph during dynamic change :)
*I will post the solution here.Maybe it might benefit someone who is facing the same problem as us! Cheers! ^_^
I am using the heatmap.js library from pa7 in github successfully to make some heatmap
http://www.patrick-wied.at/static/heatmapjs/example-heatmap-leaflet.html
But when I updated the heatmap with additional data or new data points, the leaflet library does not really update with the additional data points. There seems to be no method that can used for redraw. I dont know if someone has already solved this problem, thats why I am asking to see. Here is the simple portion of my additional script:
ndata=[{lat: 13.59, lon:-17.05, value: 11},{lat: 33.08, lon:-103.24, value: 19}]
testData.data.push.apply(ndata)
layer.addData(testData.data);
There is no errors in the console of Google chrome or no exceptions.
Thanks
There is a redraw method in the layer:
var heatmapLayer = L.TileLayer.heatMap();
// add layer to map
heatmapLayer.redraw()
Having said this, in the latest version, the heatmap layer automatically redraws when you set the data (see https://github.com/pa7/heatmap.js/blob/d09c4e99852b4849e2b4d4f12976a9fce0327ca5/src/heatmap-leaflet.js#L112).