chart.getSelection() does not work properly with google bar charts - javascript

drawBarChart = function (data) {
//few statements goes here which sets options which are being passed to chartDraw i.e. t.options.chart.options
gChart = new google.visualization.BarChart(chartingPlace);
//setTimeout(function () {
// t.options.chart.options.height = ((t.chart.size.height) - 40) + "px";
////console.log(JSON.stringify(t.options.chart.options));
//google.visualization.events.addListener(gChart, 'ready', function () {
// grab a few details before redirecting
google.visualization.events.addListener(gChart, 'select', function () {
var selectedItem = gChart.getSelection()[0];
console.log(gChart.getSelection());
if (selectedItem) {
var topping = data.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
// });
});
gChart.draw(data, t.options.chart.options);
}
My app having a number of charts displaying for different scenarios. My requirement is, click on a bar from google bar chart and open a new tab associated with the name of the bar. For this purpose, I tried using direct 'select' event on bar chart as follows:
google.visualization.events.addListener(gChart, 'select', function () {
var selectedItem = gChart.getSelection()[0];
console.log(gChart.getSelection());
if (selectedItem) {
var topping = data.getValue(selectedItem.row, 0);
alert('The user selected ' + topping);
}
});
But I could not get, this returned empty array for gChart.getSelection(), so I tried the code with 'ready' event mentioned in as first code above.
It works, but not output is not consistent. sometimes it gives empty array and sometimes with selected object.
I am still not able to find why it is showing this kind of behavior
More info: my application is having different tabs, showing number of bar,line,area,combo charts on it. getSelection() works well with line chart but not able to get the consistent output with bars.
Any help is appreciable.
Please do not mark it as duplicate, as I have gone through other similar questions but they does not answer my issue, I do not have that privilege so I could not comment in replies asking for more clarification.
Similar question here : google visualization-Click event on barchart isStacked: true
Please help!
Thank you in advance!
Updates :
I could not get any answer or any response from here.
This is really very disappointing.
Solution:
This is how i worked out the solution for this problem :
The getSelection could not work for me so i tried click event on bar text. Through the click event i could get the text on bar and i linked it to opn new tab.
If anyone need solution in code, please let me know.
Thank you.

Please go through below code snippet, I corrected or you can say organised the code in different way. If you need further explanation please let me know.
google.visualization.events.addListener(googleChartObj, 'select', function () {
var selectedBar = googleChartObj.getSelection();
////console.log(selectedBar);
data.getRowLabel(selectedBar[0].row);
/// for Bar charts, normally row-parameters are used
/// manipulate on 'data' which refers to data-table to get desired results
});

Related

amCharts 4 chart not updating with switchbutton, slider

For a radar chart, I'm trying to toggle (with a switch button) or slide (with a slider) between different sets of data to display. (I'll include the button here first, but I'm eventually try to extend that to a slider later.). 1. Initialize button and keep track of user toggle. 2. Pick which data set to use. both generateRadarData and generateRadarData2 work well on their own if I use chart.data = either one.
The below is the edited attempt:
var chartSwitchButton = chart.chartContainer.createChild(am4core.SwitchButton);
chartSwitchButton.events.on("toggle", function () {chart.data = whichData();})
function whichData() {
var dataToUse = chart.data;
if (chartSwitchButton.isActive) {dataToUse = generateRadarData();
} else {
dataToUse = generateRadarData2();}
return dataToUse};
chart.data = whichData();
I have tried commenting out the last line (since ideally it would have been updated via the event listener), but then no data displays.
Here is a more recent attempt to update the data using invalidateRawData:
chartSwitchButton.events.on("toggle", function (event) {
chart.data = whichData();
chart.invalidateRawData();
});
function whichData() {
var data = [];
if (chartSwitchButton.isActive) {
chart.data = generateRadarData();
} else {
chart.data = generateRadarData2();
}
chart.invalidateRawData(); //also tried invalidateData. tried this command in event listener as well as here.
data.push(chart.data); //attempt to replace/update raw data
//console.log(chart.data);
return chart.data; //this return line is necessary to output data but theoretically shouldn't be.
}
and have tried implementing the if-else w/in the event listener without having to use whichData as a separate function like so:
chartSwitchButton.events.on("toggle", function () {if (chartSwitchButton.isActive) {
chart.data = generateRadarData();
} else {
chart.data = generateRadarData2();
}
chart.invalidateRawData();})
I'm still unable to switch between the two sets of data with user interaction. In fact, if I don't return something for chart.data or declare what chart.data is supposed to be outside of the events.on or whichData(), then none of my data prints at all.
If anybody has suggestions on how to do this with a button (or a slider would be even better) that would be awesome.
Basically, after setting up the button, I tried to (a) keep track of the state of the button (as determined by user), (b) determine which state the button is in, and (c) pick a data set to use based off of that info. This version is edited from a previous attempt as per initial comments below. Thanks for your help.
Documentation is "toggled" not "toggle" in the events listener. The event does not recognize "toggle" but needed "toggled". https://www.amcharts.com/docs/v4/reference/switchbutton/#toggled_event

Invoke JavaScript function at GridView cell click

I have a DevExpress gridview with the following settings.
settings.Name = "DetailGridView";
// this calls DetailGridView.StartEditRow() on client side
settings.ClientSideEvents.RowClick = "Fn.startEditingRow";
settings.SettingsEditing.Mode = DevExpress.Web.GridViewEditingMode.Inline;
I have removed many other settings I have for simplicity, but ask if you think I need to show some other settings which are relevant.
Now I want to invoke a JavaScript function at each cell click. To do that I have added this settings, as per this SO answer, and this DevExpress thread
settings.HtmlDataCellPrepared += (sender, e) =>
{
string onClickFunctionJS = "Fn.DetailOnlyOnCellClick({0},'{1}');";
e.Cell.Attributes.Add("onclick", String.Format(onClickFunctionJS, e.VisibleIndex, e.DataColumn.FieldName));
};
The JS function Fn.DetailOnlyOnCellClick() prints to console the value of the field name (the 2nd argument). But it only prints clicked cell's field name the first time the row is clicked. After that clicking on a different cell in the selected row doesn't trigger the function Fn.DetailOnlyOnCellClick() anymore. I have observed that if I turn off ClientSideEvents.RowClick, it works fine, but I can't turn that off for other reasons. How can I get the which cell the user clicks on while keeping ClientSideEvents.RowClick on?
I have solved my problem, thanks to DevExpress support center. First, I couldn't use settings.HtmlDataCellPrepared because, as I mentioned in the question, the grid view enters edit mode when a row is clicked, and in edit mode settings.HtmlDataCellPrepared is not supposed to work the way I need it for my situation. So I started to use this code:
settings.CellEditorInitialize = (s, e) =>
{
var elementEditor = e.Editor;
string onClickFunctionJS = "DetailOnlyOnCellClick({0},'{1}');";
DevExpress.Web.Rendering.GridViewTableInlineEditorCell cell =
elementEditor.Parent as DevExpress.Web.Rendering.GridViewTableInlineEditorCell;
cell.Attributes.Add("onclick",
String.Format(onClickFunctionJS, e.VisibleIndex, e.Column.FieldName));
};
This code worked fine for every different control. The only catch was when the field is a checkbox and the cell is disabled. To get around this, I have used this code for checkbox controls:
string func = String.Format(
"ASPxClientUtils.AttachEventToElement(s.GetMainElement(), 'click', function() {{ {0} }} )",
String.Format(onClickFunctionJS, e.VisibleIndex, e.Column.FieldName));
(elementEditor as ASPxCheckBox).ClientSideEvents.Init = String.Format("function(s,e){{ {0}; }}", func);
This code works perfectly.
Links to the two methods used:
ASPxClientUtils.AttachEventToElement
ASPxClientControlBase.GetMainElement
P.S.: Both these approaches I have shown here are from DevExpress experts, and I got these answers from DevExpress's support center. I will provide link to my question once I can fix the issue with license and the ticket becomes public.

Ext Component Query Selector formats & options

I am a novice in Sencha Touch 2 & Ext too. I have jquery knowledge, so I am relating few things similar for quick understanding but got stuck in selector query.
I am creating dynamic textfields like:
var autoSuggestField = 'people_' + counter; // suppose counter is looping 5 times
var field = new Ext.field.Text({
name: autoSuggestField,
itemId: 'testing', // just for testing
// itemId: autoSuggestField, // actual code
inputCls:'auto-suggest',
placeHolder:'Select People',
cls:'place-holder',
listeners: {
clearicontap:function(obj, e, eOpts) {
// tried option 1
var allPeople = Ext.ComponentQuery.query('.place-holder .auto-suggest');
console.log(allPeople); // console says '[]'
// tried option 2
var allPeople = Ext.ComponentQuery.query('.place-holder');
console.log(allPeople); // console says '[]'
// tried option 3
var allPeople = Ext.ComponentQuery.query('.auto-suggest');
console.log(allPeople); // console says '[]'
// tried option 4
var allPeople = Ext.ComponentQuery.query('#testing');
console.log(allPeople); // console says '[class , class, class]'
}
}
});
But I am looking for something:
// var allPeople = Ext.ComponentQuery.query('[name^=people_]'); // as we do jquery
Or anything similar to it, which should work. Please clear what I am doing wrong in option[1,2,3] as most of the post says that using id[option 4] is bad. An how can we achieve using [name^=] "which says any element starting with people_". Is it possible in Ext? Is it possible through REGEX?(just for an idea)
Please add explanations for better understanding of selectors.
Instead of looking for regular expressinons you can add a an extra config like type:'people' for all the people related textfiled components and you can query it using the
var allPeopleComponents = Ext.ComponentQuery.query('textfield[type=people]');
The above will return the array of components having type='people'.
Please take a look here and for better understanding of ComponentQuery options here
Hope it helps you.

Use jQuery to determine when Django's filter_horizontal changes and then get the new data

I have a filter_horizontal selector in my Django admin that has a list of categories for products (this is on a product page in the admin). I want to change how the product change form looks based on the category or categories that are chosen in the filter_horizontal box.
I want to call a function every time a category is moved from the from or to section of the filter_horizontal.
What I have now is:
(function($){
$(document).ready(function(){
function toggleAttributeSection(choices) {
$.getJSON('/ajax/category-type/', { id: choices}, function (data, jqXHR) {
// check the data and make changes according to the choices
});
}
// The id in the assignment below is correct, but maybe I need to add option[]??
var $category = $('#id_category_to');
$category.change(function(){
toggleAttributeSection($(this).val());
});
});
})(django.jQuery);
The function never gets called when I move categories from the left side to the right side, or vice versa, of the filter_horizontal.
I assume that $category.change() is not correct, but I don't know what other events might be triggered when the filter_horizontal is changed. Also, I know there are multiple options inside of the select box. I haven't gotten that far yet, but how do I ensure all of them are passed to the function?
If anyone can point me in the right direction I would be very grateful. Thank!
You need to extend the SelectBox.redisplay function in a scope like so:
(function() {
var oldRedisplay = SelectBox.redisplay;
SelectBox.redisplay = function(id) {
oldRedisplay.call(this, id);
// do something
};
})();
Make sure to apply this after SelectBox has been initialized on the page and every time a select box refreshes (option moves, filter is added, etc.) your new function will be called.
(Code courtesy of Cork on #jquery)
I finally figured this out. Here is how it is done if anyone stumbles on this question. You need to listen for change events on both the _from and _to fields in the Django filter_horizontal and use a timeout to allow the Django javascript to finish running before you pull the contents of the _from or _to fields. Here is the code that worked for me:
var $category = $('#id_category_to');
$category.change(function(){
setTimeout(function () { toggleAttributeSection(getFilterCategoryIds()) }, 500);
});
var $avail_category = $('#id_category_from');
$avail_category.change(function(){
setTimeout(function () { toggleAttributeSection(getFilterCategoryIds()) }, 500);
});
And this is how I get the contents of the _to field:
function getFilterCategoryIds() {
var x = document.getElementById("id_category_to");
var counti;
var ids = [];
for (counti = 0; counti < x.length; counti++) {
ids.push(x.options[counti].value);
}
return ids;
}
I know it was a convoluted question and answer and people won't come across this often but hopefully it helps someone out.

Highcharts on click show larger graph

I'm setting up a way to be able to enlarge small-ish charts on my webpage by un-hiding a page 'overlay' div and creating a secondary, larger chart inside it with the same data as the chart which was clicked on.
function DrawSmallChart() {
chart_data = [1, 2, 3, 4, 5];
LargeChartOptions = {
series: [{
name: 'Data',
data: chart_data
}],
};
SmallChartOptions = {
series: [{
name: 'Data',
data: chart_data
}],
events: {
click = function (e) { DrawLargeChart(LargeChartOptions); }
}
};
$('#smallchart-div-container').highcharts(SmallChartOptions);
}
function DrawLargeChart(options) {
chart_container_div = document.getElementById("graph-div-id");
chart_container_div.style.display = ""
$('#graph-div-id').off();
$("#graph-overlay-graph").highcharts('StockChart', options);
}
I have another function that hides this div when I click a button.
The first time I click the small graph when the page loads, the big graph shows up fine with all the data. The second time I click it, the graph shows but with no data.
I've used the debugger to flick through what is happening and I've found exactly what the problem is, but I can't figure out how to solve it.
The first time I click the graph, the DrawLargeChart function is called with options.series = <Array containing my series object with chart_data>. The second time, DrawLargeChart is called with options.series = null.
When I refresh the page it is the same - first click works, subsequent clicks don't. I suspect it has something to do with the chart_data variable...
Any help would be greatly appreciated
EDIT 1:
After some more debugging, it is clear that the options object which is passed to DrawLargeChart() is not the same in the first click versus subsequent clicks. There is nothing in my code which is changing the LargeChartOptions structure
EDIT 2:
I figured out that this is a pass by value / pass by reference error. LargeChartOptions is being passed in by reference which no longer exists after the first click. Is there a way to pass it by value? I'd rather not have to type out the LargeChartOptions (much bigger than I've typed up here) into the function parameter in case I change anything in future
EDIT 3 // I've figured it out:
I figured out what the problem is. The $(target).highcharts(options) function actually modifies the options object and sets options.series = null
The solution
I modified the DrawLargeChart function to create a local copy of options by using options_buffer = $.extend(true,{},options);
function DrawLargeChart(options) {
chart_container_div = document.getElementById("graph-div-id");
options_buffer = $(target).highcharts(options);
chart_container_div.style.display = ""
$('#graph-div-id').off();
$("#graph-overlay-graph").highcharts('StockChart', options_buffer);
}
By creating options_buffer, the highcharts function cannot modify LargeChartOptions (because options is just a reference to that variable - yay Javascript)
I found the answer (in original post but copied here):
I modified the DrawLargeChart function to create a local copy of options by using options_buffer = $.extend(true,{},options);
function DrawLargeChart(options) {
chart_container_div = document.getElementById("graph-div-id");
options_buffer = $(target).highcharts(options);
chart_container_div.style.display = ""
$('#graph-div-id').off();
$("#graph-overlay-graph").highcharts('StockChart', options_buffer);
}
By creating options_buffer, the highcharts function cannot modify LargeChartOptions (because options is just a reference to that variable - yay Javascript)

Categories