Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package coolmap.canvas.datarenderer.renderer.impl; import com.google.common.collect.Range; import coolmap.canvas.datarenderer.renderer.model.ViewRenderer; import coolmap.data.CoolMapObject; import coolmap.data.cmatrix.model.CMatrix; import coolmap.data.cmatrixview.model.VNode; import coolmap.data.contology.model.COntology; import coolmap.utils.CImageGradient; import coolmap.utils.Tools; import coolmap.utils.graphics.GradientEditorPanel; import coolmap.utils.graphics.UI; import java.awt.Color; import java.awt.Component; import java.awt.Graphics2D; import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Image; import java.awt.Insets; import java.awt.LinearGradientPaint; import java.awt.RenderingHints; import java.awt.Transparency; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.image.BufferedImage; import java.text.DecimalFormat; import java.util.List; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTextField; import org.json.JSONArray; import org.json.JSONObject; /** * * @author sugang */ public class NumberToColor extends ViewRenderer<Double> { private GradientEditorPanel editor; private JTextField minValueField = new JTextField(); private JTextField maxValueField = new JTextField(); private Color normalBG = Color.WHITE; private Color errorBG = UI.colorRedWarning; private JComboBox presetRangeComboBox; private JComboBox presetColorComboBox; private JCheckBox drawSubMap; public static String ATTR_COLORS = "colors"; public static String ATTR_POS = "pos"; public static String ATTR_LOW = "low"; public static String ATTR_HIGH = "high"; @Override public JSONObject getCurrentState() { try { JSONObject state = new JSONObject(); state.put(ATTR_LOW, _minValue); state.put(ATTR_HIGH, _maxValue); int numPts = editor.getNumPoints(); float[] pos = new float[numPts]; int[] colors = new int[numPts]; for (int i = 0; i < editor.getNumPoints(); i++) { pos[i] = editor.getColorPositionAt(i); colors[i] = editor.getColorAt(i).getRGB(); } state.put(ATTR_COLORS, colors); state.put(ATTR_POS, pos); state = new JSONObject(state.toString()); return state; } catch (Exception e) { //log error System.err.println("View renderer save state exception"); return null; } } @Override public boolean restoreState(JSONObject savedState) { try { //putting array this wayd is not a JSONArray! double low = savedState.optDouble(ATTR_LOW, 0); double high = savedState.optDouble(ATTR_HIGH, 1); JSONArray posJ = savedState.getJSONArray(ATTR_POS); JSONArray colorsJ = savedState.getJSONArray(ATTR_COLORS); // Iterator keys = savedState.keys(); // while(keys.hasNext()){ // Object key = keys.next(); // System.out.println("Key:" + key); // System.out.println(savedState.get(key.toString()).getClass()); // } // // System.out.println(savedState.getJSONArray(ATTR_POS)); _minValue = low; _maxValue = high; // System.out.println("State to restore from:" + savedState); // System.out.println(low); // System.out.println(high); // System.out.println(posJ); // System.out.println(colorsJ); float[] p = new float[posJ.length()]; Color[] c = new Color[colorsJ.length()]; for (int i = 0; i < posJ.length(); i++) { p[i] = (float) posJ.getDouble(i); } for (int i = 0; i < colorsJ.length(); i++) { c[i] = new Color(Integer.parseInt(colorsJ.getString(i))); } // System.out.println(Arrays.toString(c)); // System.out.println(Arrays.toString(p)); // System.out.println(low + " " + high); editor.clearColors(); editor.setStart(c[0]); editor.setEnd(c[c.length - 1]); if (c.length > 2) { for (int i = 1; i < c.length - 1; i++) { editor.addColor(c[i], p[i]); } } minValueField.setText(low + ""); maxValueField.setText(high + ""); editor.setMinValue((float) low); editor.setMaxValue((float) high); updateRenderer(); return true; } catch (Exception e) { minValueField.setText("0"); maxValueField.setText("1"); editor.setMinValue(0); editor.setMaxValue(1); _minValue = 0; _maxValue = 1; System.err.println("Failed to restore renderer state"); e.printStackTrace(); return false; } } public NumberToColor() { setName("Number to Color"); setDescription("Use color to represent numeric values"); //initialize UI configUI.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.fill = GridBagConstraints.HORIZONTAL; c.gridx = 0; c.gridy = 0; c.ipadx = 5; c.ipady = 5; c.insets = new Insets(5, 5, 5, 5); c.gridwidth = 2; // c.weightx = 0.8; editor = new GradientEditorPanel(); configUI.add(editor, c); c.gridx = 0; c.gridy++; c.gridwidth = 1; // JButton button = new JButton("Apply"); // configUI.add(button, c); // button.setToolTipText("Apply preset gradient"); // // button.addActionListener(new ActionListener() { // // @Override // public void actionPerformed(ActionEvent e) { // // try { // GradientItem item = (GradientItem) presetColorComboBox.getSelectedItem(); // // editor.clearColors(); // // Color c[] = item.getColors(); // float p[] = item.getPositions(); // // editor.setStart(c[0]); // editor.setEnd(c[c.length - 1]); // // if (c.length > 2) { // for (int i = 1; i < c.length - 1; i++) { // editor.addColor(c[i], p[i]); // } // } // // } catch (Exception ex) { // editor.clearColors(); // editor.setStart(DEFAULT_MIN_COLOR); // editor.setEnd(DEFAULT_MAX_COLOR); // } // // updateRenderer(); // } // }); configUI.add(new JLabel("Preset palette:"), c); c.gridx = 1; c.gridwidth = 1; presetColorComboBox = new JComboBox(); presetColorComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { try { GradientItem item = (GradientItem) presetColorComboBox.getSelectedItem(); presetColorComboBox.setToolTipText(item.getToolTip()); editor.clearColors(); Color c[] = item.getColors(); float p[] = item.getPositions(); editor.setStart(c[0]); editor.setEnd(c[c.length - 1]); if (c.length > 2) { for (int i = 1; i < c.length - 1; i++) { editor.addColor(c[i], p[i]); } } try { Double[] ranges = item.getRanges(); if (ranges != null) { minValueField.setText(ranges[0].toString()); maxValueField.setText(ranges[1].toString()); editor.setMinValue(ranges[0].floatValue()); editor.setMaxValue(ranges[1].floatValue()); } } catch (Exception ex) { minValueField.setText("-1"); maxValueField.setText("1"); editor.setMinValue(-1); editor.setMaxValue(1); } } catch (Exception ex) { editor.clearColors(); editor.setStart(DEFAULT_MIN_COLOR); editor.setEnd(DEFAULT_MAX_COLOR); } } }); // configUI.add(presetColorComboBox, c); presetColorComboBox.setRenderer(new GradientComboItemRenderer()); presetColorComboBox .addItem(new GradientItem(new Color[] { DEFAULT_MIN_COLOR, Color.BLACK, DEFAULT_MAX_COLOR }, new float[] { 0f, 0.5f, 1f }, "TBP", "Teal - Black - Pink")); presetColorComboBox.addItem(new GradientItem(new Color[] { Color.GREEN, Color.RED }, new float[] { 0f, 1f }, "GR", "Green - Red")); presetColorComboBox.addItem(new GradientItem(new Color[] { Color.GREEN, Color.BLACK, Color.RED }, new float[] { 0f, 0.5f, 1f }, "RBG", "Red - Black - Green")); presetColorComboBox.addItem(new GradientItem(new Color[] { Color.ORANGE, Color.BLUE }, new float[] { 0f, 1f }, "OB", "Orange - Blue")); presetColorComboBox.addItem(new GradientItem(new Color[] { Color.ORANGE, Color.BLACK, Color.BLUE }, new float[] { 0f, 0.5f, 1f }, "OBB", "Orange - Black - Blue")); presetColorComboBox.addItem(new GradientItem(new Color[] { Color.BLACK, Color.GREEN }, new float[] { 0f, 1f }, "BG", "Black - Green")); presetColorComboBox .addItem(new GradientItem(new Color[] { Color.RED, UI.colorAKABENI, Color.BLACK, Color.BLACK }, new float[] { 0f, 0.05f, 0.051f, 1f }, "P.05", 0d, 1d, "P-value @ 0.05, Red to Black")); presetColorComboBox.setToolTipText(((GradientItem) presetColorComboBox.getSelectedItem()).getToolTip()); c.gridx = 0; c.gridy++; c.gridwidth = 1; // button = new JButton("Apply"); // // button.setToolTipText("Apply preset data ranges"); // button.addActionListener(new ActionListener() { // // @Override // public void actionPerformed(ActionEvent e) { // try { // MinMaxItem item = (MinMaxItem) (presetRangeComboBox.getSelectedItem()); // minValueField.setText(item.getMinMax().lowerEndpoint().toString()); // maxValueField.setText(item.getMinMax().upperEndpoint().toString()); // } catch (Exception ex) { // minValueField.setText("-1"); // maxValueField.setText("1"); // } // // updateRenderer(); // } // }); // configUI.add(button, c); configUI.add(new JLabel("Preset range:"), c); c.gridx = 1; c.gridwidth = 1; presetRangeComboBox = new JComboBox(); configUI.add(presetRangeComboBox, c); presetRangeComboBox.addItem(new DataMinMaxItem()); presetRangeComboBox.addItem(new DefinedMinMaxItem(-1, 1)); presetRangeComboBox.addItem(new DefinedMinMaxItem(0, 1)); presetRangeComboBox.addItem(new DefinedMinMaxItem(-1, 0)); presetRangeComboBox.addItem(new DefinedMinMaxItem(0, 100)); presetRangeComboBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { try { MinMaxItem item = (MinMaxItem) (presetRangeComboBox.getSelectedItem()); minValueField.setText(item.getMinMax().lowerEndpoint().toString()); maxValueField.setText(item.getMinMax().upperEndpoint().toString()); } catch (Exception ex) { minValueField.setText("-1"); maxValueField.setText("1"); } } }); //////////////////////////////////////////////////////////////////////////////// // c.weightx = 0.2; c.gridx = 0; c.gridy++; c.gridwidth = 1; configUI.add(new JLabel("Min value: "), c); c.gridx = 1; // c.weightx = 0.3; configUI.add(minValueField, c); c.gridx = 0; c.gridy++; c.gridwidth = 1; configUI.add(new JLabel("Max value: "), c); c.gridx = 1; configUI.add(maxValueField, c); c.gridx = 0; c.gridy++; c.gridwidth = 1; JLabel label = Tools.createJLabel("Draw Sub-heatmap:", null, "Draw sub-heatmaps for collapsed ontology nodes", null); configUI.add(label, c); c.gridx = 1; drawSubMap = new JCheckBox(); configUI.add(drawSubMap, c); c.gridx = 0; c.gridy++; c.gridwidth = 3; JButton button = new JButton("Update", UI.getImageIcon("refresh")); configUI.add(button, c); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //hit button, redraw! updateRenderer(); } }); // editor.applyButton.addActionListener(new ActionListener() { // // @Override // public void actionPerformed(ActionEvent e) { // updateRenderer(); // } // }); toolTipLabel = new JLabel(); toolTipLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); toolTipLabel.setBackground(UI.colorGrey3); toolTipLabel.setOpaque(true); toolTipLabel.setForeground(UI.colorBlack2); toolTipLabel.setFont(UI.fontPlain.deriveFont(12f)); } @Override public void updateRendererChanges() { // System.err.println("Renderer changes updated" + getCoolMapObject()); // System.out.println("===Update renderer changes called==="); if (getCoolMapObject() == null) { return; } //update min max try { _minValue = Double.parseDouble(minValueField.getText()); minValueField.setBackground(normalBG); } catch (Exception e) { minValueField.setBackground(errorBG); } try { _maxValue = Double.parseDouble(maxValueField.getText()); maxValueField.setBackground(normalBG); } catch (Exception e) { maxValueField.setBackground(errorBG); } editor.setMinValue(new Float(_minValue)); editor.setMaxValue(new Float(_maxValue)); updateGradient(); } private void updateGradient() { // System.out.println("Gradient updated.."); _gradient.reset(); for (int i = 0; i < editor.getNumPoints(); i++) { Color c = editor.getColorAt(i); float p = editor.getColorPositionAt(i); if (c == null || p < 0 || p > 1) { continue; } _gradient.addColor(c, p); } _gradientColors = _gradient.generateGradient(CImageGradient.InterType.Linear); int width = DEFAULT_LEGEND_WIDTH; int height = DEFAULT_LEGENT_HEIGHT; legend = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice() .getDefaultConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); Graphics2D g = (Graphics2D) legend.createGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); LinearGradientPaint paint = editor.getLinearGradientPaint(0, 0, width, 0); g.setPaint(paint); g.fillRoundRect(0, 0, width, height - 12, 5, 5); g.setColor(UI.colorBlack2); g.setFont(UI.fontMono.deriveFont(10f)); DecimalFormat format = new DecimalFormat("#.##"); g.drawString(format.format(_minValue), 2, 23); String maxString = format.format(_maxValue); int swidth = g.getFontMetrics().stringWidth(maxString); g.drawString(maxString, width - 2 - swidth, 23); g.dispose(); // System.out.println("===Gradient updated===" + _gradientColors + " " + this); } private BufferedImage legend; @Override public Image getLegend() { return legend; } private double _minValue = 0; private double _maxValue = 1; private static Color DEFAULT_MIN_COLOR = new Color(127, 205, 187); private static Color DEFAULT_MAX_COLOR = new Color(252, 146, 114); private CImageGradient _gradient = new CImageGradient(10000); private Color[] _gradientColors = null; @Override protected void initialize() { // System.out.println("===Number to color initialized==="); CoolMapObject obj = getCoolMapObject(); if (!canRender(obj.getViewClass())) { return; } double minValue = Double.MAX_VALUE; double maxValue = -Double.MAX_VALUE; for (int i = 0; i < obj.getViewNumRows(); i++) { for (int j = 0; j < obj.getViewNumColumns(); j++) { try { Double v = (Double) obj.getViewValue(i, j); if (v == null || v.isNaN()) { continue; } else { if (v < minValue) { minValue = v; } if (v > maxValue) { maxValue = v; } } } catch (Exception e) { } } } minValueField.setText(minValue + ""); maxValueField.setText(maxValue + ""); editor.clearColors(); editor.setStart(DEFAULT_MIN_COLOR); editor.addColor(Color.BLACK, 0.5f); editor.setEnd(DEFAULT_MAX_COLOR); // System.err.println("Number to color initialized"); updateRenderer(); } @Override public boolean canRender(Class<?> viewClass) { try { return Double.class.isAssignableFrom(viewClass); } catch (Exception e) { return false; } } @Override public void preRender(int fromRow, int toRow, int fromCol, int toCol, float zoomX, float zoomY) { } @Override public void prepareGraphics(Graphics2D g2D) { g2D.setFont(UI.fontMono.deriveFont(12f)); } @Override public void renderCellLD(Double v, VNode rowNode, VNode columnNode, Graphics2D g2D, int anchorX, int anchorY, int cellWidth, int cellHeight) { // renderCellSD(v, rowNode, columnNode, g2D, anchorX, anchorY, cellWidth, cellHeight); if (v == null || v.isNaN()) { //System.out.println(v); _markNull(v, rowNode, columnNode, g2D, anchorX, anchorY, cellWidth, cellHeight); } else { try { int index = (int) ((v - _minValue) / (_maxValue - _minValue) * _gradientColors.length); if (index >= _gradientColors.length) { index = _gradientColors.length - 1; } if (index < 0) { index = 0; } Color c = _gradientColors[index]; //System.out.println(c); g2D.setColor(c); // System.out.println((int) cellWidth + " " + ((int) cellHeight)) ; g2D.fillRect((int) anchorX, (int) anchorY, (int) cellWidth, (int) cellHeight); } catch (Exception e) { } } } @Override public void renderCellSD(Double v, VNode rowNode, VNode columnNode, Graphics2D g2D, int anchorX, int anchorY, int cellWidth, int cellHeight) { if (v == null || v.isNaN()) { //System.out.println(v); _markNull(v, rowNode, columnNode, g2D, anchorX, anchorY, cellWidth, cellHeight); } else { try { int index = (int) ((v - _minValue) / (_maxValue - _minValue) * _gradientColors.length); if (index >= _gradientColors.length) { index = _gradientColors.length - 1; } if (index < 0) { index = 0; } Color c = _gradientColors[index]; //System.out.println(c); g2D.setColor(c); // System.out.println((int) cellWidth + " " + ((int) cellHeight)) ; g2D.fillRect((int) anchorX, (int) anchorY, (int) cellWidth, (int) cellHeight); // System.out.println("WH:" + cellWidth + " " + cellHeight); if (drawSubMap.isSelected()) { //paint the sub heatmap block // System.out.println("draw submap"); if (rowNode == null || columnNode == null || rowNode.isSingleNode() && columnNode.isSingleNode()) { return; } else { //need to determine the number of cMatrices CoolMapObject object = getCoolMapObject(); List<CMatrix> matrices = object.getBaseCMatrices(); Double value; //row and column indices Integer[] rowIndices; Integer[] colIndices; //whether they are group node or node if (rowNode.isGroupNode()) { rowIndices = rowNode.getBaseIndicesFromCOntology( (CMatrix) object.getBaseCMatrices().get(0), COntology.ROW); } else { rowIndices = new Integer[] { ((CMatrix) object.getBaseCMatrices().get(0)) .getIndexOfRowName(rowNode.getName()) }; } if (columnNode.isGroupNode()) { colIndices = columnNode.getBaseIndicesFromCOntology( (CMatrix) object.getBaseCMatrices().get(0), COntology.COLUMN); } else { colIndices = new Integer[] { ((CMatrix) object.getBaseCMatrices().get(0)) .getIndexOfColName(columnNode.getName()) }; } //then determine the width int subMatrixWidth = Math.round(cellWidth * 1.0f / matrices.size()); int subAnchorX = anchorX; int subCellHeight = Math.round(cellHeight * 1.0f / rowIndices.length); int subCellWidth = Math.round(subMatrixWidth * 1.0f / colIndices.length); // System.out.println("CW:" + cellWidth + " " + colIndices.length + " " + subCellWidth); // System.out.println("CH:" + cellHeight + " " + rowIndices.length + " " + subCellHeight); if (subCellHeight < 1) { subCellHeight = 1; } if (subCellWidth < 1) { subCellWidth = 1; } for (CMatrix matrix : matrices) { int rowIndex = 0; for (Integer i : rowIndices) { if (i == null || i < 0) { continue; } int columnIndex = 0; for (Integer j : colIndices) { if (j == null || j < 0) { continue; } try { value = (Double) matrix.getValue(i, j); index = (int) ((value - _minValue) / (_maxValue - _minValue) * _gradientColors.length); if (index >= _gradientColors.length) { index = _gradientColors.length - 1; } if (index < 0) { index = 0; } c = _gradientColors[index]; g2D.setColor(c); int subCellX = Math .round(subMatrixWidth * 1.0f * columnIndex / colIndices.length) + subAnchorX; int subCellY = Math.round(cellHeight * 1.0f * rowIndex / rowIndices.length) + anchorY; // System.out.println("WTF:" + columnIndex + " " + rowIndex + "----" + subCellX + " " + subCellY + " " + subCellWidth + " " + subCellHeight); g2D.fillRect(subCellX, subCellY, subCellWidth, subCellHeight); } catch (Exception e) { //draw it here e.printStackTrace(); } columnIndex++; } //end of column loop rowIndex++; } //end of row loop subAnchorX += subMatrixWidth; } //end of matrix loop g2D.setStroke(UI.stroke1); g2D.setColor(Color.BLACK); g2D.drawRect(anchorX, anchorY, cellWidth, cellHeight); } } } catch (Exception e) { // System.out.println("Null pointer exception:" + v + "," + _minValue + "," + _maxValue + "," + _gradientColors + " " + getName() + "" + this); //e.printStackTrace(); } } } @Override public Image getSubTip(CoolMapObject object, VNode rowNode, VNode columnNode, float percentX, float PercentY, int cellWidth, int cellHeight) { try { if (!drawSubMap.isSelected()) { return null; } if (rowNode == null || columnNode == null || rowNode.isSingleNode() && columnNode.isSingleNode()) { return null; } List<CMatrix> matrices = object.getBaseCMatrices(); //row and column indices Integer[] rowIndices; Integer[] colIndices; //whether they are group node or node if (rowNode.isGroupNode()) { rowIndices = rowNode.getBaseIndicesFromCOntology((CMatrix) object.getBaseCMatrices().get(0), COntology.ROW); } else { rowIndices = new Integer[] { ((CMatrix) object.getBaseCMatrices().get(0)).getIndexOfRowName(rowNode.getName()) }; } if (columnNode.isGroupNode()) { colIndices = columnNode.getBaseIndicesFromCOntology((CMatrix) object.getBaseCMatrices().get(0), COntology.COLUMN); } else { colIndices = new Integer[] { ((CMatrix) object.getBaseCMatrices().get(0)).getIndexOfColName(columnNode.getName()) }; } //determine where it is in the map int matrixIndex = (int) (percentX * matrices.size()); int rowIndex = (int) (PercentY * rowIndices.length); int colIndex = (int) ((cellWidth * percentX - matrixIndex * 1.0 / matrices.size() * cellWidth) / (cellWidth / matrices.size()) * colIndices.length); // System.out.println(rowIndex + " " + colIndex + " " + percentX + " " + matrixIndex + " " + colIndices.length); if (rowIndex < 0) { rowIndex = 0; } if (colIndex < 0) { colIndex = 0; } if (rowIndex >= rowIndices.length) { rowIndex = rowIndices.length - 1; } if (colIndex >= colIndices.length) { colIndex = colIndices.length - 1; } int rowBaseIndex = rowIndices[rowIndex]; int colBaseIndex = colIndices[colIndex]; // if(rowBaseIndex < 0 )rowBaseIndex = 0; // if(colBaseIndex < 0 )colBaseIndex = 0; // // if(rowBaseIndex >= rowIndices.length) rowBaseIndex = rowIndices.length - 1; // if(colBaseIndex >= colIndices.length) colBaseIndex = colIndices.length - 1; CMatrix matrix = matrices.get(matrixIndex); Double value = (Double) matrix.getValue(rowBaseIndex, colBaseIndex); String rowLabel = matrix.getRowLabel(rowBaseIndex); String colLabel = matrix.getColLabel(colBaseIndex); // System.out.println(matrixIndex + " " + rowBaseIndex + " " + colBaseIndex + " " + rowLabel + " -- " + colLabel + " -- " + value); toolTipLabel .setText("<html><table cellspacing='1' border='0' cellpadding='1'>" + ((matrices.size() > 1) ? "<tr><td><strong>Data: </strong></td><td>" + matrices.get( matrixIndex).getName() + "</td></tr>" : "") + "<tr><td><strong>Row: </strong></td><td>" + rowLabel + "</td></tr><tr><td><strong>Column: </strong></td><td>" + colLabel + "</td></tr><tr><td><strong>Value: </strong></td><td><span style='color:#020202;font-weight:bold;'>" + df.format(value) + "</span></td></tr></table></html>"); return createToolTipFromJLabel(toolTipLabel); } catch (Exception e) { return null; } } private DecimalFormat df = new DecimalFormat("#.###"); private JLabel toolTipLabel; @Override public void renderCellHD(Double v, VNode rowNode, VNode columnNode, Graphics2D g2D, int anchorX, int anchorY, int cellWidth, int cellHeight) { if (v == null || v.isNaN()) { //System.out.println(v); _markNull(v, rowNode, columnNode, g2D, anchorX, anchorY, cellWidth, cellHeight); } else { try { int index = (int) ((v - _minValue) / (_maxValue - _minValue) * _gradientColors.length); if (index >= _gradientColors.length) { index = _gradientColors.length - 1; } if (index < 0) { index = 0; } Color c = _gradientColors[index]; //System.out.println(c); g2D.setColor(c); // System.out.println((int) cellWidth + " " + ((int) cellHeight)) ; g2D.fillRoundRect((int) anchorX + 1, (int) anchorY + 1, (int) cellWidth - 2, (int) cellHeight - 2, 4, 4); if (drawSubMap.isSelected()) { //paint the sub heatmap block // System.out.println("draw submap"); if (rowNode == null || columnNode == null || rowNode.isSingleNode() && columnNode.isSingleNode()) { return; } else { g2D.setStroke(UI.strokeDash1_5); //need to determine the number of cMatrices CoolMapObject object = getCoolMapObject(); List<CMatrix> matrices = object.getBaseCMatrices(); Double value; //row and column indices Integer[] rowIndices; Integer[] colIndices; //whether they are group node or node if (rowNode.isGroupNode()) { rowIndices = rowNode.getBaseIndicesFromCOntology( (CMatrix) object.getBaseCMatrices().get(0), COntology.ROW); } else { rowIndices = new Integer[] { ((CMatrix) object.getBaseCMatrices().get(0)) .getIndexOfRowName(rowNode.getName()) }; } if (columnNode.isGroupNode()) { colIndices = columnNode.getBaseIndicesFromCOntology( (CMatrix) object.getBaseCMatrices().get(0), COntology.COLUMN); } else { colIndices = new Integer[] { ((CMatrix) object.getBaseCMatrices().get(0)) .getIndexOfColName(columnNode.getName()) }; } //then determine the width int subMatrixWidth = Math.round(cellWidth * 1.0f / matrices.size()); int subAnchorX = anchorX; int subCellHeight = Math.round(cellHeight * 1.0f / rowIndices.length); int subCellWidth = Math.round(subMatrixWidth * 1.0f / colIndices.length); // System.out.println("CW:" + cellWidth + " " + colIndices.length + " " + subCellWidth); // System.out.println("CH:" + cellHeight + " " + rowIndices.length + " " + subCellHeight); if (subCellHeight < 1) { subCellHeight = 1; } if (subCellWidth < 1) { subCellWidth = 1; } int matrixIndex = 0; for (CMatrix matrix : matrices) { int rowIndex = 0; for (Integer i : rowIndices) { if (i == null || i < 0) { continue; } int columnIndex = 0; for (Integer j : colIndices) { if (j == null || j < 0) { continue; } try { value = (Double) matrix.getValue(i, j); index = (int) ((value - _minValue) / (_maxValue - _minValue) * _gradientColors.length); if (index >= _gradientColors.length) { index = _gradientColors.length - 1; } if (index < 0) { index = 0; } c = _gradientColors[index]; g2D.setColor(c); int subCellX = Math .round(subMatrixWidth * 1.0f * columnIndex / colIndices.length) + subAnchorX; int subCellY = Math.round(cellHeight * 1.0f * rowIndex / rowIndices.length) + anchorY; // System.out.println("WTF:" + columnIndex + " " + rowIndex + "----" + subCellX + " " + subCellY + " " + subCellWidth + " " + subCellHeight); g2D.fillRect(subCellX, subCellY, subCellWidth, subCellHeight); } catch (Exception e) { //draw it here e.printStackTrace(); } columnIndex++; } //end of column loop rowIndex++; } //end of row loop g2D.setColor(UI.colorBlack1); g2D.drawRect(subAnchorX, anchorY, subMatrixWidth, cellHeight); // // subAnchorX += subMatrixWidth; matrixIndex++; subAnchorX = anchorX + Math.round(cellWidth * 1.0f * matrixIndex / matrices.size()); } //end of matrix loop g2D.setStroke(UI.stroke2); g2D.setColor(Color.BLACK); g2D.drawRect(anchorX, anchorY, cellWidth, cellHeight); } } } catch (Exception e) { // System.out.println("Null pointer exception:" + v + "," + _minValue + "," + _maxValue + "," + _gradientColors + " " + getName() + "" + this); //e.printStackTrace(); } } } // DecimalFormat df = new DecimalFormat("#.##"); @Override public void postRender(int fromRow, int toRow, int fromCol, int toCol, float zoomX, float zoomY) { } private JPanel configUI = new JPanel(); @Override public JComponent getConfigUI() { return configUI; } private class DataMinMaxItem extends MinMaxItem { @Override public Range<Double> getMinMax() { CoolMapObject obj = getCoolMapObject(); if (!canRender(obj.getViewClass())) { return null; } double minValue = Double.MAX_VALUE; double maxValue = -Double.MAX_VALUE; try { for (int i = 0; i < obj.getViewNumRows(); i++) { for (int j = 0; j < obj.getViewNumColumns(); j++) { try { Double v = (Double) obj.getViewValue(i, j); if (v == null || v.isNaN()) { continue; } else { if (v < minValue) { minValue = v; } if (v > maxValue) { maxValue = v; } } } catch (Exception e) { } } } return Range.closed(minValue, maxValue); } catch (Exception e) { return null; } } @Override public String toString() { return "View min - max"; } } private class DefinedMinMaxItem extends MinMaxItem { private double min; private double max; public DefinedMinMaxItem(double min, double max) { this.min = min; this.max = max; } @Override public Range<Double> getMinMax() { return Range.closed(min, max); } } private abstract class MinMaxItem { public abstract Range<Double> getMinMax(); @Override public String toString() { Range<Double> range = getMinMax(); return range.lowerEndpoint() + " - " + range.upperEndpoint(); } } private class GradientItem { private final Color[] c; private final float[] pos; private final BufferedImage preview; private final String name; private final String toolTip; // @Override // public String toString(){ // return getToolTip(); // } public String getToolTip() { return toolTip; } public GradientItem(Color[] c, float[] pos, String name, Double low, Double high, String toolTip) { this.c = c; this.pos = pos; //update preview preview = new BufferedImage(100, 16, BufferedImage.TYPE_INT_ARGB); this.name = name; LinearGradientPaint paint = new LinearGradientPaint(0, 0, 100, 0, pos, c); Graphics2D g2D = preview.createGraphics(); g2D.setPaint(paint); g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2D.fillRoundRect(2, 2, 90, 12, 4, 4); g2D.dispose(); this.low = low; this.high = high; this.toolTip = toolTip; } public GradientItem(Color[] c, float[] pos, String name, String toolTip) { this(c, pos, name, null, null, toolTip); } public Image getPreview() { return preview; } @Override public String toString() { return name + getToolTip();//To change body of generated methods, choose Tools | Templates. } public Color[] getColors() { return c; } public float[] getPositions() { return pos; } public Double[] getRanges() { if (low == null || high == null) { return null; } return new Double[] { low, high }; } private Double low = null; private Double high = null; } private class GradientComboItemRenderer extends DefaultListCellRenderer { @Override public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel l = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); l.setIcon(new ImageIcon(((GradientItem) value).getPreview())); l.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); l.setText(((GradientItem) value).name); return l; } } }