Shield UI Chart won’t show again after being hidden - shieldui

I have followed your advice, however once hidden, the chart won’t show up when the check box has been unchecked. Here is my code:
var charta=document.getElementById("Chart_A").value;
var containter = $("#ChartA_Container").swidget();
containter.destroy();
if (Chart_A.checked == false){
$("#ChartA_Container").shieldChart(
{
seriesSettings: {
line: {
applyAnimation: {
duration: 0
},
pointMark:{
enabled: false
}
}
},
tooltipSettings: {
enabled: false
},
exportOptions:
{
image: false,
print: false
},
axisX: {
min: 0,
max: 55
},
primaryHeader: {
text: "EUR/USD"
},
dataSeries: [
{
seriesType: 'line',
collectionAlias: 'EUR/USD',
data: EURUSD,
}
]
}
)
}else{
document.getElementById("EURUSDChart").innerHTML="Chart Hidden"
};
I will appreciate some more detailed help on this matter.

The problem is quite simple. The containter.destroy(); statement is used to unset the chart’s container.
Once done, there is no container which to be unset the next time function is called.
What you need is to put this statement inside the checkbox clause, so that if destroyed, it is immediately recreated:
if (Chart_A.checked == false){
var containter = $("#ChartA_Container").swidget();
containter.destroy();

Related

PrimeNG p-table Lazy loading and Multi Sort - Goes in Loop - Maximum call stack size exceeded

Stackblitz: https://stackblitz.com/edit/primeng-p-table-multisort
Config:
"#angular/cli": "~7.0.2",
"primeng": "7.0.5",
I have a PrimeNG p-table implemented with lazy loading. Need multi column sort added to it.
Sample code from above Stackblitz link.
<p-table [columns]="cols" [value]="cars1" [lazy]="true" [lazyLoadOnInit]="false" (onLazyLoad)="loadList($event)" sortMode="multiple" [multiSortMeta]="multiSortMeta">
This works properly if its single sort mode.
Getting error as ERROR RangeError: Maximum call stack size exceeded.
It should be a simple implementation but not able to understand what is missing here or this is not supported by PrimeNG.
Any help is appreciated.
This issue was because of this.cdRef.detectChanges(); Here is why
loadList is binded to (onLazyLoad)="loadList($event)" in HTML.
PrimeNg calls that event every time when paging, sorting, and filtering happens. So, when we are loading and adding sorting events it keeps calling. And Angular change detection also called every time, that leads to error ERROR RangeError: Maximum call stack size exceeded
loadList($event: any = {}) {
this.cars1 = [
{
vin: "a1653d4d",
brand: "VW",
year: 1998,
color: "White",
price: 10000
},
{
vin: "ddeb9b10",
brand: "Mercedes",
year: 1985,
color: "Green",
price: 25000
}
];
this.cdRef.detectChanges(); // this is the issue
}
modified
ngOnInit() {
this.cols = [
{ field: "vin", header: "Vin" },
{ field: "year", header: "Year" },
{ field: "brand", header: "Brand" },
{ field: "color", header: "Color" }
];
this.multiSortMeta = [
{ field: "year", order: 1 },
{ field: "brand", order: -1 }
];
this.loadList();
}
loadList($event: any = {}) {
this.cars1 = [
{
vin: "a1653d4d",
brand: "VW",
year: 1998,
color: "White",
price: 10000
},
{
vin: "ddeb9b10",
brand: "Mercedes",
year: 1985,
color: "Green",
price: 25000
}
];
// this.cdRef.detectChanges();
}
The bottom line is this.cdRef.detectChanges(); need to be used carefully and smartly in anywhere in the application if you are using it.
updated stackblitz
Updated Stackblitz: https://stackblitz.com/edit/primeng-p-table-multisort
It worked with overriding the PrimeNG Table - sortMultiple method via prototype chain.
Old code:
Table.prototype.sortMultiple = function () {
var _this = this;
if (this.multiSortMeta) {
if (this.lazy) {
this.onLazyLoad.emit(this.createLazyLoadMetadata());
}
else if (this.value) {
if (this.customSort) {
this.sortFunction.emit({
data: this.value,
mode: this.sortMode,
multiSortMeta: this.multiSortMeta
});
}
else {
this.value.sort(function (data1, data2) {
return _this.multisortField(data1, data2, _this.multiSortMeta, 0);
});
}
if (this.hasFilter()) {
this._filter();
}
}
this.onSort.emit({
multisortmeta: this.multiSortMeta
});
this.tableService.onSort(this.multiSortMeta);
}
};
New code:
Table.prototype.sortMultiple = function () {
const _this = this;
if (this.multiSortMeta) {
if (this.lazy) {
// additional conditions added
if (this.lazyLoadOnInit || (!this.lazyLoadOnInit && this.initialized)) {
this.onLazyLoad.emit(this.createLazyLoadMetadata());
}
} else if (this.value) {
if (this.customSort) {
this.sortFunction.emit({
data: this.value,
mode: this.sortMode,
multiSortMeta: this.multiSortMeta
});
} else {
this.value.sort(function (data1, data2) {
return _this.multisortField(data1, data2, _this.multiSortMeta, 0);
});
}
if (this.hasFilter()) {
this._filter();
}
}
this.onSort.emit({
multisortmeta: this.multiSortMeta
});
this.tableService.onSort(this.multiSortMeta);
}
};

Display highcharts graph with a lot of data in angularjs

I have an angularjs application and I use highcharts-ng to display some graphs. I got the data from an http request and I modify the data to display them in the graph.
If I receive just a just some data, it's ok, it works but when I receive a lot of data, the highcharts component take a long time to display the data. And in this time the browser in freezed.
In my controller, I have:
widgetCtrl.chartDataLine = {
chart: {
type: 'spline',
zoomType: 'xy'
},
title: {
text: 'Power Consumption'
},
xAxis: {
type: 'datetime',
title: {
text: 'Date time'
}
},
yAxis: {
title: {
text: 'Power (W)'
},
min: 0
},
options: {
exporting: {
enabled: true,
allowHTML: true,
buttons: {
contextButton: {
menuItems: null,
onclick: function () {
this.exportChart();
}
}
}
}
},
plotOptions:{
series:{
turboThreshold:60000 // larger threshold or set to 0 to disable
}
},
series: []
};
I call the data like that:
var getMetrics = function (searchText) {
var param = {
target: searchText
};
xcsDatasource.get('beo').callAction('getPowerMetrics', param.target, widgetCtrl.pickerFrom.date, widgetCtrl.pickerTo.date).then(
function (result) {
widgetCtrl.metrics = result;
widgetCtrl.metricsAsString = JSON.stringify(result);
var t = getChartData(result);
widgetCtrl.chartDataLine.series = angular.copy(t);
console.log(widgetCtrl.chartDataLine);
//widgetCtrl.chartDataArea.series = getChartData(result);
},
function () {
widgetCtrl.metrics = {};
widgetCtrl.metricsAsString = '';
}
);
};
And this is my html:
<div ng-if="config.linechart" class="graph-container col-sm-12">
<highchart id="chart1" config="pwrDashboardViewCtrl.chartDataLine"></highchart>
</div>
Do you have an idea how I can do to continue to load the grapph without freezing the browser ?

Kendo grid not showing data only on the initial load, but works fine when stepping through with breakpoints

The problem I'm having is exactly what I said in the title. When I step through my application in the debugger it properly sets everything that needs to be set, but when I just let it go through on its own, it never loads data on the initial attempt, but if i go back and click the same thing again, or any thing else that has to send data to this grid, it will forever work. Even if I go to a page that empties everything in the grid and then go back to one that shows data again.
To me it sounds like a timing issue, but using $timeout() before the data calls doesn't seem to be working. And I set up a broadcast that should only be called after all the data is pulled in and set, and only then should it go to the code for the kendo grid and start painting it on the page.
Like I said stepping through this code line by line on the initial load of the page, it works exactly as it should and pulls in all data that it needs, but letting it just run without me doing that, it never does.
here is hopefully enough code to go off of.
Here is the code for my grid:
$scope.$on('loadRxHistoryGrids', function () {
console.log('user id of ' + pServ.patientId.get());
$scope.activeHistoryGrid = {
pageable: {
pageSizes: [5, 10, 15, 20],
},
dataSource: new kendo.data.DataSource({
type: 'aspnetmvc-ajax',
contentType: "application/json; charset=utf-8",
transport: {
read: {
url: function () {
var x = pServ.patientId.get();
return "api/rx/ActiveRxHistory/" + pServ.patientId.get();
},
dataType: "json",
type: "POST"
},
},
pageSize: 5,
schema: {
model: {
fields: {
rxId: { type: "number" },
refillsLeft: { type: "number" },
shortName: { type: "string" },
unitsRemaining: { type: "number" },
dispenseRefillQuantity: { type: "number" },
description: { type: "string" },
shipDate: { type: "date" }
},
},
data: function (data) {
if (data != undefined) {
$scope.ActiveHistoryCount = data.length;
return data;
} else { return []; }
},
total: function (data) {
return data.length;
},
},
}),
serverPaging: true,
serverSorting: true,
serverFiltering: true,
columns: [
{ hidden: true, field: "rxId"},
{ field: "shortName", title: "DRUG NAME"},
{ field: "refillsLeft", title: "REFILLS LEFT", width: "16%", template: '#= (refillsLeft == null) ? " " : kendo.toString( refillsLeft, "n0")#', attributes: { style: "text-align:left" } },// template: '<div style="text-align:left">#= ((unitsRemaining == null) || (dispenseRefillQuantity == null)) ? " " : kendo.toString(unitsRemaining / dispenseRefillQuantity, "n5")#</div>' },
{ field: "description", title: "STATUS", width: "14%", template: '<div style="text-align:left">#= (description == null) ? " " : description#</div>' },
{ field: "shipDate", title: "SHIPPED DATE", width: "15%", template: '#= (shipDate == null) ? " " : kendo.toString(kendo.parseDate(shipDate), "MM/dd/yyyy") #' }
],
groupable: false,
scrollable: true,
selectable: true,
resizeable: true,
sortable: true,
}
Here is the other code where the broadcast is being sent:
$scope.$on('loadPatientProfileData', function () {
//A lot of data gets and sets are being done here for other things on the
//page, all data is being set in the grid datasource itself
setTimeout(function () {
$rootScope.$broadcast('patientProfile-DataPullFinish');
$rootScope.$broadcast('loadRxHistoryGrids');
}, 100);
});

DevExtreme Grid - Editing mode

tvaLst = [{
id: 1,
taux: 5,
ole: true},
{ id: 2,
taux: 13.01,
ole: false
}];
Imagine that from a service I retrieve the above list of Objects, and I want to show the taux value and in the second column the Edit and Delete Option Only for the lines where the attribute ole is set to true.
this.gridSettings = {
bindingOptions: { dataSource: 'vm.tvaLst' },
allowColumnResizing: true,
scrolling: { mode: 'virtual' },
onContentReady: this.contentReadyAction,
paging: { enabled: false },
editing: {
mode: "row",
allowUpdating: true,
allowDeleting: true,
allowAdding: true
},
columns: this.gridColumns
};
In editing what should I do to allow this?
You can find and hide the Edit button in the onCellPrepared event handler.
Here is a sample code:
onCellPrepared: function (options, $container) {
if (options.column && options.column.command === "edit" && options.rowType == "data") {
if (options.cellElement.find('a').first().text() === 'Edit') {
if (options.data.ole === false){
options.cellElement.find('a').first().hide();
options.cellElement.find('a').eq(1).hide();
}
}
}
}
Here is on online example: http://plnkr.co/edit/l4PRpDkbaHRgB4ntXoQD?p=preview

get checkbox group values in angular watch

when tick on each checkbox, i can get all the checked values.
i want to put these values to their respective group.
here are my expected result :
{
'pattern' : ["Plain","Self Design"],
'colour' : ["Blue","Grey"]
}
im using angular $watch to get the selected values.
$scope.$watch('filters|filter:{selected:true}', function (nv, ov, scope) {
$scope.filter_selected = [];
angular.forEach(nv, function (value) {
angular.forEach(value.options, function (v, k) {
if (v.selected == true) {
this.push(v.name);
}
}, $scope.filter_selected);
});
}, true);
here is the full code in fiddle
UPDATE:
i manage to get my expected result with these code :
$scope.$watch('filters|filter:{selected:true}', function (nv, ov, scope) {
$scope.filter_selected = {pattern: [], colour: []};
angular.forEach(nv, function (value) {
if (value.name == 'pattern') {
angular.forEach(value.options, function (v, k) {
console.log(this);
if (v.selected == true) {
this.push(v.name);
}
}, $scope.filter_selected.pattern);
}
if (value.name == 'colour') {
angular.forEach(value.options, function (v, k) {
//console.log(this);
if (v.selected == true) {
this.push(v.name);
}
}, $scope.filter_selected.colour);
}
});
updated fiddle
now, how to make my checking part dynamic if i have more groups?
I have updated your code to simplify what you have above, hopefully achieving the outcome you want. I don't really think you need the watch (unless your update requirements are more complicated), but you should be able to build upon this never the less.
http://jsfiddle.net/j35zt/
The controller code was simplified as follows:
app.controller('FilterCtrl', function ($scope, $http) {
$scope.filters = [
{ name: 'pattern', placeholder: 'pattern',
options: [
{ name: 'Plain', selected: false },
{ name: 'Self Design', selected: false },
{ name: 'Check', selected: false },
{ name: 'Stripe', selected: false },
{ name: 'Print', selected: false }
]},
{ name: 'colour', placeholder: 'colour',
options: [
{ name: 'White', selected: false },
{ name: 'Blue', selected: false },
{ name: 'Grey', selected: false }
]}
];
$scope.updateOutput = function() {
$scope.filter_selected = {};
angular.forEach($scope.filters, function(f) {
$scope.filter_selected[f.name] = [];
angular.forEach(f.options, function(o){
if(o.selected){
$scope.filter_selected[f.name].push(o.name);
}
});
});
}
});
Just note, that the view also needed to be changed to match the controller. Basically ng-change is the sole cause of the updating.

Resources