在mschart中,我在SetAnchor(点8,点12)中使用了行注释。 如果滚动图表并隐藏点8,则看不到剩余的线注释(点9至12)。 我想查看剩余的行注释。救救我!
我的参考资料; Samples Environments for Microsoft Chart Controls ->图表功能->注释->注释锚定
private void AddLineAnnotation()
{
// create a line annotation
LineAnnotation annotation = new LineAnnotation();
// setup visual attributes
annotation.StartCap = LineAnchorCapStyle.Arrow;
annotation.EndCap = LineAnchorCapStyle.Arrow;
annotation.LineWidth = 3;
annotation.LineColor = Color.OrangeRed;
annotation.ShadowOffset = 2;
annotation.ClipToChartArea = "Default";
// prevent moving or selecting
annotation.AllowMoving = false;
annotation.AllowAnchorMoving = false;
annotation.AllowSelecting = false;
if(Chart1.Series[0].Points.Count > 13)
{
// Use the Anchor Method to anchor to points 8 and 12...
annotation.SetAnchor(Chart1.Series[0].Points[8], Chart1.Series[0].Points[12]);
}
// add the annotation to the collection
Chart1.Annotations.Add(annotation);
}
答案 0 :(得分:2)
这是一个棘手的事情。
坏消息是:我认为不可能。我认为MSChart
将忽略所有在可见区域之外开始的注释。也许是为了避免混乱,但谁能说出来..?
一种解决方法必须考虑到两个端点都在外面并且我们仍然希望看到注释的情况。
好消息是,使用ownerdraw可以编写一种变通办法,确实可以为这两种情况划清界限。
以下示例显示了绘图代码。确保分开拖动模式以缩放和拖动以绘制新注释。我使用了一个复选框及其CheckChanged
事件。
我们首先来看看它的作用:
滚动注释的起点时,画线就会插入。很难注意到。
这是xxxPaint
事件的代码:
private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
// loop only over line annotations:
List<LineAnnotation> annos =
chart1.Annotations.Where(x => x is LineAnnotation)
.Cast<LineAnnotation>().ToList();
if (!annos.Any()) return;
// a few short references
Graphics g = e.ChartGraphics.Graphics;
ChartArea ca = chart1.ChartAreas[0];
Axis ax = ca.AxisX;
Axis ay = ca.AxisY;
// we want to clip the line to the innerplotposition excluding the scrollbar:
Rectangle r = Rectangle.Round(InnerPlotPositionClientRectangle(chart1, ca));
g.SetClip(new Rectangle(r.X, r.Y, r.Width, r.Height - (int)ax.ScrollBar.Size));
g.InterpolationMode = InterpolationMode.NearestNeighbor; // pick your mode!
foreach (LineAnnotation la in annos)
{
if (Double.IsNaN(la.Width)) continue; // *
// calculate the coordinates
int x1 = (int)ax.ValueToPixelPosition(la.AnchorX);
int y1 = (int)ay.ValueToPixelPosition(la.AnchorY);
int x2 = (int)ax.ValueToPixelPosition(la.AnchorX + la.Width);
int y2 = (int)ay.ValueToPixelPosition(la.AnchorY + la.Height);
// now we draw the line if necessary:
if (x1 < r.X || x1 > r.Right)
using (Pen pen = new Pen(la.LineColor, 0.5f)) g.DrawLine(pen, x1, y1, x2, y2);
}
// reset the clip to allow the system drawing a scrollbar
g.ResetClip();
}
一些注意事项:
代码假定(*)Annotations
都以AnchorX/Y
锚定,并设置了Width/Height
。如果您使用了不同的锚定方式,则需要修改代码。
对于剪裁部分,我们需要知道InnerPlotPosition
的像素大小/正数。为此,您可以使用例如在this link的底部。
除了直线以外,我没有编码。如果您对注释进行了修饰,则可能需要扩展代码;否则,请参见注释。