Adding a custom interactor to a line chart view

Hi,

I am relatively new to Paraview and I need some help in figuring out how to add an interactor to a line chart view. I am working directly from the Paraview (Windows) UI and I am attempting to add an interactor by loading a state. If this is not the right way to do it, I would appreciate any help. Here’s what I have done so far:

I have created a state (in Python) which sets up my charts; some code which transforms data before plotting is not shown:

    """Create Charts"""
    chart1 = CreateXYPlotView()
    chart1.ChartTitle = ''
    chart1.ViewSize = [400, 150]
    chart1.LegendPosition = [595, 690]
    chart1.LeftAxisTitle = 'Title 1'
    chart1.BottomAxisTitle = 'Time(hh:mm:ss)'
    chart1.BottomAxisUseCustomLabels = 1

    # Create a new 'Line Chart View'
    chart2 = CreateView('XYChartView')
    chart2.ViewSize = [400, 150]
    chart2.LegendPosition = [499, 255]
    chart2.LeftAxisTitle = 'Annotations'
    chart2.BottomAxisTitle = 'Time(hh:mm:ss)'
    chart2.BottomAxisUseCustomLabels = 1
    chart2.LeftAxisUseCustomLabels = 1
    chart2.LeftAxisLabels = ['10','Annotation1', '20','Annotation2']
 
    """ Add to layout """
    layout1 = CreateLayout(name='Layout #1')
    layout1.SplitVertical(0, 0.500000)
    layout1.AssignView(1, chart1)
    layout1.AssignView(2, chart2)
    layout1.SetSize(400, 300)

    """Read Data and add to charts <Code not shown>"""
       chart1DataDisplay = Show(EBPlot, chart1, 'XYChartRepresentation')
       chart2DataDisplay = Show(EBPlot, chart2, 'XYChartRepresentation')

The state I have works perfectly and it plots data as I expect it to. However, I am using custom time labels on the BottomAxis and I want to update them based on Mouse Movement.

Using the Python Shell in Paraview I am able to remove all the appropriate mouse related observers.

    interactor = GetActiveView().SMProxy.GetRenderWindow().GetInteractor()
    interactor.RemoveObservers("LeftButtonPressEvent")
    interactor.RemoveObservers("MouseMoveEvent")
    interactor.RemoveObservers("RightButtonPressEvent")

    interactor.AddObserver("LeftButtonPressEvent",callback)

    def callback(obj,event):
        print(event)

However, adding this to the state code crashes Paraview.

Ideally I would like to create a class with the render views and interactors, so that I can manipulate the view better. Is there a way of doing this by loading state?

I somewhat figured out how to do this. The solution is to create a filter that will identify the source that needs to be plotted and takes care of the plotting. Hope this helps someone.

Snippet of the solution:

from paraview.util.vtkAlgorithm import *

#### import the simple module from the paraview
from paraview.simple import *
from paraview.servermanager import *
#### disable automatic camera reset on 'Show'
paraview.simple._DisableFirstRenderCameraReset()

@smproxy.filter()
@smproperty.input(name="Input")
@smdomain.datatype(dataTypes=["vtkTable"], composite_data_supported=True)
class PlotFilter(VTKPythonAlgorithmBase):
    def __init__(self):
        super().__init__(nInputPorts=1, nOutputPorts=1, outputType="vtkTable")

   def callback(self, object, event):
        print(object.GetLastEventPosition())

    def _plotData():
        """Fill in with plotting information"""
        chart1 = CreateXYPlotView()
        chart1.ChartTitle = ''
        chart1.ViewSize = [400, 150]
        chart1.LegendPosition = [595, 690]
        chart1.LeftAxisTitle = 'Title 1'
        chart1.BottomAxisTitle = 'Time(hh:mm:ss)'
        """PlotData() and Show() to create representation and show the plot"""        

        interactor = chart1.SMProxy.GetRenderWindow().GetInteractor()
        interactor.RemoveObservers("LeftButtonPressEvent")
        interactor.RemoveObservers("MouseMoveEvent")
        interactor.RemoveObservers("RightButtonPressEvent")

        interactor.AddObserver("LeftButtonPressEvent",self.callback)
       
    def RequestData(self, request, inInfoVec, outInfoVec):
        self._plotData()
        return 1
    
    def RequestInformation(self, request, inInfoVec, outInfoVec):
        executive = self.GetExecutive()
        outInfo = outInfoVec.GetInformationObject(0)
        return 1