Update of /cvsroot/jcharts/krysalis-jcharts/src/scratchpad/org/krysalis/jcharts/gantt In directory sc8-pr-cvs1:/tmp/cvs-serv9658 Added Files: RowItem.java Row.java PlanRenderer.java Plan.java DateHandler.java Log Message: Initial scratchpad commit of gantt chart impl. Still using it for another project in the making, so it will change a lot. --- NEW FILE: RowItem.java --- /*********************************************************************************************** * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved. * * Redistribution and use of this software and associated documentation ("Software"), with or * without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain copyright statements and notices. * Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote * products derived from this Software without prior written permission of Nathaniel G. * Auvil. For written permission, please contact nat...@us... * * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a * registered trademark of Nathaniel G. Auvil. * * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/). * * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ************************************************************************************************/ package org.krysalis.jcharts.gantt; import java.util.Date; /** * @author Nicola Ken Barozzi * @version $Id: RowItem.java,v 1.1 2003/09/02 08:43:15 nicolaken Exp $ **/ public class RowItem { private Date startDate, endDate; private String color = "blue"; /** * Returns the endDate. * @return Date */ public Date getEndDate() { return endDate; } /** * Returns the startDate. * @return Date */ public Date getStartDate() { return startDate; } /** * Sets the endDate. * @param endDate The endDate to set */ public void setEndDate(Date endDate) { this.endDate = endDate; } /** * Sets the startDate. * @param startDate The startDate to set */ public void setStartDate(Date startDate) { this.startDate = startDate; } /** * Returns the color. * @return Date */ public String getColor() { return color; } /** * Sets the color. * @param color The color to set */ public void setColor(String color) { this.color = color; } } --- NEW FILE: Row.java --- /*********************************************************************************************** * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved. * * Redistribution and use of this software and associated documentation ("Software"), with or * without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain copyright statements and notices. * Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote * products derived from this Software without prior written permission of Nathaniel G. * Auvil. For written permission, please contact nat...@us... * * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a * registered trademark of Nathaniel G. Auvil. * * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/). * * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ************************************************************************************************/ package org.krysalis.jcharts.gantt; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author Nicola Ken Barozzi * @version $Id: Row.java,v 1.1 2003/09/02 08:43:15 nicolaken Exp $ **/ public class Row { private DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); Date startDate; Date endDate; String owner; String label; int type = TASK; public static final int TASK = 1; public static final int MILESTONE = 2; public static final int GROUPING = 3; String dependant = ""; ArrayList milestones = new ArrayList(); private ArrayList smilestones = new ArrayList(); ArrayList multiplicities = new ArrayList(); ArrayList rowItems = new ArrayList(); String color = "lightblue"; public void setType(int t) { type = t; } public int getType() { return type; } public void setLabel(String str) { label = str; } public void setOwner(String str) { owner = str; } public void setStartDate(Date sd) { startDate = sd; if (endDate == null) { endDate = startDate; } } public void setEndDate(Date ed) { endDate = ed; } public String getLabel() { return label; } public String getOwner() { return owner; } public Date getStartDate() { return startDate; } public Date getEndDate() { return endDate; } /** * Method addMilestone. * @param dat */ public void addMilestone(Date dat) { //I have to use a string format as dates are not //correctly checked for .equals() even if I set hours //times and minutes to 0 (still dunno why) String sdat = df.format(dat); int place = smilestones.indexOf(sdat); if (place > -1) { int currentM = ((Integer) multiplicities.get(place)).intValue(); multiplicities.set(place, new Integer(currentM + 1)); } else { milestones.add(dat); smilestones.add(sdat); multiplicities.add(new Integer(1)); } } public void addRowItem(RowItem rowItem) { rowItems.add(rowItem); } public List getRowItems() { return rowItems; } public List milestones() { return milestones; } public List multiplicities() { return multiplicities; } /** * Method setColor. * @param string * @return String */ public void setColor(String color) { this.color = color; } public String getColor() { return color; } } --- NEW FILE: PlanRenderer.java --- /*********************************************************************************************** * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved. * * Redistribution and use of this software and associated documentation ("Software"), with or * without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain copyright statements and notices. * Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote * products derived from this Software without prior written permission of Nathaniel G. * Auvil. For written permission, please contact nat...@us... * * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a * registered trademark of Nathaniel G. Auvil. * * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/). * * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ************************************************************************************************/ package org.krysalis.jcharts.gantt; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.font.LineMetrics; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; /** * @author Nicola Ken Barozzi * @version $Id: PlanRenderer.java,v 1.1 2003/09/02 08:43:15 nicolaken Exp $ **/ public class PlanRenderer { int fontSize = 9; String fontFamily = "SansSerif"; float lSpace = 15; java.awt.Font font = new java.awt.Font(fontFamily, java.awt.Font.PLAIN, (int) fontSize); int barHeigth = 12; int barspaceHeight = 20; int barHeightMargin = (barspaceHeight - barHeigth) / 2; int barspaceWidth = 700; int firstSpaceWidth = 250; int secondSpaceWidth = 100; int leftWidth = secondSpaceWidth + firstSpaceWidth; int milestoneWidth = 6; int milestoneMinHeight = 3; int milestoneMaxHeight = 10; public void render( Graphics2D g2, String title, List data, Date startDate, Date endDate, HashMap hints) { //@todo int height = 6000; int width = leftWidth + barspaceWidth; String[] colours; String[] darkcolours; Font font = new Font(fontFamily, Font.PLAIN, fontSize); g2.setFont(font); //@todo String height LineMetrics lm = font.getLineMetrics(title, g2.getFontRenderContext()); float currentTopEdge = lm.getHeight() + 5; float rightEdge; Shape clip0 = new Rectangle2D.Float(0, 0, width, height); Shape clip1 = new Rectangle2D.Float(0, 0, firstSpaceWidth, height); Shape clip2 = new Rectangle2D.Float(firstSpaceWidth, 0, secondSpaceWidth, height); Shape clip3 = new Rectangle2D.Float(leftWidth, 0, width - leftWidth, height); g2.clip(clip0); g2.setBackground(Color.WHITE); g2.setPaint(Color.WHITE); g2.fill(new Rectangle2D.Float(0, 0, width, height)); //visually debug clip zones // g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)0.5)); // g2.setPaint(Color.YELLOW); // g2.fill(clip1); // g2.setPaint(Color.BLUE); // g2.fill(clip2); // g2.setPaint(Color.RED); // g2.fill(clip3); // g2.setPaintMode(); float strwidth = (float) font.getStringBounds(title, g2.getFontRenderContext()).getWidth(); float pos = (float) (80 - strwidth / 2.0); if (pos < 5) { pos = 5; } g2.setPaint(Color.BLACK); g2.drawString(title, pos, 18); DateHandler dh = new DateHandler(this, startDate, endDate); g2.setPaint(Color.BLACK); g2.draw(new Line2D.Float(0, currentTopEdge, width, currentTopEdge)); //firstdate g2.drawString( dh.simpleFormat(dh.getLastWeek()), leftWidth + 1, currentTopEdge - 1); //lastdate g2.drawString( dh.simpleFormat(dh.getFuture()), (int) width, (int) currentTopEdge - 1); g2.setPaint(new Color(150, 150, 150)); g2.draw( new Line2D.Float( firstSpaceWidth, currentTopEdge, firstSpaceWidth, height)); int offset = 0; Calendar cal = Calendar.getInstance(); cal.setTime(dh.getLastWeek()); for (int count = dh.getStartDay(); count < dh.getStartDay() + dh.getTotalDays() - 1; count++, offset++) { cal.roll(Calendar.DAY_OF_YEAR, true); float currentDateLocation = leftWidth + (offset) * (width - leftWidth) / (dh.getTotalDays() - 2); if (count % 7 == 6 || count % 7 == 0) { //Saturday and sunday g2.setPaint(new Color(230, 230, 230)); Shape holidayDay = new Rectangle2D.Float( currentDateLocation, (float) (currentTopEdge + 0.5), (float) ((width - leftWidth) / (dh.getTotalDays() - 3)), (height - 1 - currentTopEdge)); g2.fill(holidayDay); g2.draw(holidayDay); } else if (dh.isToday(cal)) { //today g2.setPaint(new Color(200, 150, 150)); Shape today = new Rectangle2D.Float( currentDateLocation, (float) (currentTopEdge + 0.5), (float) ((width - leftWidth) / (dh.getTotalDays() - 3)), (height - 1 - currentTopEdge)); g2.fill(today); g2.draw(today); } else { g2.setPaint(new Color(200, 200, 200)); g2.draw( new Rectangle2D.Float( currentDateLocation, (float) (currentTopEdge + 0.5), (float) ((width - leftWidth) / (dh.getTotalDays() - 3)), (height - 1 - currentTopEdge))); } //@todo //addDescr(doc, rect, dh.simpleFormat(cal.getTime())); if (cal.get(Calendar.DAY_OF_MONTH) == 1) { //Sunday g2.setPaint(Color.BLACK); //@todo //text.setAttributeNS(null, "style", "font-size:8"); g2.drawString( dh.monthFormat(cal.getTime()), (int) currentDateLocation, (int) (currentTopEdge - 1)); g2.setPaint(Color.BLACK); g2.draw( new Line2D.Float( currentDateLocation, (float) (currentTopEdge + 0.5), currentDateLocation, (height - 1 - currentTopEdge))); } } //for each action for (int currentActionIndex = 0; currentActionIndex < data.size(); currentActionIndex++) { Row currentAction = (Row) data.get(currentActionIndex); String name = currentAction.getOwner(); String label = currentAction.getLabel(); g2.setPaint(Color.BLACK); g2.setClip(clip1); g2.drawString(label, 0, currentTopEdge + 12); g2.setClip(null); g2.setClip(clip2); g2.drawString(name, firstSpaceWidth, currentTopEdge + 12); g2.setClip(null); int type = currentAction.getType(); Date start = DateHandler.cleanDay(currentAction.getStartDate()); Date end = DateHandler.cleanDay(currentAction.getEndDate()); if (end.after(dh.getLastWeek()) && start.before(dh.getFuture())) { //showing = true; int daysToStart = dh.getDayDiff(start, dh.getLastWeek()); int days = dh.getDayDiff(end, start); int daysFromEnd = dh.getDayDiff(dh.getFuture(), end); switch (type) { case Row.TASK : //the bar itself Shape taskGraphic = new Rectangle2D.Float( leftWidth + 1 + daysToStart * barspaceWidth / (dh.getTotalDays() - 2), currentTopEdge + barHeightMargin, (days + 1) * barspaceWidth / (dh.getTotalDays() - 2), barHeigth); g2.setClip(clip3); g2.setPaint(Color.decode(currentAction.getColor())); g2.fill(taskGraphic); g2.setPaint(Color.BLACK); g2.draw(taskGraphic); //@todo add descr //addDescr(doc, taskGraphic, name); //start and end dates g2.setPaint(Color.BLACK); g2.drawString( dh.simpleFormat(start), leftWidth + daysToStart * barspaceWidth / (dh.getTotalDays() - 2) - 25, currentTopEdge + 9); g2.drawString( dh.simpleFormat(end), leftWidth + daysToStart * barspaceWidth / (dh.getTotalDays() - 2) + days * barspaceWidth / (dh.getTotalDays() - 2) + 5, currentTopEdge + 9); g2.setClip(null); //rowItems List fragments = currentAction.getRowItems(); int fragmentsSize = fragments.size(); for (int i = 0; i < fragmentsSize; i++) { RowItem fragment = (RowItem) fragments.get(i); Date fragmentStart = DateHandler.cleanDay(fragment.getStartDate()); Date fragmentEnd = DateHandler.cleanDay(fragment.getEndDate()); int fragmentDays = dh.getDayDiff(fragmentEnd, fragmentStart); int fragmentdaysToStart = dh.getDayDiff(fragmentStart, dh.getLastWeek()); //the other bars taskGraphic = new Rectangle2D.Float( leftWidth + fragmentdaysToStart * barspaceWidth / (dh.getTotalDays() - 2), currentTopEdge + barHeightMargin, fragmentDays * barspaceWidth / (dh.getTotalDays() - 2), barHeigth); g2.setClip(clip3); g2.setPaint(Color.decode(fragment.getColor())); g2.fill(taskGraphic); g2.setPaint(Color.BLACK); g2.draw(taskGraphic); } //milestones List multiplicities = currentAction.multiplicities(); List milestones = currentAction.milestones(); //debug // System.out.println(label); // for (Iterator i = v.iterator(); i.hasNext();) { // System.out.println(i.next()); // // } int milestonesSize = milestones.size(); for (int i = 0; i < milestonesSize; i++) { int multiplicity = ((Integer) multiplicities.get(i)).intValue(); Date milestoneStart = DateHandler.cleanDay((Date) milestones.get(i)); int daysToStartMilestone = dh.getDayDiff(milestoneStart, dh.getLastWeek()); float mul = PlanRenderer.normalizeMultiplicity4Bar( multiplicity, milestoneMinHeight, milestoneMinHeight); Shape milestoneShape = new Rectangle2D.Float( (float) leftWidth + daysToStartMilestone * barspaceWidth / (dh.getTotalDays() - 2), (float) currentTopEdge + barspaceHeight - barHeightMargin - mul, (float) milestoneWidth, mul); int normMult = PlanRenderer.normalizeMultiplicity4Color(multiplicity); g2.setClip(clip3); g2.setPaint(new Color(normMult, 0, 0)); g2.fill(milestoneShape); g2.setPaint(Color.BLACK); g2.draw(milestoneShape); g2.setClip(null); } break; //@cat milestone case Row.MILESTONE : //@todo milestone break; case Row.GROUPING : //group bar taskGraphic = new Rectangle2D.Float( leftWidth + 1 + daysToStart * barspaceWidth / (dh.getTotalDays() - 2), currentTopEdge + barHeightMargin, (days + 1) * barspaceWidth / (dh.getTotalDays() - 2), barHeigth); g2.setClip(clip3); g2.setPaint(Color.BLACK); g2.fill(taskGraphic); g2.setPaint(Color.BLACK); g2.draw(taskGraphic); break; default : break; } } currentTopEdge += barspaceHeight; } int currentDays = (int) (dh.getCurrentTime() - dh.getLastWeek().getTime() + 43200000 / 86400000); g2.setPaint(new Color(100, 100, 100)); g2.drawString( dh.format(dh.getCurrentDate()), (float) (200 + (currentDays + 0.5) * 300 / 35), currentTopEdge - 1); g2.setPaint(new Color(200, 50, 50)); } public static float normalizeMultiplicity4Bar( int multiplicity, int min, int max) { int partial = multiplicity / 2 + 1; if (partial > 12) { partial = 12; } return (float) partial; } public static int normalizeMultiplicity4Color(int multiplicity) { int partial = 100 + multiplicity * 2; if (partial > 200) { partial = 255; } return partial; } } --- NEW FILE: Plan.java --- /*********************************************************************************************** * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved. * * Redistribution and use of this software and associated documentation ("Software"), with or * without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain copyright statements and notices. * Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote * products derived from this Software without prior written permission of Nathaniel G. * Auvil. For written permission, please contact nat...@us... * * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a * registered trademark of Nathaniel G. Auvil. * * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/). * * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ************************************************************************************************/ package org.krysalis.jcharts.gantt; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import javax.swing.JPanel; import org.apache.batik.dom.GenericDOMImplementation; import org.apache.batik.svggen.SVGGraphics2D; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Nicola Ken Barozzi * @version $Id: Plan.java,v 1.1 2003/09/02 08:43:15 nicolaken Exp $ **/ public class Plan extends JPanel{ private HashMap hints = new HashMap(); private String title; private List data; private Date startDate; private Date endDate; private PlanRenderer planDrawer = new PlanRenderer(); /** * Empty Constructor */ public Plan() { } public void load(Document planDoc) { Element root = planDoc.getDocumentElement(); String start = root.getAttribute("start"); startDate = DateHandler.getDate(start); String end = root.getAttribute("end"); endDate = DateHandler.getDate(end); title = root.getAttribute("title"); NodeList children = ((Element) root).getChildNodes(); data = new ArrayList(); for (int i = 0; i < children.getLength(); i++) { if("action".equals( children.item(i).getNodeName())) { Element currentElement = (Element) children.item(i); String t = currentElement.getAttribute("type"); NodeList childs = currentElement.getChildNodes(); Row currentRow = new Row(); if (t.equals("milestone")) { currentRow.setType(Row.MILESTONE); } else if (t.equals("task")) { currentRow.setType(Row.TASK); } else if (t.equals("grouping")) { currentRow.setType(Row.GROUPING); } else { } for (int i1 = 0; i1 < childs.getLength(); i1++) { Node obj = childs.item(i1); String nname = obj.getNodeName(); if (nname.equals("label")) { String dat5 = ((Element) obj).getFirstChild().getNodeValue(); currentRow.setLabel(dat5); } else if (nname.equals("owner")) { String dat1 = ((Element) obj).getFirstChild().getNodeValue(); currentRow.setOwner(dat1); } else if (nname.equals("startdate")) { Date dat3 = DateHandler.getDate((Element) obj); currentRow.setStartDate(dat3); } else if (nname.equals("enddate")) { Date dat4 = DateHandler.getDate((Element) obj); currentRow.setEndDate(dat4); } else if (nname.equals("color")) { currentRow.setColor(((Element) obj).getFirstChild().getNodeValue()); } else if (nname.equals("milestones")) { NodeList milestones = obj.getChildNodes(); for (int k = 0; k < milestones.getLength(); k++) { Node currentNode = milestones.item(k); if (currentNode.getNodeName().equals("milestone")) { NodeList els = currentNode.getChildNodes(); for (int m = 0; m < els.getLength(); m++) { currentNode = els.item(m); String currentNodeName = currentNode.getNodeName(); if (currentNodeName.equals("startdate")) { Date dat7 = DateHandler.getDate((Element) currentNode); currentRow.addMilestone(dat7); } } } } } else if (nname.equals("rowItems")) { NodeList fragments = obj.getChildNodes(); for (int k = 0; k < fragments.getLength(); k++) { Node currentNode = fragments.item(k); if (currentNode.getNodeName().equals("fragment")) { NodeList els = currentNode.getChildNodes(); RowItem fragment = new RowItem(); for (int m = 0; m < els.getLength(); m++) { currentNode = els.item(m); String currentNodeName = currentNode.getNodeName(); if (currentNodeName.equals("startdate")) { Date dat2 = DateHandler.getDate((Element) currentNode); fragment.setStartDate(dat2); } if (currentNodeName.equals("enddate")) { Date dat6 = DateHandler.getDate((Element) currentNode); fragment.setEndDate(dat6); } } currentRow.addRowItem(fragment); } } } } Row dat = currentRow; data.add(dat); }} } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); if(data!=null&&planDrawer!=null) { planDrawer.render(g2, title, data, startDate, endDate, hints); } } public Dimension getPreferredSize() { //@todo use real width and hight! return new Dimension(1100, 6000); } public void saveAsSvg(File outFile) throws IOException { //Get a DOMImplementation DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation(); // Create an instance of org.w3c.dom.Document Document document = domImpl.createDocument(null, "svg", null); // Create an instance of the SVG Generator SVGGraphics2D svgGenerator = new SVGGraphics2D(document); // Ask the test to render into the SVG Graphics2D implementation planDrawer.render(svgGenerator, title, data, startDate, endDate, hints); // Finally, stream out SVG to the standard output using UTF-8 // character to byte encoding boolean useCSS = true; // we want to use CSS style attribute Writer out = new BufferedWriter(new FileWriter(outFile)); svgGenerator.stream(out, useCSS); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } --- NEW FILE: DateHandler.java --- /*********************************************************************************************** * Copyright 2002 (C) Nathaniel G. Auvil. All Rights Reserved. * * Redistribution and use of this software and associated documentation ("Software"), with or * without modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain copyright statements and notices. * Redistributions must also contain a copy of this document. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. The name "jCharts" or "Nathaniel G. Auvil" must not be used to endorse or promote * products derived from this Software without prior written permission of Nathaniel G. * Auvil. For written permission, please contact nat...@us... * * 4. Products derived from this Software may not be called "jCharts" nor may "jCharts" appear * in their names without prior written permission of Nathaniel G. Auvil. jCharts is a * registered trademark of Nathaniel G. Auvil. * * 5. Due credit should be given to the jCharts Project (http://jcharts.sourceforge.net/). * * THIS SOFTWARE IS PROVIDED BY Nathaniel G. Auvil AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * jCharts OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE ************************************************************************************************/ package org.krysalis.jcharts.gantt; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.w3c.dom.Element; /** * @author Nicola Ken Barozzi * @version $Id: DateHandler.java,v 1.1 2003/09/02 08:43:15 nicolaken Exp $ **/ public class DateHandler { private final PlanRenderer dh; private Date currentDate; private long currentTime; private Date startDate; private Date endDate; private Date lastWeek; private Date future; private Calendar lw; private long totalDays; private int startDay; private DateFormat df; private DateFormat dmf; private DateFormat df_ddMM; public String format(Date d) { return df.format(d); } public String simpleFormat(Date d) { return df_ddMM.format(d); } public String monthFormat(Date d) { return dmf.format(d); } public Date getCurrentDate() { return currentDate; } public long getCurrentTime() { return currentTime; } public Date getEndDate() { return endDate; } public Date getFuture() { return future; } public Date getLastWeek() { return lastWeek; } public Calendar getLw() { return lw; } public Date getStartDate() { return startDate; } public int getStartDay() { return startDay; } public long getTotalDays() { return totalDays; } public boolean isToday(Calendar cal) { Calendar currcal = Calendar.getInstance(); currcal.setTime(currentDate); int day = cal.get(Calendar.DAY_OF_MONTH); int currday = currcal.get(Calendar.DAY_OF_MONTH); int month = cal.get(Calendar.MONTH); int currmonth = currcal.get(Calendar.MONTH); int year = cal.get(Calendar.YEAR); int curryear = currcal.get(Calendar.YEAR); if (day == currday && month == currmonth && year == curryear) { return true; } else { return false; } } public int getDayDiff(Date start, Date end) { return (int) ((DateHandler.cleanDay(start).getTime() - DateHandler.cleanDay(end).getTime() + 43200000) / 86400000); } public DateHandler(PlanRenderer renderer, Date startDate, Date endDate) { df = DateFormat.getDateInstance(DateFormat.SHORT); this.dh = renderer; df_ddMM = new SimpleDateFormat("dd/MM"); dmf = new SimpleDateFormat("MMMMM"); //calculate the date this.currentDate = DateHandler.cleanDay(new Date()); this.currentTime = currentDate.getTime(); this.startDate = DateHandler.cleanDay(startDate); this.endDate = DateHandler.cleanDay(endDate); lastWeek = DateHandler.cleanDay(startDate); future = DateHandler.cleanDay(endDate); lw = Calendar.getInstance(); if (lastWeek == null || future == null) { int dow = lw.get(Calendar.DAY_OF_WEEK); lw.add(Calendar.DATE, -dow - 6); lastWeek = DateHandler.cleanDay(lw.getTime()); lw.add(Calendar.DATE, 5 * 7); future = DateHandler.cleanDay(lw.getTime()); } totalDays = (long) ((future.getTime() - lastWeek.getTime() + 43200000) / 86400000); lw.setTime(lastWeek); startDay = lw.get(Calendar.DAY_OF_WEEK); df.format(currentDate); } public static Date cleanDay(long date) { return DateHandler.cleanDay(new Date(date)); } public static Date cleanDay(int date) { return DateHandler.cleanDay(new Date(date)); } public static Date cleanDay(Date date) { date.setHours(0); date.setMinutes(0); date.setSeconds(0); return date; } public static Date getDate(String label) { Calendar cal = Calendar.getInstance(); String str; str = label.substring(0, 4); int intVal = Integer.valueOf(str).intValue(); cal.set(Calendar.YEAR, intVal); str = label.substring(4, 6); intVal = Integer.valueOf(str).intValue(); cal.set(Calendar.MONTH, intVal - 1); str = label.substring(6, 8); intVal = Integer.valueOf(str).intValue(); cal.set(Calendar.DATE, intVal); return cal.getTime(); } public static Date getDate(Element ele) { String label = ele.getFirstChild().getNodeValue(); return DateHandler.getDate(label); } public static String fixDate(String date) { if (date.length() == 8) { try { return formatDate(parseDate(date)); } catch (ParseException e) { System.err.println(e); return "ERROR"; } } else { return date; } } private static Date parseDate(String date) throws ParseException { DateFormat formatter = new SimpleDateFormat("yyyyMMdd"); return (Date) formatter.parse(date); } private static String formatDate(Date date) throws ParseException { DateFormat formatter = new SimpleDateFormat("dd/MM"); return formatter.format(date); } //TODO ! add year handling!!! public static String getStringDateFromWeek(int week, boolean startDay) throws ParseException { System.out.println("TRANSFORMING WEEK: " + String.valueOf(week)); Calendar c = Calendar.getInstance(); c.setTime(new Date()); c.set(Calendar.WEEK_OF_YEAR, week); if (startDay) { c.roll(Calendar.DATE, -4); } // String resultYear = String.valueOf(c.get(Calendar.YEAR)); // String resultMonth = String.valueOf(c.get(Calendar.MONTH)); // if(resultMonth.length()==1){resultMonth="0"+resultMonth;} // String resultDay = String.valueOf(c.get(Calendar.DATE)); // if(resultDay.length()==1){resultDay="0"+resultMonth;} // return resultYear+resultMonth+resultDay; DateFormat formatter = new SimpleDateFormat("yyyyMMdd"); return formatter.format(c.getTime()); } } |