JFreeChart之堆叠柱形图(StackedBar)

JAVA
JFreeChart

最近的项目使用有个功能需要使用到堆叠柱形图,看了项目以前的代码实现没有想要的结果。所以自己就先到官网下载了 Demo,Demo里有个打包好的Jar包,直接运行看到效果,但是坑爹的是貌似没有对应的源码,所以只能根据class名称直接google了,所幸在github里找到对应的源码。
点我下载 访问密码 f62b
这是运行Demo找到想要实现的效果的大致图:

我最终想要实现的效果是这样的:

如果想要实现这个效果,可以使用

  1. 1extendedstackedbarrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{3}", 

  2. 2 NumberFormat.getPercentInstance(), new DecimalFormat("#0.0%"))); 

  3. 3 

但是柱体的返回的值是10.1/50.1=20.2%,40.1/50.1=79.8%

这不符合预期目标,所以就去看了一下源码,在StandardCategoryItemLabelGenerator的父类AbstractCategoryItemLabelGenerator中发现有createItemArray这么一个方法:

可以发现柱体的标签值应该是由这个方法进行返回的,因此自己就对StandardCategoryItemLabelGenerator进行了继承,并重写了这个方法。
在ExtendedStandardCategoryItemLabelGeneratory中增加了isPercent作为标签值是显示百分比还是仅仅格式化的判断参数,并重写了createItemArray这个方法。

此时得到的效果如图:

然而,柱体的总值还是没有格式化。再看了一下ExtendedStackedBarRenderer这个类的代码,找到了totalFormat这个属性,将其值赋为new DecimalFormat("#0.0%")。测试:

基本是想要的最终结果,下面是测试代码

  1. 1 <dependency> 

  2. 2 <groupId>jfree</groupId> 

  3. 3 <artifactId>jfreechart</artifactId> 

  4. 4 <version>1.0.13</version> 

  5. 5 </dependency> 

ExtendedStackedBarRenderer

  1. 1package com.springapp.jfreechar; 

  2. 2 

  3. 3import java.awt.Color; 

  4. 4import java.awt.Font; 

  5. 5import java.awt.Graphics2D; 

  6. 6import java.awt.geom.Rectangle2D; 

  7. 7import java.text.DecimalFormat; 

  8. 8import java.text.NumberFormat; 

  9. 9 

  10. 10import org.jfree.chart.axis.CategoryAxis; 

  11. 11import org.jfree.chart.axis.ValueAxis; 

  12. 12import org.jfree.chart.entity.CategoryItemEntity; 

  13. 13import org.jfree.chart.entity.EntityCollection; 

  14. 14import org.jfree.chart.labels.CategoryToolTipGenerator; 

  15. 15import org.jfree.chart.plot.CategoryPlot; 

  16. 16import org.jfree.chart.plot.PlotOrientation; 

  17. 17import org.jfree.chart.renderer.category.CategoryItemRendererState; 

  18. 18import org.jfree.chart.renderer.category.StackedBarRenderer; 

  19. 19import org.jfree.data.category.CategoryDataset; 

  20. 20import org.jfree.text.TextUtilities; 

  21. 21import org.jfree.ui.TextAnchor; 

  22. 22 

  23. 23public class ExtendedStackedBarRenderer extends StackedBarRenderer { 

  24. 24 

  25. 25 private static final long serialVersionUID = 1L; 

  26. 26 private boolean showPositiveTotal; 

  27. 27 private boolean showNegativeTotal; 

  28. 28 private Font totalLabelFont; 

  29. 29 private NumberFormat totalFormatter; 

  30. 30 public ExtendedStackedBarRenderer() { 

  31. 31 showPositiveTotal = true; 

  32. 32 showNegativeTotal = true; 

  33. 33 totalLabelFont = new Font("SansSerif", 1, 12); 

  34. 34 totalFormatter = new DecimalFormat("#0.0%"); 

  35. 35 } 

  36. 36 

  37. 37 /** 

  38. 38 * StackedBarRenderer 没有这个构造方法的,传入一个NumberFormat类,可以自定义实现每个柱体值显示格式 

  39. 39 * @param totalFormatter 

  40. 40 */ 

  41. 41 public ExtendedStackedBarRenderer(NumberFormat totalFormatter) { 

  42. 42 showPositiveTotal = true; 

  43. 43 showNegativeTotal = true; 

  44. 44 totalLabelFont = new Font("SansSerif", 1, 12); 

  45. 45 this.totalFormatter = totalFormatter; 

  46. 46 } 

  47. 47 

  48. 48 public NumberFormat getTotalFormatter() { 

  49. 49 return totalFormatter; 

  50. 50 } 

  51. 51 

  52. 52 public void setTotalFormatter(NumberFormat numberformat) { 

  53. 53 if (numberformat == null) { 

  54. 54 throw new IllegalArgumentException("Null format not permitted."); 

  55. 55 } else { 

  56. 56 totalFormatter = numberformat; 

  57. 57 return; 

  58. 58 } 

  59. 59 } 

  60. 60 

  61. 61 public void drawItem(Graphics2D graphics2d, CategoryItemRendererState categoryitemrendererstate, Rectangle2D rectangle2d, CategoryPlot categoryplot, CategoryAxis categoryaxis, 

  62. 62 ValueAxis valueaxis, CategoryDataset categorydataset, int i, int j, int k) { 

  63. 63 Number number = categorydataset.getValue(i, j); 

  64. 64 if (number == null) 

  65. 65 return; 

  66. 66 double d = number.doubleValue(); 

  67. 67 PlotOrientation plotorientation = categoryplot.getOrientation(); 

  68. 68 double d1 = categoryaxis.getCategoryMiddle(j, getColumnCount(), rectangle2d, categoryplot.getDomainAxisEdge()) - categoryitemrendererstate.getBarWidth() / 2D; 

  69. 69 double d2 = 0.0D; 

  70. 70 double d3 = 0.0D; 

  71. 71 for (int l = 0; l < i; l++) { 

  72. 72 Number number1 = categorydataset.getValue(l, j); 

  73. 73 if (number1 == null) 

  74. 74 continue; 

  75. 75 double d5 = number1.doubleValue(); 

  76. 76 if (d5 > 0.0D) 

  77. 77 d2 += d5; 

  78. 78 else 

  79. 79 d3 += d5; 

  80. 80 } 

  81. 81 

  82. 82 org.jfree.ui.RectangleEdge rectangleedge = categoryplot.getRangeAxisEdge(); 

  83. 83 double d4; 

  84. 84 double d6; 

  85. 85 if (d > 0.0D) { 

  86. 86 d4 = valueaxis.valueToJava2D(d2, rectangle2d, rectangleedge); 

  87. 87 d6 = valueaxis.valueToJava2D(d2 + d, rectangle2d, rectangleedge); 

  88. 88 } else { 

  89. 89 d4 = valueaxis.valueToJava2D(d3, rectangle2d, rectangleedge); 

  90. 90 d6 = valueaxis.valueToJava2D(d3 + d, rectangle2d, rectangleedge); 

  91. 91 } 

  92. 92 double d7 = Math.min(d4, d6); 

  93. 93 double d8 = Math.max(Math.abs(d6 - d4), getMinimumBarLength()); 

  94. 94 Rectangle2D.Double double1 = null; 

  95. 95 if (plotorientation == PlotOrientation.HORIZONTAL) 

  96. 96 double1 = new Rectangle2D.Double(d7, d1, d8, categoryitemrendererstate.getBarWidth()); 

  97. 97 else 

  98. 98 double1 = new Rectangle2D.Double(d1, d7, categoryitemrendererstate.getBarWidth(), d8); 

  99. 99 java.awt.Paint paint = getItemPaint(i, j); 

  100. 100 graphics2d.setPaint(paint); 

  101. 101 graphics2d.fill(double1); 

  102. 102 if (isDrawBarOutline() && categoryitemrendererstate.getBarWidth() > 3D) { 

  103. 103 graphics2d.setStroke(getItemStroke(i, j)); 

  104. 104 graphics2d.setPaint(getItemOutlinePaint(i, j)); 

  105. 105 graphics2d.draw(double1); 

  106. 106 } 

  107. 107 org.jfree.chart.labels.CategoryItemLabelGenerator categoryitemlabelgenerator = getItemLabelGenerator(i, j); 

  108. 108 if (categoryitemlabelgenerator != null && isItemLabelVisible(i, j)) 

  109. 109 drawItemLabel(graphics2d, categorydataset, i, j, categoryplot, categoryitemlabelgenerator, double1, d < 0.0D); 

  110. 110 if (d > 0.0D) { 

  111. 111 if (showPositiveTotal && isLastPositiveItem(categorydataset, i, j)) { 

  112. 112 graphics2d.setPaint(Color.black); 

  113. 113 graphics2d.setFont(totalLabelFont); 

  114. 114 double d9 = calculateSumOfPositiveValuesForCategory(categorydataset, j); 

  115. 115 float f = (float) double1.getCenterX(); 

  116. 116 float f2 = (float) double1.getMinY() - 4F; 

  117. 117 TextAnchor textanchor = TextAnchor.BOTTOM_CENTER; 

  118. 118 if (plotorientation == PlotOrientation.HORIZONTAL) { 

  119. 119 f = (float) double1.getMaxX() + 4F; 

  120. 120 f2 = (float) double1.getCenterY(); 

  121. 121 textanchor = TextAnchor.CENTER_LEFT; 

  122. 122 } 

  123. 123 TextUtilities.drawRotatedString(totalFormatter.format(d9), graphics2d, f, f2, textanchor, 0.0D, TextAnchor.CENTER); 

  124. 124 } 

  125. 125 } else if (showNegativeTotal && isLastNegativeItem(categorydataset, i, j)) { 

  126. 126 graphics2d.setPaint(Color.black); 

  127. 127 graphics2d.setFont(totalLabelFont); 

  128. 128 double d10 = calculateSumOfNegativeValuesForCategory(categorydataset, j); 

  129. 129 float f1 = (float) double1.getCenterX(); 

  130. 130 float f3 = (float) double1.getMaxY() + 4F; 

  131. 131 TextAnchor textanchor1 = TextAnchor.TOP_CENTER; 

  132. 132 if (plotorientation == PlotOrientation.HORIZONTAL) { 

  133. 133 f1 = (float) double1.getMinX() - 4F; 

  134. 134 f3 = (float) double1.getCenterY(); 

  135. 135 textanchor1 = TextAnchor.CENTER_RIGHT; 

  136. 136 } 

  137. 137 TextUtilities.drawRotatedString(totalFormatter.format(d10), graphics2d, f1, f3, textanchor1, 0.0D, TextAnchor.CENTER); 

  138. 138 } 

  139. 139 if (categoryitemrendererstate.getInfo() != null) { 

  140. 140 EntityCollection entitycollection = categoryitemrendererstate.getEntityCollection(); 

  141. 141 if (entitycollection != null) { 

  142. 142 String s = null; 

  143. 143 CategoryToolTipGenerator categorytooltipgenerator = getToolTipGenerator(i, j); 

  144. 144 if (categorytooltipgenerator != null) 

  145. 145 s = categorytooltipgenerator.generateToolTip(categorydataset, i, j); 

  146. 146 String s1 = null; 

  147. 147 if (getItemURLGenerator(i, j) != null) 

  148. 148 s1 = getItemURLGenerator(i, j).generateURL(categorydataset, i, j); 

  149. 149 CategoryItemEntity categoryitementity = new CategoryItemEntity(double1, s, s1, categorydataset, categorydataset.getRowKey(i), categorydataset.getColumnKey(j)); 

  150. 150 entitycollection.add(categoryitementity); 

  151. 151 } 

  152. 152 } 

  153. 153 } 

  154. 154 

  155. 155 private boolean isLastPositiveItem(CategoryDataset categorydataset, int i, int j) { 

  156. 156 boolean flag = true; 

  157. 157 Number number = categorydataset.getValue(i, j); 

  158. 158 if (number == null) 

  159. 159 return false; 

  160. 160 for (int k = i + 1; k < categorydataset.getRowCount(); k++) { 

  161. 161 Number number1 = categorydataset.getValue(k, j); 

  162. 162 if (number1 != null) 

  163. 163 flag = flag && number1.doubleValue() <= 0.0D; 

  164. 164 } 

  165. 165 

  166. 166 return flag; 

  167. 167 } 

  168. 168 

  169. 169 private boolean isLastNegativeItem(CategoryDataset categorydataset, int i, int j) { 

  170. 170 boolean flag = true; 

  171. 171 Number number = categorydataset.getValue(i, j); 

  172. 172 if (number == null) 

  173. 173 return false; 

  174. 174 for (int k = i + 1; k < categorydataset.getRowCount(); k++) { 

  175. 175 Number number1 = categorydataset.getValue(k, j); 

  176. 176 if (number1 != null) 

  177. 177 flag = flag && number1.doubleValue() >= 0.0D; 

  178. 178 } 

  179. 179 

  180. 180 return flag; 

  181. 181 } 

  182. 182 

  183. 183 private double calculateSumOfPositiveValuesForCategory(CategoryDataset categorydataset, int i) { 

  184. 184 double d = 0.0D; 

  185. 185 for (int j = 0; j < categorydataset.getRowCount(); j++) { 

  186. 186 Number number = categorydataset.getValue(j, i); 

  187. 187 if (number == null) 

  188. 188 continue; 

  189. 189 double d1 = number.doubleValue(); 

  190. 190 if (d1 > 0.0D) 

  191. 191 d += d1; 

  192. 192 } 

  193. 193 

  194. 194 return d; 

  195. 195 } 

  196. 196 

  197. 197 private double calculateSumOfNegativeValuesForCategory(CategoryDataset categorydataset, int i) { 

  198. 198 double d = 0.0D; 

  199. 199 for (int j = 0; j < categorydataset.getRowCount(); j++) { 

  200. 200 Number number = categorydataset.getValue(j, i); 

  201. 201 if (number == null) 

  202. 202 continue; 

  203. 203 double d1 = number.doubleValue(); 

  204. 204 if (d1 < 0.0D) 

  205. 205 d += d1; 

  206. 206 } 

  207. 207 

  208. 208 return d; 

  209. 209 } 

  210. 210 

  211. 211} 

  212. 212 

ExtendedStandardCategoryItemLabelGeneratory

  1. 1package com.springapp.jfreechar; 

  2. 2 

  3. 3import org.jfree.chart.HashUtilities; 

  4. 4import org.jfree.chart.labels.AbstractCategoryItemLabelGenerator; 

  5. 5import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; 

  6. 6import org.jfree.data.DataUtilities; 

  7. 7import org.jfree.data.category.CategoryDataset; 

  8. 8import org.jfree.util.ObjectUtilities; 

  9. 9import org.jfree.util.PublicCloneable; 

  10. 10 

  11. 11import java.io.Serializable; 

  12. 12import java.text.DateFormat; 

  13. 13import java.text.MessageFormat; 

  14. 14import java.text.NumberFormat; 

  15. 15 

  16. 16public class ExtendedStandardCategoryItemLabelGeneratory extends StandardCategoryItemLabelGenerator implements PublicCloneable, Cloneable, Serializable { 

  17. 17 

  18. 18 private static final long serialVersionUID = -7108591260223293197L; 

  19. 19 private String labelFormat; 

  20. 20 private String nullValueString; 

  21. 21 private NumberFormat numberFormat; 

  22. 22 private DateFormat dateFormat; 

  23. 23 private NumberFormat percentFormat; 

  24. 24 //新增加了参数,柱体series的值是否是总值的百分比,还是仅仅将原来的小数转化为百分数 

  25. 25 private boolean isPercent = false; 

  26. 26 

  27. 27 public ExtendedStandardCategoryItemLabelGeneratory(String labelFormat, NumberFormat formatter, NumberFormat percentFormatter,boolean isPercent){ 

  28. 28 super(labelFormat, formatter, percentFormatter); 

  29. 29 if(labelFormat == null) { 

  30. 30 throw new IllegalArgumentException("Null \'labelFormat\' argument."); 

  31. 31 } else if(formatter == null) { 

  32. 32 throw new IllegalArgumentException("Null \'formatter\' argument."); 

  33. 33 } else if(percentFormatter == null) { 

  34. 34 throw new IllegalArgumentException("Null \'percentFormatter\' argument."); 

  35. 35 } else { 

  36. 36 this.labelFormat = labelFormat; 

  37. 37 this.numberFormat = formatter; 

  38. 38 this.percentFormat = percentFormatter; 

  39. 39 this.dateFormat = null; 

  40. 40 this.nullValueString = "-"; 

  41. 41 if (isPercent) 

  42. 42 this.isPercent = isPercent; 

  43. 43 } 

  44. 44 

  45. 45 } 

  46. 46 

  47. 47 @Override 

  48. 48 protected String generateLabelString(CategoryDataset dataset, int row, int column) { 

  49. 49 if(dataset == null) { 

  50. 50 throw new IllegalArgumentException("Null \'dataset\' argument."); 

  51. 51 } else { 

  52. 52 String result = null; 

  53. 53 Object[] items = this.createItemArray(dataset, row, column); 

  54. 54 result = MessageFormat.format(this.labelFormat, items); 

  55. 55 return result; 

  56. 56 } 

  57. 57 } 

  58. 58 @Override 

  59. 59 protected Object[] createItemArray(CategoryDataset dataset, int row, int column) { 

  60. 60 Object[] result = new Object[]{dataset.getRowKey(row).toString(), dataset.getColumnKey(column).toString(), null, null}; 

  61. 61 Number value = dataset.getValue(row, column); 

  62. 62 if(value != null) { 

  63. 63 if(this.numberFormat != null) { 

  64. 64 result[2] = this.numberFormat.format(value); 

  65. 65 } else if(this.dateFormat != null) { 

  66. 66 result[2] = this.dateFormat.format(value); 

  67. 67 } 

  68. 68 } else { 

  69. 69 result[2] = this.nullValueString; 

  70. 70 } 

  71. 71 

  72. 72 if(value != null) { 

  73. 73 double total = DataUtilities.calculateColumnTotal(dataset, column); 

  74. 74 // 

  75. 75 double percent = 0D;// / total; 

  76. 76 if (this.isPercent) 

  77. 77 //StandardCategoryItemLabelGenerator 返回的值是百分比 

  78. 78 percent = value.doubleValue() / total; 

  79. 79 else 

  80. 80 //返回自己原来的值 

  81. 81 percent = value.doubleValue(); 

  82. 82 //格式化 

  83. 83 result[3] = this.percentFormat.format(percent); 

  84. 84 } 

  85. 85 

  86. 86 return result; 

  87. 87 } 

  88. 88 

  89. 89 

  90. 90} 

  91. 91 

StackedBarChartDemo3

  1. 1package com.springapp.jfreechar; 

  2. 2 

  3. 3import java.awt.*; 

  4. 4import java.text.DecimalFormat; 

  5. 5import java.text.NumberFormat; 

  6. 6import java.util.Iterator; 

  7. 7 

  8. 8import javax.swing.*; 

  9. 9 

  10. 10import com.sun.javafx.charts.Legend; 

  11. 11import org.jfree.chart.*; 

  12. 12import org.jfree.chart.axis.*; 

  13. 13import org.jfree.chart.labels.*; 

  14. 14import org.jfree.chart.plot.CategoryPlot; 

  15. 15import org.jfree.chart.plot.PlotOrientation; 

  16. 16import org.jfree.chart.title.LegendTitle; 

  17. 17import org.jfree.data.category.CategoryDataset; 

  18. 18import org.jfree.data.category.DefaultCategoryDataset; 

  19. 19import org.jfree.ui.ApplicationFrame; 

  20. 20import org.jfree.ui.RectangleEdge; 

  21. 21import org.jfree.ui.RefineryUtilities; 

  22. 22import org.jfree.ui.TextAnchor; 

  23. 23 

  24. 24// Referenced classes of package demo: 

  25. 25// ExtendedStackedBarRenderer 

  26. 26 

  27. 27public class StackedBarChartDemo3 extends ApplicationFrame { 

  28. 28 

  29. 29 private static final long serialVersionUID = 1L; 

  30. 30 

  31. 31 public StackedBarChartDemo3(String s) { 

  32. 32 super(s); 

  33. 33 JPanel jpanel = createDemoPanel(); 

  34. 34 jpanel.setPreferredSize(new Dimension(500, 270)); 

  35. 35 setContentPane(jpanel); 

  36. 36 } 

  37. 37 

  38. 38 private static CategoryDataset createDataset() { 

  39. 39 DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset(); 

  40. 40 defaultcategorydataset.addValue(.101D, "Series 1", "Cross Contamination (4.3)"); 

  41. 41 defaultcategorydataset.addValue(.4D, "Series 2", "Cross Contamination (4.3)"); 

  42. 42 return defaultcategorydataset; 

  43. 43 } 

  44. 44 

  45. 45 private static JFreeChart createChart(CategoryDataset categorydataset) { 

  46. 46 

  47. 47 JFreeChart jfreechart = ChartFactory.createStackedBarChart("Stacked Bar Chart Demo 3", "Category", "Value", categorydataset, PlotOrientation.VERTICAL, true, true, false); 

  48. 48 

  49. 49 CategoryPlot categoryplot = (CategoryPlot) jfreechart.getPlot(); 

  50. 50 //柱体 

  51. 51 ExtendedStackedBarRenderer extendedstackedbarrenderer = new ExtendedStackedBarRenderer(new DecimalFormat("#0.0%")); 

  52. 52 //柱体标签是否可见 

  53. 53 extendedstackedbarrenderer.setBaseItemLabelsVisible(true); 

  54. 54 Font labelFont = new Font("Arial", Font.PLAIN, 12); 

  55. 55 extendedstackedbarrenderer.setBaseItemLabelPaint(new GradientPaint(0.0f, 0.0f, new Color(255, 255, 255), 0.0f, 0.0f, new Color(0, 0, 0))); 

  56. 56 //设置柱体标签值的格式 

  57. 57 ExtendedStandardCategoryItemLabelGeneratory generator = new ExtendedStandardCategoryItemLabelGeneratory("{3}", 

  58. 58 NumberFormat.getPercentInstance(), new DecimalFormat("#0.0%"),false); 

  59. 59 extendedstackedbarrenderer.setBaseItemLabelGenerator(generator); 

  60. 60 //自定义柱体颜色 

  61. 61 Paint p0 = new GradientPaint(0.0f, 0.0f, new Color(237, 125, 49), 0.0f, 0.0f, new Color(237, 125, 49)); 

  62. 62 extendedstackedbarrenderer.setSeriesPaint(0, p0); 

  63. 63 Paint p1 = new GradientPaint(0.0f, 0.0f, new Color(91, 155, 213), 0.0f, 0.0f, new Color(91, 155, 213)); 

  64. 64 extendedstackedbarrenderer.setSeriesPaint(1, p1); 

  65. 65 

  66. 66 categoryplot.setRenderer(extendedstackedbarrenderer); 

  67. 67 

  68. 68 //Y 轴 

  69. 69 NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis(); 

  70. 70 //不设置是自动显示步长 

  71. 71 numberaxis.setTickUnit(new NumberTickUnit(0.05)); 

  72. 72 numberaxis.setLowerMargin(0.14999999999999999D); 

  73. 73 numberaxis.setUpperMargin(0.14999999999999999D); 

  74. 74 //设置是否是百分率 

  75. 75 numberaxis.setNumberFormatOverride(NumberFormat.getPercentInstance()); 

  76. 76 

  77. 77 //X 辆 

  78. 78 CategoryAxis categoryAxis = categoryplot.getDomainAxis(); 

  79. 79 //x轴旋转 

  80. 80 categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)); 

  81. 81 

  82. 82 //标注 

  83. 83 LegendTitle legendtitle = (LegendTitle)jfreechart.getLegend(); 

  84. 84 legendtitle.setBorder(0, 0, 0, 0); 

  85. 85 return jfreechart; 

  86. 86 } 

  87. 87 

  88. 88 public static JPanel createDemoPanel() { 

  89. 89 JFreeChart jfreechart = createChart(createDataset()); 

  90. 90 return new ChartPanel(jfreechart); 

  91. 91 } 

  92. 92 

  93. 93 public static void main(String args[]) { 

  94. 94 StackedBarChartDemo3 stackedbarchartdemo3 = new StackedBarChartDemo3("Stacked Bar Chart Demo 3"); 

  95. 95 stackedbarchartdemo3.pack(); 

  96. 96 RefineryUtilities.centerFrameOnScreen(stackedbarchartdemo3); 

  97. 97 stackedbarchartdemo3.setVisible(true); 

  98. 98 } 

  99. 99} 

  100. 100 

  101. 101 

JFreeChart之堆叠柱形图(StackedBar)的更多相关文章

  1. hcharts实现堆叠柱形图

    <!DOCTYPE > <html> <head> <meta charset="utf-8"><link rel=" ...

  2. 【前端统计图】hcharts实现堆叠柱形图(与后台数据交互)

    原型图类似如下: 图片.png <!DOCTYPE > <html> <head> <meta charset="utf-8">&l ...

  3. XCL-Charts图表库中柱形图的同源风格切换介绍

    柱形图是被使用最多的图之中的一个,在写XCL-Charts这个Android图表库时,为它花费的时间相当多,不是由于有多难绘制,而是要在设计时怎样才干保证图基类能适应各种情况,能灵活满足足够多的需求, ...

  4. R语言-画柱形图

    barplot()函数 1.柱形图 > sales<-read.csv("citysales.csv",header=TRUE) #读取数据 > barplot( ...

  5. 图表(Chart & Graph)你真的用对了吗?

    欢迎大家持续关注葡萄城控件技术团队博客,更多更好的原创文章尽在这里~~ 工作中,我们常常会遇到各式各样的数据,例如网站性能,销售业绩,客户服务 .营销活动等数据.对于这些数据,有哪些行之有效的方法来形 ...

  6. C#实现DevExpress本地化实例详解

    using System; using System.Collections.Generic; using System.Text; using DevExpress.XtraGrid.Localiz ...

  7. MPAndroidChart Wiki(译文)~Part 2

    7. 填充数据 这一章节将讲解给各式各样的图表设置数据的方法. 7.1 LineChart(线形图) 想给图表添加数据,使用如下方法: public void setData(ChartData da ...

  8. Python3 读取和写入excel

    https://blog.csdn.net/weixin_43094965/article/details/82226263一.Excel 1.Excel文件三个对象 workbook: 工作簿,一个 ...

  9. pandas可视化:各种图的简单使用

    一.Matplotlib中几种图的名字 折线图:plot 柱形图:bar 直方图:hist 箱线图:box 密度图:kde 面积图:area 散点图:scatter 散点图矩阵:scatter_mat ...

随机推荐

  1. 【译】x86程序员手册07 - 2.5操作数选择

    2.5 Operand Selection 操作数选择 An instruction can act on zero or more operands, which are the data mani ...

  2. shell编程之grep命令的使用

    大家在学习正则表达式之前,首先要明确一点,并把它牢牢记在心里,那就是: 在linux中,通配符是由shell解释的,而正则表达式则是由命令解释的,不要把二者搞混了.切记!!! 通常有三种文本处理工具/ ...

  3. 【sqli-labs】 less53 GET -Blind based -Order By Clause -String -Stacked injection(GET型基于盲注的字符型Order By从句堆叠注入)

    http://192.168.136.128/sqli-labs-master/Less-53/?sort=1';insert into users(id,username,password) val ...

  4. Java中IO对象的输入输出流

    输入流: public void inputDemo () throws IOException { //文件名称 String fileName = "d:\\aaa.txt"; ...

  5. Requests库 更新中

    1.获取网页内容 --- requests库 <需理解HTTP协议> >requests库的7个主要方法   方法 说明 requests.requests() 构造一个请求,支撑一 ...

  6. js基本类型的包装对象

    var test = "test"; test.a = "hello"; console.log(test.a); 在JavaScript中,“一切皆对象”,数 ...

  7. Echarts特效散点图全解

    mytextStyle={ color:"#333", //文字颜色 fontStyle:"normal", //italic斜体 oblique倾斜 font ...

  8. iPhone设备当前IP和SSID的获取

    #import <Foundation/Foundation.h> typedef void(^Complation)(NSString *res); @interface WIFIMan ...

  9. vue项目的路由配置

    方案一.在生成项目的时候就选择安装路由; 这个地方选择y即可; 生成项目之后在src目录下会有router文件夹,里面有index.js,并且里面已经存在一个helloWorld页面了,可以直接模仿着 ...

  10. UVA1395 Slim Span(kruskal)

    题目:Slim Span UVA 1395 题意:给出一副无向有权图,求生成树中最小的苗条度(最大权值减最小权值),如果不能生成树,就输出-1: 思路:将所有的边按权值有小到大排序,然后枚举每一条边, ...