1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package ohos.devtools.views.charts; 17 18 import ohos.devtools.views.charts.model.ChartDataModel; 19 import ohos.devtools.views.charts.model.ChartStandard; 20 import ohos.devtools.views.common.ColorConstants; 21 import ohos.devtools.views.layout.chartview.ProfilerChartsView; 22 23 import java.awt.Color; 24 import java.awt.Graphics; 25 import java.awt.event.MouseEvent; 26 import java.util.ArrayList; 27 import java.util.LinkedHashMap; 28 import java.util.List; 29 30 import static ohos.devtools.views.charts.model.ChartType.BAR; 31 import static ohos.devtools.views.charts.utils.ChartUtils.divideInt; 32 import static ohos.devtools.views.charts.utils.ChartUtils.multiply; 33 34 /** 35 * Histogram, bar chart 36 * 37 * @since 2021/11/22 38 */ 39 public class BarChart extends ProfilerChart { 40 private static final int REDUCTION_MULTIPLE = 2; 41 private static final int EXPANSION_MULTIPLE = 3; 42 43 private int default_width; 44 45 /** 46 * Constructor 47 * 48 * @param bottomPanel bottomPanel 49 * @param name name 50 * @param YAxisList YAxisList 51 */ BarChart(ProfilerChartsView bottomPanel, String name, ArrayList YAxisList)52 public BarChart(ProfilerChartsView bottomPanel, String name, ArrayList YAxisList) { 53 super(bottomPanel, name, YAxisList); 54 chartType = BAR; 55 } 56 57 /** 58 * Init legends 59 */ 60 @Override initLegends()61 protected void initLegends() { 62 } 63 64 /** 65 * Build legends of chart 66 * 67 * @param lastModels Data on the far right side of the panel 68 * @see "The legend shows the y value corresponding to the rightmost X axis, not the mouse hover position" 69 */ 70 @Override buildLegends(List<ChartDataModel> lastModels)71 protected void buildLegends(List<ChartDataModel> lastModels) { 72 } 73 74 /** 75 * Paint chart 76 * 77 * @param gra Graphics 78 */ 79 @Override paintChart(Graphics gra)80 protected void paintChart(Graphics gra) { 81 synchronized (gra) { 82 ArrayList<BarDataModel> resultList = new ArrayList<>(); 83 ChartStandard cStandard = this.bottomPanel.getPublisher().getStandard(); 84 int maxDisplayTime = cStandard.getMaxDisplayMillis(); 85 int minMarkInterval = cStandard.getMinMarkInterval(); 86 // Calculate the length of each interval 87 default_width = 5; 88 if (dataMap == null || dataMap.size() == 0) { 89 return; 90 } 91 for (int key : dataMap.keySet()) { 92 int rectLeftX = startXCoordinate + multiply(pixelPerX, key - startTime - minMarkInterval / 2) + 2; 93 int valueY; 94 int sum = 0; 95 // Folding state, summation 96 if (super.fold) { 97 valueY = getListSum(dataMap.get(key)); 98 if (valueY > 0) { 99 if (valueY > maxUnitY) { 100 maxUnitY = divideInt(valueY * EXPANSION_MULTIPLE, REDUCTION_MULTIPLE); 101 } 102 int pointY = yZero + multiply(pixelPerY, valueY); 103 resultList.add(new BarDataModel(rectLeftX, pointY, yZero - pointY, ColorConstants.CPU)); 104 } 105 } else { 106 if (dataMap.get(key) != null && dataMap.get(key).size() > 0) { 107 for (ChartDataModel chartDataModel : dataMap.get(key)) { 108 if (chartDataModel.getValue() > 0) { 109 sum += chartDataModel.getValue(); 110 valueY = chartDataModel.getValue(); 111 if (sum > maxUnitY) { 112 maxUnitY = divideInt(sum * EXPANSION_MULTIPLE, REDUCTION_MULTIPLE); 113 } 114 int pointY = yZero + multiply(pixelPerY, valueY); 115 int sumPointY = yZero + multiply(pixelPerY, sum); 116 resultList.add( 117 new BarDataModel(rectLeftX, sumPointY, yZero - pointY, chartDataModel.getColor())); 118 } 119 } 120 } 121 } 122 } 123 paintAssistLine(resultList, gra); 124 } 125 } 126 127 /** 128 * getListSum 129 * 130 * @param models models 131 * @return int 132 */ getListSum(List<ChartDataModel> models)133 public int getListSum(List<ChartDataModel> models) { 134 int sum = 0; 135 if (models != null && models.size() > 0) { 136 for (ChartDataModel chartDataModel : models) { 137 sum += chartDataModel.getValue(); 138 } 139 } 140 return sum; 141 } 142 143 /** 144 * Paint bar chart 145 * 146 * @param resultList The data list 147 * @param gra Graphics 148 */ paintAssistLine(ArrayList<BarDataModel> resultList, Graphics gra)149 private void paintAssistLine(ArrayList<BarDataModel> resultList, Graphics gra) { 150 if (!resultList.isEmpty()) { 151 for (BarDataModel bdm : resultList) { 152 gra.setColor(bdm.getColor()); 153 gra.fillRect(bdm.getPointX(), bdm.getPointY(), default_width - 4, bdm.getHeight()); 154 } 155 } 156 } 157 158 /** 159 * buildTooltipItem 160 * 161 * @param time time 162 * @param dataMap dataMap 163 * @param index index 164 * @return ChartDataModel 165 */ buildTooltipItem(int time, LinkedHashMap<Integer, List<ChartDataModel>> dataMap, int index)166 private ChartDataModel buildTooltipItem(int time, LinkedHashMap<Integer, List<ChartDataModel>> dataMap, int index) { 167 ChartDataModel chartDataModel = new ChartDataModel(); 168 if (dataMap == null || dataMap.size() == 0 || dataMap.get(time) == null) { 169 return chartDataModel; 170 } 171 for (ChartDataModel model : dataMap.get(time)) { 172 if (index == model.getIndex()) { 173 chartDataModel = model; 174 } 175 } 176 return chartDataModel; 177 } 178 179 /** 180 * Build tooltip content 181 * 182 * @param showKey Key to show 183 * @param actualKey The actual value of the key in the data map 184 * @param newChart Is it a new chart 185 */ 186 @Override buildTooltip(int showKey, int actualKey, boolean newChart)187 protected void buildTooltip(int showKey, int actualKey, boolean newChart) { 188 } 189 190 /** 191 * User defined events 192 * 193 * @param event MouseEvent 194 */ 195 @Override leftMouseClickEvent(MouseEvent event)196 protected void leftMouseClickEvent(MouseEvent event) { 197 } 198 199 /** 200 * User defined events 201 * 202 * @param event MouseEvent 203 */ 204 @Override rightMouseClickEvent(MouseEvent event)205 protected void rightMouseClickEvent(MouseEvent event) { 206 } 207 208 /** 209 * User defined events 210 * 211 * @param event MouseEvent 212 */ 213 @Override mouseDraggedEvent(MouseEvent event)214 protected void mouseDraggedEvent(MouseEvent event) { 215 } 216 217 /** 218 * User defined events 219 * 220 * @param event MouseEvent 221 */ 222 @Override mouseReleaseEvent(MouseEvent event)223 protected void mouseReleaseEvent(MouseEvent event) { 224 } 225 226 private class BarDataModel { 227 private int pointX; 228 private int pointY; 229 private int width; 230 private int height; 231 private Color color; 232 BarDataModel(int pointX, int pointY, int height, Color color)233 public BarDataModel(int pointX, int pointY, int height, Color color) { 234 this.pointX = pointX; 235 this.pointY = pointY; 236 this.height = height; 237 this.color = color; 238 } 239 getPointX()240 public int getPointX() { 241 return pointX; 242 } 243 setPointX(int pointX)244 public void setPointX(int pointX) { 245 this.pointX = pointX; 246 } 247 getPointY()248 public int getPointY() { 249 return pointY; 250 } 251 setPointY(int pointY)252 public void setPointY(int pointY) { 253 this.pointY = pointY; 254 } 255 getWidth()256 public int getWidth() { 257 return width; 258 } 259 setWidth(int width)260 public void setWidth(int width) { 261 this.width = width; 262 } 263 getHeight()264 public int getHeight() { 265 return height; 266 } 267 setHeight(int height)268 public void setHeight(int height) { 269 this.height = height; 270 } 271 getColor()272 public Color getColor() { 273 return color; 274 } 275 setColor(Color color)276 public void setColor(Color color) { 277 this.color = color; 278 } 279 } 280 } 281