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();
}
Related
I have a kendo grid with custom popup edit window to imitate popup edit, but with batch edit. Everything works fine, but I am experiencing a small issue. Whenever value is changed, the grid cell does not have that red triangle thingy in the corner indicating that this particular value different from original.
As I understand in this post, manually made changes in datasource does not appear on the grid, so I have to add them manually.
This post 'manually maintain dirty cell marker on paging in Kendo grid' gives an idea how to get it working. I could attach some listeners to kendoWindow inputs, track what fields are being edited, compare old and new values...
But is there a less painful way to achieve this functionality? Maybe there is some built in kendo function to achieve that?
Here's a small working example http://dojo.telerik.com/aSaXe/4
The red "dirty" marks appear automatically only when the built-in in-cell editing is used. From this point of view, your scenario requires these to be added manually after the custom editing popup is closed.
You may find the change event of the data item useful in the task. It will be fired each time a value in the popup is changed and the respective textbox is blurred.
var uid = $(e.target).parents('tr').attr('data-uid');
var grid = $('#grid').data("kendoGrid");
var dataItem = grid.dataSource.getByUid(uid);
dataItem.bind("change", function(args) {
// args.field
});
Finally, keep in mind that each change in the Grid dataSource causes the whole table to be redrawn (unless the built-in in-cell editing is used), so you will lose any previously applied custom styling.
You can use the save event on your kendo grid as:
save: function (e) {
addDirtyUid(e.model.uid);
setTimeout(refreshVisualDirtyElements, 100);
}
Other functions and var:
var dirtyIds = [];
function addDirtyUid(currentUid) {
if (dirtyIds.indexOf(currentUid) === -1) {
dirtyIds.push(currentUid);
}
}
function refreshVisualDirtyElements() {
for (var i = 0; i < dirtyIds.length; i++) {
var thisUid = dirtyIds[i];
$("tr[data-uid='" + thisUid + "']").find("td:eq(0)").addClass("k-dirty-cell");
$("tr[data-uid='" + thisUid + "']").find("td:eq(0)").prepend('<span class="k-dirty"></span>');
}
}
I have another question regarding AmCharts. I have got numerous graphs, but want to show only one Balloon. I am using the
chartCursor.oneBalloonOnly
right now. I am also using AmLegend. I want to dynamically change the information within the one balloon whenever the user dismisses or adds a graph via legend.
I imagine if kind of like this:
function adjustBalloonText(graphDataItem, graph){
var date = ""; //some kind of getDateInScrollbar here
var distance = ""; // some kind of getGraph1Value here
var duration = ""; // some kind of getGraph2Value here as well
return "date <br> distance <br> duration";
}
Please help me.
Thanks!
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.
If you want to understand my requirement , first you have to see this demo highcharts demo
. Now click on Tokyo from that demo chart, that tokyo line will be dissappear. Now I want to able to set that property in page load, I mean whenever the page is loaded, the tokyo link should be clicked and only one line should display, when I click on Tokyo then the tokyo line should display. You can find the source code from that demo itself Thank you in advance.
I think what you are after is a way to make only the clicked legend series show. If that is the case you can do it with the plotOptions.series.events.legendItemClick. To have only one series show up initially on the chart (but still show in the legend) you need to set that series' visible property to true and the others to false. If you want to have all series show on initial load that step can be ignored.
To get the toggle working you need to get the index of the legend item you clicked. You then loop through all the series in your chart to find the one that matches that clicked index. When it matches you set series\[i\].show() for the ones that don't you set series.hide().
Here is the basic toggling code:
series: {
events: {
legendItemClick: function (event) {
var seriesIndex = this.index;
var serie = this.chart.series;
console.log(seriesIndex);
for (i = 0; i < serie.length; i++) {
if (serie[i].index == seriesIndex) {
serie[i].show();
console.log(serie[i].index);
} else {
serie[i].hide();
}
}
return false;
}
}
}
And here is a live fiddle.
When creating chart, just set series.visible = false for series which should be hidden by default.
See docs.
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()