package org.csstudio.swt.xygraph.linearscale; import java.util.ArrayList; import org.csstudio.swt.xygraph.linearscale.AbstractScale.LabelSide; import org.csstudio.swt.xygraph.util.SWTConstants; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.Graphics; /** * Linear scale tick marks. * @author Xihui Chen */ public class LinearScaleTickMarks extends Figure { /** the scale */ private LinearScale scale; /** the line width */ protected static final int LINE_WIDTH = 1; /** the tick length */ public static final int MAJOR_TICK_LENGTH = 6; /** the tick length */ public static final int MINOR_TICK_LENGTH = 3; private int minorGridStepInPixel; private int minorTicksNumber; /** * Constructor. * @param scale * the scale */ public LinearScaleTickMarks(LinearScale scale) { this.scale = scale; setForegroundColor(scale.getForegroundColor()); } /** * Gets the associated scale. * * @return the scale */ public LinearScale getAxis() { return scale; } protected void paintClientArea(Graphics graphics) { graphics.translate(bounds.x, bounds.y); ArrayList<Integer> tickLabelPositions = scale .getScaleTickLabels().getTickLabelPositions(); int width = getSize().width; int height = getSize().height; if (scale.isHorizontal()) { drawXTickMarks(graphics, tickLabelPositions, scale.getTickLablesSide(), width, height); } else { drawYTickMarks(graphics, tickLabelPositions, scale.getTickLablesSide(), width, height); } }; /** * update the parameters for minor ticks */ public void updateMinorTickParas() { if(scale.isDateEnabled()) { minorTicksNumber = 6; minorGridStepInPixel = (int) (scale.getScaleTickLabels().getGridStepInPixel()/6.0); return; } if(scale.getScaleTickLabels().getGridStepInPixel()/5 >= scale.getMinorTickMarkStepHint()){ minorTicksNumber = 5; minorGridStepInPixel = (int) (scale.getScaleTickLabels().getGridStepInPixel()/5.0); return; } if(scale.getScaleTickLabels().getGridStepInPixel()/4 >= scale.getMinorTickMarkStepHint()){ minorTicksNumber = 4; minorGridStepInPixel = (int) (scale.getScaleTickLabels().getGridStepInPixel()/4.0); return; } minorTicksNumber = 2; minorGridStepInPixel = (int) (scale.getScaleTickLabels().getGridStepInPixel()/2.0); return; } /** * Draw the X tick marks. * * @param tickLabelPositions * the tick label positions * @param tickLabelSide * the side of tick label relative to tick marks * @param width * the width to draw tick marks * @param height * the height to draw tick marks * @param gc * the graphics context */ private void drawXTickMarks(Graphics gc, ArrayList<Integer> tickLabelPositions, LabelSide tickLabelSide, int width, int height) { updateMinorTickParas(); // draw tick marks gc.setLineStyle(SWTConstants.LINE_SOLID); if(scale.isLogScaleEnabled()) { ArrayList<Boolean> tickLabelVisibilities = scale.getScaleTickLabels().getTickVisibilities(); for (int i = 0; i < tickLabelPositions.size(); i++) { int x = tickLabelPositions.get(i); int y = 0; int tickLength =0; if(tickLabelVisibilities.get(i)) tickLength = MAJOR_TICK_LENGTH; else tickLength = MINOR_TICK_LENGTH; if (tickLabelSide == LabelSide.Secondary) { y = height - 1 - LINE_WIDTH - tickLength; } //draw minor ticks for log scale if(tickLabelVisibilities.get(i) || scale.isMinorTicksVisible()) gc.drawLine(x, y, x, y + tickLength); } } else { for (int i = 0; i < tickLabelPositions.size(); i++) { int x = tickLabelPositions.get(i); int y = 0; if (tickLabelSide == LabelSide.Secondary) { y = height - 1 - LINE_WIDTH - MAJOR_TICK_LENGTH; } gc.drawLine(x, y, x, y + MAJOR_TICK_LENGTH); //draw minor ticks for linear scale if(scale.isMinorTicksVisible()){ if(i>0) { //draw the first grid step which is start from min value if(i == 1 && (tickLabelPositions.get(1) - tickLabelPositions.get(0)) < scale.getScaleTickLabels().getGridStepInPixel()){ x = tickLabelPositions.get(1); while((x - tickLabelPositions.get(0)) > minorGridStepInPixel + 3) { x = x - minorGridStepInPixel; drawXMinorTicks(gc, tickLabelSide, x, y); } } //draw the last grid step which is end to max value else if(i == tickLabelPositions.size()-1 && (tickLabelPositions.get(i) - tickLabelPositions.get(i-1)) < scale.getScaleTickLabels().getGridStepInPixel()){ x = tickLabelPositions.get(i-1); while((tickLabelPositions.get(i) -x ) > minorGridStepInPixel + 3) { x = x + minorGridStepInPixel; drawXMinorTicks(gc, tickLabelSide, x, y); } }else{ // draw regular steps for(int j =0; j<minorTicksNumber; j++) { x =tickLabelPositions.get(i-1) + (tickLabelPositions.get(i) - tickLabelPositions.get(i-1))*j/minorTicksNumber; drawXMinorTicks(gc, tickLabelSide, x, y); } } } } } } //draw scale line if(scale.isScaleLineVisible()) { if (tickLabelSide == LabelSide.Primary) { gc.drawLine(scale.getMargin(), 0, width - scale.getMargin(), 0); } else { gc.drawLine(scale.getMargin(), height - 1, width - scale.getMargin(), height - 1); } } } private void drawXMinorTicks(Graphics gc, LabelSide tickLabelSide, int x, int y) { if(tickLabelSide == LabelSide.Primary) gc.drawLine(x, y, x, y + MINOR_TICK_LENGTH); else gc.drawLine(x, y + MAJOR_TICK_LENGTH - MINOR_TICK_LENGTH, x, y + MAJOR_TICK_LENGTH); } /** * Draw the Y tick marks. * * @param tickLabelPositions * the tick label positions * @param tickLabelSide * the side of tick label relative to tick marks * @param width * the width to draw tick marks * @param height * the height to draw tick marks * @param gc * the graphics context */ private void drawYTickMarks(Graphics gc, ArrayList<Integer> tickLabelPositions, LabelSide tickLabelSide, int width, int height) { updateMinorTickParas(); // draw tick marks gc.setLineStyle(SWTConstants.LINE_SOLID); int x = 0; int y = 0; if(scale.isLogScaleEnabled()) { ArrayList<Boolean> tickLabelVisibilities = scale.getScaleTickLabels().getTickVisibilities(); for (int i = 0; i < tickLabelPositions.size(); i++) { int tickLength =0; if(tickLabelVisibilities.get(i)) tickLength = MAJOR_TICK_LENGTH; else tickLength = MINOR_TICK_LENGTH; if (tickLabelSide == LabelSide.Primary) { x = width - 1 - LINE_WIDTH - tickLength; } else { x = LINE_WIDTH; } y = height - tickLabelPositions.get(i); if(tickLabelVisibilities.get(i) || scale.isMinorTicksVisible()) gc.drawLine(x, y, x + tickLength, y); } } else { for (int i = 0; i < tickLabelPositions.size(); i++) { if (tickLabelSide == LabelSide.Primary) { x = width - 1 - LINE_WIDTH - MAJOR_TICK_LENGTH; } else { x = LINE_WIDTH; } y = height - tickLabelPositions.get(i); gc.drawLine(x, y, x + MAJOR_TICK_LENGTH, y); //draw minor ticks for linear scale if(scale.isMinorTicksVisible()){ if(i>0) { //draw the first grid step which is start from min value if(i == 1 && (tickLabelPositions.get(1) - tickLabelPositions.get(0)) < scale.getScaleTickLabels().getGridStepInPixel()){ y = tickLabelPositions.get(1); while((y - tickLabelPositions.get(0)) > minorGridStepInPixel + 3) { y = y - minorGridStepInPixel; drawYMinorTicks(gc, tickLabelSide, x, height - y); } } //draw the last grid step which is end to max value else if(i == tickLabelPositions.size()-1 && (tickLabelPositions.get(i) - tickLabelPositions.get(i-1)) < scale.getScaleTickLabels().getGridStepInPixel()){ y = tickLabelPositions.get(i-1); while((tickLabelPositions.get(i) -y ) > minorGridStepInPixel + 3) { y = y + minorGridStepInPixel; drawYMinorTicks(gc, tickLabelSide, x, height - y); } }else{ // draw regular steps for(int j =0; j<minorTicksNumber; j++) { y =height - tickLabelPositions.get(i-1) - (tickLabelPositions.get(i) - tickLabelPositions.get(i-1))*j/minorTicksNumber; drawYMinorTicks(gc, tickLabelSide, x, y); } } } } } } // draw scale line if(scale.isScaleLineVisible()) { if (tickLabelSide == LabelSide.Primary) { gc.drawLine(width - 1, scale.getMargin(), width - 1, height - scale.getMargin()); } else { gc.drawLine(0, scale.getMargin(), 0, height - scale.getMargin()); } } } private void drawYMinorTicks(Graphics gc, LabelSide tickLabelSide, int x, int y) { //there is a misillumiation int verticalMinorTickLength = MINOR_TICK_LENGTH -1; if(tickLabelSide == LabelSide.Primary) gc.drawLine(x + MAJOR_TICK_LENGTH - verticalMinorTickLength, y, x + MAJOR_TICK_LENGTH, y); else gc.drawLine(x, y, x + verticalMinorTickLength, y); } }