C # Добавить круг при проверке удара - PullRequest
0 голосов
/ 11 октября 2018

У меня есть работающее событие щелчка мышью на графике формы Windows, и теперь я хотел бы добавлять точки данных при каждом щелчке, чтобы было видно, где на графике он был нажат.После 3-го щелчка предыдущие 2 будут очищены, а у 3-го и 4-го щелчков появятся свои новые точки данных и т. Д. И т. Д. (По 2 точки данных за раз, чтобы показать начальные и конечные местоположения, а разница / дельта рассчитывается междуэти позиции).

Мой текущий код выглядит следующим образом:

private void chart1_MouseClick(object sender, MouseEventArgs e)
{
    HitTestResult result = chart1.HitTest(e.X, e.Y);

    if (result.PointIndex >= 0)
    {
        if (diffCounter == 0)
        {
            xOne = result.Series.Points[result.PointIndex].YValues[0];
            diffCounter++;
            //Console.WriteLine("VALY " + xOne);
        }
        else if (diffCounter == 1)
        {
            xTwo = result.Series.Points[result.PointIndex].YValues[0];
            diffCounter = 0;
            //Console.WriteLine("Delta = " + Math.Round(Math.Abs(xTwo - xOne)), 2);
            pointDifferenceTextBox.Text = Math.Round((Math.Abs(xTwo - xOne)), 2).ToString();
        }
    }
}

Я ничего не могу найти где-нибудь о добавлении точки данных на основе того, где был проведен тест попадания на линейном графике (илилюбой график по этому вопросу).

Разница Counter это просто int, чтобы определить, будет ли это первый или второй щелчок.

xOne, чтобы получить первый щелчок у-значение, xTwo - для получения значения y второго щелчка.

РЕДАКТИРОВАТЬ: я хотел бы иметь точку данных окружности, основанную на том, где выполняется проверка попадания.

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Поскольку сообщение было изменено, новый ответ кажется оправданным.

Вот как можно создать две точки для рисования в событии Paint.

Сначала нам нужно сохранить их:

PointF p1 = PointNull;
PointF p2 = PointNull;

Для состояния флага мы также используем статическое значение:

static PointF PointNull = new PointF(-123f, -123f);

Вы также можете использовать другой флаг для управления переключением между 1-й и 2-й точкой.

Далее нам нужно сохранить значения в клике:

private void chart1_MouseClick(object sender, MouseEventArgs e)
{

    Axis ax = chart1.ChartAreas[0].AxisX;
    Axis ay = chart1.ChartAreas[0].AxisY;

    double x = ax.PixelPositionToValue(e.X);
    double y = ay.PixelPositionToValue(e.Y);

    y = GetMedianYValue(chart1.Series[0], x);

    if (p1 == PointNull ||(p1 != PointNull && p2 != PointNull))
    {
        p1 = new PointF((float)x, (float)y);
        p2 = PointNull;
    }
    else
    {
        p2 = new PointF((float)x, (float)y);
    }
    // values have changed, trigger drawing them!
    chart1.Invalidate();
}

Обратите внимание, что сначала я использую функции оси, чтобы получить значения осей позиции, по которой щелкнули.Затем я перезаписываю значение y функцией, которая вычисляет точку на линии ..:

double GetMedianYValue(Series s,  double xval )
{
    // Findclosest datapoints:
    DataPoint dp1 =  s.Points.Where(x => x.XValue <= xval).LastOrDefault();
    DataPoint dp2 =  s.Points.Where(x => x.XValue >= xval).FirstOrDefault();

    // optional
    dp1.MarkerStyle = MarkerStyle.Circle;
    dp1.MarkerColor = Color.Purple;
    dp2.MarkerStyle = MarkerStyle.Circle;
    dp2.MarkerColor = Color.Violet;

    double dx = dp2.XValue - dp1.XValue;
    double dy = dp2.YValues[0] - dp1.YValues[0];
    // same point
    if (dx == 0) return dp1.YValues[0];
    // calculate median
    double d = dp1.YValues[0] + dy / dx * ( xval - dp1.XValue) ;
    return d;
}

Обратите внимание, что эта функция отмечает соседние точки данных для тестирования только!

Наконец нам нужно нарисовать две точки:

private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
    Axis ax = chart1.ChartAreas[0].AxisX;
    Axis ay = chart1.ChartAreas[0].AxisY;

    int x1 = (int)ax.ValueToPixelPosition(p1.X);
    int y1 = (int)ay.ValueToPixelPosition(p1.Y);
    int x2 = (int)ax.ValueToPixelPosition(p2.X);
    int y2 = (int)ay.ValueToPixelPosition(p2.Y);

    if (x1 >= 0 && x1 < chart1.Width)  // sanity check
        if (p1 != PointNull)
            e.ChartGraphics.Graphics.DrawEllipse(Pens.LightSeaGreen, x1 - 3, y1 - 3, 6, 6);

    if (x2 >= 0 && x2 < chart1.Width)  // sanity check
        if (p2 != PointNull)
            e.ChartGraphics.Graphics.DrawEllipse(Pens.Red, x2 - 3, y2 - 3, 6, 6);
}

Вот результат:

enter image description here

0 голосов
/ 11 октября 2018

Исходное сообщение просило добавить DataPoint в выбранном месте.Для этого HitTest бесполезно.

Вместо этого вам нужна одна из функций оси ;PixelPositionToValue будет преобразовывать пикселей положение на ось значение ..:

Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;

double x = ax.PixelPositionToValue(e.X);
double y = ay.PixelPositionToValue(e.Y);

DataPoint dp = new DataPoint(x, y);
dp.Color = Color.Red;
chart1.Series[0].Points.Add(dp);

Обратите внимание, что эти функции Действителен только в одном из paint или в одном из mouse events!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...