# Reports combined Bar/Line chart

**URL:** <https://forum.inductiveautomation.com/t/reports-combined-bar-line-chart/114559>\
**Category:** Ignition\
**Tags:** reporting, ignition81, perspective\
**Created:** [March 18, 2026, 8:06pm UTC](https://forum.inductiveautomation.com/t/reports-combined-bar-line-chart/114559 "2026-03-18T20:06:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [March 18, 2026, 8:06pm UTC](https://forum.inductiveautomation.com/t/reports-combined-bar-line-chart/114559/1 "2026-03-18T20:06:51Z")

</div>

I have a chart in Perspective that I’m trying to replicate in a PDF report:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/f/1/f13e701651180bf70d425e7dd8d018b4ee3813d1.jpeg)

Problem is, the Bar Chart doesn’t allow for the trend lines, and the XY/Timeseries charts can combine bars and lines, but I can’t figure out how to get the bars to render side-by-side instead of overlapping…

---

<div class="post-metadata">

**Author:** ![Ryan\_Deardorff](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan_deardorff/32/63815_2.png) [@Ryan\_Deardorff](https://forum.inductiveautomation.com/u/Ryan_Deardorff)\
**Post date:** [March 23, 2026, 3:48pm UTC](https://forum.inductiveautomation.com/t/reports-combined-bar-line-chart/114559/2 "2026-03-23T15:48:19Z")

</div>

Thanks to help from Claude, I figured out how to get the bars separated in a TimeseriesChart using a “clustered” bar renderer:

```python
def configureChart(data, chart):
	from org.jfree.chart.renderer.xy import ClusteredXYBarRenderer, StandardXYBarPainter, XYBarRenderer
	from java.awt import Color, BasicStroke

	plot = chart.getPlot()
	
	# Only replace renderers that are already bar renderers
	for idx in range(plot.getRendererCount()):
		r = plot.getRenderer(idx)
		if isinstance(r, XYBarRenderer):
			ds = plot.getDataset(idx)
			newRenderer = ClusteredXYBarRenderer(3, False)
			newRenderer.setBarPainter(StandardXYBarPainter())
			newRenderer.setShadowVisible(False)
			newRenderer.setDrawBarOutline(True)
			newRenderer.setBaseOutlinePaint(Color.WHITE)
			newRenderer.setBaseOutlineStroke(BasicStroke(1.0))
			
			if ds is not None:
				for i in range(ds.getSeriesCount()):
					paint = r.getSeriesPaint(i)
					if paint is not None:
						newRenderer.setSeriesPaint(i, paint)
					stroke = r.getSeriesStroke(i)
					if stroke is not None:
						newRenderer.setSeriesStroke(i, stroke)
			
			plot.setRenderer(idx, newRenderer)

```

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/6/06076c40658fd186f0ce6aa93ecee972299e771f.png)
