Fakultas Ilmu Komputer UI

Commit 391e75c6 authored by Nabilah Adani's avatar Nabilah Adani
Browse files

Merge branch 'nabh/diagram-statistik-kasus-fe' into 'pbi-13-diagram-statistik-kasus'

add total all and each cases to downloaded pdf file

See merge request !45
parents 3310736c 5b54f8de
Pipeline #80254 passed with stages
in 9 minutes and 20 seconds
......@@ -7,18 +7,22 @@ const dummyImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASoAAAEsCAYAAA
describe('<ExportPDFButton />', () => {
it('should render correctly', () => {
shallow(<ExportPDFButton
png={dummyImage}
type={''}
selectedKey={''}
dataType={''}
chartType={true}
information={''}
clickable={false} />);
})
it('should call downloadAsPDF', () => {
const mod = require('../../utilities/utils');
jest.spyOn(mod, 'downloadAsPDF');
const btn = shallow(<ExportPDFButton
png={dummyImage}
type={''}
selectedKey={''}
dataType={''}
chartType={true}
information={''}
clickable={false} />);
btn.find('Button').simulate('click');
expect(mod.downloadAsPDF).toHaveBeenCalled();
......
......@@ -6,14 +6,16 @@ interface ExportPDFButtonProps {
type: string,
selectedKey: string,
dataType: string,
chartType: boolean,
information: string,
clickable: boolean,
}
function ExportPDFButton({
type, selectedKey, dataType, clickable
type, selectedKey, dataType, chartType, information, clickable
}: ExportPDFButtonProps) {
const handleDownload = React.useCallback(async (type: string, selectedKey: string, dataType: string) => {
downloadAsPDF(type, selectedKey, dataType);
const handleDownload = React.useCallback(async (type: string, selectedKey: string, dataType: string, chartType: boolean, information: string) => {
downloadAsPDF(type, selectedKey, dataType, chartType, information);
}, []);
return (
<Box
......@@ -24,7 +26,7 @@ function ExportPDFButton({
>
<Button
isBold={false}
onClick={() => handleDownload(type, selectedKey, dataType)}
onClick={() => handleDownload(type, selectedKey, dataType, chartType, information)}
clickable={clickable}
>
Export PDF
......
......@@ -48,7 +48,7 @@ describe('<Statistic />', () => {
}
};
it('render diagram statistics without crashing', () => {
it('render diagram statistics without crashing', () => {
mount(
<AppContext.Provider value={testProps}>
<Statistic
......@@ -60,7 +60,7 @@ describe('<Statistic />', () => {
);
});
it('render table statistics without crashing', () => {
it('render table statistics without crashing', () => {
mount(
<AppContext.Provider value={testProps}>
<Statistic
......@@ -72,7 +72,7 @@ describe('<Statistic />', () => {
);
});
it('render table age statistics without crashing', () => {
it('render table age statistics without crashing', () => {
mount(
<AppContext.Provider value={testProps}>
<Statistic
......@@ -84,9 +84,9 @@ describe('<Statistic />', () => {
);
});
it('render sex stats chart successfully', () => {
it('render sex stats chart successfully', () => {
mount(
<AppContext.Provider value={testProps}>
<AppContext.Provider value={testProps}>
<Statistic
isTable={false}
type={StatisticType.Sex}
......@@ -96,7 +96,7 @@ describe('<Statistic />', () => {
);
});
it('render kasus in time range stats chart successfully', () => {
it('render kasus in time range stats chart successfully', () => {
mount(
<AppContext.Provider value={testProps}>
<Statistic
......@@ -108,7 +108,7 @@ describe('<Statistic />', () => {
);
});
it('sets ignoreDateRange state after clicking ignoreDateRange button', () => {
it('sets ignoreDateRange Statistics state after clicking ignoreDateRange button', () => {
const wrapper = mount(<Statistic
isTable={false}
type={StatisticType.Date}
......@@ -118,9 +118,22 @@ describe('<Statistic />', () => {
expect(wrapper.find(Checkbox).props().isChecked).toBe(false);
wrapper.find(Checkbox).simulate('click');
expect(wrapper.find(Checkbox).props().isChecked).toBe(true);
})
});
it('sets ignoreDateRangeFilter age after clicking ignoreDateRangeFilter button', () => {
const wrapper = mount(<Statistic
isTable={false}
type={StatisticType.Age}
data={statisticData.age}
/>);
expect(wrapper.find(Checkbox).props().isChecked).toBe(false);
wrapper.find(Checkbox).simulate('click');
expect(wrapper.find(Checkbox).props().isChecked).toBe(true);
});
it('render table district in time range stats chart successfully', () => {
it('render table district in time range stats chart successfully', () => {
mount(
<AppContext.Provider value={testProps}>
<Statistic
......@@ -132,7 +145,7 @@ describe('<Statistic />', () => {
);
});
it('sets ignoreDateRangeTable false state after clicking ignoreDateRangeTable button', () => {
it('sets ignoreDateRangeTable false state after clicking ignoreDateRangeTable button', () => {
const wrapper = mount(<Statistic
isTable={true}
type={StatisticType.Date}
......
......@@ -200,7 +200,6 @@ function Statistic({
const { data } = response;
setSelectedDateData(data);
}
console.log(selectedDateData)
};
const setActiveIndexHelper = async (tempData: StatisticData) => {
......@@ -313,33 +312,35 @@ function Statistic({
)
}
return (
<BarChart
width={650}
height={265}
data={res}
margin={{
top: 50, right: 70
}}
>
<CartesianGrid strokeDasharray="4 4" />
<XAxis dataKey="name" tick={{ fontSize: 14 }} interval={0} angle={30} dy={20} height={60} />
<YAxis type="number" domain={[0, dataMax => (Math.ceil(dataMax * 1.5))]} allowDataOverflow={true} />
<Tooltip />
<Legend
layout="horizontal"
verticalAlign="bottom"
align="center"
payload={
[
<>
<BarChart
width={650}
height={265}
data={res}
margin={{
top: 50, right: 70
}}
>
<CartesianGrid strokeDasharray="4 4" />
<XAxis dataKey="name" tick={{ fontSize: 14 }} interval={0} angle={30} dy={20} height={60} />
<YAxis type="number" domain={[0, dataMax => (Math.ceil(dataMax * 1.5))]} allowDataOverflow={true} />
<Tooltip />
<Legend
layout="horizontal"
verticalAlign="bottom"
align="center"
payload={[
{ value: "Kasus Positif", type: "square", id: "Kasus Positif", color: PIE_COLORS[0] },
{ value: "Kasus Negatif", type: "square", id: "Kasus Negatif", color: PIE_COLORS[1] },
{ value: "Kasus Terduga", type: "square", id: "Kasus Terduga", color: PIE_COLORS[2] }
]
} />
<Bar dataKey="positive" stackId="a" fill={PIE_COLORS[0]} />
<Bar dataKey="negative" stackId="a" fill={PIE_COLORS[1]} />
<Bar dataKey="undetermined" stackId="a" fill={PIE_COLORS[2]} />
</BarChart>
]} />
<Bar dataKey="positive" stackId="a" fill={PIE_COLORS[0]} />
<Bar dataKey="negative" stackId="a" fill={PIE_COLORS[1]} />
<Bar dataKey="undetermined" stackId="a" fill={PIE_COLORS[2]} />
</BarChart>
<br></br>
<Text align={"center"} width={"580px"} fontSize={"19px"} isBold={true}>{`Total: ${statisticsDateData.total_count} kasus`}</Text>
</>
);
}
if (chartType) {
......@@ -472,7 +473,9 @@ function Statistic({
<ExportPDFButton
type={type}
selectedKey={ageKey.minAge.toString() + " - " + ageKey.maxAge.toString()}
dataType={(!ignoreDateRange) ? dateKeyFilter.start_date.toISOString().split('T')[0] + " s/d " + dateKeyFilter.end_date.toISOString().split('T')[0] : ""}
dataType={(!ignoreDateRangeFilter) ? (new Date(dateKeyFilter.start_date.valueOf() + 1000 * 3600 * 24)).toISOString().split('T')[0] + " s/d " + (new Date(dateKeyFilter.end_date.valueOf() + 1000 * 3600 * 24)).toISOString().split('T')[0] : ""}
chartType={chartType}
information={selectedKeyData.totalCount.toString() + selectedKeyData.parts[0]?.jumlah.toString() + selectedKeyData.parts[1]?.jumlah.toString() + selectedKeyData.parts[2]?.jumlah.toString()}
clickable={selectedKeyData.totalCount !== 0}
/>
</Box>
......@@ -516,7 +519,9 @@ function Statistic({
<ExportPDFButton
type={type}
selectedKey={"Tanggal"}
dataType={(!ignoreDateRange) ? dateKey.start_date.toISOString().split('T')[0] + " s/d " + dateKey.end_date.toISOString().split('T')[0] : ""}
dataType={(!ignoreDateRange) ? (new Date(dateKey.start_date.valueOf() + 1000 * 3600 * 24)).toISOString().split('T')[0] + " s/d " + (new Date(dateKey.end_date.valueOf() + 1000 * 3600 * 24)).toISOString().split('T')[0] : ""}
chartType={false}
information={selectedKeyData.totalCount.toString() + selectedKeyData.parts[0]?.jumlah.toString() + selectedKeyData.parts[1]?.jumlah.toString() + selectedKeyData.parts[2]?.jumlah.toString()}
clickable={Object.values(statisticsDateData['district']).reduce((a, b) => a + (b['total_count'] || 0), 0) !== 0}
/>
</Box>
......@@ -576,7 +581,9 @@ function Statistic({
<ExportPDFButton
type={type}
selectedKey={selectedKey}
dataType={(!ignoreDateRangeFilter) ? dateKeyFilter.start_date.toISOString().split('T')[0] + " s/d " + dateKeyFilter.end_date.toISOString().split('T')[0] : ""}
dataType={(!ignoreDateRangeFilter) ? (new Date(dateKeyFilter.start_date.valueOf() + 1000 * 3600 * 24)).toISOString().split('T')[0] + " s/d " + (new Date(dateKeyFilter.end_date.valueOf() + 1000 * 3600 * 24)).toISOString().split('T')[0] : ""}
chartType={chartType}
information={selectedKeyData.totalCount.toString() + selectedKeyData.parts[0]?.jumlah.toString() + selectedKeyData.parts[1]?.jumlah.toString() + selectedKeyData.parts[2]?.jumlah.toString()}
clickable={selectedKeyData.totalCount !== 0}
/>
</Box>
......
......@@ -2,6 +2,7 @@ import React from 'react';
import { Sector } from 'recharts';
import { jsPDF } from "jspdf";
import { PIE_COLORS } from 'constant';
import { PassThrough } from 'stream';
interface ActiveShapeProps {
cx: number, cy: number, midAngle: number, innerRadius: number,
......@@ -88,7 +89,7 @@ const renderActiveShape = (props: ActiveShapeProps) => {
);
};
const image2pdf = (imageType: string, type: string, key: string, dataType: string) => {
const image2pdf = (imageType: string, type: string, key: string, dataType: string, chartType: boolean, info: string) => {
const imgWidth = 232;
const imgHeight = 130;
const pageWidth = 297;
......@@ -101,7 +102,30 @@ const image2pdf = (imageType: string, type: string, key: string, dataType: stri
const header = (doc: jsPDF) => {
doc.setFontSize(26);
doc.setFont("arial", "bold");
doc.text("DATA KASUS TBC DEPOK", pageWidth/2, 18, {align:"center"});
if (key == "Tanggal")
doc.text("DATA KASUS TBC 1 DEPOK", pageWidth/2, 24, {align:"center"});
else
doc.text("DATA KASUS TBC DEPOK", pageWidth/2, 18, {align:"center"});
}
const writeInfoCases = (doc: jsPDF) => {
doc.setFontSize(20);
doc.setFont("arial", "light");
doc.text("Jumlah : " + info.slice(1, 2), 90, 35, {align:"center"})
doc.text("Jumlah : " + info.slice(2, 3), 145, 35, {align:"center"})
doc.text("Jumlah : " + info.slice(3, 4), 200, 35, {align:"center"})
}
const writeTotal = (doc: jsPDF) => {
doc.setFontSize(20);
doc.setFont("arial", "bold");
if (key == "Tanggal")
doc.text("Total Kasus : " + info.slice(0, 1), pageWidth/2, 155, {align:"center"})
else
if (chartType)
doc.text("Total : " + info.slice(0, 1) + " Kasus", pageWidth/2, 140, {align:"center"})
else
doc.text("Total : " + info.slice(0, 1) + " Kasus", pageWidth/2, 150, {align:"center"})
}
const writeTextToPDF = (doc: jsPDF) => {
......@@ -109,26 +133,26 @@ const image2pdf = (imageType: string, type: string, key: string, dataType: stri
doc.setFont("arial", "italic-bold");
if(key == "Tanggal")
if(dataType == "")
doc.text("Keseluruhan Kasus TBC di DEPOK", pageWidth/2, 160, {align:"center"});
doc.text("Keseluruhan Kasus TBC di DEPOK", pageWidth/2, 170, {align:"center"});
else
doc.text("Berdasarkan tanggal " + dataType, pageWidth/2, 160, {align:"center"})
doc.text("Berdasarkan tanggal " + dataType, pageWidth/2, 170, {align:"center"})
else
if(dataType == "")
doc.text("Keseluruhan Kasus TBC berdasarkan " + type + " " + key, pageWidth/2, 156, {align:"center"});
doc.text("Keseluruhan Kasus TBC berdasarkan " + type + " " + key, pageWidth/2, 165, {align:"center"});
else
doc.text(type + " " + key + " dari tanggal " + dataType, pageWidth/2, 156, {align:"center"});
doc.text(type + " " + key + " dari tanggal " + dataType, pageWidth/2, 165, {align:"center"});
doc.setFillColor(PIE_COLORS[0]);
doc.rect(30, 170, 5, 5, 'F');
doc.rect(30, 190, 5, 5, 'F');
doc.setFillColor(PIE_COLORS[1]);
doc.rect(30, 180, 5, 5, 'F');
doc.rect(120, 190, 5, 5, 'F');
doc.setFillColor(PIE_COLORS[2]);
doc.rect(30, 190, 5, 5, 'F');
doc.rect(220, 190, 5, 5, 'F');
doc.setFont("arial", "normal");
doc.text("Kasus Positif", 40, 174, {align:"left"});
doc.text("Kasus Negatif", 40, 184, {align:"left"});
doc.text("Kasus Terduga", 40, 194, {align:"left"});
doc.text("Kasus Positif", 40, 194, {align:"left"});
doc.text("Kasus Negatif", 130, 194, {align:"left"});
doc.text("Kasus Terduga", 230, 194, {align:"left"});
}
const svgToBlob = (svg: Element) => {
......@@ -170,7 +194,10 @@ const image2pdf = (imageType: string, type: string, key: string, dataType: stri
blobToImage(svgBlob).then(img => {
header(doc);
if (!chartType && key !== "Tanggal")
writeInfoCases(doc);
addImageToDoc(img, doc);
writeTotal(doc);
writeTextToPDF(doc);
if(key == "Tanggal")
if (dataType == "")
......@@ -186,8 +213,8 @@ const image2pdf = (imageType: string, type: string, key: string, dataType: stri
});
};
const downloadAsPDF = (type: string, selectedKey: string, dataType: string) => {
image2pdf("PNG", type, translate(selectedKey), dataType);
const downloadAsPDF = (type: string, selectedKey: string, dataType: string, chartType: boolean, info: string) => {
image2pdf("PNG", type, translate(selectedKey), dataType, chartType, info);
}
export { translate, renderActiveShape, image2pdf, downloadAsPDF, translateTypetoKey };
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment