图像作为 iReport 图表中的类别标签
Image as category label in iReport chart
我正在尝试使用类别标签(x 轴标签)的图像创建条形图。对于默认条形图,类别表达式的结果用作标签(并且必须是字符串)。我如何自定义它以显示图像?我已经编写了一个 scriptlet 来使用 BufferedImages 填充变量,现在我只需要一种使用它们的方法。我可以使用图表定制器 class 来做到这一点吗?有easier/better方法吗?
正如您所说,您可以通过自己的定制器来完成 class。这是一个可以根据您的需要进行增强的简单示例:
@Slf4j
public class CategoryAxisWithImagesCustomizer extends JRAbstractChartCustomizer {
public class CategoryAxisWithImages extends CategoryAxis {
public CategoryAxisWithImages(String label) {
super(label);
}
@Override
protected Rectangle2D getLabelEnclosure(Graphics2D g2, RectangleEdge edge) {
// enter max width and height of your images or you can do it dynamically
return new Rectangle2D.Double(0, 0, 32, 32);
}
@Override
protected AxisState drawCategoryLabels(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state, PlotRenderingInfo plotState) {
if (!isTickLabelsVisible()) {
return state;
}
List ticks = refreshTicks(g2, state, plotArea, edge);
state.setTicks(ticks);
for (int i = 0; i < ticks.size(); i++) {
double x = getCategoryMiddle(i, ticks.size(), dataArea, edge);
double y = state.getCursor() + getCategoryLabelPositionOffset();
int value = (int) ((CategoryPlot) getPlot()).getDataset().getColumnKey(i);
String imagePath = "logo_" + value + ".png";
try {
InputStream imageStream = getClass().getResourceAsStream(imagePath);
// you can of course load images using different way - here I'm using index value from the dataset
BufferedImage image = ImageIO.read(imageStream);
g2.drawImage(image, (int) (x - image.getWidth() / 2d), (int) (y), image.getWidth(), image.getHeight(), Color.black, null);
} catch (IOException e) {
log.error("Cannot load image {}", imagePath);
}
}
state.cursorDown(state.getMax() + getCategoryLabelPositionOffset());
return state;
}
}
@Override
public void customize(JFreeChart chart, JRChart jasperChart) {
CategoryPlot plot = chart.getCategoryPlot();
CategoryAxis categoryAxis = new CategoryAxisWithImages(plot.getDomainAxis().getLabel());
plot.setDomainAxis(categoryAxis);
}
}
在 JasperReport JRXML 中,您可以像这样注册定制器 class:
<barChart>
<chart customizerClass="cz.trask.experiment.jr.CategoryAxisWithImagesCustomizer"
isShowLegend="false">
<reportElement x="0" y="0" width="550" height="348" uuid="a2cbb6b5-a76d-469b-8e8e-daa533260f20"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend/>
</chart>
...
</barChart>
我的例子的结果是:
我正在尝试使用类别标签(x 轴标签)的图像创建条形图。对于默认条形图,类别表达式的结果用作标签(并且必须是字符串)。我如何自定义它以显示图像?我已经编写了一个 scriptlet 来使用 BufferedImages 填充变量,现在我只需要一种使用它们的方法。我可以使用图表定制器 class 来做到这一点吗?有easier/better方法吗?
正如您所说,您可以通过自己的定制器来完成 class。这是一个可以根据您的需要进行增强的简单示例:
@Slf4j
public class CategoryAxisWithImagesCustomizer extends JRAbstractChartCustomizer {
public class CategoryAxisWithImages extends CategoryAxis {
public CategoryAxisWithImages(String label) {
super(label);
}
@Override
protected Rectangle2D getLabelEnclosure(Graphics2D g2, RectangleEdge edge) {
// enter max width and height of your images or you can do it dynamically
return new Rectangle2D.Double(0, 0, 32, 32);
}
@Override
protected AxisState drawCategoryLabels(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state, PlotRenderingInfo plotState) {
if (!isTickLabelsVisible()) {
return state;
}
List ticks = refreshTicks(g2, state, plotArea, edge);
state.setTicks(ticks);
for (int i = 0; i < ticks.size(); i++) {
double x = getCategoryMiddle(i, ticks.size(), dataArea, edge);
double y = state.getCursor() + getCategoryLabelPositionOffset();
int value = (int) ((CategoryPlot) getPlot()).getDataset().getColumnKey(i);
String imagePath = "logo_" + value + ".png";
try {
InputStream imageStream = getClass().getResourceAsStream(imagePath);
// you can of course load images using different way - here I'm using index value from the dataset
BufferedImage image = ImageIO.read(imageStream);
g2.drawImage(image, (int) (x - image.getWidth() / 2d), (int) (y), image.getWidth(), image.getHeight(), Color.black, null);
} catch (IOException e) {
log.error("Cannot load image {}", imagePath);
}
}
state.cursorDown(state.getMax() + getCategoryLabelPositionOffset());
return state;
}
}
@Override
public void customize(JFreeChart chart, JRChart jasperChart) {
CategoryPlot plot = chart.getCategoryPlot();
CategoryAxis categoryAxis = new CategoryAxisWithImages(plot.getDomainAxis().getLabel());
plot.setDomainAxis(categoryAxis);
}
}
在 JasperReport JRXML 中,您可以像这样注册定制器 class:
<barChart>
<chart customizerClass="cz.trask.experiment.jr.CategoryAxisWithImagesCustomizer"
isShowLegend="false">
<reportElement x="0" y="0" width="550" height="348" uuid="a2cbb6b5-a76d-469b-8e8e-daa533260f20"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend/>
</chart>
...
</barChart>
我的例子的结果是: