Jspdf-autotable Rowspan Fix - javascript

I have been generating PDF using Jspdf and Jspdf-autotable plugin. Check this code that I am using to make my customized pdf -
import React, { Component } from 'react';
import jsPDF from "jspdf";
import autotable from "jspdf-autotable";
var getColumns = function () {
return [
{ title: "Student", dataKey: "studentName" },
{ title: "Gender", dataKey: "studentGender" },
{ title: "Mother Name", dataKey: "motherName" },
{ title: "Father Name", dataKey: "fatherName" }
]
};
var getData = function () {
return rows
};
var rows;
class FeaturePage extends Component {
constructor() {
super();
this.exportpdf = this.exportpdf.bind(this);
this.state = {
sales: [
{
"studentId": "100122000116",
"name": "hasan",
"customStudentId": "1510020",
"studentName": "Tasnim Tabassum",
"studentGender": "Female",
"studentDOB": "2012-07-27",
"studentReligion": "Islam",
"motherName": "Sb",
"fatherName": "Md. Mamunar Rashid"
},
{
"studentId": "100122000116",
"name": "hasan",
"customStudentId": "1510020",
"studentName": "Star",
"studentGender": "Female",
"studentDOB": "2012-07-27",
"studentReligion": "Islam",
"motherName": "Sd",
"fatherName": "Md. Mamunar Rashid"
},
{
"studentId": "100122000116",
"name": "arif",
"customStudentId": "1510020",
"studentName": "Tasnim Tabassum",
"studentGender": "Female",
"studentDOB": "2012-07-27",
"studentReligion": "Islam",
"motherName": "safd",
"fatherName": "Md. Mamunar Rashid"
},
{
"studentId": "100122000216",
"name": "arif",
"customStudentId": "1510000",
"studentName": "Star2",
"studentGender": "Female",
"studentDOB": "2012-06-30",
"studentReligion": "Islam",
"motherName": "Mst. Fawalia Akter",
"fatherName": "Md. Azaharul Islam"
}
]
};
}
exportpdf() {
var doc = new jsPDF('p', 'pt');
doc.autoTable(getColumns(), getData(), {
theme: 'grid',
startY: 60,
drawRow: function (row, data) {
if (data.row.raw.name) {
doc.autoTableText(data.row.raw.name, data.settings.margin.left + data.table.width / 2, row.y + row.height / 2, {
halign: 'center',
valign: 'middle'
}
);
data.cursor.y += 20;
}
},
});
doc.save('Student List.pdf');
}
render() {
rows = this.state.sales;
return (
<div>
<button onClick={this.exportpdf} className="exportPDF">Export to PDF</button>
</div>
);
}
}
export default FeaturePage;
And it is generating this pdf
But I want to generate something like this one
How can I do that. I have tried out all the hooks that i Read in the documentation , but nonetheless couldn't make it work the way i want it.

Related

I am trying to save the values form the DataGridPro MUI, a TreeData ... How can i save Values of the Cells after i edit them

I am novice at this. I am trying to save the values form the DataGridPro MUI, I am using a TreeData. How can i save Values of the Cells after i edit them. I watched a video online in by which i was able to understand how it will work on a Single DataTable, But for the Parent one, i dont know how i will be able to save it. I have looked up but i found no method which could be helpful. I am getting the values from the GridColumn and GridRowsProp.
Basically i want to save the values of the children. how can i save them?
Thanks.
import * as React from "react";
import { DataGridPro, GridColumns, GridRowsProp, DataGridProProps } from "#mui/x-data-grid-
pro";
import {
GridCellEditCommitParams,
GridCellEditStopParams,
GridCellEditStopReasons,
GridRowModel,
MuiEvent,
} from "#mui/x-data-grid";
import { applyInitialState } from "#mui/x-data-grid/hooks/features/columns/gridColumnsUtils";
const rows: GridRowsProp = [
{
hierarchy: ["Documents"],
rubrics: "Head of Human Resources",
totalMarks: "",
id: 0,
},
{
hierarchy: ["Scope"],
rubrics: "Head of Sales",
totalMarks: "15",
id: 1,
},
{
hierarchy: ["Scope", "Rubric item 1"],
rubrics: "Sales Person",
totalMarks: "2",
id: 2,
},
{
hierarchy: ["Scope", "Rubric item 2"],
rubrics: "Sales Person",
totalMarks: "5",
id: 3,
},
{
hierarchy: ["Scope", "Rubric item 3"],
rubrics: "Sales Person",
totalMarks: "8",
id: 4,
},
];
const columns: GridColumns = [
{ field: "rubrics", headerName: "Rubric Type", width: 200, editable: true },
{
field: "totalMarks",
headerName: "Total Marks",
width: 150,
editable: true,
},
];
const getTreeDataPath: DataGridProProps["getTreeDataPath"] = (row) => row.hierarchy;
export default function TreeDataSimple() {
const [state, setState] = React.useState<GridRowModel[]>(applyInitialState); //i was seeing online for this how can i add the array here but no luck.
const handleCommit = (e: GridCellEditCommitParams) => {
const array = state.map((r) => {
if (r.id === e.id) {
return { ...r, [e.field]: e.value };
} else {
return { ...r };
}
});
setState(array);
};
return (
<div style={{ height: 400, width: "100%" }}>
<DataGridPro
treeData
rows={rows}
columns={columns}
getTreeDataPath={getTreeDataPath}
onCellEditCommit={handleCommit}
experimentalFeatures={{ newEditingApi: true }}
onCellEditStop={(params: GridCellEditStopParams, event: MuiEvent) => {
if (params.reason === GridCellEditStopReasons.cellFocusOut) {
event.defaultMuiPrevented = true;
}
}}
/>
</div>
);
}}

I am getting an error when using fusioncharts in Vuejs

I'm getting this error Uncaught RuntimeException: #03091456 chartobject-1.render() Error >> Unable to find the container DOM element. Using vue2
I'm trying to work with fusioncharts in vuejs Here are the docs
https://www.fusioncharts.com/dev/getting-started/vue/your-first-chart-using-vuejs
I have used the Boilerplate code from this website
import VueFusionCharts from 'vue-fusioncharts';
import FusionCharts from 'fusioncharts';
import Column2D from 'fusioncharts/fusioncharts.charts';
import FusionTheme from 'fusioncharts/themes/fusioncharts.theme.fusion';
Vue.use(VueFusionCharts, FusionCharts, Column2D, FusionTheme);
// STEP 2: Prepare the data
const chartData = [
{
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: "30"
},
{
label: "China",
value: "30"
}
];
// STEP 3: Configure your chart
const 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: chartData
};
export default {
name: 'app',
data() {
return {
"type": "column2d",
"renderAt": "chart-container",
"width": "550",
"height": "350",
"dataFormat": "json",
dataSource
}
}
}
</script>
//STEP 4: Render the chart
<template>
<div id="app">
<div id="chart-container">
<fusioncharts
:type="type"
:width="width"
:height="height"
:dataformat="dataFormat"
:dataSource="dataSource"
>
</fusioncharts>
</div>
</div>
</template>

I am using #SwimLineNgx-Chart Horizontal Stacked bar graph.The Chart Data Format is different from Api Response.How I can Map this any suggestion

The following below is the Data format that Ngx-Chart is expecting for render;
ChartDataFormat=[
{
name:'First Item '
series:[
{
name:'Availablity Loss' //activity
value:'1200' //duration
},
{
name:'Slow Cycle' //activity
value:'1200' //duration
},
{
name:'Ideal Cyle' //activity
value:'1200' //duration
},
{
name:'Performance Loss' //activity
value:'1200' //duration
},
{
name:'Small Stop' //activity
value:'1200' //duration
}
]
},
{
name:'Second Item'
series:[
{
name:'Availablity Loss' //activity
value:'1200' //duration
},
{
name:'Slow Cycle' //activity
value:'1200' //duration
},
{
name:'Ideal Cyle' //activity
value:'1200' //duration
},
{
name:'Performance Loss' //activity
value:'1200' //duration
},
{
name:'Small Stop' //activity
value:'1200' //duration
}
]
},
]
Response I am getting from the Api is following
var ApiResponse = [
{
"activity": "Stand By",
"endTime": "2020-08-13T19:06:21.770407",
"duration": 522.3547,
"counterValue": 0
},
{
"activity": "Ideal Cycle",
"endTime": "2020-08-13T19:06:22.275242",
"duration": 0.504835,
"counterValue": 1
},
{
"activity": "Slow Cycle",
"endTime": "2020-08-13T19:06:49.310398",
"duration": 27.035156,
"counterValue": 2
},
{
"activity": "Ideal Cycle",
"endTime": "2020-08-13T19:07:36.136659",
"duration": 46.826263,
"counterValue": 4
},
{
"activity": "Availability Loss",
"endTime": "2020-08-13T19:09:01.920427",
"duration": 85.78377,
"counterValue": 5
},
{
"activity": "Ideal Cycle",
"endTime": "2020-08-13T19:09:24.20074",
"duration": 22.280313,
"counterValue": 6
},
{
"activity": "Slow Cycle",
"endTime": "2020-08-13T19:10:15.615391",
"duration": 51.41465,
"counterValue": 8
},
{
"activity": "Ideal Cycle",
"endTime": "2020-08-13T19:10:39.174414",
"duration": 23.559023,
"counterValue": 9
},
{
"activity": "Availability Loss",
"endTime": "2020-08-13T19:12:09.1893",
"duration": 90.014885,
"counterValue": 10
},
.....................
]
I am trying with the following code but the problem is I don't know how to check that the series already have an item inside it or I am doing it wrong;
The chartDataModel I am using it for
export class ChartDataModel {
public data: SerieModel[];
constructor(data: SerieModel[]) {
this.data = data;
}
}
export class SerieModel {
public name: string;
public series: SeriersChildModel[];
constructor(name: string, series: SeriersChildModel[]) {
this.name = name;
this.series = series;
}
}
export class SeriersChildModel {
public name: string;
public value: number;
constructor(name: string, value: number) {
this.name = name;
this.value = value;
}
}
I am doing inside the component in following way;
export class LiveViewComponent implements OnInit {
multi: any[] = [];
view: any[] = [900, 400];
ngxData: ChartDataModel = {
data: [
{
name: 'Series 1',
series: []
},
{
name: 'Series 2',
series: []
}
]
};
constructor(private productionLocationSvc: ProductionMonitoringService) {
console.log(this.ngxData.data);
Object.assign(this.ngxData);
}
// options
showXAxis: boolean = true;
showYAxis: boolean = true;
gradient: boolean = true;
showLegend: boolean = true;
showXAxisLabel: boolean = true;
yAxisLabel: string = 'Workstations';
showYAxisLabel: boolean = true;
xAxisLabel: string = '';
showDataLabel: boolean = true;
colorScheme = {
domain: ['red', 'green', 'orange']
};
ngOnInit() {
this.getMonitoringData();
}
getMonitoringData() {
this.productionLocationSvc.getMonitoringData().subscribe(response => {
let currData;
response.map((p) => {
**How to convert this into ChartDataForm,Please see above ChartDataFormat**
console.log(p);
this.ngxData.data[0].series.push({ name:p.activity, value: p.duration});
this.ngxData.data[1].series.push({ name:p.activity, value: p.activity})
});
this.ngxData.data = [...this.ngxData.data];
},
(err) => {
console.log(err);
});
}
}

React Table - Show nested object fields

Hey so I cannot figure this out for the life of me. SOS.
I have a JSON with nested objects that looks like this:
[
{
"id": 1,
"internalToolName": "HP ALM",
"statuses": [
{
"id": 57,
"statusType": "Ok",
"date": "2018-12-17"
},
{
"id": 67,
"statusType": "Ok",
"date": "2018-12-23"
},
{
"id": 37,
"statusType": "Ok",
"date": "2018-01-06"
}
]
},
{
"id": 2,
"internalToolName": "Artifactory",
"appType": null,
"statuses": [
{
"id": 1652,
"statusType": "Ok",
"date": "2018-12-31"
},
{
"id": 119,
"statusType": "Ok",
"date": "2018-12-28"
}
]
}
]
I'm trying to populate a react-table like this
I was able to populate the tool name rows using the 'Internal Tools' header and populated the days of the current month. I'm having trouble figuring out the logic to populate the cells with the status on the given date field of the status object. Here is my code:
export default class ToolsIssue2 extends Component {
constructor(props) {
super(props);
this.state = {
month: moment().format('MMMM, YYYY'),
internalToolData: [{
internalToolName: '',
statuses: [{
date: '',
statusType: '',
}]
}],
}
}
componentDidMount() {
this.generateData();
}
generateData() {
axios.get('http://localhost:8080/internal_tool')
.then(response => {
this.setState({
internalToolData: response.data
});
console.log(this.state.internalToolData);
}).catch(error => alert(error));
}
setStatusSVG(statusType) {
switch (statusType) {
case 'Ok': return <img src={ok} className='OK' alt='ok-logo' />
case 'Warning': return <img src={warning} className='Warning' alt='warning-logo' />
case 'Unavailable': return <img src={unavailable} className='Unavailable' alt='unavailable-logo' />
}
}
getMonth() {
return moment().format('MMMM, YYYY');
}
getCurrentColumns() {
var daysInMonth = moment().daysInMonth();
var monthDaysColumn = [];
for (var i = 1; i <= daysInMonth; i++) {
monthDaysColumn.push(
{
// id: 'statusDate',
Header: i,
accessor: 'statuses',
Cell: (row) => {
if(moment(`${row.row.statuses.date}`).year() === moment().year() && moment(`${row.row.statuses.date}`).date() === i) {
this.setStatusSVG(row.row.statuses.statusType);
}
},
resizable: false,
sortable: false,
width: 35,
})
}
return monthDaysColumn;
}
render() {
const { internalToolData } = this.state;
return (
<div>
<ReactTable
data={internalToolData}
columns={[{
Header: 'Internal Tools',
columns: [{
accessor: 'internalToolName',
width: 150,
resizable: false,
}]
}, {
Header: this.getMonth(),
columns: this.getCurrentColumns(),
}
]}
defaultPageSize={15}
className="-striped -highlight"
/>
<br />
</div>
)
}
}

Parse array of objects recursively and filter object based on id

i have this array of objects : getCategory (variable)
[
{
"id": "20584",
"name": "Produits de coiffure",
"subCategory": [
{
"id": "20590",
"name": "Coloration cheveux",
"subCategory": [
{
"id": "20591",
"name": "Avec ammoniaque"
},
{
"id": "20595",
"name": "Sans ammoniaque"
},
{
"id": "20596",
"name": "Soin cheveux colorés"
},
{
"id": "20597",
"name": "Protection"
},
{
"id": "20598",
"name": "Nuancier de couleurs"
}
]
},
{
"id": "20593",
"name": "Soins cheveux",
"subCategory": [
{
"id": "20594",
"name": "Shampooing"
},
{
"id": "20599",
"name": "Après-shampooing"
},
{
"id": "20600",
"name": "Masques"
},
and i tried everything i could search in stackoverflow ..
lets say on this array i want to get recursively and object with the specified id .. like 20596 and it should return
{
"id": "20596",
"name": "Soin cheveux colorés"
}
The logic way i am doing is like this :
var getSubcategory = getCategory.filter(function f(obj){
if ('subCategory' in obj) {
return obj.id == '20596' || obj.subCategory.filter(f);
}
else {
return obj.id == '20596';
}
});
dont know what else to do .
Thanks
PS : I dont use it in browser so i cannot use any library . Just serverside with no other library . find dont work so i can only use filter
You need to return the found object.
function find(array, id) {
var result;
array.some(function (object) {
if (object.id === id) {
return result = object;
}
if (object.subCategory) {
return result = find(object.subCategory, id);
}
});
return result;
}
var data = [{ id: "20584", name: "Produits de coiffure", subCategory: [{ id: "20590", name: "Coloration cheveux", subCategory: [{ id: "20591", name: "Avec ammoniaque" }, { id: "20595", name: "Sans ammoniaque" }, { id: "20596", name: "Soin cheveux colorés" }, { id: "20597", name: "Protection" }, { id: "20598", name: "Nuancier de couleurs" }] }, { id: "20593", name: "Soins cheveux", subCategory: [{ id: "20594", name: "Shampooing" }, { id: "20599", name: "Après-shampooing" }, { id: "20600", name: "Masques" }] }] }];
console.log(find(data, '20596'));
console.log(find(data, ''));

Categories

Resources