How I can manipulate with legend items on the chart from AgChartsReact? - javascript

I use a standalone chart from the Ag Grid library and want to manipulate manually which legend items should be shown/selected by default. I didn't find any specific API/property which can cover this use-case.
E.g., I want to see selected only the diesel legend item (and petrol should be shown unselected),
AgChartsReact always shows all legend items.
What did I investigate and try?
The chart is a canvas element, so I thought that it is possible to manipulate legend items from the canvas context, which I can get with useRef hook. But I cannot find how exactly it can be done and is it possible? Here is a ref to Plunker
UPD:
if someone is looking for how to store the data which legends is active or not, here is a function to get this (the same function you will find in Plunker):
const getLegendStatuses = () => {
const [changeEvent] = chartRef.current.chart.legend.allEventListeners.get("change");
const [, data] = changeEvent;
const [event] = data;
console.log(
event.data.map(({ enabled, label }) => ({ label: label.text, enabled }))
);
}

I think you want to use visible: false on the Petrol series.
This will still show up as greyed out in the legend, but you can click it to open it again.
You can also add showInLegend: false if you want to remove it from the legend.
If you want it greyed out in the legend but NOT clickable on the legend to make it visible, you might be able to make a custom listener for nodeClick, but I haven't tried that.

Related

ChartJS showing wrong dataset following visibility property toggle

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();
}

amCharts pie chart how to customize the balloon text

I am using amCharts pie chart (v3) and I want to customize the pop up balloon that comes on mouseover on a slice: in addition to routine text like [[value]] [[percent]],
(a) a text that depends on the data item, and
(b) provide different click options to the user depending on data item. Every data row might not have these possibilities in which case the options should not appear.
For example, the pie chart might show wine consumption by country. On hover, I want to provide the user two different click options - one to see consumption by season if available, plus another to see consumption by age group if available.
Is it possible to do so in amCharts? I saw an exit for event clickSlice() here http://docs.amcharts.com/3/javascriptcharts/AmPieChart but nothing on how to modify the balloon text on the fly and add behavior to the balloon that comes on hover.
Will greatly appreciate your help.
For writing dynamic text in the balloon you can also do the folowing:
"graphs": [{
"balloonFunction": function(graphDataItem, graph) {
var value = graphDataItem.values.value;
if (value < 500) {
return value + "<br>(Little)";
} else {
return value + "<br>(A Lot)";
}
}
}],
You can use the following tags: [[title]], [[description]], [[value]] and [[percent]]. says the documentation.
I have used description for a custom field, it works fine.
You can add any custom field to your data provider and then display it in your balloon in the same way as value:
{value:15, title:"slice title", someCustomField:"some custom data"}
and then:
chart.balloonText = "[[someCustomField]]";

add message on hover series name highcharts

i'm trying to add a message when hover a series name and i just cant find the way to do it,
this is what i want want to happen:
when the user hover the "all your locations" series name the red box will apear.
as for now the only way i found to do it is to search div contains the same words but its a really bad practice and im pretty sure there is a better way to do it..
is it possible to do it via highcharts ?
A popup like that is not in the Highchart API for the legend. The closet thing is Legend.ItemOnHover
legend: {
itemHoverStyle: {
color: '#FF0000'
}
}
But that really only styles it.
The way you are currently doing it is probably fine if you are careful about it.
You can try to add tooltip to the legend item, like in the related topic Add tooltip to legend in highcharts when hovering
the only way i have found to do this popup is by adding this function in the end of the function building the chart :
var titles = $("tspan");
$("tspan").each(function(index) {
if( (this.textContent.indexOf("cashiers data") !== -1) ){
$(titles[index]).click(function(){
alert('to use our new cashiers bars \n'
+'please contact us at our contact page');
return false;
})
}
});

Persisting flot legend label checkbox on un-check

I have a scenario where I want to toggle series based on checkbox selection. I have added the checkbox to the legend using labelFormatting in legend option like:
var otherOptions = {
legend: {
container: legend,
labelFormatter: function (label, series) {
var cb = '<input type="checkbox" name="' + label + '" checked="checked" id="id' + label + '"> ' + label;
return cb;
}
},
};
And I have added the click event for the legend so that I can manipulate the series based on checked items. It all works fine except when I uncheck a label in legend, on re-draw it removes that series line from the legend as well. So for ex., below is the before and after image:
Before
After
Notice that in after image "USA" checkbox is missing.
Is there any way I can still show the unchecked "USA" checkbox in legend?
I looked at the suggestion here: flot graph, use legend to turn on/off series
But the only problem is that I don't want to have legend AND checkbox legend separate. The question on the given link was answered 1+ year ago so I thought I am gonna take a chance and ask the question again in case someone knows a way to do this.
Please let me know.
Thanks!
Instead of removing the series all together if the checkbox is unchecked, add it with empty data.
Something like this:
function plotByChoice(doAll)
{
$('#legend .legendCB').each(
function(){
if (this.checked)
{
data.push(datasets[someLabel]);
}
else
{
data.push({label: someLabel, data: []})
}
}
);
// plot call etc...
}
Working fiddle is here.
For anyone looking for a clean solution AND for Chart.js v3 :
This is unfortunately not possible for Chart.js v3 as legends are generated with text (no HTML can be appended to the legend itself, unfortunately).
We have to use generateLabels function to render the legend labels.
I suggest using the pointStyle option to render an image (checkbox, actually), instead of a rectangle by default, so we can rerender automatically everytime the user checks or not the legend (it's dynamic, ofc, and we don't have to do something complicated programmatically).
So, first, generate the 2 images, corresponding to the checkboxes (I'm using FontAwesome icons that I've generated in PNG from SVG files) :
let checkboxYes = new Image(14, 14);
checkboxYes.src = '/static/img/check_yes.png';
let checkboxNo = new Image(14, 14);
checkboxNo.src = '/static/img/check_no.png';
Then, we can use it in the Chart.js options:
legend: {
labels: {
usePointStyle: true,
generateLabels: function(chart) {
labels = Chart.defaults.plugins.legend.labels.generateLabels(chart);
for (var key in labels) {
labels[key].pointStyle = labels[key].hidden ? checkboxNo : checkboxYes
}
return labels;
}
}
},
Explanations
I'm setting usePointStyle to true so that I can customize the point style
later
Chart.defaults.plugins.legend.labels.generateLabels(chart) kind of pre generate the labels for me (and store it into labels), so it's like a function override!
Then for each label, I'm changing its pointStyle to the checkbox image depending on the hidden parameter (if the user checked the box)
Finally, return the labels
It's perhaps not the best solution, but works amazingly well for me:
Click here to see the animated result in GIF :)

how to hide column in google charts table

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.

Categories