I am using c3.js and c3.css to make several graphs on one page. I have multiple charts and want to update the data every 60 seconds so I use set interval, get the updated data, and then load it to a chart, however, it puts all of the data in the most recently made chart. I attempted to add a bindto to the data so it goes to the correct graph, but it still loads onto the bottom graph. how can I fix this?
...
<div id='chart1'></div>
<div id='chart2'></div>
...
function update()//this function collects the new data in arrays cols and xrows
...
setInterval(function(){
update();
chart.unload();
chart.load({bindto:'#chart1',columns:cols, xs:xrows});
},3000);
For showing update data atfirst
hide previous data's DIV
Use CLEAR to for cleaning Data
Again Load the DIV
If anyone's still looking to do this I've found a solution.
When you generate each chart, the declaration ends with:
}); }, chart = generate();
If you rename chart like so:
}); }, first_chart = generate();
Then you can manipulate that chart like so:
first_chart.load ({ <some_stuff> })
Give each chart variable a distinct name and you can edit them distinctly.
Related
In my project I have I have ten graphs in a table with each graph showing two datasets.
I want to toggle the visibility of each dataset by clicking it which is default behaviour in ChartJS.
All the charts are held in an array and following the built in toggle method of ChartJS, every chart is updated to the dataset of the first chart. So to be clear, when the page loads, each chart is shown correctly, but if I made the dataset invisible and visible again, it becomes visible but with the wrong data.
I tried writing my own update function to toggle the visibility.
var option = {
legend: {
onClick: ToggleDatasetVisibility,
}}
and then
function ToggleDatasetVisibility() {
this.chart.getDatasetMeta(1).hidden = !this.chart.getDatasetMeta(1).hidden;
// this.chart.update();
}
However exactly the same thing happens. After the update,
*Note, I'm only toggling the second dataset of each DatasetMeta so that's why the 1 is hardcoded in this example. That's not the chart in question.
In case it's useful, we is the code when the charts are primed with data when the page loads and here the update shows the correct data.
for (var i = 0; i < 10; i++) {
var MyArray= await fetch("http://localhost:1234/Demo/FetchResults?model_id=" + i);
//Add the recorded tunnel data to dataset 0
LineChartArray[i].data.datasets[0].data = ResultsArray;
LineChartArray[i].data.datasets[0].label = '';
LineChartArray[i].data.datasets[1].data = MyArray;
LineChartArray[i].data.datasets[1].label = 'LabelXYZ';
LineChartArray[i].update(); //This update updates the graph with the correct data.
}
}
So, I don't know if there's a bug with chart JS or a correct determine which chart to update but I discovered that the render method works. This updates the chart following the visibility toggle loads the correct data back in when made visible. I thought it might be my use of the 'this' command but it works fine with the render method.
I just updated the toggle function like so,
function ToggleDatasetVisibility() {
this.chart.getDatasetMeta(1).hidden = !this.chart.getDatasetMeta(1).hidden;
this.chart.render();
}
I would like to create a highCharts page with a button to "re-animate" the chart.
When I initially create the series, I set the 'redraw' to FALSE:
$("contain").highcharts().addSeries({
name: "filter",
data: result
}, false, {duration: 300000, easing: 'linear'});
When I then manually call redraw() on the entire chart:
$("contain").highcharts().redraw()
...the chart animates from the start - BUT ONLY ONCE. After the charts are animated 'on-screen', I've found no way to have them re-animate from the start EXCEPT FOR REMOVING AND THEN RE-ADDING, not an ideal solution for my case as there will be many series (lines) & ALOT of data such that I was hoping there was a simpler solution (I see somebody answered while I editted the question)...
Is there any way to do this or will have to remove and then re-add the series each time I want to re-animate?
Here is the fiddle I promised earlier. It's using the remove/re-add concept which I do not love : http://jsfiddle.net/bhilleli/854jbbhg/
If you want to reanimate the same series, you will want to remove your current one and redraw it as a new series.
$('#button').click(function() {
$("contain").highcharts().series[0].remove();
$("contain").highcharts().addSeries({
name:"filter",
data: result} );
});
I would like to visualise a number of variables per country on a world map. With Google Fusion Tables I set up the map. Now I would like to flip between the variables/layers (Var_A and Var_B) I would like to visualise with a dropdown menu. I followed the code the Guardian used in this article.
In this example the formatting of the info window in the FusionTable itself seems to simply show up but that doesn't work for me.
This is the fusion table: https://www.google.com/fusiontables/embedviz?viz=GVIZ&t=TABLE&q=select+col0%2C+col1%2C+col2%2C+col3%2C+col4%2C+col5%2C+col6%2C+col7+from+19I14XgRDOk7697iWA8XSukbYBBelNRymFOqjw_ru&containerId=googft-gviz-canvas
Clicking on the respective country I would like to display an info window, which shows a chart (bar chart for example) showing the values Var_A and Var_A1 when Layer 'Var_A' is selected and Var_B and Var_B1 when Layer 'Var_B' is selected.
I tried with the code example in Add a google chart to a infowindow using google maps api ....
function drawChart(marker) {
var node = document.createElement('div'),
infoWindow = new google.maps.InfoWindow(),
chart = new google.visualization.PieChart(node);
chart.draw(data, options);
infoWindow.setContent(node);
infoWindow.open(marker.getMap(),marker);
}
... but not even the static google chart worked for me.
So I really have three problems here:
1) show ANY chart in the info window
2) show a chart using data from the respective data row (country)
3) show a chart using data from the respective data row (country) and depending on the selected layer
I tried for a couple of days now with many unsuccessful ways and I am stuck - ready to leave google maps if I can not get it to work. This is the fiddle of the last thing that did at least show a map - I had to remove all event listeners again...
fiddle: http://jsfiddle.net/sytpp/ovfauhwb/
Any help greatly apprechiated!!
observe the click-event of the FusionTablesLayer, you will get there the values for the particular row:
google.maps.event.addListener(layer,'click',function(e){
//which values need to be drawn in the chart, A or B ?
var prefix=document.getElementById('selector').value,
//collect the data
row={title:e.row.Country.value,rows:[]};
//Var_A or Var_B
row.rows.push([prefix,Number(e.row[prefix].value)]);
//Var_A or Var_B1
row.rows.push([prefix+'1',Number(e.row[prefix+'1'].value)]);
//call drawChart by passing the collected data and clicked position as arguments
drawChart(row,e.latLng);
});
Now use the data(Note: you may initially set the content of the infoWindow to an empty div-element, there is no need to create a new node each time)
function drawChart(row,position) {
// Create the data table.
var data = new google.visualization.DataTable();
//set the scheme
data.addColumn('string', 'label');
data.addColumn('number', 'amount');
//add the data
data.addRows(row.rows);
// Set chart options
var options = {'title':row.title,
'width':300,
'height':200,
legend:'none'};
//assuming the infoWindow already has the content set to a DOMNode, e.g. a div
var chart = new google.visualization.BarChart(infoWindow.getContent());
chart.draw(data, options);
infoWindow.setOptions({map:map,position:position});
}
Note: you must set the suppressInfoWindows-option of the FusionTablesLayer to true, otherwise 2 InfoWindows will open, the built-in and the custom where the chart will be drawn.
Demo: http://jsfiddle.net/doktormolle/o1fyarnf/
I've created a form that will allow me to edit parts of my chart. One of them is the subtitle but for some reason the chart.redraw() isn't working and I'm not getting an error message back. The chart needs to redraw once the input field has changed. The chart already updates with a redraw every minute so I know it works otherwise but for some reason in this single function it won't call redraw(). This is very important because another option is to hide/show the legend and that will need a redraw().
HTML:
<input type="text" placeholder="Sub Title" data-chart="chart_3972002" data-action="chartSub">
JavaScript:
$('input[data-action="chartSub"]').change(function(){
$('.unSaved').html('Saving').css('color','#669900').delay(800).fadeOut();
var key = $(this).data('chart');
var chart = JSON.parse(localStorage.getItem(key));
chart.subTitle = $(this).val();
localStorage.setItem(key, JSON.stringify(chart));
var Chart = $('#'+key).highcharts();
Chart.setTitle(null, {text: chart.subTitle});
Chart.redraw();
});
Set title function redraws chart automatically, so you don't need to use redraw() function.
http://api.highcharts.com/highcharts#Chart.setTitle()
I've got a Google Charts Table that displays a couple of columns and rows. Say for instance we have 4 columns(A,B,C,D respectively). How would I be able to still load column C's values, but just hide the column so that it's not getting displayed?
Thanks in advance!
Instead of drawing the DataTable, you have to create an in-between DataView object where you filter the original data. Something like this:
//dataResponse is your Datatable with A,B,C,D columns
var view = new google.visualization.DataView(dataResponse);
view.setColumns([0,1,3]); //here you set the columns you want to display
//Visualization Go draw!
visualizationPlot.draw(view, options);
The hideColumns method is maybe better instead of setColumns, choose yourself!
Cheers
Here's an alternative using a ChartWrapper instead of a chart.
var opts = {
"containerId": "chart_div",
"dataTable": datatable,
"chartType": "Table",
"options": {"title": "Now you see the columns, now you don't!"}
}
var chartwrapper = new google.visualization.ChartWrapper(opts);
// set the columns to show
chartwrapper.setView({'columns': [0, 1, 4, 5]});
chartwrapper.draw();
If you use a ChartWrapper, you can easily add a function to change the hidden columns, or show all the columns. To show all the columns, pass null as the value of 'columns'. For instance, using jQuery,
$('button').click(function() {
// use your preferred method to get an array of column indexes or null
var columns = eval($(this).val());
chartwrapper.setView({'columns': columns});
chartwrapper.draw();
});
In your html,
<button value="[0, 1, 3]" >Hide columns</button>
<button value="null">Expand All</button>
(Note: eval used for conciseness. Use what suits your code. It's beside the point.)
var view = new google.visualization.DataView(dataTable); //datatable contains col and rows
view.setColumns([0,1,3,4]); //only show these column
chart.draw(view, options); //pass the view to draw chat
You can do this with CSS.
"#table_div" is the div my table is wrapped in. I use this because there a multiple tables on the same page.
#table_div .google-visualization-table table.google-visualization-table-table
td:nth-child(1),th:nth-child(1){
display:none;
}
I also have an event handler on the chart's rows, and can still pick up the data from the hidden column.
If you want to use particular column value in control wrapper but don't want to show that column in Google Charts then do following things.
1) Add all column to your google charts data table.
2) Add following things to options of your chartWrapper.
// Set chart options
optionsUser = {
"series": {
0: {
color: "white",
visibleInLegend: false
}
}
};
3) In above code series, 0 means the first line in your line chart. So It will set the color to white and also hide column name in Legends.
4) This way is not the proper way to hide columns, Using DataView is recommended. Whenever you want to use data in the data table for adding controls to your chart but don't want to show that column in the chart this is the way.