Hi Marcus,
The only way to achieve this is to use the custom painting feature. The following code shows how to select points based on polygon that the user can input by pressing the Ctrl key and then clicking on the chart - you can use the same technique to paint the polygon on the chart as well:
public partial class Form1 : Form
{
public List<NPointF> m_SelectionPoints = new List<NPointF>();
NPointSeries m_PointSeries;
bool m_ControlKey;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
NChart chart = nChartControl1.Charts[0];
// create a point series and add some dummy data
m_PointSeries = new NPointSeries();
chart.Series.Add(m_PointSeries);
m_PointSeries.DataLabelStyle.Visible = false;
m_PointSeries.UseXValues = true;
Random rand = new Random();
for (int i = 0; i < 20; i++)
{
m_PointSeries.Values.Add(rand.Next(100));
m_PointSeries.XValues.Add(rand.Next(100));
}
// subscribe to paint callback from the control (will be used for custom painting)
chart.PaintCallback = new NCustomPaintCallback(this);
// subscribe to key events
nChartControl1.KeyDown += new KeyEventHandler(nChartControl1_KeyDown);
nChartControl1.KeyUp += new KeyEventHandler(nChartControl1_KeyUp);
nChartControl1.MouseDown += new MouseEventHandler(nChartControl1_MouseDown);
}
/// <summary>
/// Handle key up event. In case key up is control, transform the collected points to
/// scale coordinates and check which points from the point series fall in the selected polygon.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void nChartControl1_KeyUp(object sender, KeyEventArgs e)
{
if (!m_ControlKey)
return;
// release mouse capture
this.nChartControl1.Capture = false;
m_ControlKey = false;
m_PointSeries.FillStyles.Clear();
if (m_SelectionPoints.Count >= 3)
{
// transform points from view to scale coordinates
NViewToScale2DTransformation view2Scale = new NViewToScale2DTransformation(
nChartControl1.View.Context,
nChartControl1.Charts[0],
(int)StandardAxis.PrimaryX,
(int)StandardAxis.PrimaryY);
NPolygonF polygon = new NPolygonF();
for (int i = 0; i < m_SelectionPoints.Count; i++)
{
NVector2DD pointScale = new NVector2DD();
view2Scale.Transform(m_SelectionPoints[i], ref pointScale);
polygon.Vertices.Add(new NPointF((float)pointScale.X, (float)pointScale.Y));
}
// if a point is contained in the selection polygon mark it as red
for (int i = 0; i < m_PointSeries.Values.Count; i++)
{
float pointY = (float)(double)m_PointSeries.Values[i];
float pointX = (float)(double)m_PointSeries.XValues[i];
if (polygon.Contains(new NPointF(pointX, pointY), System.Drawing.Drawing2D.FillMode.Alternate))
{
m_PointSeries.FillStyles[i] = new NColorFillStyle(Color.Red);
}
}
}
// clear selection points and trigger repaint
m_SelectionPoints.Clear();
nChartControl1.Refresh();
}
void nChartControl1_KeyDown(object sender, KeyEventArgs e)
{
// in case of control key - capture mouse and start tracking mouse downs
m_ControlKey = e.Control;
if (m_ControlKey)
{
this.nChartControl1.Capture = true;
}
}
void nChartControl1_MouseDown(object sender, MouseEventArgs e)
{
// if mouse down in place check if this is a control key and
// add the point to the selection points array + trigger repaint
if (m_ControlKey)
{
m_SelectionPoints.Add(new NPointF(e.X, e.Y));
nChartControl1.Invalidate();
}
}
}
class NCustomPaintCallback : NPaintCallback
{
public NCustomPaintCallback(Form1 form)
{
m_Form = form;
}
/// <summary>
/// Handles after paint event for the chart panel
/// </summary>
/// <param name="panel"></param>
/// <param name="eventArgs"></param>
public override void OnAfterPaint(NPanel panel, NPanelPaintEventArgs eventArgs)
{
if (m_Form.m_SelectionPoints.Count < 3)
return;
// paint a polygon in case more than three points
NPointF[] points = m_Form.m_SelectionPoints.ToArray();
eventArgs.Graphics.PaintPolygon(
new NColorFillStyle(Color.FromArgb(125, Color.LightBlue)),
new NStrokeStyle(1, Color.Black),
points);
}
Form1 m_Form;
}
Hope this helps - let me know if you meet any problems.
Best regards,
Bob