# Change each bar width in histogram chart

**URL:** <https://forum.inductiveautomation.com/t/change-each-bar-width-in-histogram-chart/66847>\
**Category:** Ignition\
**Tags:** vision, scripting\
**Created:** [November 23, 2022, 11:49am UTC](https://forum.inductiveautomation.com/t/change-each-bar-width-in-histogram-chart/66847 "2022-11-23T11:49:56Z")\
**Posts on this page:** 1\
**Showing post:** 33

<div class="post-metadata">

**Author:** ![justinedwards.jle](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/justinedwards.jle/32/37854_2.png) [@justinedwards.jle](https://forum.inductiveautomation.com/u/justinedwards.jle)\
**Post date:** [December 1, 2022, 9:00pm UTC](https://forum.inductiveautomation.com/t/change-each-bar-width-in-histogram-chart/66847/33 "2022-12-01T21:00:49Z")

</div>

I played around with this a little more this morning, and came up with a more flexible approach to changing the tick labels.

First, I added the following method to the beginning of the configureChart extension function to hide the stock labels and create a set of new labels to take their place:

```auto
	def dynamicLabelCreator(self, chart, rawData):
		domainAxis = chart.getCategoryPlot().getDomainAxis()
		for row, category in enumerate(chart.getCategoryPlot().getCategories()):
			for component in self.getComponents():
					if isinstance(component, PMILabel) and component.name == category:
						self.remove(component)
			domainAxis.setTickLabelPaint(category, Color(0,0,0,0))
			customLabel = PMILabel()
			labelName = category
			customLabel.setName(labelName)
			customLabel.setVisible(True)
			self.add(customLabel)
	rawData = self.rawData
	dynamicLabelCreator(self, chart, rawData)

```

Then, I set the stock labels to a 90 degree orientation to give myself more room at the bottom of the chart, and while experimenting, I found that the bars rendered better if I set the lower margin of the category axis to .1

Finally, I modified the calculateW0 method to set the labels based on the center of the bar minus 1/2 the width of the label. Initially, the result looked good, but as I added more bars, the labels began to overlap:

 ![Overlap](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/7/178e28f803c09f6ccf6e849fc80706a1e999a2ff.png)  
Consequently, I reduced the number of line breaks, and changed the rotation of the labels. I also decided to go ahead and employ an innate label generator to put the actual values on top of the bars:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/e/8e04ff9828950ff1079f44932caa9b2e3d6f46df.png)

Below is the full code. I am certain this will still require quite a bit of tweaking, changing, and refactoring to produce an acceptable product for your usage case, but there should be more than enough directions here to go off of. **Good Luck!**

> **Full Code:**
>
> ```auto
> def configureChart(self, chart):
> from com.inductiveautomation.factorypmi.application.components import PMILabel
> from java.awt import Color
> from org.jfree.chart.renderer.category import BarRenderer, StandardBarPainter
> from java.text import NumberFormat
> from org.jfree.chart.labels import StandardCategoryItemLabelGenerator
> def dynamicLabelCreator(self, chart, rawData):
> domainAxis = chart.getCategoryPlot().getDomainAxis()
> for row, category in enumerate(chart.getCategoryPlot().getCategories()):
> for component in self.getComponents():
> if isinstance(component, PMILabel) and component.name == category:
> self.remove(component)
> domainAxis.setTickLabelPaint(category, Color(0,0,0,0))
> customLabel = PMILabel()
> labelName = category
> customLabel.setName(labelName)
> customLabel.setVisible(True)
> customLabel.rotation = 290
> self.add(customLabel)
> rawData = self.rawData
> dynamicLabelCreator(self, chart, rawData)	
> chart.setTitle("Histogram")
> data = self.data
> padding = self.width * .25
> width = self.width - padding
> maxTimeValue = data.getRowCount()-1
> chartStartTime = data.getValueAt(0,0)
> chartEndTime = data.getValueAt(maxTimeValue,0)
> totalTime = system.date.minutesBetween(chartStartTime,chartEndTime)
> timeRatio = float(width)/float(totalTime)
> scaleRatio = float(self.width)*0.018
> class DynamicWidthRenderer(BarRenderer):
> def	calculateBarW0(BarRenderer, plot, orientation, dataArea, domainAxis, state, row, column):
> from com.inductiveautomation.factorypmi.application.components import PMILabel
> barStartTime = data.getValueAt(column,0)
> barStartingLocation = float(system.date.minutesBetween(chartStartTime, barStartTime))*timeRatio + padding * .5
> customLabel = self.getComponent(column)
> try:
> barEndTime = data.getValueAt((column + 1), 0)
> barScaleParameter = float(system.date.minutesBetween(barStartTime, barEndTime))*scaleRatio
> customLabel.text = '<html><b><center>WO# ' + str(self.rawData.getValueAt(column,1)) + '<br>' + str(system.date.format(barStartTime, "MM/dd HH:mm:ss")) + '<br>to ' + str(system.date.format(barEndTime, "HH:mm:ss"))
> labelOffset = customLabel.width * .5
> labelLocation = barStartingLocation+((float(system.date.minutesBetween(barStartTime, barEndTime))*.5)*timeRatio)-labelOffset
> except:
> barScaleParameter = float(width + padding - barStartingLocation)*scaleRatio
> customLabel.text = '<html><b><center>WO# ' + str(self.rawData.getValueAt(column,1)) + '<br>' + str(system.date.format(barStartTime, "MM/dd HH:mm:ss")) + '<br>to ' + '[...]'
> labelOffset = customLabel.width * .5
> labelLocation = barStartingLocation - (.5 * labelOffset)
> heightJustification = float(len(chart.getCategoryPlot().getCategories()[column]))*9
> customLabel.setLocation(int(labelLocation), self.height - int(heightJustification))
> customLabel.setSize(250,250)		
> dataArea.width = barScaleParameter
> BarRenderer.calculateBarWidth(plot, dataArea, 0, state)
> return barStartingLocation			
> def getItemPaint(BarRenderer, row, column):
> if column % 2 == 0:
> return Color.blue
> else:
> return Color.yellow
> chart.getCategoryPlot().setRenderer(DynamicWidthRenderer())
> numberFormat = NumberFormat.getInstance()
> defaultFormat = StandardCategoryItemLabelGenerator.DEFAULT_LABEL_FORMAT_STRING
> labelGenerator = StandardCategoryItemLabelGenerator(defaultFormat, numberFormat)
> chart.getCategoryPlot().getRenderer().setBaseItemLabelGenerator(labelGenerator)
> chart.getCategoryPlot().getRenderer().setBaseItemLabelsVisible(True)
> chart.getCategoryPlot().getRenderer().setBarPainter(StandardBarPainter())
> chart.getCategoryPlot().getRenderer().setShadowVisible(False)
> 
> ```

---

_[View the full topic](https://forum.inductiveautomation.com/t/change-each-bar-width-in-histogram-chart/66847)._
