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

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.

Related

how to implement progress bar in ag-grid table

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).

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

Search text from cell template not working in ui-grid

I have defined a conditional cell template for one of the column. Its displaying the data correctly but I am not able to search for the text in the cell template.
Here is my plunkr:
https://plnkr.co/edit/TDX5jtPord1hkzCVaw3L?p=preview
var template1 = '<div class="">' +
'<div class="" ng-if="COL_FIELD > 30">Greater </div> ' +
'<div class="" ng-if="COL_FIELD < 30"> Lesser </div> ' +
'</div>';
In the template I have put the condition that.. if COL_FIELD > 30 then then write Greater.. or else write Lesser. And now I should be able to search for the Greater or Lesser in Number column.
A solution could be to add a property on your data like :
$http.get('data.json').success(function(data) {
data.map(function(item) {
item.greaterLesser = item.amount > 30 ? 'Greater' : 'Lesser';
});
$scope.gridOptions.data = data;
});
and then instead of using the amount with a template, just bind on this property.
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [{
field: 'name',
width: 70
}, {
field: 'greaterLesser',
name: 'Number',
width: 90,
}, {
field: 'amount',
name: 'Currency',
cellFilter: 'currencyFilter:this',
}]
};
Here is the updated plunker
Edit
If you want to use the template, you could implement the search function yourself. You can add the filter option to your field and implement the condition function. Something like:
filter: {
condition: function(searchTerm, cellValue) {
var value = cellValue > 30 ? 'greater' : 'lesser';
var result = value.search(searchTerm.toLowerCase());
return result > -1;
}
}
Here I used the search function but you could use match or some other function.
Here is a demo plunker
I used the below code to make search work
field: 'EmpId',
displayName: 'Employee Type',
cellTemplate: '<div style="cursor:pointer" class="ui-grid-cell-contents">{{grid.appScope.GetEmployeeType(row)}}</div>',
filter: {
condition: function (searchTerm, cellValue,row,column) {
var value = $scope.GetEmployeeType(row);//same function that you use to display value in cell Template
return (value.toLocaleLowerCase().indexOf(searchTerm.toLocaleLowerCase())>-1);
}
}

Chart.js - Formatting Y axis

I'm using Chart.js to draw a simple bar plot and I need to format its Y axis like
123456.05 to 123 456,05 $
I don't understand how to use scaleLabel : "<%=value%>"
I saw someone pointing to "JS Micro-Templating",
but no clue how to use that with our scaleLabel option.
Does someone know how to format this Y axis, and maybe give me an example ?
I had the same problem, I think in Chart.js 2.x.x the approach is slightly different like below.
ticks: {
callback: function(label, index, labels) {
return label/1000+'k';
}
}
More in details
var options = {
scales: {
yAxes: [
{
ticks: {
callback: function(label, index, labels) {
return label/1000+'k';
}
},
scaleLabel: {
display: true,
labelString: '1k = 1000'
}
}
]
}
}
An undocumented feature of the ChartJS library is that if you pass in a function instead of a string, it will use your function to render the y-axis's scaleLabel.
So while, "<%= Number(value).toFixed(2).replace('.',',') + ' $' %>" works, you could also do:
scaleLabel: function (valuePayload) {
return Number(valuePayload.value).toFixed(2).replace('.',',') + '$';
}
If you're doing anything remotely complicated, I'd recommend doing this instead.
scaleLabel : "<%= Number(value).toFixed(2).replace('.', ',') + ' $'%>"
For anyone using 3.X.X, here's the updated syntax to change y axis labels:
scales: {
y: {
ticks: {
callback: (label) => `$ ${label}`,
},
},
},
Chart.js 2.X.X
I know this post is old. But if anyone is looking for more flexible solution, here it is
var options = {
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
callback: function(label, index, labels) {
return Intl.NumberFormat().format(label);
// 1,350
return Intl.NumberFormat('hi', {
style: 'currency', currency: 'INR', minimumFractionDigits: 0,
}).format(label).replace(/^(\D+)/, '$1 ');
// ₹ 1,350
// return Intl.NumberFormat('hi', {
style: 'currency', currency: 'INR', currencyDisplay: 'symbol', minimumFractionDigits: 2
}).format(label).replace(/^(\D+)/, '$1 ');
// ₹ 1,350.00
}
}
}]
}
}
'hi' is Hindi. Check here for other locales argument
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation#locales_argument
for more currency symbol
https://www.currency-iso.org/en/home/tables/table-a1.html
As Nevercom said the scaleLable should contain javascript so to manipulate the y value just apply the required formatting.
Note the the value is a string.
var options = {
scaleLabel : "<%= value + ' + two = ' + (Number(value) + 2) %>"
};
jsFiddle example
if you wish to set a manual y scale you can use scaleOverride
var options = {
scaleLabel : "<%= value + ' + two = ' + (Number(value) + 2) %>",
scaleOverride: true,
scaleSteps: 10,
scaleStepWidth: 10,
scaleStartValue: 0
};
jsFiddle example
Here you can find a good example of how to format Y-Axis value.
Also, you can use scaleLabel : "<%=value%>" that you mentioned, It basically means that everything between <%= and %> tags will be treated as javascript code (i.e you can use if statments...)

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