gpt4 book ai didi

java - jfreechart - 为每个饼图自定义饼图标签

转载 作者:行者123 更新时间:2023-12-04 04:54:49 26 4
gpt4 key购买 nike

我正在尝试根据传递的数据类型(整数 vs 美元金额 vs 百分比)为图表上的每个饼图添加自定义渲染器。但是,PieDataset 中的数据似乎只有 1 个键(而当数据集创建为 DefaultCategoryDataset 时,它有一个 rowKey 和一个 columnKey )。

在下图中,我想要实现的是右侧的图表(“销售总额”)将显示美元金额( $ #,##0.00 )。

enter image description here

我尝试过的:我尝试创建一个自定义渲染器并传入数据类型的 ENUM,但这不起作用,因为数据类型,因为我无法在渲染器中确定正在渲染哪个馅饼:

    static class CustomLabelGenerator implements PieSectionLabelGenerator {
public String generateSectionLabel(PieDataset dataset, Comparable key) {
NumberFormat nf;
// How do you find out which pie is being rendered? "key" relates to Bob, Sally, George, Tom, etc.
switch (data_type) {
case currency:
nf = new DecimalFormat("$ #,##0.00");
break;
case integer:
nf = new DecimalFormat("#,##0");
break;
case percentage:
nf = new DecimalFormat("#,##0.00 %");
break;
default:
throw new IllegalStateException("Invalid ENUM. This is impossible");
}
return nf.format(dataset.getValue(key));
}
public AttributedString generateAttributedSectionLabel(
PieDataset dataset, Comparable key) {
return null;
}
}

这甚至可能吗?所有 jFreeChart 多饼图演示在同一屏幕上显示所有饼图的对称数据类型。这是否需要分成两个单独的图形/面板?要是这样就太可惜了……

这是 SSCCE(如果您有 jFreeChart 库):
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.text.AttributedString;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.PieSectionLabelGenerator;
import org.jfree.chart.plot.MultiplePiePlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.TableOrder;

/**
* This example is similar to {@link MultiplePieChartDemo1}, but slices the
* dataset by column rather than by row.
*/
public class MultiplePieChart extends JPanel {

/**
* Creates a sample dataset.
*
* @return A sample dataset.
*/
private static CategoryDataset createDataset() {
int bob_quantity = 100;
int sally_quantity = 115;
int george_quantity = 112;
int tom_quantity = 99;
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(bob_quantity, "Bob", "Sales Quantity");
dataset.addValue(sally_quantity, "Sally", "Sales Quantity");
dataset.addValue(george_quantity, "George", "Sales Quantity");
dataset.addValue(tom_quantity, "Tom", "Sales Quantity");

double bob_total = 1450.40;
double sally_total = 1545.12;
double george_total = 1550.56;
double tom_total = 1200.90;
dataset.addValue(bob_total, "Bob", "Sales Total");
dataset.addValue(sally_total, "Sally", "Sales Total");
dataset.addValue(george_total, "George", "Sales Total");
dataset.addValue(tom_total, "Tom", "Sales Total");

return dataset;
}

/**
* Creates a sample chart with the given dataset.
*
* @param dataset the dataset.
*
* @return A sample chart.
*/
private static JFreeChart createChart(CategoryDataset dataset, String chartTitle, boolean includeLegend, Data_Type data_type) {
JFreeChart chart = ChartFactory.createMultiplePieChart(
chartTitle, // chart title
dataset, // dataset
TableOrder.BY_COLUMN,
includeLegend, // include legend
true,
false
);
MultiplePiePlot plot = (MultiplePiePlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setOutlineStroke(new BasicStroke(1.0f));

JFreeChart subchart = plot.getPieChart();
PiePlot p = (PiePlot) subchart.getPlot();

p.setBackgroundPaint(null);
p.setOutlineStroke(null);
p.setStartAngle(0);

// p.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} ({2})",
// NumberFormat.getNumberInstance(),
// NumberFormat.getPercentInstance()));
p.setMaximumLabelWidth(0.20);

p.setLabelGenerator(new CustomLabelGenerator(data_type));


return chart;
}

/**
* Creates a panel for the demo (used by SuperDemo.java).
*
* @return A panel.
*/
public static JPanel createPanel(CategoryDataset dataset, Dimension size, String chartTitle, boolean includeLegend, Data_Type data_type) {
JFreeChart chart = createChart(dataset, chartTitle, includeLegend, data_type);
ChartPanel panel = new ChartPanel(chart);
panel.setMouseWheelEnabled(true);
if(size != null)
panel.setPreferredSize(size);
return panel;
}

public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = createPanel(createDataset(), new Dimension(800, 500), "Sales", true, Data_Type.integer);
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}


enum Data_Type {
integer,
percentage,
currency
}

static class CustomLabelGenerator implements PieSectionLabelGenerator {


private final Data_Type data_type;

public CustomLabelGenerator(Data_Type data_type) {
this.data_type = data_type;
}

public String generateSectionLabel(PieDataset dataset, Comparable key) {
NumberFormat nf;
switch (data_type) {
case currency:
nf = new DecimalFormat("$ #,##0.00");
break;
case integer:
nf = new DecimalFormat("#,##0");
break;
case percentage:
nf = new DecimalFormat("#,##0.00 %");
break;
default:
throw new IllegalStateException("Invalid ENUM. This is impossible");
}
return nf.format(dataset.getValue(key));
}

public AttributedString generateAttributedSectionLabel(
PieDataset dataset, Comparable key) {
return null;
}

}
}

最佳答案

这感觉有点笨拙,但似乎有效。我正在做的是带 PieDataset传递给 generateSectionLabel并找出它在原始 CategoryDataset 中的哪一列.据我了解 CategoryToPieDataset#equals(PieDataset)正在比较所有的键和值以查看它们是否匹配。这种方法根本不使用您的枚举,它只是查看它为哪个列生成:

static class CustomLabelGenerator implements PieSectionLabelGenerator {
private final CategoryDataset catDataset;

public CustomLabelGenerator(CategoryDataset catDataset) {
this.catDataset = catDataset;
}

public String generateSectionLabel(PieDataset dataset, Comparable key) {
int column = 0;
for (int c = 0; c < catDataset.getColumnCount(); c++) {
CategoryToPieDataset categoryToPieDataset =
new CategoryToPieDataset(catDataset, TableOrder.BY_COLUMN, c);
if (categoryToPieDataset.equals(dataset)) {
column = c;
break;
}
}
NumberFormat nf;
switch (column) {
case 0: // the 'Sales Quantity' column
nf = new DecimalFormat("#,##0");
break;
case 1: // the 'Sales Total' column
nf = new DecimalFormat("$ #,##0.00");
break;
default:
throw new IllegalStateException("Invalid column. This is impossible");
}
return nf.format(dataset.getValue(key));
}
}

结果:
result

除非更熟悉 JFree API 的人有更好的解决方案,否则创建单个饼图并将它们放入 X_AXIS 可能会更清晰。 BoxLayout .

关于java - jfreechart - 为每个饼图自定义饼图标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16901331/

26 4 0