How do I disable the export menu in amCharts - javascript

For one of our charts, we load it in batches, which could take a while. We'd like to disable the export menu (i.e., not allow it to open when the user clicks it) while the batches are loaded and enable it again once the last batch is in the chart. How does one go about doing that? Ideally, some indication that it's disabled (e.g., dimming, grey text) would also be nice to have.
For further info, the code for creating the menu is something along these lines:
chart.exporting.menu = new am4core.ExportMenu();
chart.exporting.menu.items = [
{
label: "...",
menu: [
{
type: "custom",
label: "CSV",
title: "Download CSV,
options:
{
callback: function()
{
// function for downloading CSV data
}
}
}]
}];
if (needPrintOption)
{
chart.exporting.menu.items[0].menu.push(
{
label: "Print",
title: "Print Chart",
type: "custom",
options:
{
callback: function()
{
// function to print chart contents
}
}
});
}
The menu is created when the chart is created. Essentially, I want the top level (labeled "...") to be disabled (ideally with some visual indication) while the chart is loading or being updated. (I don't want to have to create and destroy the menu, as we do have a live mode where the data in the chart is added to periodically. It would be less jarring for the user, visually, to disable the menu when I don't want user interaction with it and re-enable it when user interaction is allowed.)

You can use ready event:
chart.events.on('ready', () => {
chart.exporting.menu = new am4core.ExportMenu();
});

Related

Highmaps get country name on click when country has no data

I have a Highmaps-map of the world, and display data for some countries. Getting a click handler for these countries is simple. (see also highmaps get country name on click event)
However, I would like to be able to also detect clicks on countries without data.
I found I can add a generic click handler to the map, but the event does not give me the selected country.
Any hints?
Relevant part of the options:
options: {
chart: {
events: {
click: function (e) { console.log( e);},
All points without data are rendered as null points by default, so you need to only enable nullInteraction property:
series: [{
nullInteraction: true,
point: {
events: {
click: function() {
console.log(this.name)
}
},
},
...
}]
Live demo: https://jsfiddle.net/BlackLabel/wnfrza5j/1/
API Reference: https://api.highcharts.com/highmaps/series.map.nullInteraction

How to preserve ui-grid selection after changing data source?

As I understand, ui-grid uses the primaryKey grid option to preserve your selection across updates, but this simple plunker shows this is not true:
http://plnkr.co/edit/WYXeQShHWKDYDs4MIZnP?p=preview
Steps to repro:
Click a row to select it
Click "click me to reset the data source". This will reset the data source (to a data source that contains exactly the same data as before).
Your selection is now gone.
The initial data source is:
data: [
{ id: "item1" },
{ id: "item2" }
],
With
primaryKey: 'id',
When you click on the button, here is the handler:
$scope.resetDataSource = function()
{
$scope.gridOptions.data = [ { id: "item1" }, { id: "item2" } ];
$scope.$apply();
};
Removing the $scope.gridOptions.data = line will preserve the selection just fine.
The new data source is exactly the same (contents) as the old.
What can I do to preserve selection after assigning a new data source?
Try to use option restoreSelection
http://ui-grid.info/docs/#/api/ui.grid.saveState.service:uiGridSaveStateService

ExtJS 5.1 - Grid with gridfilters plugin breaks after grid.reconfigure

I'm migrating some ExtJS 4 stuff to ExtJS 5.1. I have a grid that gets it's metadata from the server and reconfigures the store on the metachange event:
store: Ext.create('Ext.data.Store', {
model: 'MyModel',
listeners: {
metachange: function (store, meta) {
this.grid.reconfigure(store, meta.columns);
},
scope: this
},
proxy: {
type: 'ajax',
url: '/mygriddata',
reader: {
type: 'json',
rootProperty: 'rows',
totalProperty: 'totalRows'
}
}
})
I also have gridfilters enabled for this grid. When the store loads for the first time, everything works correctly. I can press the trigger button for a grid column, the column menu appears with 'Sort Ascending', 'Sort Descending', 'Filters', and I can use the filter (date, string, etc) that I had specified for that column.
However, things break after the store reloads with different metadata, thus firing the metachange event and calling grid.reconfigure. Specifically, when I click on the trigger button of a grid column I get an 'undefined is not a function error' and the column menu does not appear.
This error does not occur if I change the metadata without first clicking on a column trigger button - it's something to do with building the filter menu item and then reconfiguring the grid, which breaks the filter menu item. It appears that when I reconfigure the grid I also need to somehow refresh the filters or rebuild the menu items but I'm not sure how to do that. Any help would be greatly appreciated, thanks!
Full stack trace of error:
Uncaught TypeError: undefined is not a function ext-all-debug.js:86455
Ext.define.getDockedItems ext-all-debug.js:86465
Ext.define.getDockingRefIt emsext-all-debug.js:87641
Ext.define.getRefItems ext-all-debug.js:130763
Ext.define.getRefItems ext-all-debug.js:75497
Ext.define.getRefItems ext-all-debug.js:7378
Ext.Base.Base.addMembers.callParent ext-all-debug.js:87640
Ext.define.getRefItems ext-all-debug.js:15057
getItems ext-all-debug.js:15310
cq.Query.Ext.extend._execute ext-all-debug.js:15271
cq.Query.Ext.extend.execute ext-all-debug.js:15480
Ext.apply.query ext-all-debug.js:63058
Ext.define.query ext-all-debug.js:63101
Ext.define.down ext-all-debug.js:101658
Ext.define.showMenuBy ext-all-debug.js:101651
Ext.define.onHeaderTriggerClick ext-all-debug.js:101179
Ext.define.onHeaderCtEvent ext-all-debug.js:11800
fire ext-all-debug.js:18530
Ext.define.fire ext-all-debug.js:18506
Ext.define.publish ext-all-debug.js:18556
Ext.define.doDelegatedEvent ext-all-debug.js:18543
Ext.define.onDelegatedEvent ext-all-debug.js:4402
Ext.Function.ExtFunction.bind.method
My solution:
Ext.define('Overrides.grid.filters.Filters', {
override: 'Ext.grid.filters.Filters',
onReconfigure: function(grid, store, columns, oldStore) {
var me = this;
me.sep = Ext.destroy(me.sep);
if (me.menuItems && me.menuItems[grid.id]) {
me.menuItems[grid.id].destroy();
}
me.callParent(arguments);
}
});

Rally App SDK 2.0rc1 - Why does my combobox ignore datastore filters only on first click?

I have the following code (sloppy, I know...first javascript app). I am trying to get a combobox to populate with a list of features that fall under a given release (as selected in the first combobox). Almost everything is now working correctly, except everytime I click the feature combobox for the first time, it loads ALL features and completely ignores the filter. Even if I change the release box first, the feature box still populates with all features only on first click. Subsequent times it shows the correctly filtered features.
Even stranger, I've tried writing the total records in the Feature Store to the console, so I can see when this happens. When the feature combobox is first created, it has the correct number of records in it. However, as soon as I click the feature combobox for the first time, it triggers the "load" listener of the combobox, and pulls in all the features, ignoring the filter completely.
I'm so boggled, I've tried so many things to debug this, and at this point have no other options. Does anyone have any ideas as to why it would load the correct data first, then reload it and ignore the filters on first click?
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var relComboBox = Ext.create("Rally.ui.combobox.ReleaseComboBox", {
fieldLabel: 'Choose a Release',
width: 300,
listeners: {
ready: function(combobox) {
this._releaseRef = combobox.getRecord().get("_ref");
this._loadFeatureInfo();
},
select: function(combobox) {
this._releaseRef = combobox.getRecord().get("_ref");
this._loadFeatureInfo();
},
scope: this
}
});
this.add(relComboBox);
},
_loadFeatureInfo: function() {
var featureStore = Ext.create("Rally.data.WsapiDataStore", {
model: "portfolioitem/Feature",
fetch: ["Name", "_ref"],
autoLoad: true,
filters: [
{
property: "Release",
operator: "=",
value: this._releaseRef
}
],
listeners: {
load: function(store) {
this._updateFeatureBox(store);
},
scope: this
}
});
},
_createFeatureBox: function(featureStore) {
this._featureComboBox = Ext.create("Rally.ui.combobox.ComboBox", {
fieldLabel: 'Choose a Feature to move',
store: featureStore,
listeners: {
select: function (combobox) {
this._featureRef = combobox.getRecord().get("_ref");
//calls method to get and display children of this feature in a grid
},
scope: this
}
});
this.add(this._featureComboBox);
},
_updateFeatureBox: function(featureStore) {
if (this._featureComboBox === undefined) {
this._createFeatureBox(featureStore);
} else {
this._featureComboBox.clearValue();
this._featureComboBox.bindStore(featureStore);
//calls method to get and display children of this feature in a grid
}
}
This is probably an issue caused by the featureStore loading twice: once when you created it, and the combobox also tells it to load again once the user opens the combobox to pick a Feature.
I encountered a very similar issue with a combobox on Stories, and I'd betcha dollars to donuts that Matt Greer's answer:
Strange Load behavior with Rally.ui.combobox.ComboBox
To my question, is the answer to yours too...

setActiveItem() passing data sencha touch

I would like to send data with setActiveItem() when doing view change from this store:
Ext.define('SkSe.store.Places',{
extend:'Ext.data.Store',
config:{
autoDestroy: true,
model:'SkSe.model.Places',
//hardcoded data
data: [
{
name: 'Caffe Bar XS', //naziv objekta
icon: 'Icon.png', //tu bi trebala ići ikona kategorije kojoj pripada
stamps: 'stamps1' //broj "stampova" koje je korisnik prikupio
},
{
name: 'Caffe Bar Mali medo',
icon: 'Icon.png',
stamps: 'stamps2'
},
{
name: 'Caffe Bar VIP',
icon: 'Icon.png',
stamps: 'stamps3'
}
]
//dynamic data (Matija)
//remember to change the icon path in "Akcije.js -> itemTpl"
/*proxy:{
type:'ajax',
url:'https://maps.googleapis.com/maps/api/place/search/json?location=-33.8670522,151.1957362&radius=500&types=food&name=harbour&sensor=false&key=AIzaSyCFWZSKDslql5GZR0OJlVcgoQJP1UKgZ5U',
reader:{
type:'json',
//name of array where the results are stored
rootProperty:'results'
}
}*/
}
});
This is my my details controller that should get data from places store:
Ext.define('SkSe.controller.Details', {
extend: 'Ext.app.Controller',
config: {
refs: {
placesContainer:'placesContainer',
Details: 'details'
},
control: {
//get me the list inside the places which is inside placesContainer
'placesContainer places list':{
itemsingletap:'onItemTap'
//itemtap:'onItemTap'
}
}
},
onItemTap:function(list,index,target,record){
console.log('omg');
var addcontact= Ext.create('SkSe.view.Details',
{
xtype:'details',
title:record.data.name,
data:record.data
});
var panelsArray = Ext.ComponentQuery.query('details');
console.log(panelsArray);
Ext.Viewport.add(addcontact);
addcontact.update(record.data.name);
Ext.Viewport.setActiveItem(addcontact);
console.log(record.data.name);
}
});
I would like to send name record from the places.js model above. I heard that you can't pass data with setActiveItem but should create a function that updates view(No I can't use pop and push here).
I'm not very familiar with sencha touch syntax and I'm not sure what functions to use to do that, clearly update function is not that.
I switched up your logic slightly but have provided a working example of what I think you are trying to do.
SenchaFiddle is a little different from what I get running on my machine but you should be able to get the idea.
The initial list loaded gets the data from your store, and on itemtap will push a new view onto the viewport.
You will need to add a navigation button to get back to the list from view.View as well as a better layout for the details. I would suggest nested containers or panels with custom styles to get the details just right. Alternatively you can just drop a full html snippet in there with all the data laid out like you want.
Would be happy to help more.
Fiddle: http://www.senchafiddle.com/#XQNA8

Categories