# Vision Chart - Multiple markers and movable

**URL:** <https://forum.inductiveautomation.com/t/vision-chart-multiple-markers-and-movable/92689>\
**Category:** General Discussion\
**Tags:** perspective, vision\
**Created:** [July 2, 2024, 3:12pm UTC](https://forum.inductiveautomation.com/t/vision-chart-multiple-markers-and-movable/92689 "2024-07-02T15:12:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Overcraft31](https://avatars.discourse-cdn.com/v4/letter/o/5f9b8f/32.png) [@Overcraft31](https://forum.inductiveautomation.com/u/Overcraft31)\
**Post date:** [July 2, 2024, 3:12pm UTC](https://forum.inductiveautomation.com/t/vision-chart-multiple-markers-and-movable/92689/1 "2024-07-02T15:12:41Z")

</div>

Hello,

I try to make markers in Vision's chart working like range brush in Perspective's chart:

- Set 2 markers on the chart by clicking on it
- 2 markers are movable by dragging the mouse
- I want to calculate min/max/average for the data between this 2 markers

I have looked for Markers and IntervalMarkers in JFreeChart library, but they are not movable easily: I can une mouse pressed event to select a marker and mouse released to change its possition, but it seems to be a complex solution.

Do you have any idea about this functionnality please? 🙂

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 2, 2024, 4:09pm UTC](https://forum.inductiveautomation.com/t/vision-chart-multiple-markers-and-movable/92689/2 "2024-07-02T16:09:34Z")

</div>

It is complex. I have a 3rd party module that makes this relatively easy:

> [@NoteChart Module v2 with Reporting](https://forum.inductiveautomation.com/t/notechart-module-v2-with-reporting/61404):
>
> Automation Professionals is pleased to announce a release candidate for its NoteChart Module, now with support for annotations on charts in the Reporting module. This module determines if either Vision or Reporting is installed (or both) and adds its components to the corresponding designer palettes. The new ReportNoteChart component functions like the native [Timeseries Chart](https://docs.inductiveautomation.com/display/DOC81/Report+Charts#ReportCharts-TimeseriesChart), but with the data key property and other properties needed to display timestamped annotations. Documentation is [here](https://www.automation-pros.com/notechart/doc/index.html). …

With this module, you would set one marker timestamp in the `notes` dataset property to show a reference timestamp, then use the chart's (revamped) XTrace mode to control the 2nd timestamp. Both would be true Ignition datetime values that you can then feed to the historian to get the detailed information for the timespan.

---

<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:** [July 4, 2024, 4:36am UTC](https://forum.inductiveautomation.com/t/vision-chart-multiple-markers-and-movable/92689/3 "2024-07-04T04:36:44Z")

</div>

> [@Overcraft31](#):
>
> Do you have any idea about this functionnality

This doesn't seem like it would be that difficult to develop. The chart comes with every mouse event handler, so it's a simple matter of adding an interval marker using the mouse position, and then performing calculations within the interval.

**Example:**  
Start by adding a couple of custom properties to the parent container of the chart to store the start date and end date as millis for the interval marker:  
 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/5/8/585c9a2dfc56a98649173f0267c0815b60f15507.png)

Store the starting point on the mousePressed event:

```python
# Reset the marking process and set a new starting point
event.source.parent.endingPoint == None
event.source.chart.plot.clearDomainMarkers()
dataArea = event.source.chartRenderingInfo.plotInfo.dataArea
event.source.parent.startingPoint = event.source.chart.plot.domainAxis.java2DToValue(event.x, dataArea, event.source.chart.plot.domainAxisEdge)

```

Use the mouseDragged event handler to store the end point:

```python
# Clear the domain marker, recalculate where it should be, and repaint it on the chart
from org.jfree.chart.plot import IntervalMarker
event.source.chart.plot.clearDomainMarkers()
dataArea = event.source.chartRenderingInfo.plotInfo.dataArea
event.source.parent.endingPoint = event.source.chart.plot.domainAxis.java2DToValue(event.x, dataArea, event.source.chart.plot.domainAxisEdge)

# Flip the starting and ending points of the interval marker if the drag event is moving from right to left
startingPoint = min(event.source.parent.startingPoint, event.source.parent.endingPoint)
endingPoint = max(event.source.parent.startingPoint, event.source.parent.endingPoint)

# Add the interval marker
event.source.chart.plot.addDomainMarker(IntervalMarker(startingPoint, endingPoint, system.gui.color(20, 10, 10, 40)))

```

Finally, run the necessary calculations on the mouse released event:

```python
# If the mouse dragged event occured to create a marked area, run the calculations
if event.source.parent.endingPoint:
	# Reverse the starting and ending points if the mouse dragged event was from right to left
	startingPoint = min(event.source.parent.startingPoint, event.source.parent.endingPoint)
	endingPoint = max(event.source.parent.startingPoint, event.source.parent.endingPoint)
	
	# Calculate the min, max, and average for all values that correspond to dates that are within the marked interval
	data = event.source.Data
	headers = system.dataset.getColumnHeaders(data)
	startDate = system.date.fromMillis(int(startingPoint))
	endDate = system.date.fromMillis(int(endingPoint))
	for column in xrange(1, data.columnCount):
		header = headers[column]
		values = []
		for row in xrange(data.rowCount):
			if startDate <= data.getValueAt(row, 0) <= endDate:
				values.append(data.getValueAt(row, column))
		
		print startDate, ' to ', endDate
		print header, 'minValue:', min(values)
		print header, 'maxValue:', max(values)
		print header, 'avgValue:', sum(values) / len(values)
		print

```

**Result:**  
 ![chartDemo](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/e/8e1115e5a28f1ea0fe04c91ec7d3794bf6698bba.gif)

**Sample Output:**

```python
Fri Jun 28 04:53:53 CDT 2024 to Sun Jun 30 10:53:32 CDT 2024
Process Temp minValue: 74
Process Temp maxValue: 114
Process Temp avgValue: 90

Fri Jun 28 04:53:53 CDT 2024 to Sun Jun 30 10:53:32 CDT 2024
Output Temp minValue: 0
Output Temp maxValue: 16
Output Temp avgValue: 6

```

---

<div class="post-metadata">

**Author:** ![Overcraft31](https://avatars.discourse-cdn.com/v4/letter/o/5f9b8f/32.png) [@Overcraft31](https://forum.inductiveautomation.com/u/Overcraft31)\
**Post date:** [July 4, 2024, 7:54am UTC](https://forum.inductiveautomation.com/t/vision-chart-multiple-markers-and-movable/92689/4 "2024-07-04T07:54:02Z")

</div>

Wow thank you so much! That is exactly what I needed 🙂

Solution tested and approuved 👍

@pturmel : I'll take a look at your module, but right now I need only home made solutions because we are doing a POC with Ignition 🙂
