how to implement progress bar in ag-grid table - angularjs

I have to implement progress bar in ag-grid table column , i have search in ag-grid documentation section but there is nothing. any other website for the same.
Thank you in advanced.

You can use cellRenderer config of a column to specify which function or compnent should be rendered in the cell.
Here is a link to examples that does not really talk about rendering the progressbar but it shows quite a few examples to render custom elements in the cell. You can modify the HTML of these to return and render an HTML div as per your requirement.
https://www.ag-grid.com/javascript-grid-cell-rendering-components/

Do like this may be it will help you (it is JavaScript version). to get more info click on below link . may be it will help you
https://docs.google.com/document/d/10K54wwj12IH9P1CI1Uv2k3MD__P8-LQDYqL8ofe9Exk/edit?usp=sharing
process bar is from https://getbootstrap.com/docs/4.0/components/progress/
const columnDefs = [
{
headerName: "Process Bar",
minWidth: 150,
field: "process_bar",
sortable: true,
valueFormatter: function (params) {
if (params.value !== undefined) {
if(params.value==""){
return '<div class="progress">
<div class="progress-bar" role="progressbar"style="width: 25%;" aria-valuenow="'+params.value+'" aria-valuemin="0" aria-valuemax="100">25%
</div>
</div>';
}else{
return params.value;
}
}
}
}
];
const gridOptions = {
defaultColDef: {
flex: 1,
resizable: true,
},
getRowStyle: params => {
if (params.data != undefined){
if (params.data.rowColor=="blue") {
return { background: '#f9f9f9' };
}else{
return { background: 'white' };
}
}
},
components: {
loadingRenderer: function (params) {
if (params.value !== undefined) {
return params.value;
} else {
return '<img src="loading.gif">';
}
},
},
singleClickEdit: true,
rowBuffer: 0,
rowSelection: 'multiple',
caseSensitive: false,
rowModelType: 'infinite',
columnDefs: columnDefs,
pagination: false,
paginationPageSize:100,
cacheOverflowSize: 2,
maxConcurrentDatasourceRequests: 1,
infiniteInitialRowCount: 1000,
maxBlocksInCache: 10,
overlayNoRowsTemplate:'<span style="padding: 10px; border: 2px solid #444; background: lightgoldenrodyellow;">No Data Found!</span>',
};

One possible way: create your own loading overlay for the grid.
https://www.ag-grid.com/javascript-grid-overlays/
or
https://www.ag-grid.com/javascript-grid-overlay-component/
In the overlay, you can use any progress bar of choice (e.g. Bootstrap).

Related

custom legend hide() does not remove data labels

I am building a project using React with a doughnut and bar chart. Working with Chart.js 3.xx.
I am trying to make my custom legend functional. I want to make data fractions disappear when the user clicks my legend items - like in the native legend, and optimally also remove the data and make the chart present it's updated data after removal.
I also use data labels to present percentage of the data on the fractions.
import ChartDataLabels from 'chartjs-plugin-datalabels';
I came across this topic: ChartJS - Show/hide data individually instead of entire dataset on bar/line charts
and used this suggested code there:
function chartOnClick(evt) {
let chart = evt.chart
const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
if (points.length) {
const firstPoint = points[0];
//var label = myChart.data.labels[firstPoint.index];
//var value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
let datasetIndex = firstPoint.datasetIndex, index = firstPoint.index;
if (firstPoint.element.hidden != true) {
chart.hide(datasetIndex, index);
} else {
chart.show(datasetIndex, index);
}
}
}
options: { // chart options
onClick: chartOnClick
}
It almost works, but the hide() method doesn't remove the fraction's percentage data label when activated, whereas when clicking the native legend it does remove it entirely.
I tried looking in the plugin's docs but didn't manage to find how to remove a single label.
How can I achieve what I am looking for?
EDIT:
Options Object:
export const doughnutOptsObj = {
onClick: chartOnClick,
responsive: true,
maintainAspectRatio: false,
layout: { padding: { top: 16, bottom: 16 } },
hoverOffset: 32,
plugins: {
legend: {
display: true,
position: 'bottom',
},
datalabels: {
formatter: (value, dnct1) => {
let sum = 0;
let dataArr = dnct1.chart.data.datasets[0].data;
dataArr.map((data) => {
sum += Number(data);
});
let percentage = ((value * 100) / sum).toFixed() + '%';
return percentage;
},
color: ['#fbfcfd'],
font: { weight: 'bold' },
// display: false, <-- this works and makes all of the data labels disappear
},
},
};
It seems that the onClick function is working properly.
I have tried the attached code, leveraging on toggleDataVisibility API, and it's working as requested (codepen: https://codepen.io/stockinail/pen/abKNJqJ):
function chartOnClick(evt) {
let chart = evt.chart
const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
if (points.length) {
const firstPoint = points[0];
chart.toggleDataVisibility(firstPoint.index);
chart.update();
}
}

Se Chartjs horizontal

I want to create a horizontal bar chart like this photo using Chartjs library
So I follow the instructions and I have something like:
TS:
createAreaChart() {
this.barChart1 = document.getElementById('barChart1');
this.ctx1 = this.barChart1.getContext('2d');
let i = 0;
this.data1.forEach(div => {
if(i==0){
this.backgroundColors.push('#A60A2D');
} if(i==1) {
this.backgroundColors.push('#00A2C3');
} if(i==2) {
this.backgroundColors.push('#434F55');
i = -1;
}
i++;
});
this.chart1 = new Chart(this.ctx1, {
type: 'bar',
data: {
labels: this.data1.map(r => r.icon),
datasets: [{
data: this.data1.map(r => r.total),
label: 'Annual Cost',
backgroundColor: this.backgroundColors,
borderColor: this.backgroundColors,
borderWidth: 1
}]
},
options: {
legend: {
display: false
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var value = data.datasets[0].data[tooltipItem.index];
if (parseInt(value) >= 1000) {
return '$' + value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return '$' + value.toFixed(2).toString();
}
}
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
precision: 2,
userCallback : function(value, index, values) {
if(parseInt(value) >= 1000){
return '$' + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return '$' + value;
}
}
}
}]
}
}
});
this.chart1.height = 225;
}
HTML
<div class="card chart-card">
<div class="card-header">
<div class="card-title">Test</div>
</div>
<div class="card-body">
<div class="chart">
<canvas id="barChart1" height="220px"></canvas>
</div>
</div>
</div>
But for some reason I get a vertical bar like this:
How can I do to change it to be horizontally orientation, the current Y axis be at X axis and above each bar use current X axis, exactly like the first photo? Regards
UPDATE
As the comment below I currently using Chartjs V 2.9.4, now it works, the chart is oriented horizontally
Now, I need to place Y axis text above each bar, is this possible?
It seems that you're still using Chart.js version 2. The current latest version is 3.5.1.
Change type: 'bar' into type: 'horizontalBar' and it should work.
new Chart(this.ctx1, {
type: 'horizontalBar',
...
For further details, please consult Horizontal Bar Chart from the Chart.js v2.9.4 documentation.
Add this:
options: {
indexAxis: 'y',
...
}
Here is ChartJS documentation

How to insert HTML inside an Ext.each() in the labeFormatter function of legend-EXTJS -highcharts

I was referring to the Highcharts doc but I don't quite understand how to add an HTMl inside an EXT js loop inside the labelFormatter func.
Here is the code:
getLegendConfig: function() {
var ct = this;
return {
align: 'right',
verticalAlign: 'top',
layout: 'vertical',
x: -25,
y: 25,
borderWidth: 0,
floating: type === 'column',
itemMarginBottom: 5,
labelFormatter: function() {
var count = this.y || 0;
Ext.each(ct.data.series, function(ct) {
ct.data.map(function(pt) {
if (pt !== null) {
return [
'<div>',
Ext.util.Format.ellipsis("some name", 48),
'<span class="qx-highchart-legend-item-count">',
Ext.util.Format.number(pt.count, '0,000'),
'</span>',
'</div>'
].join('');
}
})
});
},
useHTML: true
};
}.createDelegate(this)
With the above code, nothing gets populated inside the element, not sure how to get this running. Any ideas?
Here is the fiddle:
https://fiddle.sencha.com/#view/editor&fiddle/2k5v
Thanks
Since you do not have in your fiddle the actual highchart but only the getLegendConfig portion it would be tricky to give exact answer. However this goes back to the previous question you asked about the panel with values. So this is a similar example where the values are rendered on a panel: https://fiddle.sencha.com/#view/editor&fiddle/2k60
Here is the main part:
series.map((x) => {
return x.data.map(function(pt) {
if (pt !== null) {
return [
'<div>',
Ext.util.Format.ellipsis("name", 48),
'<span class="qx-highchart-legend-item-count">',
Ext.util.Format.number(pt.count, '0,000'),
'</span>',
'</div>'
].join('');
}
})
}),
You have to compose that with your code and see if you get the output you want. Based on the example I gave above this will render on a simple panel the values you wanted so it should be working with your pieces. Let me know how it goes.

Altering the class values or styles of cells in ui-grid

I have several unique cases inside ui-grid where the cells of certain table contents need additional class, or even style rules assigned, so the appearance for these cells stands out compared to others. Looking through the official ui-grid documentation I found that it could be done with cellTemplate, but I couldn't get any consistent results. What is the best approach here?
Below are the code changes I have attempted before, with the intent being to change the class name based on the returned value from a filter call made
//Define Grid Headings
$scope.scheduledPatientAppointments = [
{
field: 'appointment_date',
displayName: 'Appointment Date'
},
{
field: 'doctor_name',
displayName: 'Doctor Name'
},
{
field: 'procedure_type_eng',
displayName: 'Medical Procedure Type'
},
{
field: 'appointment_status_eng',
displayName: 'Appointment Status'
},
{
field: 'docs_received',
displayName: 'Related Documents',
cellTemplate: '<div class="ui-grid-cell-contents" ng-click="grid.appScope.loadDocumentsModal(\'{{row.entity.id}}\')">{{grid.getCellValue(row, col) | hasDocuments}}</div>',
cellFilter: 'hasDocuments',
cellClass: function(grid, row, col, rowRenderIndex, colRenderIndex) {
if (grid.getCellValue(row, col).toLowerCase() === 'missing') {
return 'missing';
} else if (grid.getCellValue(row, col).toLowerCase() === 'received') {
return 'received';
} else {
return 'undefined';
}
}
}
];
// Define Grid Options
$scope.PatientAppointmentsGrid = {
selectionRowHeaderWidth: 25,
enableHorizontalScrollbar: false,
rowHeight: 35,
enableSorting: true,
columnDefs: $scope.columnsPatient,
data: [],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
//Behavior for patient page load
$scope.appointmentsProvider = patientsService.patientFactory.getAppointmentsForPatient($stateParams.id).then(
function successCallback(response) {
var preFetchData = response.data.data;
angular.forEach(preFetchData, function (value, key) {documentsService.documentsFactory.getDocumentsByAppointmentId(value.id).then(
function successCallback(response2) {
if (response2.data.length >= 1) {
//Append value state to the preFetchData object (count size)
var totalFiles = response2.data.length;
preFetchData[key].docs_received = totalFiles;
} else {
preFetchData[key].docs_received = 0;
}
}, function errorCallback(response2) {
console.debug("Error", response2);
});
});
$scope.PatientAppointmentsGrid.data = preFetchData;
},
function errorCallback(response) {
console.debug("Error", response);
});
The contents from the "Related Documents" are initally set to Missing (the original rest call returns nothing, and the filter call sets it to that. However, a later call actually loads associated documents per row, and I believe the inactivity of the grid on this particular call is what is causing no class to get set here.
Thoughts on the best approach here?
adding custom class with cellTemplate:
columnDefs: [
{
name:'firstName',
field: 'first-name',
// adding custom class
cellTemplate: "<div class=\"ui-grid-cell-contents custom-class\" title=\"TOOLTIP\">{{COL_FIELD CUSTOM_FILTERS}}</div>"
},
{ name:'1stFriend', field: 'friends[0]' },
{ name:'city', field: 'address.city'},
{ name:'getZip', field: 'getZip()', enableCellEdit:false}
],
.......
there are plenty of predefined customizable templates defined with $templateCache at the bottom of https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.2.9/ui-grid.js
adding custom style:
.......
onRegisterApi: function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
// adding custom style
gridApi.grid.registerStyleComputation({
func: function () {
return [
'.custom-class { ',
' color: red; ',
' font-weight: bold; ',
'} ',
'.ui-grid-row:nth-child(1) .custom-class { ',
' color: blue; ',
'} '
].join('\n');
}
});
}
plunker: http://plnkr.co/edit/YbnYoWLlEYzwmjuKOFa0?p=preview

Can not export renderer text using highcharts/highstock when click range selector

I have a question related the chart export.
Please see Jsfiddle here
I added a text label using chart.renderer.text on the Yaxis for the latest value of series.
If I directly click button "Export Image". There is no problem, the label can be displayed. I'm using the following way to export image. draw_labels() is a function to draw yaxis label.
$("#b").click(function () {
chart.exportChart(null, {
chart: {
backgroundColor: '#FFFFFF',
width: 972,
height: 480,
events: {
load: function () {
draw_labels(this);
}
}
}
});
});
The problem is after I clicked range selector or change Xaxis range. When I try to export the
chart to image, there is no labels are drawn. The following is the complete code.
The following is the complete code:
$(function () {
var chart;
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?', function (data) {
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
events: {
load: function () {
draw_labels(this);
$("#b").click(function () {
chart.exportChart(null, {
chart: {
backgroundColor: '#FFFFFF',
width: 972,
height: 480,
events: {
load: function () {
draw_labels(this);
}
}
}
});
});
}
}
},
series: [{
name: 'AAPL',
id: 'test',
data: data,
tooltip: {
valueDecimals: 2
}
}],
navigator: {
enabled: false
},
yAxis: {
tickWidth: 0,
id: 'value_axis',
type: 'linear',
gridLineColor: '#EEE',
lineColor: '#D0CDC9',
lineWidth: 0,
minorTickInterval: null,
opposite: true,
offset: 0
},
xAxis: {
events: {
afterSetExtremes: function (e) {
console.log('test');
$('[id="test_text"]').remove();
draw_labels(chart);
}
}
}
});
});
function draw_labels(chart) {
$(chart.series).each(function (i, serie) {
var s_id = serie.options.id;
var temp_id = s_id;
var point = serie.points[serie.points.length - 1];
if (point) {
var pre, post;
if (point.y) {
var last_value_dis = (point.y).toFixed(1);
yaxis_name = 'value_axis';
//Get Yaxis position
var y_axis = chart.get(yaxis_name);
offsite_yaxis = 0;
element_text = chart.renderer.text(
//the text to render
'<span style="font-size:10px;font-weight:bold;color:' + serie.color + ';">' + last_value_dis + '</span>',
//the 'x' position
y_axis.width + y_axis.offset,
//the 'y' position
chart.plotTop + point.plotY + 3).attr({
id: temp_id + '_text',
zIndex: 999
}).add();
}
}
});
}
});
Here, I have fixed it for you. Here is a saved image:
Following changes have been done:
Added a redraw event to your exportchart
redraw: function () {
$("#test_text").remove() ;
draw_labels(this);
}
Changed this line in afterSetExtremes
$('[id="test_text"]').remove();
to
$("#test_text").remove() ;
Earlier one was not working as expected, so I had to change it.
Problem with disappearing text is related with id, when I removed it, label appears. But then I came across second issue, wrong y position. So i declare global variable, then when you call your function, set position of label, and use in chart exporting this variable. As a result label is exported correct.
http://jsfiddle.net/UGbpJ/11/

Resources