這晚,並沒有真正短,但國際海事組織是圖表中的顏色區域的最佳途徑。
通過用正確的數據編碼Paint
事件,可以非常精確地將Lines
和Spline
charttypes着色。必要的像素值可以通過軸功能ValueToPixelPosition
獲得。再例如here!
下面的代碼是一個長一點,因爲我們需要在開始和都圖表和每個彩色區域末尾添加某些點。除此之外,它非常直接:通過將像素座標與AddLines
相加來創建GraphicsPaths
,並在Paint
事件中填入GraphicsPaths
。
爲了測試和樂趣,我添加了一個可移動的HorizontalLineAnnotation
,所以我可以看到這些區域在上下拖動時會有所不同。:
![enter image description here](https://i.stack.imgur.com/E6vbG.png)
的Paint
事件是相當簡單的;它指的是一個HorizontalLineAnnotation hl
:
private void chart1_Paint(object sender, PaintEventArgs e)
{
double limit = hl.Y; // get the limit value
hl.X = 0; // reset the x value of the annotation
List<GraphicsPath> paths = getPaths(chart1.ChartAreas[0], chart1.Series[0], limit);
using (SolidBrush brush = new SolidBrush(Color.FromArgb(127, Color.Red)))
foreach (GraphicsPath gp in paths)
{ e.Graphics.FillPath(brush, gp); gp.Dispose(); }
}
的代碼來獲取路徑顯然是太長了舒適..:
List<GraphicsPath> getPaths(ChartArea ca, Series ser, double limit)
{
List<GraphicsPath> paths = new List<GraphicsPath>();
List<PointF> points = new List<PointF>();
int first = 0;
float limitPix = (float)ca.AxisY.ValueToPixelPosition(limit);
for (int i = 0; i < ser.Points.Count; i++)
{
if ((ser.Points[i].YValues[0] > limit) && (i < ser.Points.Count - 1))
{
if (points.Count == 0) first = i; // remember group start
// insert very first point:
if (i == 0) points.Insert(0, new PointF(
(float)ca.AxisX.ValueToPixelPosition(ser.Points[0].XValue), limitPix));
points.Add(pointfFromDataPoint(ser.Points[i], ca)); // the regular points
}
else
{
if (points.Count > 0)
{
if (first > 0) points.Insert(0, median(
pointfFromDataPoint(ser.Points[first - 1], ca),
pointfFromDataPoint(ser.Points[first], ca), limitPix));
if (i == ser.Points.Count - 1)
{
if ((ser.Points[i].YValues[0] > limit))
points.Add(pointfFromDataPoint(ser.Points[i], ca));
points.Add(new PointF(
(float)ca.AxisX.ValueToPixelPosition(ser.Points[i].XValue), limitPix));
}
else
points.Add(median(pointfFromDataPoint(ser.Points[i - 1], ca),
pointfFromDataPoint(ser.Points[i], ca), limitPix));
GraphicsPath gp = new GraphicsPath();
gp.FillMode = FillMode.Winding;
gp.AddLines(points.ToArray());
gp.CloseFigure();
paths.Add(gp);
points.Clear();
}
}
}
return paths;
}
它使用兩個輔助功能:
PointF pointfFromDataPoint(DataPoint dp, ChartArea ca)
{
return new PointF((float)ca.AxisX.ValueToPixelPosition(dp.XValue),
(float)ca.AxisY.ValueToPixelPosition(dp.YValues[0]));
}
PointF median(PointF p1, PointF p2, float y0)
{
float x0 = p2.X - (p2.X - p1.X) * (p2.Y - y0)/(p2.Y - p1.Y);
return new PointF(x0, y0);
}
的HorizontalLineAnnotation
設置如下:
hl = new HorizontalLineAnnotation();
hl.AllowMoving = true;
hl.LineColor = Color.OrangeRed;
hl.LineWidth = 1;
hl.AnchorDataPoint = S1.Points[1];
hl.X = 0;
hl.Y = 0; // or some other starting value..
hl.Width = 100; // percent of chart..
hl.ClipToChartArea = chart1.ChartAreas[0].Name; // ..but clipped
chart1.Annotations.Add(hl);
它的工作原理,但我不明白你在做什麼。你能否詳細說明並創建一個像'private void UpdateChart(float straight_line,List curve)'這樣的函數http://pastebin.com/i6tf9iWA –
@DeadGirl我編輯了我的答案。 – user3093781
太好了。你能詳細說明它的工作原理嗎?特別是'if((y0> y && y1 y))'部分。 –