From 4965ec7c0d4bd0d509bd1de10a786c763cc78205 Mon Sep 17 00:00:00 2001 From: "jungwook.ryu" Date: Fri, 31 Oct 2014 10:05:50 +0900 Subject: [PATCH] UI : revision tooltip of file chart add custom chart renderer for file chart. Change-Id: Iae81d3ffbc930aafc9709622ef6701fa9c33e439 Signed-off-by: jungwook.ryu --- .../dynamicanalyzer/ui/file/FileChartBoard.java | 2 +- .../dynamicanalyzer/ui/file/FileChartRenderer.java | 301 +++++++++++++++++++++ 2 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartRenderer.java diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartBoard.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartBoard.java index 8f5470e..b6ca983 100644 --- a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartBoard.java +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartBoard.java @@ -349,7 +349,7 @@ public class FileChartBoard extends DAChartBoard { return; } DAChartPlot plot = chart.getPlot(); - + chart.setChartRenderer(new FileChartRenderer()); // need to custom Chart Render for file chart if (isParent) { DAChartSeries statusSeries = new DAChartSeries( FilePageLabels.FILE_CHART_SERIES, diff --git a/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartRenderer.java b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartRenderer.java new file mode 100644 index 0000000..39e9900 --- /dev/null +++ b/org.tizen.dynamicanalyzer/src/org/tizen/dynamicanalyzer/ui/file/FileChartRenderer.java @@ -0,0 +1,301 @@ +/* + * Dynamic Analyzer + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * Hyeran kim + * Jungwook Ryu + * Juyoung Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +package org.tizen.dynamicanalyzer.ui.file; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.tizen.dynamicanalyzer.widgets.chart.DAChart; +import org.tizen.dynamicanalyzer.widgets.chart.DAChartPlotTooltip; +import org.tizen.dynamicanalyzer.widgets.chart.DAChartRenderer; +import org.tizen.dynamicanalyzer.widgets.chart.DAChartSeries; +import org.tizen.dynamicanalyzer.widgets.chart.DAChartSeriesItem; +import org.tizen.dynamicanalyzer.widgets.helper.ColorResources; + +public class FileChartRenderer extends DAChartRenderer { + @Override + protected void drawToGc(GC gc, DAChart chart) { + if (!preDraw(gc, chart)) { + return; + } + for (int i = 0; i < seriesList.size(); i++) { + drawSeries(gc, seriesList.get(i), i, seriesList.size()); + } + } + + /* + * This method is one of Chart renderer. Real chart using this method is + * File Analysis chart. This renderer draws Rectangle and bar in multi line + * and need specific seriesItem type. Type is possible SERIES_AREA_START, + * SERIES_AREA_END, SERIES_AREA_BAR. + */ + private void drawSeries(GC gc, DAChartSeries series, int seriesIndex, int seriesSize) { + List seriesItems = series.getSeriesItemList(); + if (null == seriesItems) { + return; + } + + int seriesItemSize = seriesItems.size(); + if (seriesItemSize < 1) { + return; + } + int index = series.getPrevIndexByXvalue(plot.getVisibleStartX()); + if (index < 0) { + index = 0; + } + + final int MARGIN_PERCENT = 20; // It's mean 20% + final int STATE_AREA_BAR_WIDTH = 1; + final int DIAGONAL_DIVIDE = 16; // divided in 16 pieces for diagonal box + // size. + final Color DIAGONAL_BOX_COLOR = ColorResources.WHITE; + /* + * Formula to divide in equal series heights. + */ + int margin = (int) ((r.height * (MARGIN_PERCENT / 100.0)) / (seriesSize + 1)); + int areaHeight = (r.height - margin * (seriesSize + 1)) / seriesSize; + int pixcelStartY = (margin * (seriesIndex + 1)) + (areaHeight * seriesIndex); + + List barSeriesItems = new ArrayList(); + /* + * 1. Draw Start/End Status Area. + */ + for (int i = 0; i < seriesItemSize; i++) { + DAChartSeriesItem seriesItem = seriesItems.get(i); + DAChartSeriesItem endSeriesItem = null; + + int type = (int) seriesItem.getY(); + if (DAChartSeriesItem.SERIES_AREA_START == type) { + int startCount = 1; + /* + * Find end series item matched with start series item. + */ + for (int ii = i + 1; ii < seriesItemSize; ii++) { + DAChartSeriesItem nextSeriesItem = seriesItems.get(ii); + int nextType = (int) nextSeriesItem.getY(); + if (nextType == DAChartSeriesItem.SERIES_AREA_START) { + startCount += 1; + } else if (nextType == DAChartSeriesItem.SERIES_AREA_END) { + --startCount; + if (startCount == 0) { + endSeriesItem = nextSeriesItem; + break; + } + } + } + Color foreGroundColor = seriesItem.getGradationForegroundColor(); + Color backGroundcolor = seriesItem.getColor(); + gc.setForeground(foreGroundColor); + gc.setBackground(backGroundcolor); + + int pixcelStartX = plot.getXPixcelFromX(seriesItem.getX(), r); + int pixcelWidth; + if (endSeriesItem != null) { + pixcelWidth = plot.getXPixcelFromX(endSeriesItem.getX(), r) - pixcelStartX; + } else { + /* + * endSeriesItem is null when end series is not exist. this + * case, draw it as much as getValidEndX. + */ + pixcelWidth = plot.getXPixcelFromX(plot.getValidEndX(), r) - pixcelStartX; + } + if (pixcelWidth == 0) { // If diffence is less than 1 second. + // draw 1 pixcel force. + pixcelWidth = 1; + } + gc.fillRectangle(pixcelStartX, pixcelStartY, pixcelWidth, areaHeight); + + /* + * If it's needed, draw diagonal line. diagonal line is composed + * of square boxes. Direction of diagonal line is right top to + * left down like "/". + */ + if (seriesItem.getDiagonal()) { + int diagonalBoxSize = areaHeight / DIAGONAL_DIVIDE; + gc.setForeground(DIAGONAL_BOX_COLOR); + gc.setBackground(DIAGONAL_BOX_COLOR); + for (int j = 0; j < 16; j++) { + int boxY = pixcelStartY + (diagonalBoxSize * j); + // Formula to draw diagonal line like "/" + for (int k = 3 - (j % 4) - (j / 4); k < pixcelWidth; k = k + 3) { + int boxX = diagonalBoxSize * k + pixcelStartX; + if (pixcelStartX <= boxX && boxX <= pixcelWidth + pixcelStartX - diagonalBoxSize) { + gc.fillRectangle(boxX, boxY, diagonalBoxSize, diagonalBoxSize); + } + } + } + } + } else if (DAChartSeriesItem.SERIES_AREA_BAR == type) { + barSeriesItems.add(seriesItem); + } + } + + /* + * 2. Draw Bar series + */ + for (int i = 0; i < barSeriesItems.size(); i++) { + DAChartSeriesItem barSeriesItem = barSeriesItems.get(i); + Color foreGroundColor = barSeriesItem.getGradationForegroundColor(); + Color backGroundcolor = barSeriesItem.getColor(); + gc.setForeground(foreGroundColor); + gc.setBackground(backGroundcolor); + int pixcelStartX = plot.getXPixcelFromX(barSeriesItem.getX(), r); + gc.fillRectangle(pixcelStartX, pixcelStartY, STATE_AREA_BAR_WIDTH, areaHeight); + } + } + + @Override + protected void drawTooltip(GC gc) { + DAChartPlotTooltip tooltip = plot.getTooltip(); + if (tooltip == null || tooltip.shouldBeDrawn() == false || tooltip.getStartVal() == -1) { + return; + } + + gc.setFont(tooltip.getFont()); + + List tooltipTexts = new ArrayList(); + List tooltipTimes = new ArrayList(); + List tooltipColor = new ArrayList(); + + // make text,time & draw auxiliary line + int textWidthMax = 0; + double realXVal = tooltip.getStartVal(); + int tooltipSize = 0; + + int seriesIndex = (int) (seriesList.size() * tooltip.getYPosRatio()); + DAChartSeries series = seriesList.get(seriesIndex); + + int index = series.getPrevIndexByXvalue(realXVal); + String text = ""; + String time = ""; + Color color; + if (index >= 0) { + double xVal = series.getSeriesItemList().get(index).getX(); + + text += series.getName() + ": "; + time += toTimeFormat(xVal); + + if (true == series.isSummarizeTooltip() && true == checkOverlapFromPrevItem(series, index)) { + text += series.getSummarizeString(); + } else { + text += series.getSeriesItemList().get(index).getTooltipText(); + } + + gc.setForeground(tooltip.getLineColor()); + gc.setLineStyle(SWT.LINE_DOT); + gc.setLineWidth(1); + gc.drawLine(plot.getXPixcelFromX(xVal), 0, plot.getXPixcelFromX(xVal), r.height); + gc.setLineStyle(SWT.LINE_CUSTOM); + + // event color + color = series.getSeriesItemList().get(index).getColor(); + } else { + text = series.getName(); + color = null; + } + + tooltipTexts.add(text); + tooltipTimes.add(time); + tooltipColor.add(color); + + int textWidth = gc.textExtent(text).x + DAChartPlotTooltip.TOOLTIP_TIME_MARGIN + gc.textExtent(time).x; + if (textWidthMax < textWidth) { + textWidthMax = textWidth; + } + + /* + * Drawing Tooltip Box + */ + int preTextWidthMargin = DAChartPlotTooltip.TOOLTIP_MARGIN + DAChartPlotTooltip.TOOLTIP_SERIES_RECT_LENGTH + + DAChartPlotTooltip.TOOLTIP_MARGIN; + int startX = getTooltipStartX(realXVal, textWidthMax + preTextWidthMargin, DAChartPlotTooltip.TOOLTIP_MARGIN); + + int totalHeight; + if (!tooltipTexts.isEmpty()) { + totalHeight = gc.textExtent(tooltipTexts.get(0)).y + DAChartPlotTooltip.TOOLTIP_MARGIN + + DAChartPlotTooltip.TOOLTIP_MARGIN; + } else { + totalHeight = DAChartPlotTooltip.TOOLTIP_TEXT_HEIGHT + DAChartPlotTooltip.TOOLTIP_MARGIN + + DAChartPlotTooltip.TOOLTIP_MARGIN; + } + + int startY; + tooltipSize = seriesList.size(); + int heightPerSeries = r.height / tooltipSize; + int currentSeries = ((int) (tooltip.getYPosRatio() * tooltipSize) + 1); + startY = r.y + (heightPerSeries * (currentSeries - 1)) + (heightPerSeries / 2) - (totalHeight / 2); + if (r.height - startY - totalHeight < 0) { + startY = r.height - totalHeight - 1; + if (startY < 0) { + startY = DAChartPlotTooltip.TOOLTIP_MARGIN; + } + } + gc.setAlpha(150); + gc.setBackground(tooltip.getBackgroundColor()); + gc.setForeground(tooltip.getForegroundColor()); + gc.fillGradientRectangle(startX, startY, preTextWidthMargin + textWidthMax + DAChartPlotTooltip.TOOLTIP_MARGIN, + totalHeight, true); + gc.setAlpha(255); + gc.setForeground(tooltip.getLineColor()); + gc.drawRoundRectangle(startX, startY, preTextWidthMargin + textWidthMax + DAChartPlotTooltip.TOOLTIP_MARGIN, + totalHeight, 5, 5); + gc.setFont(tooltip.getFont()); + + /* + * Drawing Tooltip contents (color square, text, time) + */ + + int y = startY + DAChartPlotTooltip.TOOLTIP_MARGIN; + Color col = tooltipColor.get(0); + if (col == null) { + gc.setBackground(series.getColor()); + } else { + gc.setBackground(col); + } + + gc.fillRectangle(startX + DAChartPlotTooltip.TOOLTIP_MARGIN, y + DAChartPlotTooltip.TOOLTIP_TEXT_HEIGHT / 2 + - DAChartPlotTooltip.TOOLTIP_SERIES_RECT_LENGTH / 2, DAChartPlotTooltip.TOOLTIP_SERIES_RECT_LENGTH, + DAChartPlotTooltip.TOOLTIP_SERIES_RECT_LENGTH); + gc.setBackground(tooltip.getBackgroundColor()); + + gc.setForeground(tooltip.getTextColor()); + gc.drawText(tooltipTexts.get(0), startX + DAChartPlotTooltip.TOOLTIP_MARGIN + + DAChartPlotTooltip.TOOLTIP_SERIES_RECT_LENGTH + DAChartPlotTooltip.TOOLTIP_MARGIN, y, + SWT.DRAW_DELIMITER | SWT.DRAW_TRANSPARENT); + + gc.setForeground(tooltip.getTimeColor()); + String timeStr = tooltipTimes.get(0); + gc.drawText(tooltipTimes.get(0), startX + DAChartPlotTooltip.TOOLTIP_MARGIN + + DAChartPlotTooltip.TOOLTIP_SERIES_RECT_LENGTH + DAChartPlotTooltip.TOOLTIP_MARGIN + textWidthMax + - DAChartPlotTooltip.TOOLTIP_MARGIN - gc.textExtent(timeStr).x, y, SWT.DRAW_DELIMITER + | SWT.DRAW_TRANSPARENT); + } +} -- 2.7.4