Java 使用lineTo和curveTo的apache pdfBox问题
我正在使用Apache的PDFBox版本2.0.4,但在使用lineTo和curveTo时遇到问题。我的函数获取弧度、起始度和结束度的参数,然后使用lineTo和curveTo生成饼图的切片Java 使用lineTo和curveTo的apache pdfBox问题,java,pdfbox,Java,Pdfbox,我正在使用Apache的PDFBox版本2.0.4,但在使用lineTo和curveTo时遇到问题。我的函数获取弧度、起始度和结束度的参数,然后使用lineTo和curveTo生成饼图的切片 mContents.setNonStrokingColor(color); mContents.moveTo(0, 0); List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(en
mContents.setNonStrokingColor(color);
mContents.moveTo(0, 0);
List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(endDeg));
mContents.lineTo(smallArc.get(0), smallArc.get(1));
mContents.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4), smallArc.get(5), smallArc.get(6), smallArc.get(7));
mContents.closePath();
mContents.fill();
当pi图表包含在生成的pdf中时,页脚和图像不在pdf中。截短代码以生成饼图,页脚将显示包含的图像
当前必须在生成页面后添加指定特定坐标的饼图,否则饼图下面的其他行不会显示
curveTo和lineTo生成的输出是否会大于导致这些问题的显示值
编辑-在绘制图形之前在页脚中添加图像,并且图像、图形和文本都会出现
感谢你的指点
完整代码:
import com.google.code.geocoder.Geocoder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.util.Matrix;
import org.apache.tomcat.jni.Address;
import org.slf4j.Logger;
import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
/** * Created by tim on 7/6/2017. */
public class ReportDataPDFBox {
private PDDocument mDoc = null;
private PDPage mPage = null;
private PDImageXObject pdImage = null;
private PDFont mHeaderFont = PDType1Font.HELVETICA_BOLD;
private final int FONT_SIZE_HDR1 = 16;
private final int FONT_SIZE_HDR2 = 14;
private final int FONT_SIZE_REG = 12;
private final int HDR_INDENT = 30;
private final int BODY_INDENT_1 = 55;
private final int BODY_INDENT_2 = 65;
private final int BODY_INDENT_3 = 75;
private PDFont mRegFont = PDType1Font.HELVETICA;
PDPageContentStream mContents = null;
private String mReportName = null;
private String mFullImagePath = null;
private String mMonth = null;
private boolean mReportDone = true;
private int mHorizonVal = 700;
private int mHorizonGrph = 0;
private long[] mDayPercent;
private Calendar mCurrentCalendar = null;
ProcessFrequencyData pfd = null;
ProcessWeatherData pwd = null;
ProcessPerformanceData ppd = null;
Logger log = null;
Color[] mColor = {Color.PINK,Color.YELLOW,Color.CYAN, Color.BLUE,Color.RED,Color.GREEN,Color.ORANGE,Color.LIGHT_GRAY};
public ReportDataPDFBox(Logger logger, ProcessFrequencyData pfd, ProcessWeatherData pwd, ProcessPerformanceData ppd){
this.log = logger;
this.pfd = pfd;
this.pwd = pwd;
this.ppd = ppd;
initializeDoc();
}
public void initializeDoc(){
mDoc = new PDDocument();
mPage = new PDPage();
mDoc.addPage(mPage);
mFullImagePath = "logo.png";
mCurrentCalendar = Calendar.getInstance();
mMonth = mCurrentCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
mReportName = mMonth + ".pdf";
try{
mContents = new PDPageContentStream(mDoc, mPage);
}catch(IOException e){System.out.println("Error setting content stream - "+e.getLocalizedMessage());}
}
public boolean writeTheReport(){
addHeader();
addFooter();
generateReportContent();
// addFooter();
cleanUpALlDone();
return mReportDone;
}
private void addHeader(){
try {
mContents.beginText();
mContents.setFont(mHeaderFont,FONT_SIZE_HDR1);
mContents.newLineAtOffset(200, 740);
mContents.showText(mMonth + " - ActoTracker Report - " + mCurrentCalendar.get(Calendar.YEAR));
mContents.endText();
}catch (IOException io){System.out.println("Error with text content screen");}
}
private void generateReportContent(){
addNumberRunInfo();
addLocationRunInfo();
addWeekDayInfo();
addWeekInfo();
addFrequencyData();
pukeMeAChart();
// generateDailyChart();
}
private void addNumberRunInfo(){
int daysActive = Utility.getDaysBetweenDates(Utility.getOldestDate(pfd.getFirstDate(),
pwd.getFirstDate()), Calendar.getInstance().getTimeInMillis());
writeLine(mHeaderFont, FONT_SIZE_HDR2,HDR_INDENT, "Frequency Information");
long percentActiveIdle = (pfd.getTotalDaysRun()*100/daysActive);
String line = "Number of Runs - " + pfd.getTotalDaysRun() + " Number of days ActoTracker active - " + daysActive + " Percent run =
"+percentActiveIdle;
writeLine(mRegFont, FONT_SIZE_REG, BODY_INDENT_1, line);
}
private void addLocationRunInfo(){
String line = "Number of locations run = " + pfd.getLocationRun();
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
for (int i=1; i<=pfd.getLocationRun();i++){
String[] locationInfo = pfd.getLocationInfo(i);
long percent = pfd.getRunsByLocation(i)*100/pfd.getTotalDaysRun();
String line2= new String( locationInfo[0] + " - " + locationInfo[1] +" , "+locationInfo[2]+ " Number of runs = " +
pfd.getRunsByLocation(i) + " Percent of runs = " +percent );
writeLine(mRegFont, FONT_SIZE_REG,BODY_INDENT_2,line2);
}
}
private void addWeekDayInfo(){
int totDaysRunning = pfd.getTotalRunDay();
int leastCnt = 0;
int mostCnt = 0;
mHorizonGrph = mHorizonVal - 90;
mDayPercent = new long[8];
String mostDay = " most common day";
String leastDay = " least common day";
DayFrequencyResults frequency = pfd.getDayDistribution();
int[] leastDays = frequency.getLessDays();
int[] mostDays = frequency.getMostDays();
StringBuilder leastString = new StringBuilder();
StringBuilder mostString = new StringBuilder();
for (int i=0; i< leastDays.length;i++){
if (leastDays[i] != 0) {
leastString.append(Utility.getDayName(leastDays[i])).append(" ");
leastCnt++;
}
}
for (int j=0; j< mostDays.length;j++){
if (mostDays[j] != 0) {
mostString.append(Utility.getDayName(j+1)).append(" ");
mostCnt++;
}
}
if (leastCnt > 1){leastDay += "s";}
if (mostCnt > 1) {mostDay +="s";}
String line = mostString.toString()+mostDay+ " to run"+ " "+leastString.toString()+leastDay+" to run";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
for (int i=1;i<8;i++){
String day = new String(Utility.getDayName(i)+" " + pfd.getRweekDayCount(i) + " runs "+"
"+pfd.getRweekDayCount(i)*100/totDaysRunning)+ "%";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_2,day);
double x = pfd.getRweekDayCount(i) / (double)pfd.getTotalDaysRun();
mDayPercent[i] = Math.round(360*x);
}
System.out.println("BreakPoint");
}
private void addWeekInfo(){
String line;
Integer[] largestWeekTotals = {0,0,0,0,0,0,0};
double largestDistance = 0D;
double firstHalfDist = 0D;
double secondHalfDist = 0D;
DecimalFormat df = new DecimalFormat("####.##");
int[] distFreq = pfd.getMonthlySummaryInfo();
if (distFreq[0] > distFreq[1]){
line = "Ran more in first half of months run. "+ distFreq[0] + " times versus "+ distFreq[1]+" times";
}else{
line = "Ran more in second half of months run. " + distFreq[1] + " times versus " + distFreq[0]+" times";
}
writeLine(mRegFont,FONT_SIZE_REG, BODY_INDENT_1, line);
for (int i = 1; i<7;i++){
if (i<4){
firstHalfDist += Utility.getMileage(pfd.fa.getWeekDistanceTotal(i),false);
}else{
secondHalfDist += Utility.getMileage(pfd.fa.getWeekDistanceTotal(i),false);
}
}
if (firstHalfDist > secondHalfDist){
line = new String ("Ran further in the first half of the month " + df.format(firstHalfDist) + " miles versus " +
df.format(secondHalfDist) + " miles");
}else{
line = new String ("Ran further in the second half of the month " + df.format(secondHalfDist) + " miles versus " +
df.format(firstHalfDist)+ " miles");
}
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1, line);
}
private void addFrequencyData(){
int greatestFreq = 0;
int leastDiff = 0;
int greatestDiff = 0;
int leastFreq = 0;
for (int i=0; i<30; i++){
int cnt = ppd.getRunsByFrequentcy(i);
if (cnt > greatestFreq){
greatestFreq = cnt;
greatestDiff = i;
}
else{
if (cnt > 0 && i>leastDiff){
leastDiff = i;
leastFreq = cnt;
}
}
log.info("Frequency?? = " + cnt + " index = "+i);
}
String line = greatestDiff + " days is the most common frequency between runs "+greatestFreq+" times";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
String line2 = leastDiff + " days longest time between runs " + leastFreq + " times";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line2);
}
private void writeLine(PDFont font, int fontSize, int indent, String text){
mHorizonVal -= 20;
try {
mContents.beginText();
mContents.setFont(font, fontSize);
mContents.newLineAtOffset(indent,mHorizonVal);
mContents.showText(text);
mContents.endText();
}catch(IOException e){}
}
private void addFooter(){
log.info("IN addFooter");
mPage = new PDPage();
mDoc.addPage(mPage);
try {
pdImage = PDImageXObject.createFromFile(mFullImagePath, mDoc);
}catch(IOException ie){System.out.println("Error opening image file - "+ie.getMessage());}
try {
mContents.drawImage(pdImage,250,5,pdImage.getWidth()/2,pdImage.getHeight()/2);
}catch(IOException e){log.error("Error adding image file - "+ e.getLocalizedMessage());}
}
private void cleanUpALlDone(){
try {
mContents.close();
mDoc.save(mReportName);
mDoc.close();
}catch (IOException ie){System.out.println("Error closing PDF document - " + ie.getMessage());}
}
private void generateDailyChart(){
int totalVal = 0;
try {
mContents.transform(Matrix.getTranslateInstance(375, 525));
}catch(IOException e){}
for (int i=1; i< 8;i++){
totalVal += mDayPercent[i];
writeTheChart(mDayPercent[i-1], totalVal,mColor[i]);
log.info("Color selected = " +mColor[i] +"Index = "+i);
}
}
private void writeTheChart(long beg, long end, Color color){
try {
log.info("Color received = " + color);
drawSlice(color, 60,beg, end);
}catch(IOException e){}
}
private void pukeMeAChart(){
try {
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
mContents.fill();
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
mContents.fill();
drawSlice(Color.WHITE, 60, 181, 208);
mContents.fill();
drawSlice(Color.GREEN, 60, 208, 272);
mContents.fill();
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.fill();
} catch(IOException e ){}
}
private void drawSlice(Color color, float rad, float startDeg, float endDeg) throws IOException
{
mContents.setNonStrokingColor(color);
mContents.moveTo(0, 0);
List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(endDeg));
mContents.lineTo(smallArc.get(0), smallArc.get(1));
mContents.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4), smallArc.get(5), smallArc.get(6), smallArc.get(7));
mContents.closePath();
mContents.fill();
}
private List<Float> createSmallArc(double r, double a1, double a2)
{
// Compute all four points for an arc that subtends the same total angle
// but is centered on the X-axis
double a = (a2 - a1) / 2;
double x4 = r * Math.cos(a);
double y4 = r * Math.sin(a);
double x1 = x4;
double y1 = -y4;
double q1 = x1*x1 + y1*y1;
double q2 = q1 + x1*x4 + y1*y4;
double k2 = 4/3d * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
double x2 = x1 - k2 * y1;
double y2 = y1 + k2 * x1;
double x3 = x2;
double y3 = -y2;
// Find the arc points' actual locations by computing x1,y1 and x4,y4
// and rotating the control points by a + a1
double ar = a + a1;
double cos_ar = Math.cos(ar);
double sin_ar = Math.sin(ar);
List<Float> list = new ArrayList<Float>();
list.add((float) (r * Math.cos(a1)));
list.add((float) (r * Math.sin(a1)));
list.add((float) (x2 * cos_ar - y2 * sin_ar));
list.add((float) (x2 * sin_ar + y2 * cos_ar));
list.add((float) (x3 * cos_ar - y3 * sin_ar));
list.add((float) (x3 * sin_ar + y3 * cos_ar));
list.add((float) (r * Math.cos(a2)));
list.add((float) (r * Math.sin(a2)));
return list;
}
}
import com.google.code.geocoder.geocoder;
导入org.apache.pdfbox.pdmodel.PDDocument;
导入org.apache.pdfbox.pdmodel.PDPage;
导入org.apache.pdfbox.pdmodel.PDPageContentStream;
导入org.apache.pdfbox.pdmodel.font.PDFont;
导入org.apache.pdfbox.pdmodel.font.PDType1Font;
导入org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
导入org.apache.pdfbox.util.Matrix;
导入org.apache.tomcat.jni.Address;
导入org.slf4j.Logger;
导入java.awt.*;
导入java.io.IOException;
导入java.text.DecimalFormat;
导入java.util.ArrayList;
导入java.util.Calendar;
导入java.util.List;
导入java.util.Locale;
/***由tim于2017年7月6日创建*/
公共类ReportDataPDFBox{
私有PDDocument mDoc=null;
私有PDPage mPage=null;
私有PDImageXObject pdImage=null;
私有PDFont mHeaderFont=PDType1Font.HELVETICA_BOLD;
专用最终整数字体大小HDR1=16;
私有最终整数字体大小HDR2=14;
私人最终整数字体大小注册=12;
私人最终int HDR_缩进=30;
私有最终整数正文缩进1=55;
私有最终整数正文缩进2=65;
私有最终整数正文\u缩进\u 3=75;
私有PDFont mRegFont=PDType1Font.HELVETICA;
PDPageContentStream mContents=null;
私有字符串mReportName=null;
私有字符串mFullImagePath=null;
私有字符串mMonth=null;
私有布尔值mReportDone=true;
私有int mHorizonVal=700;
私有int mHorizonGrph=0;
私人长[]日百分比;
私有日历mCurrentCalendar=null;
ProcessFrequencyData pfd=null;
ProcessWeatherData pwd=null;
ProcessPerformanceData ppd=null;
记录器日志=空;
Color[]mColor={Color.粉红色,Color.黄色,Color.青色,Color.蓝色,Color.红色,Color.绿色,Color.橙色,Color.浅灰色};
公共报告数据PDFBox(记录器记录器、ProcessFrequencyData pfd、ProcessWeatherData pwd、ProcessPerformanceData ppd){
this.log=记录器;
this.pfd=pfd;
this.pwd=pwd;
this.ppd=ppd;
初始化为c();
}
public void initializeDoc(){
mDoc=新的PDDocument();
mPage=新的PDPage();
mDoc.addPage(mPage);
mfullmagepath=“logo.png”;
mCurrentCalendar=Calendar.getInstance();
mMonth=mccurrentcalendar.getDisplayName(Calendar.MONTH、Calendar.LONG、Locale.getDefault());
mReportName=mMonth+“.pdf”;
试一试{
mContents=新的PDPageContentStream(mDoc,mPage);
}catch(IOException e){System.out.println(“设置内容流时出错-”+e.getLocalizedMessage());}
}
公共布尔写以太网端口(){
addHeader();
addFooter();
generateReportContent();
//addFooter();
cleanUpALlDone();
返回mReportDone;
}
私有void addHeader(){
试一试{
mContents.beginText();
mContents.setFont(mHeaderFont,FONT\u SIZE\u HDR1);
mContents.newlineatofset(200740);
mContents.showText(mMonth+“-ActoTracker报告-”+mCurrentCalendar.get(Calendar.YEAR));
mContents.endText();
}catch(IOException io){System.out.println(“文本内容屏幕错误”);}
}
私有void generateReportContent(){
addNumberRunInfo();
addLocationRunInfo();
addWeekDayInfo();
addWeekInfo();
addFrequencyData();
pukeMeAChart();
//generateDailyChart();
}
私有void addNumberRunInfo(){
int daysActive=Utility.getdaysbetween日期(Utility.getOldestDate(pfd.getFirstDate()),
pwd.getFirstDate()),Calendar.getInstance().getTimeInMillis();
writeLine(mHeaderFont,字体大小HDR2,HDR缩进,“频率信息”);
长百分比活动空闲=(pfd.getTotalDaysRun()*100/天活动);
String line=“运行次数-”+pfd.getTotalDaysRun()+“ActTracker活动天数-“+DaysActivity+”运行百分比=
“+闲置百分比;
书写线(mRegFont、字体大小、正文缩进、行);
}
私有void addLocationRunInfo(){
String line=“运行的位置数=“+pfd.getLocationRun();
书写线(mRegFont、字体大小、正文缩进、行);
对于(inti=1;i1){leastDay+=“s”}
如果(mostCnt>1){mostDay+=“s”}
字符串行=mostString.toString()+mostDay+“运行”+“”+leastString.toString()+leastDay+“运行”;
书写线(mRegFont、字体大小、正文缩进、行);
对于(int i=1;i distFreq[1]){
line=“在运行的前半个月运行了更多。”+distFreq[0]+“次,而不是“+distFreq[1]+”次”;
}否则{
line=“在运行的下半个月运行了更多。”+distFreq[1]+“次,而“+distFreq[0]+”次;
}
书写线(mRegFont、字体大小、正文缩进、行);
对于(int i=1;i 0&&i>leastDiff){
leastDiff=i;
leastFreq=cnt;
}
}
log.info(“频率=”
import com.google.code.geocoder.Geocoder;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.util.Matrix;
import org.apache.tomcat.jni.Address;
import org.slf4j.Logger;
import java.awt.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
/** * Created by tim on 7/6/2017. */
public class ReportDataPDFBox {
private PDDocument mDoc = null;
private PDPage mPage = null;
private PDImageXObject pdImage = null;
private PDFont mHeaderFont = PDType1Font.HELVETICA_BOLD;
private final int FONT_SIZE_HDR1 = 16;
private final int FONT_SIZE_HDR2 = 14;
private final int FONT_SIZE_REG = 12;
private final int HDR_INDENT = 30;
private final int BODY_INDENT_1 = 55;
private final int BODY_INDENT_2 = 65;
private final int BODY_INDENT_3 = 75;
private PDFont mRegFont = PDType1Font.HELVETICA;
PDPageContentStream mContents = null;
private String mReportName = null;
private String mFullImagePath = null;
private String mMonth = null;
private boolean mReportDone = true;
private int mHorizonVal = 700;
private int mHorizonGrph = 0;
private long[] mDayPercent;
private Calendar mCurrentCalendar = null;
ProcessFrequencyData pfd = null;
ProcessWeatherData pwd = null;
ProcessPerformanceData ppd = null;
Logger log = null;
Color[] mColor = {Color.PINK,Color.YELLOW,Color.CYAN, Color.BLUE,Color.RED,Color.GREEN,Color.ORANGE,Color.LIGHT_GRAY};
public ReportDataPDFBox(Logger logger, ProcessFrequencyData pfd, ProcessWeatherData pwd, ProcessPerformanceData ppd){
this.log = logger;
this.pfd = pfd;
this.pwd = pwd;
this.ppd = ppd;
initializeDoc();
}
public void initializeDoc(){
mDoc = new PDDocument();
mPage = new PDPage();
mDoc.addPage(mPage);
mFullImagePath = "logo.png";
mCurrentCalendar = Calendar.getInstance();
mMonth = mCurrentCalendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault());
mReportName = mMonth + ".pdf";
try{
mContents = new PDPageContentStream(mDoc, mPage);
}catch(IOException e){System.out.println("Error setting content stream - "+e.getLocalizedMessage());}
}
public boolean writeTheReport(){
addHeader();
addFooter();
generateReportContent();
// addFooter();
cleanUpALlDone();
return mReportDone;
}
private void addHeader(){
try {
mContents.beginText();
mContents.setFont(mHeaderFont,FONT_SIZE_HDR1);
mContents.newLineAtOffset(200, 740);
mContents.showText(mMonth + " - ActoTracker Report - " + mCurrentCalendar.get(Calendar.YEAR));
mContents.endText();
}catch (IOException io){System.out.println("Error with text content screen");}
}
private void generateReportContent(){
addNumberRunInfo();
addLocationRunInfo();
addWeekDayInfo();
addWeekInfo();
addFrequencyData();
pukeMeAChart();
// generateDailyChart();
}
private void addNumberRunInfo(){
int daysActive = Utility.getDaysBetweenDates(Utility.getOldestDate(pfd.getFirstDate(),
pwd.getFirstDate()), Calendar.getInstance().getTimeInMillis());
writeLine(mHeaderFont, FONT_SIZE_HDR2,HDR_INDENT, "Frequency Information");
long percentActiveIdle = (pfd.getTotalDaysRun()*100/daysActive);
String line = "Number of Runs - " + pfd.getTotalDaysRun() + " Number of days ActoTracker active - " + daysActive + " Percent run =
"+percentActiveIdle;
writeLine(mRegFont, FONT_SIZE_REG, BODY_INDENT_1, line);
}
private void addLocationRunInfo(){
String line = "Number of locations run = " + pfd.getLocationRun();
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
for (int i=1; i<=pfd.getLocationRun();i++){
String[] locationInfo = pfd.getLocationInfo(i);
long percent = pfd.getRunsByLocation(i)*100/pfd.getTotalDaysRun();
String line2= new String( locationInfo[0] + " - " + locationInfo[1] +" , "+locationInfo[2]+ " Number of runs = " +
pfd.getRunsByLocation(i) + " Percent of runs = " +percent );
writeLine(mRegFont, FONT_SIZE_REG,BODY_INDENT_2,line2);
}
}
private void addWeekDayInfo(){
int totDaysRunning = pfd.getTotalRunDay();
int leastCnt = 0;
int mostCnt = 0;
mHorizonGrph = mHorizonVal - 90;
mDayPercent = new long[8];
String mostDay = " most common day";
String leastDay = " least common day";
DayFrequencyResults frequency = pfd.getDayDistribution();
int[] leastDays = frequency.getLessDays();
int[] mostDays = frequency.getMostDays();
StringBuilder leastString = new StringBuilder();
StringBuilder mostString = new StringBuilder();
for (int i=0; i< leastDays.length;i++){
if (leastDays[i] != 0) {
leastString.append(Utility.getDayName(leastDays[i])).append(" ");
leastCnt++;
}
}
for (int j=0; j< mostDays.length;j++){
if (mostDays[j] != 0) {
mostString.append(Utility.getDayName(j+1)).append(" ");
mostCnt++;
}
}
if (leastCnt > 1){leastDay += "s";}
if (mostCnt > 1) {mostDay +="s";}
String line = mostString.toString()+mostDay+ " to run"+ " "+leastString.toString()+leastDay+" to run";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
for (int i=1;i<8;i++){
String day = new String(Utility.getDayName(i)+" " + pfd.getRweekDayCount(i) + " runs "+"
"+pfd.getRweekDayCount(i)*100/totDaysRunning)+ "%";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_2,day);
double x = pfd.getRweekDayCount(i) / (double)pfd.getTotalDaysRun();
mDayPercent[i] = Math.round(360*x);
}
System.out.println("BreakPoint");
}
private void addWeekInfo(){
String line;
Integer[] largestWeekTotals = {0,0,0,0,0,0,0};
double largestDistance = 0D;
double firstHalfDist = 0D;
double secondHalfDist = 0D;
DecimalFormat df = new DecimalFormat("####.##");
int[] distFreq = pfd.getMonthlySummaryInfo();
if (distFreq[0] > distFreq[1]){
line = "Ran more in first half of months run. "+ distFreq[0] + " times versus "+ distFreq[1]+" times";
}else{
line = "Ran more in second half of months run. " + distFreq[1] + " times versus " + distFreq[0]+" times";
}
writeLine(mRegFont,FONT_SIZE_REG, BODY_INDENT_1, line);
for (int i = 1; i<7;i++){
if (i<4){
firstHalfDist += Utility.getMileage(pfd.fa.getWeekDistanceTotal(i),false);
}else{
secondHalfDist += Utility.getMileage(pfd.fa.getWeekDistanceTotal(i),false);
}
}
if (firstHalfDist > secondHalfDist){
line = new String ("Ran further in the first half of the month " + df.format(firstHalfDist) + " miles versus " +
df.format(secondHalfDist) + " miles");
}else{
line = new String ("Ran further in the second half of the month " + df.format(secondHalfDist) + " miles versus " +
df.format(firstHalfDist)+ " miles");
}
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1, line);
}
private void addFrequencyData(){
int greatestFreq = 0;
int leastDiff = 0;
int greatestDiff = 0;
int leastFreq = 0;
for (int i=0; i<30; i++){
int cnt = ppd.getRunsByFrequentcy(i);
if (cnt > greatestFreq){
greatestFreq = cnt;
greatestDiff = i;
}
else{
if (cnt > 0 && i>leastDiff){
leastDiff = i;
leastFreq = cnt;
}
}
log.info("Frequency?? = " + cnt + " index = "+i);
}
String line = greatestDiff + " days is the most common frequency between runs "+greatestFreq+" times";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line);
String line2 = leastDiff + " days longest time between runs " + leastFreq + " times";
writeLine(mRegFont,FONT_SIZE_REG,BODY_INDENT_1,line2);
}
private void writeLine(PDFont font, int fontSize, int indent, String text){
mHorizonVal -= 20;
try {
mContents.beginText();
mContents.setFont(font, fontSize);
mContents.newLineAtOffset(indent,mHorizonVal);
mContents.showText(text);
mContents.endText();
}catch(IOException e){}
}
private void addFooter(){
log.info("IN addFooter");
mPage = new PDPage();
mDoc.addPage(mPage);
try {
pdImage = PDImageXObject.createFromFile(mFullImagePath, mDoc);
}catch(IOException ie){System.out.println("Error opening image file - "+ie.getMessage());}
try {
mContents.drawImage(pdImage,250,5,pdImage.getWidth()/2,pdImage.getHeight()/2);
}catch(IOException e){log.error("Error adding image file - "+ e.getLocalizedMessage());}
}
private void cleanUpALlDone(){
try {
mContents.close();
mDoc.save(mReportName);
mDoc.close();
}catch (IOException ie){System.out.println("Error closing PDF document - " + ie.getMessage());}
}
private void generateDailyChart(){
int totalVal = 0;
try {
mContents.transform(Matrix.getTranslateInstance(375, 525));
}catch(IOException e){}
for (int i=1; i< 8;i++){
totalVal += mDayPercent[i];
writeTheChart(mDayPercent[i-1], totalVal,mColor[i]);
log.info("Color selected = " +mColor[i] +"Index = "+i);
}
}
private void writeTheChart(long beg, long end, Color color){
try {
log.info("Color received = " + color);
drawSlice(color, 60,beg, end);
}catch(IOException e){}
}
private void pukeMeAChart(){
try {
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
mContents.fill();
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
mContents.fill();
drawSlice(Color.WHITE, 60, 181, 208);
mContents.fill();
drawSlice(Color.GREEN, 60, 208, 272);
mContents.fill();
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.fill();
} catch(IOException e ){}
}
private void drawSlice(Color color, float rad, float startDeg, float endDeg) throws IOException
{
mContents.setNonStrokingColor(color);
mContents.moveTo(0, 0);
List<Float> smallArc = createSmallArc(rad, Math.toRadians(startDeg), Math.toRadians(endDeg));
mContents.lineTo(smallArc.get(0), smallArc.get(1));
mContents.curveTo(smallArc.get(2), smallArc.get(3), smallArc.get(4), smallArc.get(5), smallArc.get(6), smallArc.get(7));
mContents.closePath();
mContents.fill();
}
private List<Float> createSmallArc(double r, double a1, double a2)
{
// Compute all four points for an arc that subtends the same total angle
// but is centered on the X-axis
double a = (a2 - a1) / 2;
double x4 = r * Math.cos(a);
double y4 = r * Math.sin(a);
double x1 = x4;
double y1 = -y4;
double q1 = x1*x1 + y1*y1;
double q2 = q1 + x1*x4 + y1*y4;
double k2 = 4/3d * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
double x2 = x1 - k2 * y1;
double y2 = y1 + k2 * x1;
double x3 = x2;
double y3 = -y2;
// Find the arc points' actual locations by computing x1,y1 and x4,y4
// and rotating the control points by a + a1
double ar = a + a1;
double cos_ar = Math.cos(ar);
double sin_ar = Math.sin(ar);
List<Float> list = new ArrayList<Float>();
list.add((float) (r * Math.cos(a1)));
list.add((float) (r * Math.sin(a1)));
list.add((float) (x2 * cos_ar - y2 * sin_ar));
list.add((float) (x2 * sin_ar + y2 * cos_ar));
list.add((float) (x3 * cos_ar - y3 * sin_ar));
list.add((float) (x3 * sin_ar + y3 * cos_ar));
list.add((float) (r * Math.cos(a2)));
list.add((float) (r * Math.sin(a2)));
return list;
}
}
private void pukeMeAChart(){
try {
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
mContents.fill();
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
mContents.fill();
drawSlice(Color.WHITE, 60, 181, 208);
mContents.fill();
drawSlice(Color.GREEN, 60, 208, 272);
mContents.fill();
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.fill();
} catch(IOException e ){}
}
mContents.transform(Matrix.getTranslateInstance(375,525));
private void pukeMeAChart(){
try {
mContents.saveGraphicsState();
mContents.transform(Matrix.getTranslateInstance(375,525));
drawSlice(Color.YELLOW, 60, 0, 69);
drawSlice(Color.BLUE, 60, 69, 117);
drawSlice(Color.RED, 60, 117, 181);
drawSlice(Color.WHITE, 60, 181, 208);
drawSlice(Color.GREEN, 60, 208, 272);
drawSlice(Color.YELLOW, 60, 272, 336);
drawSlice(Color.BLUE, 60, 336, 360);
mContents.restoreGraphicsState();
} catch(IOException e ){}
}
private void generateDailyChart(){
mContents.saveGraphicsState();
int totalVal = 0;
try {
mContents.transform(Matrix.getTranslateInstance(375, 525));
}catch(IOException e){}
for (int i=1; i< 8;i++){
totalVal += mDayPercent[i];
writeTheChart(mDayPercent[i-1], totalVal,mColor[i]);
log.info("Color selected = " +mColor[i] +"Index = "+i);
}
mContents.restoreGraphicsState();
}