Change each bar width in histogram chart

Hi,
I am using this script to change the bar width.

"""
	from org.jfree.chart.renderer.category import StandardBarPainter                   
	from org.jfree.chart.labels import StandardCategoryItemLabelGenerator
	from java.awt import Font
	from java.awt import Color
	plot = chart.getPlot()
	renderer = plot.getRenderer()
	    
	renderer.setMaximumBarWidth(0.50)

But i want to change the each bar width separately

can any one please give me idea

This looks like you are working with Vision. Can you add the tag to your question to make it clear and give the exact name of the component you are using.

1 Like

Any idea u have?

The bar widths are calculated automatically by the renderer. Based on the plot width and the dataset provided. The maximum Bar width is used to limit the size of the bar if the number of bars is small enough that the entire plot width would not be used.

I suppose that you could potentially extend the BarRenderer class, but that would be a complicated undertaking to say the least.

What exactly are you trying to accomplish? What would the bar width represent?

1 Like

Ok i will explain you have
start time and end time for each data i have

Soo i want to show is

6am to 7pm one bar and 7 to 7:30 one bar
Soo bar width should change accordingly based on the time frame

How to achieve this ?

I don’t know in this case how to pass datasets to the. Chart

1 Like

@lrose My explanation is clear?

Your explanation is understood, and this seems like an interesting problem. Can we see an example dataset and an example chart?

@prasath.t - It certainly looks like this is possible. To get you started, below is an example of how to extend the BarRenderer class using the configureChart extension function. In the example, I use a variable called barStartingLocation to set the beginning point of each bar, and then I use a barScaleParameter to adjust the width of the bar. For both variables, I have just stuck in numbers to illustrate the effect, but it shouldn't be too difficult to develop a way to loop through each row in the chart's dataset and dynamically adjust these variables. I have also added code to change the color of each bar to make it easier to see what is actually being accomplished.

Here is the code:

	from org.jfree.chart.renderer.category import BarRenderer, StandardBarPainter
	from java.awt import Color
	chart.setTitle("Histogram")
	class DynamicWidthRenderer(BarRenderer):
		def	calculateBarW0(BarRenderer, plot, orientation, dataArea, domainAxis, state, row, column):
			if column == 0:
				barStartingLocation = 82
				barScaleParameter = 100
				dataArea.width = barScaleParameter
				BarRenderer.calculateBarWidth(plot, dataArea, 0, state)
				return barStartingLocation
			elif column == 1:
				barStartingLocation = 100
				barScaleParameter = 600
				dataArea.width = barScaleParameter
				BarRenderer.calculateBarWidth(plot, dataArea, 0, state)
				return barStartingLocation
			elif column == 2:
				barStartingLocation = 212
				barScaleParameter = 2600
				dataArea.width = barScaleParameter
				BarRenderer.calculateBarWidth(plot, dataArea, 0, state)
				return barStartingLocation
			else:
				barStartingLocation = 699
				barScaleParameter = 867.030849457
				dataArea.width = barScaleParameter
				BarRenderer.calculateBarWidth(plot, dataArea, 0, state)
				return barStartingLocation
		def getItemPaint(BarRenderer, row, column):
			if column == 0:
				return Color.orange
			elif column == 1:
				return Color.gray
			elif column == 2:
				return Color.red
			else:
				return Color.blue
	chart.getCategoryPlot().setRenderer(DynamicWidthRenderer())
	chart.getCategoryPlot().getRenderer().setBarPainter(StandardBarPainter())
	chart.getCategoryPlot().getRenderer().setShadowVisible(False)

The preceding code produces the following result:

1 Like

great can you please share me the example dataset.

i need to see how you created the dataset please

I didn't spend any time on that. I copied a bar chart onto my test window and used the sample data that was already there. The only modification I made was to delete the two stock x axis columns. These, I replaced with a single time column that I simply threw some random times into. I also deleted one of the rows because four bars seemed like the right number for the illustration.

Obviously, the code I developed for this post will require significant further development for your usage case, but even though it's not a finished product, it does at least demonstrate a way that this can be done; I sincerely hope that it helps you.

1 Like

Yes , Based on the time range we need to adjust the bar location and width. i will try it out

Hi @justinedwards.jle I tired to change the bar location based on timestamp of the dataset. But i could not able to achieve it.

If you found any idea to do that please let me know

Show your code.

You're basically in uncharted territory here (as I could find no example of a standard chart that uses this method). Since only you know what you are looking for, and you're basically writing a renderer from scratch, it's going to take some time and effort.

If you show us some code and an explanation of what you expected to happen and what actually happened, then maybe we can help you figure out why it didn't work the way you expected.

1 Like

@prasath.t - Also, provide a sample dataset. This would be most useful for knowing what's needed to adapt the custom render.

image

actually this is the dataset. updated time is start time, End time of the one work order will be the starting time of the next work order

example chart how it's look

based on the work order we are showing the data

But now what i want is based on the start and end time of the work order i need to resize the width of the each bar

i don't know based on the time how to resize the each bar. please help me out

There are two y-axis and overlapping bars; is this intentional? The work order numbers are being listed along the x-axis, where--being a histogram--I had anticipated datetimes being depicted; is this intentional as well? Ideally, what do you want depicted on the x and y axis?

Will probably need an additional X-Axis for the time?

You still didn't show any code where you have tried to implement this.

If you look at what @justinedwards.jle showed as an example you can see that the dataArea.width is used to scale the width of the Bar in the BareRenderer.calculateBarWidth() function. The problem here is that you need to somehow calculate that width based on where the timestamp would reside on the domain axis, and right now you would need to look at data "presumably" in the future, this can be done but the last bar will run into the edge of the chart as it would still be "in progress".

There is a lot that goes into accurately plotting data in this manner.

2 Likes

Here's an idea on how to circumvent this problem:
Since we're generating a renderer from scratch, we could possibly use a label generator to stick the work order numbers in a label centered above each bar.

2 Likes

Code same what justin given i tried adjusting it couldn’t able to solve it that’s why

Any example code please

How to adjust the width based on the timeframe