#c# #charts #annotations #mschart
#c# #Диаграммы #аннотации #mschart
Вопрос:
Как создать аннотацию на ходу и как включить размещение конечным пользователем Annotation.BeginPlacement()
? Я пытался сделать это несколькими способами, но не смог заставить его работать. Он должен отображаться в режиме реального времени после вызова BeginPlacement() .
Документации по этому вопросу практически нет — и в основном нет — поэтому я не могу найти никакой помощи по этой проблеме.
То, что я пробовал до сих пор, это создать аннотацию и поместить ее с помощью anchorX / Y , установить для всех разрешающих флагов значение true и вызвать BeginPlacement() во время перемещения мыши, но не может видеть аннотацию при ее размещении и не будет помещаться на свое место соответственно. Например, LineAnnotation начинается в правильном положении, но не заканчивается там, где я его оставил. Когда я перемещаю его так, чтобы он начинался с моих диаграмм {0,0}, он достигнет конечной точки.
Что я хочу знать, так это когда и как использовать эти доступные инструменты? То, что я пытаюсь сделать, это позволить пользователю рисовать аннотации на диаграмме и использовать их в качестве инструментов при анализе диаграмм.
Ответ №1:
Вам нужно рассчитать правильные позиции. Помните, что перемещение мыши не даст вам позиции (проценты) или значения (данные), а пиксели. Вы можете преобразовать их, используя различные функции axis. Официально они работают только в событии xxxPaint, но во время событий мыши они также работают нормально.
Обновление: есть два способа привязки:
- Либо с помощью «Позиций«, то есть процентов, либо «Значений», то есть значений данных.
Вот пример 1-го рода:
LineAnnotation laNew = null;
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
if (cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
laNew = new LineAnnotation();
chart1.Annotations.Add(laNew);
double vx = ax.ValueToPosition(ax.PixelPositionToValue(e.X));
double vy = ay.ValueToPosition(ay.PixelPositionToValue(e.Y));
laNew.X = vx;
laNew.Y = vy;
}
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left) amp;amp; cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
double vx = ax.ValueToPosition(ax.PixelPositionToValue(e.X))- laNew.X;
double vy = ay.ValueToPosition(ay.PixelPositionToValue(e.Y)) - laNew.Y;
laNew.Width = Math.Min(100, vx);
laNew.Height = Math.Min(100, vy);
laNew.LineColor = rb_green.Checked ? Color.Green : Color.Red;
laNew.AllowMoving = true; // optional
}
}
Это работает нормально, если вам не нужно каким-либо образом изменить масштаб оси, например, изменить минимальные и / или максимальные значения оси.
- В этом случае вам нужно привязать к значениям данных.
Сначала нам нужно связать Annotation
с Axes
, а также установить IsSizeAlwaysRelative
false
. Затем мы можем вычислить значения привязки и размера:
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
if (cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
laNew = new LineAnnotation();
chart1.Annotations.Add(laNew);
laNew.IsSizeAlwaysRelative = false;
laNew.AxisX = ax;
laNew.AxisY = ay;
laNew.AnchorX = ax.PixelPositionToValue(e.X);
laNew.AnchorY = ay.PixelPositionToValue(e.Y);
laNew.LineColor = rb_green.Checked ? Color.Green : Color.Red;
laNew.AllowMoving = true;
}
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left) amp;amp; cbx_drawAnnotation.Checked)
{
Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
laNew.Width = ax.PixelPositionToValue(e.X) - laNew.AnchorX; // values
laNew.Height = ay.PixelPositionToValue(e.Y) - laNew.AnchorY;
}
}
Обратите внимание, как теперь я могу масштабировать максимум, а также изменять размер диаграммы, и аннотации остаются с точками данных..:
Обновление: чтобы ограничить строку ChartArea
, добавьте это в определение в MouseDown
событии:
laNew.ClipToChartArea = chart1.ChartAreas[0].Name;
Чтобы исключение не покидало диаграмму, добавьте это к условию в MouseMove
..:
.. amp;amp; chart1.ClientRectangle.Contains(e.Location)
Комментарии:
1. Я заметил, что вы используете проценты по ширине и высоте LineAnnotation . Возможно ли получить его в значениях оси? Я разрешаю изменять размер временного окна (только с помощью оси min / max, без масштабирования), и строки не «изменяют размер» правильно. РЕДАКТИРОВАТЬ: или ваша диаграмма просто 100×100 …?
2. Это верно. Все элементы диаграммы. Значения Position.xxx указаны в процентах от соответствующего контейнера. Я рассмотрю возможность перехода от этого типа привязки к привязке относительно значений точек данных..
3. Было бы здорово, если бы вы нашли решение… Заранее спасибо!
4. Привязка начальной точки проста, но каким-то образом размер не является. Странно. Я буду держать вас в курсе..
5. Выполнено. Пожалуйста, протестируйте!