Existing mouse events connecting with own mouse events

A forum dedicated to WinForms version of LightningChart Ultimate.

Moderator: Arction_LasseP

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Existing mouse events connecting with own mouse events

Post by Felix » Wed Nov 06, 2013 7:55 am

I have created a Grid Series 3D Surface Chart and Intensity Grid Series Chart.
I now want to use both the standard mouse events, to move the object, as well as my own events.
To use my own events I have the property "MouseInteraction" to true, but now no default events are executed more.

What can I do to solve the problem.
Last edited by Felix on Tue Nov 12, 2013 8:44 am, edited 1 time in total.

User avatar
ArctionPasi
Posts: 1366
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Existing mouse events link with own mouse events

Post by ArctionPasi » Wed Nov 06, 2013 2:24 pm

Hi Felix,

if you define chart.MouseMove event like this:
chart.MouseMove += new MouseEventHandler(m_chart_MouseMove);

void m_chart_MouseMove(object sender, MouseEventArgs e)
{
System.Diagnostics.Debug.WriteLine("mouse moved "+DateTime.Now.ToLongTimeString());
}

The MouseMove event fires and string is outputted in VS output window every time you move the mouse over the chart, dispite of surface.MouseInteraction or instensityGrid.MouseInteraction setting.

Or... are you talking about chart.MouseInteraction setting? It will block all mouse events and you shouldn't use it. Instead, disable the MouseInteraction from LC's objects.

I hope this helps :freak:
LightningChart Support Team, PT

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Re: Existing mouse events link with own mouse events

Post by Felix » Wed Nov 06, 2013 2:54 pm

Hi Pasi,

I use the following events:
chart.MouseDown += chart_MouseDown;
chart.MouseUp += chart_MouseUp;
chart.MouseDoubleClick += chart_MouseDoubleClick; -> This is used to switch from "SurfaceGridSeries3D" to "IntensityGridSeries".

intensityGridSeries.MouseInteraction = false; -> Set this property by the event is not called, but it runs the desired default behavior.
intensityGridSeries.MouseTraceCellChanged += intensityGridSeries_MouseTraceCellChanged; -> This is used to display the current position of the point to sense on which of the cursor is

surfaceGridSeries3D.MouseInteraction = false; -> Set this property by the event is not called, but it runs the desired default behavior.
surfaceGridSeries3D.MouseTraceCellChanged += surfaceGridSeries3D_MouseTraceCellChanged; -> This is used to display the current position of the point to sense on which of the cursor is.

User avatar
ArctionPasi
Posts: 1366
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Existing mouse events link with own mouse events

Post by ArctionPasi » Wed Nov 06, 2013 6:03 pm

Could you send me a reduced project which I can use to reproduce the problem, please? :|
LightningChart Support Team, PT

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Re: Existing mouse events link with own mouse events

Post by Felix » Thu Nov 07, 2013 9:10 am

Hi Pasi,

Here is the code, hope it is understandable?
You just need to create a form and add the code, then it should be executable.

Code: Select all

#region Members


private List<double> _xAxisCoordinates;
private List<double> _yAxisCoordinates;
private List<double> _hardnessValueList;

private bool _isRightMouseButtonPressed;


#endregion Members

#region Constructors


public Form1()
{
	InitializeComponent();

	chart.ActiveView = ActiveView.ViewXY;
	chart.RenderOptions.AntiAliasLevel = 4;
	chart.RenderOptions.MultiCoreProcessing = MultiCoreProcessing.AllAvailableCores;
	chart.Parent = this;

	chart.ViewXY.LegendBox.Layout = LegendBoxLayout.Vertical;

	chart.View3D.LegendBox.Layout = LegendBoxLayout.Vertical;
	chart.View3D.LegendBox.Fill.Style = RectFillStyle.None;
	chart.View3D.LegendBox.Shadow.Visible = false;
	chart.View3D.LegendBox.BorderWidth = 0;

	// **************************************************************************

	// Chart Maus Events
	chart.MouseDown += chart_MouseDown;
	chart.MouseUp += chart_MouseUp;
	chart.MouseDoubleClick += chart_MouseDoubleClick;

	// **************************************************************************
}


#endregion Constructors

#region Properties


public bool IsHeatMapDisplayed
{
	get
	{
		return chart.ActiveView.Equals(ActiveView.ViewXY);
	}

	set
	{
		if (value)
		{
			chart.ActiveView = ActiveView.ViewXY;
		}
		else
		{
			chart.ActiveView = ActiveView.View3D;
		}
	}
}


#endregion Properties

#region Methods


private static ValueRangePalette CreateColorPalette(ValueRangePalette palette, double rangeMinValue, double rangeMaxValue)
{
	#region CreateColorPalette


	double averageValue = (rangeMaxValue - rangeMinValue) / 2.0 + rangeMinValue;
	double stepValue = (rangeMaxValue - rangeMinValue) / 6.0;

	palette.Steps.Clear();
	palette.MinValue = rangeMinValue;
	palette.Type = PaletteType.Gradient;

	palette.Steps.Add(new PaletteStep(palette, Color.Transparent, -1));
	palette.Steps.Add(new PaletteStep(palette, Color.Black, 0));
	palette.Steps.Add(new PaletteStep(palette, Color.Blue, stepValue));
	palette.Steps.Add(new PaletteStep(palette, Color.Teal, stepValue * 2));
	palette.Steps.Add(new PaletteStep(palette, Color.LimeGreen, averageValue));
	palette.Steps.Add(new PaletteStep(palette, Color.Yellow, stepValue * 4));
	palette.Steps.Add(new PaletteStep(palette, Color.Red, stepValue * 5));
	palette.Steps.Add(new PaletteStep(palette, Color.White, rangeMaxValue));

	return palette;


	#endregion CreateColorPalette
}

private void Create3DChart(SurfacePoint[,] data)
{
	#region Create3DChart


	chart.View3D.Camera.RotationX = 45;
	chart.View3D.Camera.OrthographicCamera = true;

	chart.View3D.XAxisPrimary3D.SetRange(_xAxisCoordinates.Min<double>(), _xAxisCoordinates.Max<double>());
	chart.View3D.ZAxisPrimary3D.SetRange(_yAxisCoordinates.Min<double>(), _yAxisCoordinates.Max<double>());
	chart.View3D.YAxisPrimary3D.SetRange(_hardnessValueList.Min(), _hardnessValueList.Max());

	SurfaceGridSeries3D surfaceGrid = new SurfaceGridSeries3D(chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);

	// **************************************************************************

	// Mouse Events
	surfaceGrid.MouseInteraction = false; // For the default behavior // true for the mouse cursor coordinates
	surfaceGrid.MouseTraceCellChanged += surfaceGrid_MouseTraceCellChanged;

	// **************************************************************************

	surfaceGrid.SetRangesXZ(_xAxisCoordinates.Min<double>(), _xAxisCoordinates.Max<double>(), _yAxisCoordinates.Min<double>(), _yAxisCoordinates.Max<double>());
	surfaceGrid.SetSize(data.GetLength(0), data.GetLength(1));

	surfaceGrid.Data = data;
	surfaceGrid.InvalidateData();

	surfaceGrid.WireframeType = SurfaceWireframeType.Wireframe;
	surfaceGrid.ContourPalette = CreateColorPalette(new ValueRangePalette(surfaceGrid), _hardnessValueList.Min(), _hardnessValueList.Max());
	surfaceGrid.ContourLineType = ContourLineType.None;
	surfaceGrid.Fill = SurfaceFillStyle.Paletted;

	// Oberfläche dem Chart hinzufügen
	chart.View3D.SurfaceGridSeries3D.Clear();
	chart.View3D.SurfaceGridSeries3D.Add(surfaceGrid);


	#endregion Create3DChart
}

private void CreateHeatMap(IntensityPoint[,] data)
{
	#region CreateHeatMap


	chart.ViewXY.XAxes[0].ValueType = AxisValueType.Number;
	chart.ViewXY.YAxes[0].ValueType = AxisValueType.Number;
	chart.ViewXY.XAxes[0].SetRange(_xAxisCoordinates.Min<double>(), _xAxisCoordinates.Max<double>());
	chart.ViewXY.YAxes[0].SetRange(_yAxisCoordinates.Min<double>(), _yAxisCoordinates.Max<double>());

	IntensityGridSeries intensityGrid = new IntensityGridSeries(chart.ViewXY, chart.ViewXY.XAxes[0], chart.ViewXY.YAxes[0]);

	intensityGrid.SetRangesXY(_xAxisCoordinates.Min<double>(), _xAxisCoordinates.Max<double>(), _yAxisCoordinates.Min<double>(), _yAxisCoordinates.Max<double>());

	// **************************************************************************

	// Maus Events
	intensityGrid.MouseInteraction = false; // For the default behavior // true for the mouse cursor coordinates
	intensityGrid.MouseTraceCellChanged += intensityGrid_MouseTraceCellChanged;

	// **************************************************************************

	intensityGrid.Data = data;
	intensityGrid.InvalidateValuesDataOnly();

	intensityGrid.WireframeType = SurfaceWireframeType.Wireframe;
	intensityGrid.Fill = IntensityFillStyle.Paletted;
	intensityGrid.ValueRangePalette = CreateColorPalette(new ValueRangePalette(intensityGrid), _hardnessValueList.Min(), _hardnessValueList.Max());
	intensityGrid.ContourLineType = ContourLineType.None;

	chart.ViewXY.IntensityGridSeries.Clear();
	chart.ViewXY.IntensityGridSeries.Add(intensityGrid);


	#endregion CreateHeatMap
}

private static float[,] GetValueArray(int sizeX, int sizeY)
{
	#region GetDemoArray


	Random rand = new Random();
	float[,] array = new float[sizeX, sizeY];

	for (int iCol = 0; iCol < sizeX; iCol++)
	{
		for (int iRow = 0; iRow < sizeY; iRow++)
		{
			double result = 50.0 + 30.0 * Math.Sin(0.01 * (iCol * iRow)) + (rand.NextDouble() - 0.5) * 20.0;
			array[iCol, iRow] = (float)result;
		}
	}

	return array;


	#endregion GetDemoArray
}

private void GenerateDemoData(int arraySizeX, int arraySizeY, double xMin, double xMax, double zMin, double zMax, out SurfacePoint[,] surfacePointList, out IntensityPoint[,] intensityPointList)
{
	#region GenerateDemoData


	float[,] array = GetValueArray(arraySizeX, arraySizeY);

	surfacePointList = new SurfacePoint[arraySizeX * 2, arraySizeY * 2];
	intensityPointList = new IntensityPoint[arraySizeX * 2, arraySizeY * 2];

	_xAxisCoordinates = new List<double>();
	_yAxisCoordinates = new List<double>();
	_hardnessValueList = new List<double>();

	float y;
	float dXStep = (float)((xMax - xMin) / arraySizeX);
	float dZStep = (float)((zMax - zMin) / arraySizeY);
	float x1, x2, z1, z2;

	for (int iCol = 0; iCol < arraySizeX; iCol++)
	{
		for (int iRow = 0; iRow < arraySizeY; iRow++)
		{
			y = array[iCol, iRow];
			x1 = (float)(xMin + dXStep * iCol);
			x2 = (float)(xMin + dXStep * (iCol + 1));
			z1 = (float)(zMin + dZStep * iRow);
			z2 = (float)(zMin + dZStep * (iRow + 1));

			surfacePointList[iCol * 2, iRow * 2] = new SurfacePoint(x1, y, z1, Color.Black);
			surfacePointList[iCol * 2 + 1, iRow * 2] = new SurfacePoint(x2, y, z1, Color.Black);
			surfacePointList[iCol * 2, iRow * 2 + 1] = new SurfacePoint(x1, y, z2, Color.Black);
			surfacePointList[iCol * 2 + 1, iRow * 2 + 1] = new SurfacePoint(x2, y, z2, Color.Black);

			intensityPointList[iCol * 2, iRow * 2] = new IntensityPoint(x1, z1, y, Color.Black);
			intensityPointList[iCol * 2 + 1, iRow * 2] = new IntensityPoint(x2, z1, y, Color.Black);
			intensityPointList[iCol * 2, iRow * 2 + 1] = new IntensityPoint(x1, z2, y, Color.Black);
			intensityPointList[iCol * 2 + 1, iRow * 2 + 1] = new IntensityPoint(x2, z2, y, Color.Black);

			_xAxisCoordinates.Add(x1);
			_yAxisCoordinates.Add(z1);
			_hardnessValueList.Add(y);
		}
	}


	#endregion GenerateDemoData
}


#endregion Methods

#region Events


private void Form1_Load(object sender, EventArgs e)
{
	SurfacePoint[,] surfacePointList;
	IntensityPoint[,] intensityPointList;

	GenerateDemoData(25, 25, 0, 25, 0, 25, out surfacePointList, out intensityPointList);

	Create3DChart(surfacePointList);
	CreateHeatMap(intensityPointList);
}

private void chart_MouseDown(object sender, MouseEventArgs e)
{
	#region MouseClick


	switch (e.Button)
	{
		case MouseButtons.Right:
			{
				#region Right Button


				_isRightMouseButtonPressed = true;

				break;


				#endregion Right Button
			}
	}


	#endregion MouseClick
}

private void chart_MouseUp(object sender, MouseEventArgs e)
{
	#region MouseClick


	switch (e.Button)
	{
		case MouseButtons.Right:
			{
				#region Right Button


				// Flag reset
				_isRightMouseButtonPressed = false;

				// TODO:
				// Show context menu

				break;


				#endregion Right Button
			}
	}


	#endregion MouseClick
}

private void chart_MouseDoubleClick(object sender, MouseEventArgs e)
{
	#region MouseDoubleClick


	switch (e.Button)
	{
		case MouseButtons.Left:
			{
				#region Left Button


				IsHeatMapDisplayed = !IsHeatMapDisplayed;

				break;


				#endregion Left Button
			}
	}


	#endregion MouseDoubleClick
}

private void surfaceGrid_MouseTraceCellChanged(SurfaceSeries3DBase sender, int newColumn, int newRow)
{
	#region MouseTraceCellChanged


	if (_isRightMouseButtonPressed)
	{
		// TODO:
		// Do not show context menu
	}

	// TODO:
	// Show mouse cursor coordinates

	Console.WriteLine("Mouse Coordinates:");


	#endregion MouseTraceCellChanged
}

private void intensityGrid_MouseTraceCellChanged(IntensitySeriesBase sender, int mouseX, int mouseY, int newCellColumn, int newCellRow, int nearestDataColumnIndex, int nearestDataRowIndex, IntensityPoint nearestCornerPoint, float nearestDataColumnCoord, float nearestDataRowCoord)
{
	#region MouseTraceCellChanged

	
	if (_isRightMouseButtonPressed)
	{
		// TODO:
		// Do not show context menu
	}
	
	// TODO:
	// Show mouse cursor coordinates

	Console.WriteLine("Mouse Coordinates:");


	#endregion MouseTraceCellChanged
}


#endregion Events
:freak: :D

User avatar
ArctionPasi
Posts: 1366
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Existing mouse events link with own mouse events

Post by ArctionPasi » Thu Nov 07, 2013 10:41 pm

Your code is understandable (probably more clear than our own examples :? ), and I got it to run.

So you are wondering that if you set intensityGrid.MouseInteraction = false, or respectively the 3D equivalent surfaceGrid.MouseInteraction = false, you get no MouseCellTraceChanged events anymore? That's naturally the case if you make the series passive to mouse. All chart.MouseMove, DoubleClick etc. event work fine whether or not the series MouseInteraction is enabled.

And I'm still wondering what kind of handling you are after. Maybe keep the series passive-looking, without highlighting the series when you move the mouse over it?

To make the MouseCellTraceChanged event fire, and keep the series passive-looking, set intensityGrid and surfaceGrid.MouseHighlight = None, and keep MouseInteraction = true.
:geek:
LightningChart Support Team, PT

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Re: Existing mouse events link with own mouse events

Post by Felix » Fri Nov 08, 2013 7:47 am

Hi Pasi,

I want to use, as your example "Intensity grid mouse control" the mouse functions.
In the example, a cross-hair and a tooltip with the current position is displayed when the mouse movement.

In addition I would like to use the mouse functions as in the example "heat map".
In the "heat map" I can change the scale using the mouse.

The mouse features, both examples I would like to use in my chart.

;) :D

User avatar
ArctionPasi
Posts: 1366
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Existing mouse events link with own mouse events

Post by ArctionPasi » Fri Nov 08, 2013 2:51 pm

So, implement them based on our examples. Set Annotations there, and update them in MouseCellTraceChanged event. :shock:
LightningChart Support Team, PT

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Re: Existing mouse events link with own mouse events

Post by Felix » Mon Nov 11, 2013 3:04 pm

Hi Pasi,

I did not quite understand your answer.
I want to use the mouse functions of your examples.

I'm using a tooltip that displays the current coordinates when I move the mouse Coursor over the chart. To the coordinates of the tool tip I get to use the mouse event
"intensityGrid_MouseTraceCellChanged (IntensitySeriesBase sender, int mouseX, int mouseY, newCellColumn int, int newCellRow, nearestDataColumnIndex int, int nearestDataRowIndex, IntensityPoint nearestCornerPoint, nearestDataColumnCoord float, float nearestDataRowCoord)"
So that the event is triggered I put the object IntensityGridSeries that MouseInteraction property to true.
intensityGridSeries.MouseInteraction = true;
intensityGridSeries.MouseInteraction = true;
Chart with mouse move.jpg (182.56 KiB) Viewed 20758 times
I would also like the mouse scrolling event to move the chart object.
The move is possible with the right mouse button. To use this, I have set the MouseInteraction property to false, in the object IntensityGridSeries.
intensityGridSeries.MouseInteraction = false;
intensityGridSeries.MouseInteraction = false;
Chart move with right mouse click.jpg (169.99 KiB) Viewed 20758 times
My problem is that I would like to use both options.
I want to show tool tip on mouse move, and move the chart object when pressing the right mouse button.

User avatar
ArctionPasi
Posts: 1366
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Existing mouse events link with own mouse events

Post by ArctionPasi » Mon Nov 11, 2013 3:53 pm

The series mouse-interaction blocks the mouse event to be passed to the panning handler. That's the way it is in all of series in the chart.

To start the view panning over the grid, respond to chart.MouseDown event. In chart.MouseMoved event, call chart.ViewXY.Pan method. Supply the delta related to the previous Pan delta.

Alternatively, call axis.SetRange method in your chart mouse handlers. You can use axis.CoordToValue method to convert screen coordinate to axis values, axis.ValueToCoord to convert axis value to screen coordinate.

That's the way it can be done. :P
LightningChart Support Team, PT

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Re: Existing mouse events link with own mouse events

Post by Felix » Tue Nov 12, 2013 7:11 am

Can you provide me a code snippet available for the function? :geek:

User avatar
ArctionPasi
Posts: 1366
Joined: Tue Mar 26, 2013 10:57 pm
Location: Finland

Re: Existing mouse events connecting with own mouse events

Post by ArctionPasi » Wed Nov 13, 2013 8:01 am

This code does the panning from code, initiated with right mouse button over a mouse-interactive heatmap.

Code: Select all

m_chart.MouseDown += new MouseEventHandler(m_chart_MouseDown);
            m_chart.MouseUp += new MouseEventHandler(m_chart_MouseUp);
            m_chart.MouseMove += new MouseEventHandler(m_chart_MouseMove);



private int m_iMousePanStartX, m_iMousePanStartY;
        private bool m_bPanningByCode = false;
        private bool m_bIsOverHeatMap = false; 

void m_chart_MouseMove(object sender, MouseEventArgs e)
        {

            if (m_chart.ViewXY.IntensityGridSeries[0].IsMouseOver(e.X, e.Y))
            {
                m_bIsOverHeatMap = true;
                m_chart.ViewXY.ZoomPanOptions.RightMouseButtonAction = MouseButtonAction.None; 
            }
            else
            {
                m_bIsOverHeatMap = false; 
            }

            if (m_bPanningByCode)
            {
                m_chart.BeginUpdate(); 
                m_chart.ViewXY.Pan(-(e.X - m_iMousePanStartX), e.Y - m_iMousePanStartY);
                m_iMousePanStartX = e.X;
                m_iMousePanStartY = e.Y;
                m_chart.EndUpdate(); 

            }
        }

        void m_chart_MouseUp(object sender, MouseEventArgs e)
        {
            m_bPanningByCode = false;
            m_chart.ViewXY.ZoomPanOptions.RightMouseButtonAction = MouseButtonAction.Pan; 
        }



        void m_chart_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right && m_bIsOverHeatMap)
            {
                m_bPanningByCode = true;
                m_iMousePanStartX = e.X;
                m_iMousePanStartY = e.Y;
            } 
        }

:ugeek:
LightningChart Support Team, PT

Felix
Posts: 72
Joined: Tue Oct 29, 2013 8:10 am

Re: Existing mouse events connecting with own mouse events

Post by Felix » Wed Nov 13, 2013 8:45 am

Hi Pasi,

thanks, I've been thinking too complicated, the solution was quite simple.

:shock: :? :D