Update of /cvsroot/jrobin/src/jrobin/graph In directory sc8-pr-cvs1:/tmp/cvs-serv8118/src/jrobin/graph Modified Files: TimeAxisUnit.java RrdGraph.java RrdGraphDef.java ChartGraphics.java Grapher.java ValueAxisUnit.java Range.java Log Message: GRAPH LIB UPDATES Fix zero comment line problem Option to disable the legend Option to bring grid to front or back Option to set rigid grid lines Option to set fixed upper and lower value Add change border option Possibility to disable grid lines (no minor grid) Fix background color option Better Time and Value axis markers Index: TimeAxisUnit.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/TimeAxisUnit.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TimeAxisUnit.java 25 Sep 2003 21:58:05 -0000 1.2 --- TimeAxisUnit.java 30 Sep 2003 21:45:21 -0000 1.3 *************** *** 43,46 **** --- 43,56 ---- Calendar.YEAR }; + private static final int[] nullValue = + { + 0, + 0, + 0, + 1, + 1, + 0, + 1970 // Should never be used, but put there to avoid index out of bounds + }; // Indices in the calendarUnit table *************** *** 84,88 **** t.setTimeInMillis( exactStart ); for (int i = 0; i < calendarUnit.length && i <= unit; i++) ! t.set( calendarUnit[i], 0 ); } --- 94,100 ---- t.setTimeInMillis( exactStart ); for (int i = 0; i < calendarUnit.length && i <= unit; i++) ! t.set( calendarUnit[i], nullValue[i] ); ! if ( unit == WEEK ) ! t.set( Calendar.DAY_OF_WEEK, t.getFirstDayOfWeek() ); } Index: RrdGraph.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/RrdGraph.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** RrdGraph.java 22 Sep 2003 17:15:17 -0000 1.2 --- RrdGraph.java 30 Sep 2003 21:45:21 -0000 1.3 *************** *** 115,118 **** --- 115,127 ---- public byte[] getPNGBytes(int width, int height) throws IOException { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try + { + BufferedImage gImage = grapher.createImage( width, height ); + + ImageIO.write( (RenderedImage) gImage, "png", outputStream ); + } + catch ( RrdException e ) { + e.printStackTrace(); + } //ChartUtilities.writeBufferedImageAsPNG(outputStream, getBufferedImage(width, height)); return outputStream.toByteArray(); Index: RrdGraphDef.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/RrdGraphDef.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** RrdGraphDef.java 25 Sep 2003 21:58:05 -0000 1.3 --- RrdGraphDef.java 30 Sep 2003 21:45:21 -0000 1.4 *************** *** 134,142 **** private int timeUnit, timeUnitCount; private SimpleDateFormat timeFormat; ! private long endTime = Util.getTime(); ! private long startTime = endTime - 86400L; private String title = null; // Default to null, to check private String timeAxisLabel = ""; private String valueAxisLabel = null; private Range valueRange; private boolean logarithmic = false; --- 134,158 ---- private int timeUnit, timeUnitCount; private SimpleDateFormat timeFormat; ! private long endTime = Util.getTime(); ! private long startTime = endTime - 86400L; private String title = null; // Default to null, to check private String timeAxisLabel = ""; private String valueAxisLabel = null; + + // Visibility of grid settings + private boolean gridX = true; + private boolean gridY = true; + private boolean minorGridX = true; + private boolean minorGridY = true; + private boolean majorGridX = true; + private boolean majorGridY = true; + private boolean rigidGrid = false; + private boolean frontGrid = true; + + private boolean showLegend = true; + + private BasicStroke borderStroke; + private Color borderColor; + private Range valueRange; private boolean logarithmic = false; *************** *** 541,544 **** --- 557,692 ---- this.backColor = backColor; } + + /** + * Determines if the minor grid for the X axis needs to be drawn. + * @param visible True if minor grid needs to be drawn, false if not. + */ + public void setMinorGridX( boolean visible ) { + this.minorGridX = visible; + } + + /** + * Determines if the minor grid for the X axis needs to be drawn. + * @param visible True if minor grid needs to be drawn, false if not. + */ + public void setMinorGridY( boolean visible ) { + this.minorGridY = visible; + } + + public boolean getMinorGridX() { + return minorGridX; + } + + public boolean getMinorGridY() { + return minorGridY; + } + + /** + * Determines if the major grid with labels for the X axis needs to be drawn. + * @param visible True if major grid needs to be drawn, false if not. + */ + public void setMajorGridX( boolean visible ) { + this.majorGridX = visible; + } + + /** + * Determines if the major grid for the X axis needs to be drawn. + * @param visible True if major grid needs to be drawn, false if not. + */ + public void setMajorGridY( boolean visible ) { + this.majorGridY = visible; + } + + public boolean getMajorGridX() { + return majorGridX; + } + + public boolean getMajorGridY() { + return majorGridY; + } + + /** + * Determines if the X axis grid should be drawn. + * This will not change the left padding of the drawing area. + * @param visible True if grid needs to be drawn, false if not. + */ + public void setGridX( boolean visible ) { + this.gridX = visible; + } + + /** + * Determines if the Y axis grid should be drawn. + * This will not change the bottom padding of the drawing area. + * @param visible True if grid needs to be drawn, false if not. + */ + public void setGridY( boolean visible ) { + this.gridY = visible; + } + public boolean getGridX() { + return gridX; + } + + public boolean getGridY() { + return gridY; + } + + /** + * Specifies the settings of the image border + * @param c Bordercolor of the image + * @param w Pixel width of the image border + */ + public void setImageBorder( Color c, int w ) { + this.borderStroke = new BasicStroke( w ); + if ( c != null ) + this.borderColor = c; + } + + public Color getImageBorderColor() { + return borderColor; + } + + public BasicStroke getImageBorderStroke() { + return borderStroke; + } + + /** + * Determines if the grid should have rigid upper and lower limits. + * If so the upper and lower limit will not autoscale depending on the + * graph values. + * @param rigid True if the grid should have rigid limits + */ + public void setRigidGrid( boolean rigid ) { + this.rigidGrid = rigid; + } + + public boolean getRigidGrid() { + return this.rigidGrid; + } + + /** + * Determine if the graph grid is in front of the graphs itself, or behind it. + * Default is in front of the graph itself. + * @param frontGrid True if the grid is in front of the graphs + */ + public void setFrontGrid( boolean frontGrid ) { + this.frontGrid = frontGrid; + } + + public boolean getFrontGrid() { + return this.frontGrid; + } + + /** + * Determine if the legend should be visible or not, default: visible. + * @param showLegend True if the legend is visible + */ + public void setShowLegend( boolean showLegend ) { + this.showLegend = showLegend; + } + + public boolean getShowLegend() { + return this.showLegend; + } + } Index: ChartGraphics.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/ChartGraphics.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ChartGraphics.java 25 Sep 2003 21:58:05 -0000 1.2 --- ChartGraphics.java 30 Sep 2003 21:45:21 -0000 1.3 *************** *** 94,98 **** if ( Double.isNaN(value) ) return Integer.MIN_VALUE; ! int tmp = new Double(value * heightDelta).intValue(); return ( tmp > value * heightDelta ? tmp - 1 : tmp ); } --- 94,99 ---- if ( Double.isNaN(value) ) return Integer.MIN_VALUE; ! int tmp = new Double( (value - ( yStart < 0 ? 0 : Math.abs(yStart) ) ) * heightDelta).intValue(); ! return ( tmp > value * heightDelta ? tmp - 1 : tmp ); } Index: Grapher.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/Grapher.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Grapher.java 25 Sep 2003 21:58:05 -0000 1.3 --- Grapher.java 30 Sep 2003 21:45:21 -0000 1.4 *************** *** 48,54 **** private static final int CHART_UPADDING = 5; ! private static final int CHART_BPADDING = 25; private static final int CHART_RPADDING = 10; ! private static final int CHART_LPADDING = 50; private static final int LINE_PADDING = 4; --- 48,56 ---- private static final int CHART_UPADDING = 5; ! private static int CHART_BPADDING = 25; private static final int CHART_RPADDING = 10; ! private static int CHART_LPADDING = 50; ! private static final int CHART_BPADDING_NM = 10; // No legend makers on the axis ! private static final int CHART_LPADDING_NM = 10; private static final int LINE_PADDING = 4; *************** *** 71,75 **** private int graphOriginX, graphOriginY, x_offset, y_offset; ! private double lowerValue = 0.0d, upperValue = 0.0d; --- 73,77 ---- private int graphOriginX, graphOriginY, x_offset, y_offset; ! private double lowerValue = Double.MAX_VALUE, upperValue = Double.MIN_VALUE; *************** *** 105,108 **** --- 107,114 ---- if ( cWidth > GRAPH_RESOLUTION ) numPoints = cWidth; + // Padding depends on grid visibility + CHART_LPADDING = ( graphDef.getMajorGridY() ? Grapher.CHART_LPADDING : CHART_LPADDING_NM ); + CHART_BPADDING = ( graphDef.getMajorGridX() ? Grapher.CHART_BPADDING : CHART_BPADDING_NM ); + // Calculate the complete image dimensions for the creation of the bufferedimage font_height = SUBTITLE_FONT.getSize(); // Determine font dimensions for regular comment font *************** *** 111,115 **** tfont_width = tfont_height / 2 + 1; ! commentBlock = calculateCommentBlock(); // Size of all lines below chart x_offset = LBORDER_SPACE; --- 117,121 ---- tfont_width = tfont_height / 2 + 1; ! commentBlock = ( graphDef.getShowLegend() ? calculateCommentBlock() : 0 ); // Size of all lines below chart x_offset = LBORDER_SPACE; *************** *** 135,139 **** plotChart( graphics ); ! plotComments( graphics ); } catch (IOException e) --- 141,146 ---- plotChart( graphics ); ! if ( graphDef.getShowLegend() ) ! plotComments( graphics ); } catch (IOException e) *************** *** 147,150 **** --- 154,159 ---- } + System.out.println( "Graph created ok." ); + return bImg; } *************** *** 157,160 **** --- 166,176 ---- int lux = x_offset + CHART_LPADDING; int luy = y_offset + CHART_UPADDING; + + boolean gridX = graphDef.getGridX(); + boolean gridY = graphDef.getGridY(); + boolean minorX = graphDef.getMinorGridX(); + boolean minorY = graphDef.getMinorGridY(); + boolean majorX = graphDef.getMajorGridX(); + boolean majorY = graphDef.getMajorGridY(); long start = graphDef.getStartTime(); *************** *** 176,253 **** g.drawLine( tmpx + 4, tmpy + 3, tmpx + 9, tmpy); ! int pixWidth = 0; ! if (vLabelCentered) ! pixWidth = (chartGraph.getX( vLabelGridWidth ) - chartGraph.getX( 0 )); ! ! for (int i = 0; i < timeList.length; i++) { ! secTime = timeList[i].timestamp / 1000; ! int posRel = chartGraph.getX(secTime); ! int pos = lux + posRel; ! ! if ( posRel >= 0 ) { ! if ( timeList[i].isLabel() ) ! { ! g.setColor( new Color(130,30,30) ); ! g.setStroke( dStroke ); ! g.drawLine( pos, luy, pos, luy + chartHeight); ! g.setStroke( new BasicStroke() ); ! g.drawLine( pos, luy - 2, pos, luy + 2); ! g.drawLine( pos, luy + chartHeight - 2, pos, luy + chartHeight + 2); ! // Only draw label itself if we are far enough from the side axis ! // Use extra 2 pixel padding (3 pixels from border total at least) ! int txtDistance = (timeList[i].text.length() * font_width) / 2; ! ! if ( vLabelCentered ) { ! if ( pos + pixWidth <= lux + chartWidth ) { g.setColor( Color.BLACK ); ! g.drawString( timeList[i].text, pos + 2 + pixWidth/2 - txtDistance, luy + chartHeight + font_height + LINE_PADDING ); } } ! else if ( (pos - lux > txtDistance + 2) && (pos + txtDistance + 2 < lux + chartWidth) ) ! { ! g.setColor( Color.BLACK ); ! g.drawString( timeList[i].text, pos - txtDistance, luy + chartHeight + font_height + LINE_PADDING ); } } ! else ! { g.setColor( new Color(140,140,140) ); g.setStroke( dStroke ); ! g.drawLine( pos, luy, pos, luy + chartHeight); g.setStroke( new BasicStroke() ); ! g.drawLine( pos, luy - 1, pos, luy + 1); ! g.drawLine( pos, luy + chartHeight - 1, pos, luy + chartHeight + 1); ! } - } - } - for (int i = 0; i < valueList.length; i++) - { - int valRel = chartGraph.getY( valueList[i].value ); - - if ( valueList[i].isLabel() ) - { - g.setColor( new Color(130,30,30) ); - g.setStroke( dStroke ); - g.drawLine( graphOriginX, graphOriginY - valRel, graphOriginX + chartWidth, graphOriginY - valRel ); - g.setStroke( new BasicStroke() ); - g.drawLine( graphOriginX - 2, graphOriginY - valRel, graphOriginX + 2, graphOriginY - valRel); - g.drawLine( graphOriginX + chartWidth - 2, graphOriginY - valRel, graphOriginX + chartWidth + 2, graphOriginY - valRel ); - g.setColor( Color.BLACK ); - g.drawString( valueList[i].text, graphOriginX - (valueList[i].text.length() * font_width) - 7, graphOriginY - valRel + font_height/2 - 1 ); } - else - { - g.setColor( new Color(140,140,140) ); - g.setStroke( dStroke ); - g.drawLine( graphOriginX, graphOriginY - valRel, graphOriginX + chartWidth, graphOriginY - valRel ); - g.setStroke( new BasicStroke() ); - g.drawLine( graphOriginX - 1, graphOriginY - valRel, graphOriginX + 1, graphOriginY - valRel); - g.drawLine( graphOriginX + chartWidth - 1, graphOriginY - valRel, graphOriginX + chartWidth + 1, graphOriginY - valRel ); - } - } } --- 192,275 ---- g.drawLine( tmpx + 4, tmpy + 3, tmpx + 9, tmpy); ! if ( gridX ) { ! int pixWidth = 0; ! if (vLabelCentered) ! pixWidth = (chartGraph.getX( vLabelGridWidth ) - chartGraph.getX( 0 )); ! ! for (int i = 0; i < timeList.length; i++) ! { ! secTime = timeList[i].timestamp / 1000; ! int posRel = chartGraph.getX(secTime); ! int pos = lux + posRel; ! ! if ( posRel >= 0 ) { ! if ( majorX && timeList[i].isLabel() ) { ! g.setColor( new Color(130,30,30) ); ! g.setStroke( dStroke ); ! g.drawLine( pos, luy, pos, luy + chartHeight); ! g.setStroke( new BasicStroke() ); ! g.drawLine( pos, luy - 2, pos, luy + 2); ! g.drawLine( pos, luy + chartHeight - 2, pos, luy + chartHeight + 2); ! // Only draw label itself if we are far enough from the side axis ! // Use extra 2 pixel padding (3 pixels from border total at least) ! int txtDistance = (timeList[i].text.length() * font_width) / 2; ! ! if ( vLabelCentered ) ! { ! if ( pos + pixWidth <= lux + chartWidth ) { ! g.setColor( Color.BLACK ); ! g.drawString( timeList[i].text, pos + 2 + pixWidth/2 - txtDistance, luy + chartHeight + font_height + LINE_PADDING ); ! } ! } ! else if ( (pos - lux > txtDistance + 2) && (pos + txtDistance + 2 < lux + chartWidth) ) ! { g.setColor( Color.BLACK ); ! g.drawString( timeList[i].text, pos - txtDistance, luy + chartHeight + font_height + LINE_PADDING ); } } ! else if ( minorX ) ! { ! g.setColor( new Color(140,140,140) ); ! g.setStroke( dStroke ); ! g.drawLine( pos, luy, pos, luy + chartHeight); ! g.setStroke( new BasicStroke() ); ! g.drawLine( pos, luy - 1, pos, luy + 1); ! g.drawLine( pos, luy + chartHeight - 1, pos, luy + chartHeight + 1); ! } } ! } ! } ! ! if ( gridY ) ! { ! for (int i = 0; i < valueList.length; i++) ! { ! int valRel = chartGraph.getY( valueList[i].value ); ! ! if ( majorY && valueList[i].isLabel() ) ! { ! g.setColor( new Color(130,30,30) ); ! g.setStroke( dStroke ); ! g.drawLine( graphOriginX, graphOriginY - valRel, graphOriginX + chartWidth, graphOriginY - valRel ); ! g.setStroke( new BasicStroke() ); ! g.drawLine( graphOriginX - 2, graphOriginY - valRel, graphOriginX + 2, graphOriginY - valRel); ! g.drawLine( graphOriginX + chartWidth - 2, graphOriginY - valRel, graphOriginX + chartWidth + 2, graphOriginY - valRel ); ! g.setColor( Color.BLACK ); ! g.drawString( valueList[i].text, graphOriginX - (valueList[i].text.length() * font_width) - 7, graphOriginY - valRel + font_height/2 - 1 ); ! } ! else if ( minorY ) ! { g.setColor( new Color(140,140,140) ); g.setStroke( dStroke ); ! g.drawLine( graphOriginX, graphOriginY - valRel, graphOriginX + chartWidth, graphOriginY - valRel ); g.setStroke( new BasicStroke() ); ! g.drawLine( graphOriginX - 1, graphOriginY - valRel, graphOriginX + 1, graphOriginY - valRel); ! g.drawLine( graphOriginX + chartWidth - 1, graphOriginY - valRel, graphOriginX + chartWidth + 1, graphOriginY - valRel ); } } } } *************** *** 370,377 **** g.setMeasurements( chartWidth, chartHeight ); g.setXRange( graphDef.getStartTime(), graphDef.getEndTime() ); ! ValueMarker[] vlist = calculateValueMarkers(); TimeMarker[] tlist = calculateTimeMarkers(); ! // Upper and lower were set in value markers double diff = 1.0d; --- 392,399 ---- g.setMeasurements( chartWidth, chartHeight ); g.setXRange( graphDef.getStartTime(), graphDef.getEndTime() ); ! ValueMarker[] vlist = calculateValueMarkers(); TimeMarker[] tlist = calculateTimeMarkers(); ! // Upper and lower were set in value markers double diff = 1.0d; *************** *** 383,387 **** g.setYRange( lowerValue, upperValue ); ! //plotChartGrid( g, tlist, vlist ); graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); --- 405,409 ---- g.setYRange( lowerValue, upperValue ); ! if ( !graphDef.getFrontGrid() ) plotChartGrid( g, tlist, vlist ); graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); *************** *** 426,430 **** graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF ); ! plotChartGrid( g, tlist, vlist ); } --- 448,452 ---- graphics.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF ); ! if ( graphDef.getFrontGrid() ) plotChartGrid( g, tlist, vlist ); } *************** *** 572,583 **** // Border ! g.setColor( new Color( 0xdc, 0xdc, 0xdc ) ); ! g.fillRect( 0, 0, 2, imgHeight - 1 ); ! g.fillRect( 0, 0, imgWidth - 1, 2 ); ! g.setColor( Color.GRAY ); ! g.drawLine( 0, imgHeight - 1, imgWidth, imgHeight - 1 ); ! g.drawLine( imgWidth - 1, 0, imgWidth - 1, imgHeight ); ! g.drawLine( 1, imgHeight - 2, imgWidth, imgHeight - 2 ); ! g.drawLine( imgWidth - 2, 1, imgWidth - 2, imgHeight ); plotImageTitle( g ); --- 594,619 ---- // Border ! Color bc = graphDef.getImageBorderColor(); ! BasicStroke bs = graphDef.getImageBorderStroke(); ! ! if ( bc != null && bs != null ) ! { ! g.setColor( bc ); ! g.setStroke( bs ); ! int w = new Float(bs.getLineWidth()).intValue(); ! if ( w > 0 ) g.drawRect( w / 2, w / 2, imgWidth - w, imgHeight - w); ! g.setStroke( new BasicStroke() ); ! } ! else ! { ! g.setColor( new Color( 0xdc, 0xdc, 0xdc ) ); ! g.fillRect( 0, 0, 2, imgHeight - 1 ); ! g.fillRect( 0, 0, imgWidth - 1, 2 ); ! g.setColor( Color.GRAY ); ! g.drawLine( 0, imgHeight - 1, imgWidth, imgHeight - 1 ); ! g.drawLine( imgWidth - 1, 0, imgWidth - 1, imgHeight ); ! g.drawLine( 1, imgHeight - 2, imgWidth, imgHeight - 2 ); ! g.drawLine( imgWidth - 2, 1, imgWidth - 2, imgHeight ); ! } plotImageTitle( g ); *************** *** 595,599 **** Comment[] list = graphDef.getComments(); ! int commentLines = 1; for (int i = 0; i < list.length; i++) --- 631,635 ---- Comment[] list = graphDef.getComments(); ! int commentLines = (list.length > 0 ? 1 : 0); for (int i = 0; i < list.length; i++) *************** *** 619,647 **** /* - JFreeChart createJFreeChart() throws RrdException, IOException { - PlotDef[] plotDefs = graphDef.getPlotDefs(); - OverlayGraph[] graphs = graphDef.getGraphs(); - if(plotDefs.length == 0) { - throw new RrdException("Nothing to plot"); - } - calculateSeries(); - OverlaidXYPlot plot = new OverlaidXYPlot(createTimeAxis(), createValueAxis()); - for(int i = 0; i < graphs.length; i++) { - plot.add(graphs[i].getXYPlot()); - } - JFreeChart chart = new JFreeChart("", plot); - chart.setTitle(new TextTitle(graphDef.getTitle(), TITLE_FONT)); - Color backColor = graphDef.getBackColor(); - if(backColor == null) { - backColor = BACK_COLOR; - } - chart.setBackgroundPaint(backColor); - StandardLegend legend = (StandardLegend) chart.getLegend(); - legend.setOutlinePaint(backColor); - legend.setBackgroundPaint(backColor); - addSubtitles(chart); - return chart; - } - private void calculateSeries() throws RrdException, IOException { Source[] sources = graphDef.getSources(); --- 655,658 ---- *************** *** 663,674 **** } - private ValueAxis createTimeAxis() { - HorizontalDateAxis axis = new HorizontalDateAxis(graphDef.getTimeAxisLabel()); - axis.setLowerMargin(0.0); - axis.setUpperMargin(0.0); - axis.setTickUnit(calculateDateTickUnit()); - return axis; - } - private DateTickUnit calculateDateTickUnit() { SimpleDateFormat simpleDateFormat = graphDef.getTimeFormat(); --- 674,677 ---- *************** *** 752,791 **** return axis; } - - private void addSubtitles(JFreeChart chart) throws RrdException { - String currentLine = ""; - ArrayList subtitles = new ArrayList(); - Comment[] comments = graphDef.getComments(); - int lastScaleIndex = ValueScaler.NO_SCALE; - for(int i = 0; i < comments.length; i++) { - if(currentLine.length() > 0) { - currentLine += SPACER; - } - Comment comment = comments[i]; - // uniform scaling is now supported - comment.setScaleIndex(lastScaleIndex); - currentLine += comment.getMessage(); - lastScaleIndex = comment.getScaleIndex(); - if(comment.isAlignSet()) { - // should finish current line - int align = comment.getAlign(); - TextTitle subtitle = new TextTitle(currentLine, SUBTITLE_FONT, Color.BLACK, - TextTitle.BOTTOM, align, TextTitle.DEFAULT_VERTICAL_ALIGNMENT, SUBTITLE_SPACER); - subtitles.add(subtitle); - currentLine = ""; - } - } - if(currentLine.length() > 0) { - TextTitle subtitle = new TextTitle(currentLine, SUBTITLE_FONT, - Color.BLACK, TextTitle.BOTTOM, DEFAULT_ALIGN, - TextTitle.DEFAULT_VERTICAL_ALIGNMENT, SUBTITLE_SPACER); - subtitles.add(subtitle); - } - for(int i = subtitles.size() - 1; i >= 0; i--) { - TextTitle subtitle = (TextTitle) subtitles.get(i); - chart.addSubtitle(subtitle); - } - } */ private TimeMarker[] calculateTimeMarkers() { --- 755,764 ---- return axis; } */ + + /** + * + * @return List of timemarkers to plot + */ private TimeMarker[] calculateTimeMarkers() { *************** *** 806,837 **** vLabelCentered = false; ! if(days <= 2.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.MINUTE, 10, new SimpleDateFormat("mm")); } ! else if (days <= 1) ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 1, TimeAxisUnit.HOUR, 6, new SimpleDateFormat("HH:mm")); ! else if(days <= 2) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 2, new SimpleDateFormat("HH")); } ! else if(days <= 3) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 6, new SimpleDateFormat("HH:mm")); } ! else if(days <= 8) { ! t = new TimeAxisUnit( TimeAxisUnit.DAY, 1, new SimpleDateFormat("EEE dd MMM")); } ! else if (days <= 32) { ! //t = new TimeAxisUnit( TimeAxisUnit.HOUR, 24, TimeAxisUnit.DAY, 1, new SimpleDateFormat("dd")); ! t = new TimeAxisUnit( TimeAxisUnit.DAY, 1, TimeAxisUnit.WEEK, 1, new SimpleDateFormat("'week' ww")); vLabelCentered = true; ! } ! else if(days <= 63) { t = new TimeAxisUnit( TimeAxisUnit.DAY, 1, TimeAxisUnit.WEEK, 1, new SimpleDateFormat("'week' ww")); ! //t = new TimeAxisUnit( TimeAxisUnit.WEEK, 2, new SimpleDateFormat("dd")); } ! else if(days <= 120) { ! t = new TimeAxisUnit( TimeAxisUnit.WEEK, 4, new SimpleDateFormat("dd")); } else { ! t = new TimeAxisUnit( TimeAxisUnit.MONTH, 1, new SimpleDateFormat("MMM")); } --- 779,830 ---- vLabelCentered = false; ! if (days <= 2.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.MINUTE, 5, TimeAxisUnit.MINUTE, 10, new SimpleDateFormat("HH:mm")); } ! else if (days <= 3.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.MINUTE, 5, TimeAxisUnit.MINUTE, 20, new SimpleDateFormat("HH:mm")); } ! else if (days <= 5.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.MINUTE, 10, TimeAxisUnit.MINUTE, 30, new SimpleDateFormat("HH:mm")); } ! else if (days <= 10.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.MINUTE, 15, TimeAxisUnit.HOUR, 1, new SimpleDateFormat("HH:mm")); } ! else if (days <= 15.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.MINUTE, 30, TimeAxisUnit.HOUR, 2, new SimpleDateFormat("HH:mm")); ! //t = new TimeAxisUnit( TimeAxisUnit.HOUR, 2, TimeAxisUnit.HOUR, 6, new SimpleDateFormat("HH:mm")); ! } ! else if(days <= 20.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 1, TimeAxisUnit.HOUR, 1, new SimpleDateFormat("HH")); vLabelCentered = true; ! } ! else if(days <= 36.0 / 24.0) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 1, TimeAxisUnit.HOUR, 4, new SimpleDateFormat("HH:mm")); ! } ! else if (days <= 2) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 2, TimeAxisUnit.HOUR, 6, new SimpleDateFormat("HH:mm")); ! } ! else if (days <= 3) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 3, TimeAxisUnit.HOUR, 12, new SimpleDateFormat("HH:mm")); ! } ! else if(days <= 7) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 6, TimeAxisUnit.DAY, 1, new SimpleDateFormat("EEE dd")); ! vLabelCentered = true; ! } ! else if(days <= 14) { ! t = new TimeAxisUnit( TimeAxisUnit.HOUR, 12, TimeAxisUnit.DAY, 1, new SimpleDateFormat("dd")); ! vLabelCentered = true; ! } ! else if (days <= 43) { t = new TimeAxisUnit( TimeAxisUnit.DAY, 1, TimeAxisUnit.WEEK, 1, new SimpleDateFormat("'week' ww")); ! vLabelCentered = true; } ! else if(days <= 157) { ! t = new TimeAxisUnit( TimeAxisUnit.WEEK, 1, TimeAxisUnit.WEEK, 1, new SimpleDateFormat("ww")); ! vLabelCentered = true; } else { ! t = new TimeAxisUnit( TimeAxisUnit.MONTH, 1, TimeAxisUnit.MONTH, 1, new SimpleDateFormat("MMM")); ! vLabelCentered = true; } *************** *** 841,850 **** } private ValueMarker[] calculateValueMarkers() { ! ValueAxisUnit v = null; ! ! double range = upperValue - lowerValue; double shifted = ( Math.abs(upperValue) > Math.abs(lowerValue) ? Math.abs(upperValue) : Math.abs(lowerValue) ); double mod = 1.0; --- 834,867 ---- } + /** + * + * @return List of value markers to plot + */ private ValueMarker[] calculateValueMarkers() { ! ValueAxisUnit v = null; ! boolean lowerFromRange = false; ! boolean upperFromRange = false; ! boolean rigid = graphDef.getRigidGrid(); + // Exceptional case + if ( upperValue == 0 && upperValue == lowerValue ) + upperValue = 0.9; + + Range vr = graphDef.getValueRange(); + if ( vr != null ) + { + double rLower = vr.getLowerValue(); + if ( !Double.isNaN(rLower) && (rigid || rLower < lowerValue) ) { + lowerValue = rLower; + lowerFromRange = true; + } + double rUpper = vr.getUpperValue(); + if ( !Double.isNaN(rUpper) && (rigid || rUpper > upperValue) ) { + upperValue = rUpper; + upperFromRange = true; + } + } + double shifted = ( Math.abs(upperValue) > Math.abs(lowerValue) ? Math.abs(upperValue) : Math.abs(lowerValue) ); double mod = 1.0; *************** *** 861,873 **** v = new ValueAxisUnit( 1, 0.2*mod, 1, 1.0*mod ); else if ( shifted <= 5 ) ! v = new ValueAxisUnit( 1, 0.5*mod, 1, 1.0*mod ); else if ( shifted <= 9 ) v = new ValueAxisUnit( 1, 0.5*mod, 1, 2.0*mod ); else v = new ValueAxisUnit( 1, 1.0*mod, 1, 5.0*mod ); - - upperValue = v.getNiceHigher( upperValue ); - lowerValue = v.getNiceLower( lowerValue ); return v.getValueMarkers( lowerValue, upperValue ); } --- 878,890 ---- v = new ValueAxisUnit( 1, 0.2*mod, 1, 1.0*mod ); else if ( shifted <= 5 ) ! v = new ValueAxisUnit( 1, 0.5*mod, 1, 1.0*mod ); else if ( shifted <= 9 ) v = new ValueAxisUnit( 1, 0.5*mod, 1, 2.0*mod ); else v = new ValueAxisUnit( 1, 1.0*mod, 1, 5.0*mod ); + if ( !upperFromRange ) upperValue = v.getNiceHigher( upperValue ); + if ( !lowerFromRange ) lowerValue = v.getNiceLower( lowerValue ); + return v.getValueMarkers( lowerValue, upperValue ); } Index: ValueAxisUnit.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/ValueAxisUnit.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ValueAxisUnit.java 25 Sep 2003 21:58:05 -0000 1.2 --- ValueAxisUnit.java 30 Sep 2003 21:45:21 -0000 1.3 *************** *** 68,71 **** --- 68,75 ---- } + private double round( double value ) + { + return new java.math.BigDecimal(value).setScale(14 , java.math.BigDecimal.ROUND_HALF_EVEN).doubleValue(); + } public ValueMarker[] getValueMarkers( double lower, double upper ) *************** *** 76,87 **** // Find the first visible gridpoint if ( lower > 0 ) { ! while ( minPoint <= lower ) minPoint += gridStep; ! while ( majPoint <= lower ) majPoint += mGridStep; } else { ! while ( minPoint >= lower ) minPoint -= gridStep; ! while ( majPoint >= lower ) majPoint -= mGridStep; // Go one up to make it visible ! minPoint += gridStep; ! majPoint += mGridStep; } --- 80,91 ---- // Find the first visible gridpoint if ( lower > 0 ) { ! while ( minPoint < lower ) minPoint += gridStep; ! while ( majPoint < lower ) majPoint += mGridStep; } else { ! while ( minPoint > lower ) minPoint -= gridStep; ! while ( majPoint > lower ) majPoint -= mGridStep; // Go one up to make it visible ! if (minPoint != lower ) minPoint += gridStep; ! if (majPoint != lower ) majPoint += mGridStep; } *************** *** 92,99 **** while ( minPoint <= upper && majPoint <= upper ) { if ( minPoint < majPoint ) { markerList.add( new ValueMarker(minPoint, "", false) ); ! minPoint += gridStep; } else --- 96,104 ---- while ( minPoint <= upper && majPoint <= upper ) { + //System.out.println( minPoint + "||" + majPoint ); if ( minPoint < majPoint ) { markerList.add( new ValueMarker(minPoint, "", false) ); ! minPoint = round( minPoint + gridStep ); } else *************** *** 110,120 **** { markerList.add( new ValueMarker(majPoint, str, true) ); ! minPoint += gridStep; ! majPoint += mGridStep; } else { markerList.add( new ValueMarker(majPoint, str, true) ); ! majPoint += mGridStep; } } --- 115,125 ---- { markerList.add( new ValueMarker(majPoint, str, true) ); ! minPoint = round( minPoint + gridStep ); ! majPoint = round( majPoint + mGridStep ); } else { markerList.add( new ValueMarker(majPoint, str, true) ); ! majPoint = round( majPoint + mGridStep ); } } *************** *** 124,128 **** { markerList.add( new ValueMarker(minPoint, "", false) ); ! minPoint += gridStep; } --- 129,133 ---- { markerList.add( new ValueMarker(minPoint, "", false) ); ! minPoint = round( minPoint + gridStep ); } *************** *** 138,142 **** markerList.add( new ValueMarker(majPoint, str, true) ); ! majPoint += mGridStep; } --- 143,147 ---- markerList.add( new ValueMarker(majPoint, str, true) ); ! majPoint = round( majPoint + mGridStep ); } *************** *** 144,186 **** } ! public double getNiceLower( double value ) { int valueInt = new Double(value).intValue(); int roundStep = new Double(gridUnit * gridParts).intValue(); int num = valueInt / roundStep; int mod = valueInt % roundStep; ! double gridValue = (roundStep * (num - 1)) * 1.0d; ! if ( gridValue - value < (gridParts * gridUnit) / 4 ) gridValue -= roundStep; roundStep = new Double(mGridUnit * mGridParts).intValue(); num = valueInt / roundStep; mod = valueInt % roundStep; ! double mGridValue = (roundStep * (num - 1)) * 1.0d; ! if ( value != 0.0d ) { ! if ( mGridValue - gridValue < (mGridParts * mGridUnit) / 2) ! return mGridValue; else ! return gridValue; } ! return value; ! ! /* ! int valueInt = new Double(value).intValue(); ! int num = valueInt / roundStep; ! int mod = valueInt % roundStep; ! ! if ( value != 0 ) ! return (roundStep * (num - 1)) * 1.0d; ! ! return value; ! */ } ! public double getNiceHigher( double value ) { int valueInt = new Double(value).intValue(); int roundStep = new Double(gridUnit * gridParts).intValue(); --- 149,222 ---- } ! public double getNiceLower( double ovalue ) { + // Add some checks + double gridParts = this.gridParts; + double mGridParts = this.mGridParts; + double gridFactor = 1.0; + double mGridFactor = 1.0; + + if ( gridUnit * gridParts < 1.0 ) { + gridParts *= 100; + gridFactor = 100; + } + + if ( mGridUnit * mGridParts < 1.0 ) { + mGridParts *= 100; + mGridFactor = 100; + } + + double value = ovalue * gridFactor; int valueInt = new Double(value).intValue(); int roundStep = new Double(gridUnit * gridParts).intValue(); int num = valueInt / roundStep; int mod = valueInt % roundStep; ! double gridValue = (roundStep * num) * 1.0d; ! if ( gridValue > value ) ! gridValue -= roundStep; ! ! if ( num == 0 && value >= 0 ) ! gridValue = 0.0; ! else if ( Math.abs(gridValue - value) < (gridParts * gridUnit) / 16 ) gridValue -= roundStep; + value = ovalue * mGridFactor; roundStep = new Double(mGridUnit * mGridParts).intValue(); num = valueInt / roundStep; mod = valueInt % roundStep; ! double mGridValue = (roundStep * num) * 1.0d; ! if ( mGridValue > value ) ! mGridValue -= roundStep; ! if ( value != 0.0d ) { ! if ( Math.abs(mGridValue - gridValue) < (mGridParts * mGridUnit) / 2) ! return mGridValue / mGridFactor; else ! return gridValue / gridFactor; } ! return ovalue; } ! public double getNiceHigher( double ovalue ) { + // Add some checks + double gridParts = this.gridParts; + double mGridParts = this.mGridParts; + double gridFactor = 1.0; + double mGridFactor = 1.0; + + if ( gridUnit * gridParts < 1.0 ) { + gridParts *= 100; + gridFactor = 100; + } + + if ( mGridUnit * mGridParts < 1.0 ) { + mGridParts *= 100; + mGridFactor = 100; + } + + double value = ovalue * gridFactor; int valueInt = new Double(value).intValue(); int roundStep = new Double(gridUnit * gridParts).intValue(); *************** *** 188,194 **** int mod = valueInt % roundStep; double gridValue = (roundStep * (num + 1)) * 1.0d; ! if ( gridValue - value < (gridParts * gridUnit) / 4 ) gridValue += roundStep; roundStep = new Double(mGridUnit * mGridParts).intValue(); num = valueInt / roundStep; --- 224,231 ---- int mod = valueInt % roundStep; double gridValue = (roundStep * (num + 1)) * 1.0d; ! if ( gridValue - value < (gridParts * gridUnit) / 8 ) gridValue += roundStep; + value = ovalue * mGridFactor; roundStep = new Double(mGridUnit * mGridParts).intValue(); num = valueInt / roundStep; *************** *** 198,208 **** if ( value != 0.0d ) { ! if ( mGridValue - gridValue < (mGridParts * mGridUnit) / 2) ! return mGridValue; else ! return gridValue; } ! return value; } } --- 235,245 ---- if ( value != 0.0d ) { ! if ( Math.abs(mGridValue - gridValue) < (mGridParts * mGridUnit) / 2) ! return mGridValue / mGridFactor; else ! return gridValue / gridFactor; } ! return ovalue; } } Index: Range.java =================================================================== RCS file: /cvsroot/jrobin/src/jrobin/graph/Range.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Range.java 22 Sep 2003 17:15:17 -0000 1.1 --- Range.java 30 Sep 2003 21:45:21 -0000 1.2 *************** *** 25,29 **** class Range { ! private double lower, upper; Range ( double lower, double upper ) --- 25,30 ---- class Range { ! private double lower = Double.NaN; ! private double upper = Double.NaN; Range ( double lower, double upper ) *************** *** 31,34 **** --- 32,43 ---- this.lower = lower; this.upper = upper; + } + + double getLowerValue() { + return lower; + } + + double getUpperValue() { + return upper; } } |