ag-grid community v20, Angular 7.
I have a working ag-grid in my Angular 7 app. I want to display an image in a column. The https address is contained in the columns field. I've searched ag-grid's documentation and the web and have not found an example of this basic scenario. Can someone give a code example for the columnDef. Is cellRenderer the way to do this?
{ headerName: 'Select', field: 'Image', width: 75, sortable: false,
cellRenderer: '<span><img border="0" width = "15" height="10" src=xxxx ></span>' },
It is a multi-step process.
See Learn to customize Angular grid in less than 10 minutes
Create a custom component. 'ImageFormatterComponent.ts'
import { Component } from "#angular/core";
#Component({
selector: 'app-image-formatter-cell',
template: `<img border="0" width="50" height="50" src=\"{{ params.value }}\">` })
export class ImageFormatterComponent {
params: any;
agInit(params: any){
this.params = params;
}
}
Register in the app.module.ts
import { ImageFormatterComponent } from "./album/ImageFormatterComponent";
#NgModule({
declarations: [ImageFormatterComponent],
imports: [
AgGridModule.withComponents([ImageFormatterComponent])
],
In the component you are using it in:
import { ImageFormatterComponent } from "./ImageFormatterComponent";
columnDefs = [
{ headerName: 'Select',
field: 'Image',
width: 60,
sortable: false,
autoHeight: true,
cellRendererFramework: ImageFormatterComponent
}
Related
I am building an app in Ag-grid React
I would like the grid to highlight a row if the user has tagged it by clicking on a checkbox. I am using rowClassRules, and it works fine: if the user edits the value of the tag field for a row from false to true, the row becomes highlighted
When I add in a cell renderer to make the tag field a checkbox it stops working, see code below
Any advice on what I am doing wrong would be appreciated
index.js
import React, { useState } from "react";
import { render } from "react-dom";
import { AgGridReact } from "ag-grid-react";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css";
import "./index.css"
const App = () => {
const AgGridCheckbox = (props) => {
const boolValue = props.value && props.value.toString() === "true";
const [isChecked, setIsChecked] = useState(boolValue);
const onChanged = () => {
props.setValue(!isChecked);
setIsChecked(!isChecked);
};
return (
<div>
<input
type="checkbox"
checked={isChecked}
onChange={onChanged}
/>
</div>
);
};
const [rowData] = useState([
{ tag: true, make: "Toyota", model: "Celica", price: 35000 },
{ tag: false, make: "Ford", model: "Mondeo", price: 32000 },
{ tag: false, make: "Porsche", model: "Boxter", price: 72000 },
]);
const [columnDefs] = useState([
{ field: "tag", cellRenderer: AgGridCheckbox },
// { field: "tag", editable: true },
{ field: "make" },
{ field: "model" },
{ field: "price" },
]);
const gridOptions = {
rowClassRules: {
"row-tagged": (params) => params.api.getValue("tag", params.node),
},
};
return (
<div className="ag-theme-alpine" style={{ height: 400, width: 800 }}>
<AgGridReact
gridOptions={gridOptions}
rowData={rowData}
columnDefs={columnDefs}
></AgGridReact>
</div>
);
};
render(<App />, document.getElementById("root"));
index.css
.row-tagged {
background-color: #91bd80 !important;
}
I've done some more research and if I add redrawRows() to the onChanged() handler in the cell renderer thus:
const onChanged = () => {
props.setValue(!isChecked);
setIsChecked(!isChecked);
setRowData(rowData);
console.log(props);
props.api.redrawRows({ rowNodes: [props.node] });
};
It now works. Note that passing { rowNodes: [props.node] } means (I assume) that it only redraws a single row.
Supplementary Question: Is this the right way to go? Is there a more efficient way?
I am using ag-grid table for first time. I am not able to change the default font size of row cells(Not header portion). I want to change the font size of row cells(row data). I am using ag-theme-alpine.
Here is the code which I am using.
import React, { Component } from 'react';
import { render } from 'react-dom';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [
{headerName: 'Make', field: 'make'},
{headerName: 'Model', field: 'model'},
{headerName: 'Price', field: 'price'}
],
rowData: [
{make: 'Toyota', model: 'Celica', price: 35000},
{make: 'Ford', model: 'Mondeo', price: 32000},
{make: 'Porsche', model: 'Boxter', price: 72000}
]
}
}
render() {
return (
<div
className="ag-theme-alpine"
style={{ height: '500px', width: '100%',fontSize:'20px' }}
>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}>
</AgGridReact>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Please suggest a good solution.
You can do this in the ColDef by setting the cellStyle property in ColDef. You can set the font size as follows
columnDefs: [
{
headerName: 'Make',
field: 'make',
cellStyle: {fontSize: '11px'}
}
]
You can override the font size via CSS. Ag-Grid's CSS sets the font at the row level, and unfortunately it has an !important tag. Providing a higher selector specificity should do the trick:
div.ag-theme-alpine div.ag-row {
font-size: 12px !important;
}
You can set font-size and other parameters globally by customizing a theme: React Data Grid: Customising Themes
Define the style parameters in the styles.scss file like this:
.ag-theme-alpine {
#include ag-theme-alpine((
font-size: 10px,
));
}
Wants to open a mat-dialog on click of Detail Icon. But the issue is this is not referring to class. Its referring to the current grid.
constructor(private dialog: MatDialog) {}
ngOnInit() {
this.gridOptions = <GridOptions>{
rowSelection: 'multiple',
floatingFilter: true
};
this.gridOptions.columnDefs = [
{
headerName: 'Detail', field: '', filter: false, width: 80,
sortable: false,
onCellClicked: this.openModal,
cellRenderer: (data) => {
return `<mat-icon class="mat-icon material-icons" style="cursor:pointer;" aria-hidden="true">
keyboard_capslock</mat-icon>`;
}
},
{ headerName: 'Field Name', field: 'fieldName'}
];
openModal(row): void {
const detailRef = this.dialog.open(DetailComponent, {
height: '100vw',
width: '80vh',
direction: 'ltr',
data: {
record: row.data
}
});
Error: Unable to get property 'open' of undefined or null reference
Here this is referring to Grid and not to the class.
How can I refer to the class method to open the dialog?
Inline cellRenderer could be used only for simple cases.
If it's required to use functions inside or connect to third-party libraries, it has to be written as a custom cell renderer component.
I am using high chart wrapper in my angular5 app with the help of below link.
high chart wrapper
but how can I use addSeries() to add series into the existing chart and how can I update the properties of existing chart.
how can I use addSeries() to add series into the existing chart and
how can I update the properties of existing chart.
When using highcharts-angular wrapper it is not recommended to use chart methods like addSeries() or update() directly on chart reference.
You have to update a whole component, not only chart properties. It can be achieved by updating chartOptions object (add new series, point, title etc) and setting updateFlag = true. Check the code and demo posted below.
app.module.ts:
import { BrowserModule } from "#angular/platform-browser";
import { NgModule } from "#angular/core";
import { HighchartsChartModule } from "highcharts-angular";
import { ChartComponent } from "./chart.component";
import { AppComponent } from "./app.component";
#NgModule({
declarations: [AppComponent, ChartComponent],
imports: [BrowserModule, HighchartsChartModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
chart.component.html:
<div class="boxChart__container">
<div>
<highcharts-chart
id="container"
[Highcharts]="Highcharts"
[constructorType]="chartConstructor"
[options]="chartOptions"
[callbackFunction]="chartCallback"
[(update)]="updateFlag"
[oneToOne]="true"
style="width: 100%; height: 400px; display: block;"
>
</highcharts-chart>
<button (click)="updateChart()">Update Chart</button>
</div>
</div>
chart.component.ts:
import { Component, OnInit } from "#angular/core";
import * as Highcharts from "highcharts";
import * as HighchartsMore from "highcharts/highcharts-more";
import * as HighchartsExporting from "highcharts/modules/exporting";
HighchartsMore(Highcharts);
HighchartsExporting(Highcharts);
#Component({
selector: "app-chart",
templateUrl: "./chart.component.html"
})
export class ChartComponent implements OnInit {
title = "app";
chart;
updateFlag = false;
Highcharts = Highcharts;
chartConstructor = "chart";
chartCallback;
chartOptions = {
series: [
{
data: [1, 2, 3, 6, 9]
}
],
exporting: {
enabled: true
},
yAxis: {
allowDecimals: false,
title: {
text: "Data"
}
}
};
constructor() {
const self = this;
this.chartCallback = chart => {
// saving chart reference
self.chart = chart;
};
}
ngOnInit() {}
updateChart() {
const self = this,
chart = this.chart;
chart.showLoading();
setTimeout(() => {
chart.hideLoading();
self.chartOptions.series = [
{
data: [10, 25, 15]
},
{
data: [12, 15, 10]
}
];
self.chartOptions.title = {
text: "Updated title!"
};
self.updateFlag = true;
}, 2000);
}
}
Demo:
https://codesandbox.io/s/oomo7424pz
Docs reference:
updateFlag - https://github.com/highcharts/highcharts-angular#options-details
here is a very useful answer for learning how to updata a highchart.
https://www.highcharts.com/demo/chart-update
it explains a method chart.update
chart.update({
chart: {
inverted: false,
polar: false
},
subtitle: {
text: 'Plain'
}
});
For adding series the following method is used
chart.addSerie(serie,true);
flag 'true' here is equivalent to chart.redraw();
OR
var chart = new Highcharts.Chart(options);
chart.addSeries({
name: array.name,
data: array.value
});
If you are going to add several series you should set the redraw flag to false and then call redraw manually after as that will be much faster.
var chart = new Highcharts.Chart(options);
chart.addSeries({
name: 'Bill',
data: [1,2,4,6]
}, false);
chart.addSeries({
name: 'John',
data: [4,6,4,6]
}, false);
chart.redraw();
For more information and methods you can visit the Official Highcharts API page:
https://api.highcharts.com/class-reference/Highcharts.Chart
When using angular-highcharts wrapper as
import { Chart } from 'angular-highcharts';
create charts as below
chart = new Chart({
chart: {
type: 'line'
},
title: {
text: 'Linechart'
},
credits: {
enabled: false
},
series: [
{
name: 'Line 1',
data: [1, 2, 3]
}
]
});
now you can call all API methods on this
had a tough time trying to get ng2-highcharts and angular2 to work nicely together.
what I have is;
import * as Highcharts from 'highcharts';
window['Highcharts'] = Highcharts;
bootstrap(AppComponent);
SystemJS Config;
map: {
"highcharts": "node_modules/highcharts/highcharts.js",
"ng2-highcharts": "node_modules/ng2-highcharts",
}
as you can see, this is quite a hack but its the only way I could get it working - when I remove the manual window assignment, I get
ReferenceError: Highcharts is not defined
at Ng2Highcharts.Object.defineProperty.set
So my question is, surely there is a better way? Any ideas?
I am using it like so;
import { Component, OnInit } from 'angular2/core';
import { Ng2Highcharts } from 'ng2-highcharts/ng2-highcharts';
#Component({
selector: 'component',
styleUrls: ['.comp.css'],
templateUrl: '.comp.html',
directives: [Ng2Highcharts]
})
Thanks
I have slightly modified the original implementation of ng2-highcharts I retreived few months ago to overcome some issues (I had to use jQuery - probably the most current version of the package does not need any twick any more). In any case this is the code of the directive I use
/// <reference path="../../typings/highcharts/highcharts.d.ts" />
declare var jQuery: any;
import {Directive, ElementRef, Input} from 'angular2/core';
#Directive({
selector: '[ng2-highcharts]'
})
export class Ng2Highcharts {
hostElement: ElementRef;
chart: HighchartsChartObject;
constructor(ele: ElementRef) {
this.hostElement = ele;
}
#Input('ng2-highcharts') set options(opt:HighchartsOptions) {
if(!opt) {
console.log('No valid options...');
console.log(opt);
return;
}
if(opt.series || opt.data) {
let nativeEl = this.hostElement.nativeElement;
let jQ = jQuery(nativeEl);
this.chart = jQ.highcharts(opt);
} else {
console.log('No valid options...');
console.dir(opt);
}
}
}
In index.html I have
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
},
ng2Highcharts: {
format: 'register',
defaultExtension: 'js'
},
.....
.....
}})
and
<script src="./lib/jquery/dist/jquery.js"></script>
<script src="./lib/highcharts/highstock.js"></script>
<script src="./lib/highcharts/modules/exporting.js"></script>
<script src="./lib/highcharts/highcharts-more.js"></script>
In the components that need to use the directive the html code looks like the following:
<div [ng2-highcharts]="chartOptions"></div>
chartOptions are created with code like this
createNewchartOptions() {
return {
title: {text: "Performance vs Benchmark (" + this.periodText + ")"},
rangeSelector: {
selected: 4},
xAxis: {
type: 'datetime'
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'}]
},
plotOptions: {
series: {
compare: 'percent'}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2}
};
}
Last thing you need to do is to set the series in the chartOptions (I do not put code since too linked to my app).
I hope this helps