PageRenderTime 23ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/chart/BarChart.java

http://github.com/matthewhk/visual-simulation
Java | 336 lines | 247 code | 66 blank | 23 comment | 43 complexity | bac9b8dc8e1c041aa7b1f1f4b2e9cbfd MD5 | raw file
  1. package chart;
  2. import java.awt.Color;
  3. import java.awt.Dimension;
  4. import java.awt.Font;
  5. import java.awt.FontMetrics;
  6. import java.awt.Graphics;
  7. import java.awt.Insets;
  8. import java.io.Serializable;
  9. import java.util.LinkedList;
  10. public class BarChart extends Presentation implements Serializable {
  11. /**
  12. *
  13. */
  14. private static final long serialVersionUID = -4867663508259956099L;
  15. private final Dimension _smallestSize = new Dimension(600, 450);
  16. private Dimension _immediateSize = new Dimension(600, 450);
  17. // private BufferedImage bi = new
  18. // BufferedImage(_immediateSize.width,_immediateSize.height,BufferedImage.TYPE_INT_ARGB);
  19. private BarChartMouseAdapter _myMouseAdapter;
  20. private double _gridLineUnit = 100;
  21. private double _assistantLineUnit = 10;
  22. private int _numOfDisplayOnXAxis = 30;
  23. private Insets _border;
  24. private int _x, _y, _width, _height;
  25. private LinkedList _sampleValues;
  26. private boolean _isDrawVerticalLine = true;
  27. private boolean _isDrawBarLabel = true;
  28. private boolean _isDrawYGridLine = true;
  29. private boolean _isDrawSecondaryYGridLine = true;
  30. private boolean _isDrawValueIndicator = true;
  31. private String _mouseOnBarLabel = "";
  32. private int _space;
  33. public BarChart() {
  34. this(null);
  35. }
  36. public BarChart(Chart chartToShow) {
  37. super(chartToShow);
  38. if (getChart() != null) {
  39. _sampleValues = getChart().getSampleValues();
  40. }
  41. setPreferredSize(_immediateSize);
  42. this.setBounds(0, 0, _immediateSize.width, _immediateSize.height);
  43. setDrawVerticalLine(false);
  44. setDrawBarLabel(false);
  45. _myMouseAdapter = new BarChartMouseAdapter(this);
  46. addMouseListener(_myMouseAdapter);
  47. addMouseMotionListener(_myMouseAdapter);
  48. _border = this.getInsets();
  49. }
  50. protected void paintComponent(Graphics g) {
  51. if (getChart() == null) {
  52. return;
  53. }
  54. _sampleValues = getChart().getSampleValues();
  55. if (_sampleValues.size() <= 0) {
  56. super.paintComponent(g);
  57. return;
  58. }
  59. _numOfDisplayOnXAxis = getChart().getNumOfSampleValue();
  60. updateSize();
  61. _space = _width / (_numOfDisplayOnXAxis + 1);
  62. // System.out.println("paintComponent: calculate points");
  63. double maxPoint = getChart().getMaxSampleValue().getValue();
  64. double tmp = maxPoint;
  65. int powCounter = 0;
  66. if (maxPoint > 1) {
  67. while (tmp >= 10) {
  68. powCounter++;
  69. tmp = tmp / 10;
  70. }
  71. } else {
  72. while (tmp < 1) {
  73. powCounter--;
  74. tmp = tmp * 10;
  75. // System.out.println("powCounter: " +powCounter);
  76. }
  77. }
  78. adjustLineUnit(maxPoint, powCounter);
  79. _border = this.getInsets();
  80. int chartHeight;
  81. chartHeight = getHeight() - ((getHeight() / 10) + _border.top);
  82. g.setColor(Color.white);
  83. g.fillRect(0, 0, getWidth(), getHeight());
  84. g.setColor(Color.gray);
  85. g.drawRect(_x, _y, _width - 1, _height - 1);
  86. double scaleFactor;
  87. scaleFactor = calScaleFactor(maxPoint + ((Math.pow(10.0, powCounter)) * 0.5) / 5, chartHeight);
  88. // scaleFactor = this.calScaleFactor(maxPoint +
  89. // (double)((Math.pow(10.0,(double)powCounter))*0.5)/5, chartHeight);
  90. if (_isDrawVerticalLine) {
  91. drawVerticalLine(g, _space, chartHeight);
  92. }
  93. drawBars(g, _space, chartHeight, scaleFactor);
  94. drawHorizontalLine(g, maxPoint, powCounter, chartHeight, scaleFactor);
  95. plotLine(g, _space, chartHeight, scaleFactor);
  96. g.setColor(Color.black);
  97. drawMouseOnBarLabel(g, _mouseOnBarLabel);
  98. // this.drawLabels(g);
  99. }
  100. private void adjustLineUnit(double maxPoint, int powCounter) {
  101. int firstSigDigit;
  102. // powCounter=-1.0;
  103. if (maxPoint >= 10) {
  104. firstSigDigit = Integer.parseInt((String.valueOf(maxPoint)).substring(0, 1));
  105. } else {
  106. int length = String.valueOf(maxPoint).length();
  107. int i = 0;
  108. boolean match = false;
  109. while (i < length && !match) {
  110. if (!((String.valueOf(maxPoint)).substring(i, i + 1).equals("0") || (String.valueOf(maxPoint).substring(i, i + 1)).equals("."))) {
  111. // terminate the loop
  112. length = i;
  113. match = true;
  114. } else {
  115. i++;
  116. }
  117. }
  118. firstSigDigit = Integer.parseInt((String.valueOf(maxPoint)).substring(i, i + 1));
  119. }
  120. if (firstSigDigit > 7) {
  121. _gridLineUnit = (Math.pow(10.0, powCounter));
  122. _assistantLineUnit = (Math.pow(10.0, powCounter)) / 5;
  123. } else if (firstSigDigit <= 7 && firstSigDigit > 4) {
  124. _gridLineUnit = (Math.pow(10.0, powCounter));
  125. _assistantLineUnit = (Math.pow(10.0, powCounter)) / 10;
  126. } else if (firstSigDigit <= 4 && firstSigDigit > 2) {
  127. _gridLineUnit = ((Math.pow(10.0, powCounter)) * 0.5);
  128. _assistantLineUnit = ((Math.pow(10.0, powCounter)) * 0.5) / 5;
  129. } else {
  130. _gridLineUnit = ((Math.pow(10.0, powCounter)) * 0.5);
  131. _assistantLineUnit = ((Math.pow(10.0, powCounter)) * 0.5) / 10;
  132. }
  133. }
  134. private void updateSize() {
  135. _border = getInsets();
  136. _width = getWidth() - (_border.left + _border.right);
  137. _height = getHeight() - (_border.top + _border.bottom);
  138. _x = _border.left;
  139. _y = _border.top;
  140. }
  141. private double calScaleFactor(double maxPoint, long chartHeight) {
  142. double factor;
  143. if (maxPoint != 0.0) {
  144. factor = chartHeight / maxPoint;
  145. return factor;
  146. } else {
  147. return 0.0; // Avoid divided by zero expection
  148. }
  149. }
  150. private void drawHorizontalLine(Graphics g, double maxPoint, int powCounter, int chartHeight, double scaleFactor) {
  151. int limit, remainder;
  152. int counterTmp = 0;
  153. // draw _SecondaryYLine
  154. g.setColor(Color.lightGray);
  155. limit = (int) ((maxPoint + ((long) ((Math.pow(10.0, powCounter)) * 0.5) / 5)) / _assistantLineUnit);
  156. remainder = (chartHeight) - (int) (limit * _assistantLineUnit * scaleFactor);
  157. for (int i = limit; 0 - 5 <= i; i--) {
  158. g.drawLine(_x, (int) (i * _assistantLineUnit * scaleFactor) + remainder, _width - _border.right, (int) (i * _assistantLineUnit * scaleFactor) + remainder);
  159. counterTmp++;
  160. }
  161. // System.out.println("counterTmp: " +counterTmp);
  162. // draw gridLine
  163. g.setColor(Color.black);
  164. limit = (int) ((maxPoint + ((long) ((Math.pow(10.0, powCounter)) * 0.5) / 5)) / _gridLineUnit);
  165. remainder = (chartHeight) - (int) (limit * _gridLineUnit * scaleFactor);
  166. g.setFont(new Font("Dialog", Font.PLAIN, 10));
  167. for (int i = limit; 0 - 5 <= i; i--) {
  168. g.drawString(String.valueOf((limit * _gridLineUnit) - (i * _gridLineUnit)), _x, (int) (i * _gridLineUnit * scaleFactor) + remainder);
  169. g.drawLine(_x, (int) (i * _gridLineUnit * scaleFactor) + remainder, _width - _border.right, (int) (i * _gridLineUnit * scaleFactor) + remainder);
  170. }
  171. }
  172. private void drawVerticalLine(Graphics g, int space, int chartHeight) {
  173. // draw vertical line
  174. for (int i = 1; i <= _numOfDisplayOnXAxis; i++) {
  175. g.drawLine(_border.left + space * i, _y, _border.left + space * i, chartHeight);
  176. }
  177. }
  178. private void drawBars(Graphics g, int space, int chartHeight, double scaleFactor) {
  179. // draw bars
  180. int barWidth = (int) ((double) _width / _numOfDisplayOnXAxis);
  181. int i;
  182. for (i = 0; i < _sampleValues.size(); i++) {
  183. g.setColor(Color.cyan);
  184. g.fillRect(_border.left + space * (i + 1) - barWidth / 2, chartHeight - (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i - 1)).getValue()), barWidth, (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i - 1)).getValue()));
  185. g.setColor(Color.blue);
  186. g.drawRect(_border.left + space * (i + 1) - barWidth / 2, chartHeight - (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i - 1)).getValue()), barWidth, (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i - 1)).getValue()));
  187. if (_isDrawBarLabel) {
  188. g.drawString(((SampleValue) (_sampleValues.get(_sampleValues.size() - (i + 1)))).getLabel(), space * (i + 1) - (getWidth() / 100), chartHeight + (getHeight() / 20));
  189. }
  190. if (_isDrawValueIndicator) {
  191. g.setColor(Color.black);
  192. g.fillOval(space * (i + 1) - ((getWidth() / 100) / 2), (chartHeight - (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i - 1)).getValue())) - ((getWidth() / 100) / 2), getWidth() / 100, getWidth() / 100);
  193. }
  194. }
  195. }
  196. private void plotLine(Graphics g, int space, int chartHeight, double scaleFactor) {
  197. g.setColor(Color.red);
  198. for (int i = 1; _sampleValues.size() > i; i++) {
  199. g.drawLine(_border.left + space * (i), chartHeight - (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i)).getValue()), _border.left + space * (i + 1), chartHeight - (int) (scaleFactor * ((SampleValue) _sampleValues.get(_sampleValues.size() - i - 1)).getValue()));
  200. }
  201. }
  202. /*
  203. * private void drawLabels(Graphics g){
  204. * g.drawString(_xAxisUnit,(this.getWidth() / 2), this.getHeight() - 5); }
  205. */
  206. public void setDrawVerticalLine(boolean value) {
  207. _isDrawVerticalLine = value;
  208. }
  209. public boolean isDrawVerticalLine() {
  210. return _isDrawVerticalLine;
  211. }
  212. public void setDrawYGridLine(boolean value) {
  213. _isDrawYGridLine = value;
  214. }
  215. public boolean isDrawYGridLine() {
  216. return _isDrawYGridLine;
  217. }
  218. public void setDrawSecondaryYGridLine(boolean value) {
  219. _isDrawSecondaryYGridLine = value;
  220. }
  221. public boolean isDrawValueIndicator() {
  222. return _isDrawValueIndicator;
  223. }
  224. public void setDrawValueIndicator(boolean value) {
  225. _isDrawValueIndicator = value;
  226. }
  227. public boolean isDrawSecondaryYGridLine() {
  228. return _isDrawSecondaryYGridLine;
  229. }
  230. public void setDrawBarLabel(boolean value) {
  231. _isDrawBarLabel = value;
  232. }
  233. public boolean isDrawBarLabel() {
  234. return _isDrawBarLabel;
  235. }
  236. public String getMouseOnBarLabel() {
  237. return _mouseOnBarLabel;
  238. }
  239. // override setChart() method in super class Presentation
  240. public void setChart(Chart chartToShow) {
  241. super.setChart(chartToShow);
  242. if (getChart() != null) {
  243. _sampleValues = getChart().getSampleValues();
  244. }
  245. }
  246. protected void setMouseOnBarLabel(String label) {
  247. _mouseOnBarLabel = label;
  248. }
  249. private void drawMouseOnBarLabel(Graphics g, String label) {
  250. int strWidth, strHeight;
  251. FontMetrics fm = g.getFontMetrics(g.getFont());
  252. strWidth = fm.stringWidth(label);
  253. strHeight = fm.getHeight();
  254. g.drawString(label, (getWidth() / 2) - (strWidth / 2), getHeight() - strHeight);
  255. }
  256. protected int calSampleValuesIndex(int xOnXAxis) {
  257. if (_sampleValues.size() == 0) {
  258. return -1;
  259. } else {
  260. int barWidth = (int) ((double) _width / _numOfDisplayOnXAxis);
  261. for (int i = 0; i < _sampleValues.size(); i++) {
  262. if ((_border.left + _space * (i + 1) - barWidth / 2 <= xOnXAxis) && (xOnXAxis < _border.left + _space * (i + 2) - barWidth / 2)) {
  263. return _sampleValues.size() - 1 - i;
  264. }
  265. }
  266. // not in bar field
  267. return -1;
  268. }
  269. }
  270. }