/** * if any column is pressed, then we will create a filled box for the dragging the field box will * start from the y starting of the beginning point to the last y point the mouse is left * * @param currentX the current x of the drag * @param currentY the current y of the drag * @param oldX * @param oldY * @return */ @Override public boolean mousedragged(int currentX, int currentY, int oldX, int oldY) { // checked if the beginning of the dragging is within a specific vertical field. // if it is, then we will create a filled box, from the y starting of the beginning point to the // last y point the mouse is left if (pressedColumn >= 0) { // check if pressing has began on a column setSelectedColumn(NONE_SELECTED); // unset the selected column // reset the previous drag verticalFieldsDragged[pressedColumn].setBeganDragging(true); resetPreviousColumnDrag(); /* make sure the currentY does not go beyond the boundary of the line */ if (currentY > (init_y + line_height)) { // if it is greater than the highest point for data currentY = init_y + line_height; } else if (currentY < init_y) { // if it is less than the lowest point for data currentY = init_y; } // set the height of the rectangle. // compute the current height of the column. Note it will be currentY and the beginning of the // dragging of the Y. int height = (currentY - verticalFieldsDragged[pressedColumn].getDragBeginY()); if (height < 0) { // if drawing up height = Math.abs(height); // find the positive value of the height int newY = verticalFieldsDragged[pressedColumn].getDragBeginY() - height; // set the new Y verticalFieldsDragged[pressedColumn].setY(newY); // System.out.println("The height is " + height); } verticalFieldsDragged[pressedColumn].setH(height); verticalFieldsDragged[pressedColumn].setDragged(true); // remove the tooltip when dragging is on this.setToolTipText(""); return true; } return false; }
/** * if mouse was pressed on a column and began_dragging of the column is true then set the last * height of the dragging * * @param x x-coordinate of the mouse pointer * @param y y-coordinate of the mouse pointer * @param button * @return true or false */ @Override public boolean mousereleased(int x, int y, int button) { // int index; // check if mouse was pressed on a column and began_dragging of the column is true if (pressedColumn >= 0) { if (verticalFieldsDragged[pressedColumn].getBeganDragging() == true) { /* make sure the y does not go beyond the boundary of the line */ if (y > (init_y + line_height)) { // if it is greater than the highest point for data y = init_y + line_height; } else if (y < init_y) { // if it is less than the lowest point for data y = init_y; } int height = (y - verticalFieldsDragged[pressedColumn].getDragBeginY()); if (height < 0) { height = Math.abs(height); // find the positive value of the height int newY = verticalFieldsDragged[pressedColumn].getDragBeginY() - height; // set the new Y verticalFieldsDragged[pressedColumn].setY(newY); } verticalFieldsDragged[pressedColumn].setH(height); verticalFieldsDragged[pressedColumn].setBeganDragging(false); verticalFieldsDragged[pressedColumn].setDragged(true); setPressedColumn(NONE_SELECTED); // reset the pressed column return true; } } return false; }
/** * *********************************************************** Render the dataLines that connect * the vertical lines * * @param g - the graphics2D object ********************************************************** */ public void renderDataLines(Graphics2D g) { float curpoint, nextpoint; int x, y; /*Draw the lines of the data */ double curmax, nextmax; g.setStroke(new BasicStroke(0.2f)); for (int i = 0; i < rowCount; i++) { x = init_x; y = init_y; for (int j = 0; j < colCount - 1; j++) { dataLinesColor = dataLinesColors[i]; g.setColor( new Color( dataLinesColor.getRed(), dataLinesColor.getGreen(), dataLinesColor.getBlue(), dataLinesColor.getAlpha())); // g.setColor(dataLinesColors[i],alpha); // set the point on the current line curmax = colMax[j] - colMin[j]; // to curpoint = (float) ((line_height / curmax) * XY_coords[i][j]); // set the point on the next line nextmax = colMax[j + 1] - colMin[j + 1]; // set nextpoint = (float) ((line_height / nextmax) * XY_coords[i][j + 1]); // } g.draw( new Line2D.Float( x, Math.abs((line_height + y) - curpoint), x + separation, Math.abs((line_height + y) - nextpoint))); // g.drawLine(x, Math.abs((y + curpoint) - line_height), x + separation, Math.abs((y + // nextpoint)-line_height)); // Draw the small ovals for the data dataOvals[i][j] = new SmallOvals( x - SMALL_OVAL_SIZE / 2, (int) Math.abs((line_height + y) - curpoint - 1), SMALL_OVAL_SIZE, SMALL_OVAL_SIZE); dataOvals[i][j + 1] = new SmallOvals( x + separation - SMALL_OVAL_SIZE / 2, (int) Math.abs((line_height + y) - nextpoint - 1), SMALL_OVAL_SIZE, SMALL_OVAL_SIZE); // set the labels for the dataovals dataOvals[i][j].setLabel(data[i][j]); dataOvals[i][j + 1].setLabel(data[i][j + 1]); // distance between vertial lines x += separation; } } }
/** * generates the color gradients to be used for the lines based on a selected column * * @param colid : the selected column id. */ public void setLineColors() { int colid = selectedColumn; // the selected column. the initial value for selected column is 0 if (colid >= 0) { /*varying the color of the lines */ for (int i = 0; i < rowCount; i++) { // find the percentage value of the coordinate to be used as offset float offset = (colMax[colid] - XY_coords[i][colid]) / colMax[colid]; float red, green, blue; red = dataLinesColor.getRed(); green = dataLinesColor.getGreen(); blue = dataLinesColor.getBlue(); /*The color gradient combination will range between red and blue. Green will remain constant * NB: */ dataLinesColors[i] = new Color( (int) Math.abs((red - (offset * MAX_RGB))), (int) Math.abs(((green))), (int) Math.abs((blue - (offset * MAX_RGB))), alpha); } } else { // check the dragged coordinates and draw those lines colid = pressedColumn; // the selected column. the initial value for selected column is 0 // if no column is selected, we will select the first column by default for the data line // colouring if (colid < 0) { // do nothing return; // no need to do colors } /*varying the color of the lines */ for (int i = 0; i < rowCount; i++) { float r, g, b; r = dataLinesColor.getRed(); g = dataLinesColor.getGreen(); b = dataLinesColor.getBlue(); float offset = (colMax[colid] - XY_coords[i][colid]) / colMax[colid]; if (dataWithinDragged(i, colid) == true) { // if ((curpoint >= dragY) && (curpoint <= (dragY + dragHeight))) { dataLinesColors[i] = new Color( (int) Math.abs((r - (offset * MAX_RGB))), (int) Math.abs(((g))), (int) Math.abs((b - (offset * MAX_RGB))), 255); // note the alpha of this one will be opaque */ } else { dataLinesColors[i] = new Color( (int) Math.abs((r - (offset * MAX_RGB))), (int) Math.abs(((g))), (int) Math.abs((b - (offset * MAX_RGB))), 5); // note the alpha of this one will be close to transparent } } } }
/** * ************************************************************************************ Initialize * the canvas, and render all the vertical lines of the parallel coordinates * * @param g - the graphic2D object * ************************************************************************************ */ public void initializeCanvas(Graphics2D g) { // set the color gradients using the selected column default is the first column i.e. 0) this.setLineColors(); int x = init_x, y = init_y, miny = init_miny, maxy = init_maxy; // set background of the canvas to white g.setBackground(new Color(255, 240, 240)); g.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); g.setStroke(new BasicStroke(0.3f)); // set the thickness of the stroke // render all vertical lines for (int i = 0; i < colCount; i++) { g.setColor(vertLinesColor); // set the color // render vertical lines line_height pixels high g.drawLine(x, miny, x, maxy); // draw small horizontal lines to mark the dimensions of the data on the vertical lines g.drawLine(x - 3, y, x + 3, y); g.drawLine(x - 3, y + line_height, x + 3, y + line_height); // render 2 vertical lines on the sides of the main vertical lines to form boxes around them. g.setColor(new Color(170, 150, 140, 100)); g.drawLine(x - 2, miny, x - 2, maxy); g.drawLine(x + 2, miny, x + 2, maxy); /** ************ Printing the Headings ************************ */ // set color used to print the headings g.setColor(new Color(0, 0, 0)); AffineTransform orig = g.getTransform(); // get the current transform double rotateRadian = 0, offset = 0, labelX, halfRotAngle = 0; rotateRadian = (headerAngle) * Math.PI / 180; // radians = degrees * pi/180 halfRotAngle = (headerAngle / 2.0) * Math.PI / 180; // compute the offset offset = 2 * Math.sin((halfRotAngle)) * (x - 10); // 2 * SOH to find the base of the isocelles triangle found labelX = (x - 10); // the 5 is to move the text a 5pixels to the left when it is rotated offset = Math.abs(offset); // rotateRadian = angle * Math.PI/180 ; //radians = degrees * pi/180 g.rotate(-rotateRadian); double xtrans = 0, ytrans = 0; double xrad = 0; /*find the distance of the x after the rotation. : i.e. find the distance where the base of the isoceles triangle * formed during the rotation forms a right-angle with the header of the rotated figure */ int isoAngle = (180 - headerAngle) / 2; xrad = (isoAngle) * Math.PI / 180; ytrans = Math.sin(xrad) * offset; xtrans = Math.sqrt(Math.pow(offset, 2) - Math.pow(ytrans, 2)); labelX = (x - 10) - xtrans; // (x-5) because we want the label to start a few pixels before the vertical // line g.drawString( tab.getColumnName(i), (int) labelX, (int) ((miny - 10) + ytrans)); // write the header on top of the line. Note the 10 is because we // wanted the text to be 30 pixels above the vertical line. // after writing the rotated text, continue with the normal rotation. g.setTransform(orig); /* Set the field dimensions. these dimensions represent the box around the vertical lines*/ verticalFields[i] = new VerticalFields( x - (verticalFieldWidth / 2), y - 20, line_height + 40, verticalFieldWidth); /*Filling of selection*/ if (verticalFieldsDragged[i] .getDragged()) { // if the column has been dragged, then fill the drag area verticalFieldsDragged[i].setX(verticalFields[i].getX()); verticalFieldsDragged[i].setFill(true); verticalFieldsDragged[i].draw(g); } else if (i == selectedColumn) { // if the whole column has been selected then fill the whole column verticalFields[i].setFill(true); verticalFields[i].draw(g); } x += separation; } // render top and bottom ovals at the endpoints of the vertical lines x = init_x; for (int i = 0; i < colCount; i++) { bottomOvals[i] = new SmallOvals(x - OVAL_WIDTH / 2, y + line_height + 20, OVAL_WIDTH, OVAL_HEIGHT); topOvals[i] = new SmallOvals(x - OVAL_WIDTH / 2, y - 20 - OVAL_HEIGHT, OVAL_WIDTH, OVAL_HEIGHT); topOvals[i].setLabel(tab.getColumnName(i)); bottomOvals[i].setLabel(tab.getColumnName(i)); topOvals[i].draw(g); bottomOvals[i].draw(g); x += separation; // the horizontal separation of the vertical lines. } }