Read array inside array into table Material UI - reactjs

So i have an array of response from backend services as below (array inside an array), i try to figure it how to turn it into table but have some problem on the logic:
"data": [
{
"id": "63ad33c69acfa205d354256b",
"material": "1000000000",
"material_name": "SAMPEL",
"plant": "K111",
"type": "rm",
"current_price": 7718,
"price": []
},
{
"id": "63ad33c69acfa205d354256a",
"material": "1000000000",
"material_name": "SAMPEL",
"plant": "K109",
"type": "rm",
"current_price": 7718,
"price": []
},
{
"id": "63ad33c69acfa205d3542565",
"material": "1000000000",
"material_name": "SAMPEL",
"plant": "K103",
"type": "rm",
"current_price": 37259,
"price": [
{
"date": "januari",
"price": 37258.978184562315
},
{
"date": "februari",
"price": 37258.978184562315
},
{
"date": "maret",
"price": 37258.978184562315
},
{
"date": "april",
"price": 37258.978184562315
},
{
"date": "mei",
"price": 37258.978184562315
},
{
"date": "juni",
"price": 37258.978184562315
},
{
"date": "juli",
"price": 37258.978184562315
},
{
"date": "agustus",
"price": 37258.978184562315
},
{
"date": "september",
"price": 37258.978184562315
},
{
"date": "oktober",
"price": 37258.978184562315
},
{
"date": "november",
"price": 37258.978184562315
},
{
"date": "desember",
"price": 37258.978184562315
}
]
},
]
does it possible to turn it into table as below using material UI datagrid or similar table library?:
any help on this will be very helpful....

https://github.com/ChangeWithCode/datantable
Here I have implemented that you can have a look.
<div className="App">
<table>
<tr>
<th rowspan="2">material</th>
<th rowspan="2">material_name</th>
<th rowspan="2">plant</th>
<th rowspan="2">type</th>
<th rowspan="2">current_price</th>
<th colspan="12">Price</th>
</tr>
<tr>
<td>januari</td>
<td>februari</td>
<td>maret</td>
<td>april</td>
<td>mei</td>
<td>juni</td>
<td>juli</td>
<td>agustus</td>
<td>september</td>
<td>oktober</td>
<td>november</td>
<td>desember</td>
</tr>
{object.data.map((item) => {
return (
<tr>
<td>{item.material}</td>
<td>{item.material_name}</td>
<td>{item.plant}</td>
<td>{item.current_price}</td>
<td>{item.material_name}</td>
{item.price.map((obj) => {
return <td>{obj.price}</td>;
})}
</tr>
);
})}
</table>
</div>

The following solution using material table import MaterialTable from 'material-table';:
<MaterialTable
columns={[
{ title: 'material', field: 'material' },
{ title: 'material_name', field: 'material_name' },
{ title: 'plant', field: 'plant' },
{ title: 'type', field: 'type' },
{
title: 'current_price',
field: 'current_price',
},
{
title: 'price',
field: 'price',
render: (rowData) => (
<MaterialTable
columns={
rowData.price.length > 0
? rowData.price.map((el) => ({ title: el.date, field: 'price' }))
: [
{ title: 'januari', field: '' },
{ title: 'februari', field: '' },
{ title: 'maret', field: '' },
{ title: 'april', field: '' },
{ title: 'mei', field: '' },
{ title: 'juni', field: '' },
{ title: 'juli', field: '' },
{ title: 'agustus', field: '' },
{ title: 'september', field: '' },
{ title: 'oktober', field: '' },
{ title: 'november', field: '' },
{ title: 'desember', field: '' },
]
}
data={rowData.price}
options={{ toolbar: false }}
/>
),
},
]}
data={data}
title="Demo Title"
/>

Related

Set minimum height or width for column FusionCharts

If data is very lower than others, it's almost like zero, and the user can't click or hover because it's too small.
How can I set a minimum height or width for very small numbers?
I have this problem with ApexCharts too.
const chartConfigs = {
type: "column2d",
width: "100%",
height: 500,
dataFormat: "json",
dataSource: {
chart: {
caption: "Countries With Most Oil Reserves [2017-18]",
subCaption: "In MMbbl = One Million barrels",
xAxisName: "Country",
yAxisName: "Reserves (MMbbl)",
numberSuffix: "K",
theme: "fusion",
},
data: [
{
label: "Venezuela",
value: "290",
},
{
label: "Saudi",
value: "260",
},
{
label: "Canada",
value: "180",
},
{
label: "Iran",
value: "140",
},
{
label: "Russia",
value: "115",
},
{
label: "UAE",
value: "100",
},
{
label: "US",
value: "3000000",
},
{
label: "China",
value: "30",
},
],
},
};
This is normal since your y-axis scale is linear if one of your plots has a very large value & the other plot values are very low compared to the large plot value then the plot area of the smaller value plot will be very minimum.
To overcome this you can use logarithmic y-axis, here is an example -
FusionCharts.ready(function() {
var footfallChart = new FusionCharts({
type: 'logmscolumn2d',
renderAt: 'chart-container',
width: '500',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"theme": "fusion",
"caption": "Store footfall vs Online visitors ",
"subCaption": "Last Year",
"xAxisName": "Quarter",
"yAxisName": "No of visitors",
"showXAxisLine": "1",
"axisLineAlpha": "10"
},
"categories": [{
"category": [{
"label": "Q1"
},
{
"label": "Q2"
},
{
"label": "Q3"
},
{
"label": "Q4"
}
]
}],
"dataset": [{
"seriesname": "Total footfalls",
"data": [{
"value": "126734"
},
{
"value": "64"
},
{
"value": "34"
},
{
"value": "56"
},
{
"value": "78"
}
]
}]
}
}).render();
});
<script src="https://cdn.fusioncharts.com/fusioncharts/latest/fusioncharts.js"></script>
<script src="https://cdn.fusioncharts.com/fusioncharts/latest/themes/fusioncharts.theme.fusion.js"></script>
<div id="chart-container">FusionCharts will render here</div>

React project - Material UI Data grid display nested array object in a cell

I have been trying to create a Material Data Grid to display the number of users and the roles assigned to them.
The data structure looks like:
User 1: {admin, seller}
User 2: {admin}
User 3: {admin, seller, user}
The json response from the api for the users object looks like:
users: [
{
"id": 7,
"email": "ajha#gmail.com",
"phone": "+91-9686660322",
"firstName": "Ankur",
"lastName": "Jhavery",
"avatar": "http:img.bb/123we",
"verified": false,
"createdAt": "2022-04-07T16:09:35.000Z",
"updatedAt": "2022-04-07T16:09:35.000Z",
"roles": [
{
"id": 1,
"roleName": "admin",
"userRoles": {
"createdAt": "2022-04-07T16:09:35.000Z",
"updatedAt": "2022-04-07T16:09:35.000Z",
"roleId": 1,
"userId": 7
}
},
{
"id": 2,
"roleName": "seller",
"userRoles": {
"createdAt": "2022-04-07T16:09:35.000Z",
"updatedAt": "2022-04-07T16:09:35.000Z",
"roleId": 2,
"userId": 7
}
},
{
"id": 3,
"roleName": "user",
"userRoles": {
"createdAt": "2022-04-07T16:09:35.000Z",
"updatedAt": "2022-04-07T16:09:35.000Z",
"roleId": 3,
"userId": 7
}
}
]
}
]
I am trying to render it in a React component:
const getFullName = (params) => {
return `${params.row.firstName || ''} ${params.row.lastName || ''}`;
};
const columns = [
{ field: 'id', headerName: 'Id', width: 50 },
{
field: 'fullName',
headerName: 'Full Name',
width: 150,
valueGetter: getFullName,
},
{ field: 'email', headerName: 'Email', width: 150 },
{ field: 'phone', headerName: 'Phone', width: 150 },
{ field: 'verified', headerName: 'Verified', width: 150 },
{
field: 'roles',
headerName: 'Roles',
width: 150,
valueFormatter: (params) => params.value.roleName,
type: 'string',
},
];
const Users = () => {
const [users, setUsers] = useState([]);
const getAllUsers = async () => {
try {
const response = await axios.get(
'http://localhost:8000/api/v1/admin/users'
);
if (response) {
const users = response.data.users;
setUsers(users);
}
} catch (err) {
console.log(`Error: ${err}`);
}
};
useEffect(() => {
getAllUsers();
}, []);
return (
<div className="p-5">
Users
<div className="flex flex-grow w-[60rem] h-[20rem]">
<DataGrid rows={users} columns={columns} />
</div>
</div>
);
};
export default Users;
However, the output is still showing as [Object, object]
The output that I am willing to produce for the Roles cell is to get an array of string objects which I can then display as a list using:
<ul className='flex'>
{roles.map((role, index) =>(
<li key={index}>{role}</li>
))}
</ul>
Solved it using the below code in Roles column:
{
field: 'roles',
headerName: 'Roles',
width: 150,
renderCell: (params) => (
<ul className="flex">
{params.value.map((role, index) => (
<li key={index}>{role.roleName}</li>
))}
</ul>
),
type: 'string',
},

Antd tree table grouped by column value

I need to implement tree table in my react application. that has grouped by an object property value.
The object is as follows
{
"SP": [
{
"DisplayName": "audi",
"Name": "r8",
"Type": "2012"
},
{
"DisplayName": "audi",
"Name": "rs5",
"Type": "2013"
}
],
"Code": [
{
"DisplayName": "ford",
"Name": "mustang",
"Type": "2012"
},
{
"DisplayName": "ford",
"Name": "fusion",
"Type": "2015"
}
],
"Message": [
{
"DisplayName": "kia",
"Name": "optima",
"Type": "2012"
}
]
}
And my table should be as the following image
I have used antd in my project and I tried to implement this functionality with antd table and could not implement as I want. I need the filter functionality too.
Can anyone suggest a solution
You need to restructure your dataSource witch children prop:
function NestedTables() {
return (
<Flexbox>
<Table
size="small"
indentSize={0}
columns={columns}
dataSource={source}
/>
</Flexbox>
);
}
When your source is:
const source = [
{
key: '1',
Code: 'SP',
children: [
{
key: '11',
Code: '5001',
DisplayName: 'audi',
Name: 'r8',
Type: '2012'
},
{
key: '12',
Code: '313',
DisplayName: 'audi',
Name: 'rs5',
Type: '2013'
}
]
},
{
key: '2',
Code: 'Code',
children: [
{
key: '21',
Code: '243',
DisplayName: 'ford',
Name: 'mustang',
Type: '2012'
},
{
key: '22',
Code: '503431',
DisplayName: 'ford',
Name: 'fusion',
Type: '2015'
}
]
},
{
key: '3',
Code: 'Message',
children: [
{
key: '31',
Code: '4311',
DisplayName: 'kia',
Name: 'optima',
Type: '2012'
}
]
}
];
And defined columns filters:
const columns = [
{
title: 'Code',
dataIndex: 'Code',
key: 'Code',
filters: [
{ text: 'SP', value: 'SP' },
{ text: 'Code', value: 'Code' },
{ text: 'Message', value: 'Message' }
],
onFilter: (value, record) => record.Code.indexOf(value) === 0
},
{
title: 'Display Name',
dataIndex: 'DisplayName',
key: 'DisplayName',
filters: [
{ text: 'audi', value: 'audi' },
{ text: 'ford', value: 'ford' },
{ text: 'kia', value: 'kia' }
],
onFilter: (value, record) =>
record.children.filter(child => child.DisplayName === value).length > 0
},
{ title: 'Name', dataIndex: 'Name', key: 'Name' },
{ title: 'Type', dataIndex: 'Type', key: 'Type' }
];
Demo:

react display multi dimensional array from redux-form

I need to display data in table with crud from redux-form with field arrays. What the best way would be to do this in Reactjs?
At the moment I am using react-table, but cant get subtable maped with parent values it just repeats the same values. Any ideas? Thanks
table sample code below for this table:
var result = _.flatMap(items, item =>
_(item.panel_group)
.map(v => ({id: item._id, inst_name:item.name, lat:item.lat, lon:item.lon, pv_name: v.name, azimuth: v.azimuth, inv_eff: v.inv_eff, losses: v.losses, system_capacity: v.system_capacity, tilt: v.tilt}))
.value()
);
const columns2 = [
{
Header: "Pv Name",
id:"pv_name",
accessor:"pv_name"
},
{
Header: "Size",
id:"size",
accessor:"system_capacity"
},
{
Header: "losses",
id: "losses",
accessor: "losses"
},
]
<div>
<ReactTable
data={items}
columns={columns}
defaultPageSize={5}
filterable
SubComponent={row => {
return (
<div style={{ padding: "20px" }}>
<ReactTable
data={result}
columns={columns2}
defaultPageSize={3}
showPagination={false}
/>
</div>
);
}}
/>
</div>
as well I tried to do like this as well result in picture :
{
Header: "Instalation Name",
id:"name",
accessor: "name"
},
{
Header: "latitude",
id: "latitude",
accessor: "lat"
},
{
Header: "longitude",
id: "longitude",
accessor: "lon"
},
{
Header: "Pv Name",
id:"pv_name",
accessor:row => {
return (
<div>
{row.panel_group.map((panel) => (
<div key={panel.id}>{panel.name} </div>
))}
</div>
)
},
},
{
Header: "Size",
id:"size",
accessor:row => {
return (
<span>
{row.panel_group.map((panel) => (
<div key={panel.id}>{panel.system_capacity}</div>
))}
</span>
)
},
},
is there any better ways to represent such data?
sample json
[
{
"_id": "59e0cbdf438488010f84968d",
"name": "hh",
"lat": 12.33,
"lon": -12.555,
"panel_group": [
{
"installation_id": "test",
"name": "name",
"system_capacity": 2,
"azimuth": 120,
"tilt": 12,
"losses": 4,
"inv_eff": 98,
"_id": "59e0cbdf438488010f84968f",
},
{
"installation_id": "test2",
"name": "name2",
"system_capacity": 1,
"azimuth": 110,
"tilt": 11,
"losses": 14,
"inv_eff": 18,
"_id": "59e0cbdf438488010f84968e"
}
],
{
"_id": "59e7798821306f001beeed19",
"name": "installation1",
"lat": 12.33,
"lon": -12.555,
"panel_group": [
{
"name": "panelgroup1",
"system_capacity": 20,
"azimuth": 120,
"tilt": 12,
"losses": 4,
"inv_eff": 98,
"_id": "59e7798821306f001beeed1b"
},
{
"name": "panelgroup2",
"system_capacity": 100,
"azimuth": 110,
"tilt": 11,
"losses": 14,
"inv_eff": 18,
"_id": "59e7798821306f001beeed1a"
}
],
}]

FullCalendar event does not remove when the events array empty

js code
(function(){
angular.module('calendarApp',['ngGrid', 'ui.calendar', 'ui.bootstrap'])
.controller('calendarCtrl',function($scope){
$scope.selectedGridItems = [];
$scope.test = [{
"id": 1,
"date": "01/09/2014T00:00:00",
"details": "test1",
"check": false,
"check1": false
}, {
"id": 2,
"date": "02/09/2014T00:00:00",
"details": "test2",
"check": false,
"check1": false
}, {
"id": 3,
"date": "03/09/2014T00:00:00",
"details": "test3",
"check": false,
"check1": false
}, {
"id": 4,
"date": "04/09/2014T00:00:00",
"details": "test4",
"check": false,
"check1": false
}, {
"id": 5,
"date": "05/09/2014T00:00:00",
"details": "test5",
"check": false,
"check1": false
}, {
"id": 6,
"date": "06/09/2014T00:00:00",
"details": "test6",
"check": false,
"check1": false
}, {
"id": 7,
"date": "07/09/2014T00:00:00",
"details": "test7",
"check": false,
"check1": false
}, {
"id": 8,
"date": "08/09/2014T00:00:00",
"details": "test8",
"check": false,
"check1": false
}, {
"id": 9,
"date": "09/09/2014T00:00:00",
"details": "test9",
"check": false,
"check1": false
}, {
"id": 10,
"date": "10/09/2014T00:00:00",
"details": "test10",
"check": false,
"check1": false
}, {
"id": 11,
"date": "11/09/2014T00:00:00",
"details": "test11",
"check": false,
"check1": false
}, {
"id": 12,
"date": "12/09/2014T00:00:00",
"details": "test12",
"check": false,
"check1": false
}, {
"id": 13,
"date": "13/09/2014T00:00:00",
"details": "test13",
"check": false,
"check1": false
}, {
"id": 14,
"date": "14/09/2014T00:00:00",
"details": "test14",
"check": false,
"check1": false
}];
$scope.ngGridOptions = {
data: 'test',
multiSelect: false,
columnDefs: [{
field: "id",
displayName: "ID",
width: "50px"
}, {
field: "date",
displayName: "Date",
width: "100px"
}, {
field: "details",
displayName: "Details"
}, {
field: "check",
displayName: "",
cellTemplate: "<div class='ngCellText'><input type='checkbox' ng-checked='COL_FIELD' ng-model='COL_FIELD' ng-change='selectChange(row,COL_FIELD)' /></div>",
width: "20px"
}, {
field: "check1",
displayName: "",
cellTemplate: "<div class='ngCellText'><input type='checkbox' ng-checked='COL_FIELD' ng-model='COL_FIELD' ng-change='selectChange1(row,COL_FIELD)' /></div>",
width: "20px"
}]
};
/* ----------------Calendar Control----------------- */
$scope.alertOnEventClick=function( event, allDay, jsEvent)
{
debugger;
};
$scope .events = [];
$scope.eventSources = [$scope.events];
$scope.uiConfig = {
calendar: {
height: 450,
editable: false,
disableDragging:false,
header: {
left: 'title',
center: '',
right: 'today prev,next'
},
eventClick:$scope.alertOnEventClick
}
};
/* ---------------------- ends ---------------------- */
$scope.selectChange = function (row, value) {
var className= (value) ? ((row.entity.check1) ? "row-selected-blue-green" : "row-selected-blue") : ((row.entity.check1) ? "row-selected-green" : "");
if (typeof(_.find($scope.events, function (item) {return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');})) == 'undefined') {
$scope.events.push({
id: moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY'),
title: moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY'),
start: moment(row.entity.date,'DD/MM/YYYYThh:mm:ss'),
className: [className]
});
} else {
_.find($scope.events, function (item) {
return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');
}).className = [className];
}
var elem = row.elm;
if (row.entity.check || row.entity.check1) {
$(elem).addClass('row-color');
} else if (!row.entity.check && !row.entity.check1) {
var index =$scope.events.indexOf(_.find($scope.events, function (item) {return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');}));
$scope.events.splice(index, 1);
$(elem).removeClass('row-color');
}
};
$scope.selectChange1 = function (row, value) {
var className = (value) ? ((row.entity.check) ? "row-selected-blue-green" : "row-selected-green") : ((row.entity.check) ? "row-selected-blue" : "");
if (typeof(_.find($scope.events, function (item) {return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');})) == 'undefined') {
$scope.events.push({
id: moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY'),
title: moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY'),
start: moment(row.entity.date,'DD/MM/YYYYThh:mm:ss'),
className: [className]
});
} else {
_.find($scope.events, function (item) {
return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');
}).className = [className];
}
var elem = row.elm;
if (row.entity.check || row.entity.check1) {
$(elem).addClass('row-color');
} else if (!row.entity.check && !row.entity.check1) {
var index = $scope.events.indexOf(_.find($scope.events, function (item) {
return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');
}));
$scope.events.splice(index, 1);
console.log($scope.events);
$(elem).removeClass('row-color');
}
};
$scope.rowScroll = function (item) {
$(item.elm).fadeTo(500, 0.5).fadeTo(700, 1.0);
var grid = $scope.ngGridOptions.ngGrid;
var dataIndex = $scope.ngGridOptions.ngGrid.data.indexOf(item.entity);
$scope.ngGridOptions.selectItem(dataIndex, true);
grid.$viewport.scrollTop(dataIndex * grid.config.rowHeight);
};
});
})();
Html code
<div ng-app="calendarApp">
<div ng-controller="calendarCtrl">
<div ng-grid="ngGridOptions" class="gridStyle"></div>
<div ui-calendar="uiConfig.calendar" class="span2 calendar" ng-model="eventSources"></div>
</div>
</div>
FIDDLE LINK
html changes
<div ui-calendar="uiConfig.calendar" class="span2 calendar" ng-model="eventSources" id="calendar"></div>
js change
var item = _.find($scope.events, function (item) {
return item.id == moment(row.entity.date,'DD/MM/YYYYThh:mm:ss').format('MMMDDYYYY');
});
$("div#calendar").fullCalendar('removeEvents',item.id);
$scope.events.splice(($scope.events.indexOf(item)),1);
updated link is working fine. check that link
FIDDLE SOLUTION LINK
Tried all of the above. But only the following worked
$scope.events.length = 0;

Resources