2014-12-19 60 views
3

我想用3點創建圖表,然後畫一條線。它將如下圖 ![c#form chart] [1] 但是我的編碼幾乎沒有劃線和沒有分數。請幫忙圖表點和劃線

public partial class Form5 : Form 
{ 
    public Form5() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Point[] pts = { new Point(150, 12), new Point(130, 15), new Point(160, 18) }; 
     //int count = 0; 

     // pts[count] = new Point((int)NumericUpDown1.Value, (int)NumericUpDown2.Value); 
     for (int i = 0; i < pts.Length; i++) 
     { 
      if (i != 0) 
      { 
       this.CreateGraphics().DrawLine(new Pen(Brushes.Black, 3), pts[i - 1], pts[1]); 
      } 
      else 
      { 
       this.CreateGraphics().DrawLine(new Pen(Brushes.Black, 3), pts[i], pts[1]); 
      } 
     } 
    } 
} 
+0

哪兒的例子圖表圖像去? – 2014-12-28 03:09:35

回答

0

你的代碼中的主要問題是硬編碼pts[1]。您應該使用pts[i]來代替。請記住 - C#中的數組索引從零開始。

此外,您不需要在每次迭代中都創建圖形。聲明局部變量並將其移至循環之外。而不是在每次迭代時檢查循環值,您可以將第一個點繪圖也循環移出。然後,你將能夠以同樣的方式處理其他幾點:

var g = this.CreateGraphics(); 
var blackPen = new Pen(Brushes.Black, 3); 

g.DrawLine(blackPen, pts[0], pts[0]); 

for(i = 1; i < pts.Length; i++) 
    g.DrawLine(blackPen, pts[i - 1], pts[i]); 

注意:您所標記問題LINQ的標籤。當然,你可以使用LINQ創建對點,並以此對畫線:

var lines = pts.Zip(pts.Skip(1), (a,b) => new { a, b }); 

foreach(var line in lines) 
    g.DrawLine(blackPen, line.a, line.b); 
+0

-3:每個Winforms繪圖都有錯誤:你應該使用DrawLines和Paint事件!而你應該處理這支筆......! – TaW 2014-12-19 09:42:12

+0

@你在我的答案中看到事件處理程序?答案無效?通常我使用Pen/Brush和其他gdi對象作爲類字段並將它們配置到表單上。 -1表示將有效答案標記爲「無用」,這是一個謊言。如果您有需要改進的地方,則無法註冊或撰寫評論 – 2014-12-19 10:41:39

+0

您繼續使用CreateGraphics,它清楚地表明您不使用繪畫事件。因此,你的答案不僅有用,而且是有害的。至於你低估我的答案對報復沒有幫助,這顯然違反了所有投票規則。你叫我騙子留下我(幾乎)無語.. – TaW 2014-12-19 10:47:49

-1

下面是正確的代碼:

// keep your data at class level: 
// lists are more flexible than arrays: 
List<Point> pts = new List<Point>(); 

// all drawing in the paint event: 
private void Form1_Paint(object sender, PaintEventArgs e) 
{ 

    // put the pen creation in a using scope: 
    using (Pen Pen = new Pen(Color.Red, 3f)) 
    { 
     // make the corners nicer: 
     pen.MiterLimit = pen.Width/2f; 

     // drawing all lines in one call greatly improves quality. 
     // we need at least two points: 
     if (pts.Count > 1) e.Graphics.DrawLines(Pen, pts); 
    } 
} 

// trigger the drawing when needed, eg when you have added more points: 
private void button1_Click(object sender, EventArgs e) 
{ 
    // maybe add more points.. 
    pts.AddRange(new Point[] 
       { new Point(150, 12), new Point(130, 15), new Point(160, 18) }); 

    // trigger the paint event 
    this.Invalidate(); 
} 

考慮繪製到Panel!這將允許您移動它並將所有控件獨立放置在您的Form上。

如果您認真想要創建圖表,請考慮在工具箱的數據箱中使用Chart控件!

它具有真實圖表所需的一切功能,包括標記軸和許多顯示風格。

要使用你的數據都需要是這幾行:

using System.Windows.Forms.DataVisualization.Charting; 
//.. 
private void button2_Click(object sender, EventArgs e) 
{ 
    chart1.Legends.Clear(); 
    chart1.Series[0].ChartType = SeriesChartType.FastLine; 
    chart1.Series[0].Color = Color.Red; 
    chart1.Series[0].BorderWidth = 3; 

    chart1.Series[0].Points.AddXY(130, 15); 
    chart1.Series[0].Points.AddXY(150, 12); 
    chart1.Series[0].Points.AddXY(160, 18); 
} 

注意,我已命令分,但是這是沒有必要對所有charttypes。我使用Fastline,並與您原來的訂單一起工作。它甚至可以顯示幾個具有相同X值的點。並詛咒它自動縮放..

另請注意,圖表以自然的方式顯示Y值,即從下到上,而GDI從上到下繪製!

這裏的兩種方式的截圖顯示的圖表:

enter image description here

+0

的評論中陳述了這一點-X很多問題。這個答案與OP問題無關。 OP問題沒有給出答案。命名是可怕的 - 'pts'而不是'points',button1,button2等。同樣每個按鈕點擊都會將另一組相同的點添加到'pts'列表中。這是一個錯誤。 – 2014-12-19 10:49:06

+0

而不是writng評論,你應該閱讀我的代碼,包括評論。當然,如果它幫助OP與他的項目代碼相關聯,就應該保持命名。沒有錯誤需要修復。 – TaW 2014-12-19 10:56:34

+0

而不是爭論你應該閱讀我的意見和OP問題。此外,它會很高興爲你讀**非常仔細** [downvoting的描述以及何時應該應用它(http://stackoverflow.com/help/privileges/vote-down) – 2014-12-19 11:00:12