Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB .NET > Элемент для рисования графиков в VB


Автор: Cleric 20.12.2005, 17:01
не подскажите какой нибудь? (обычные графики типа простейших экселевских с линиями)
жылательно попроще в обращении... заранее спасибо

Автор: Exception 20.12.2005, 23:23
Это же самому нетрудно реализовать. Есть COMовский эл-т MSChart, посмотри его

Автор: Cleric 21.12.2005, 10:25
Цитата
Есть COMовский эл-т MSChart, посмотри его


тока как в нем рисовать? (допустим у меня есть массив У())


Цитата
самому нетрудно реализовать


ну частично я сам реализовал, но там оси прорисовывать и всякая другая мелочь...
а вот кстати еще вопрос: если в pictureboxе рисовать что то с помощью create graphics, то если например потом нарисованное чем то закроется, то оно стирается в этом месте... как сделать что бы не стиралось?
smile

Автор: arilou 21.12.2005, 17:41
Цитата(Cleric @ 21.12.2005, 10:25)
вот кстати еще вопрос: если в pictureboxе рисовать что то с помощью create graphics, то если например потом нарисованное чем то закроется, то оно стирается в этом месте... как сделать что бы не стиралось

Можно, например, прицепить обработчик к событию PictureBox.Paint и рисовать там. Тогда при перерисовке PictureBox'а будет перерисовываться и твоя графика.

Автор: Cleric 22.12.2005, 11:54
Цитата
Можно, например, прицепить обработчик к событию PictureBox.Paint и рисовать там. Тогда при перерисовке PictureBox'а будет перерисовываться и твоя графика.


что то я попробовал и мне не понравилось... она не всегда перересовывается.... иногда белые куски остаются... как нибудь по другому нельзя?



Автор: arilou 22.12.2005, 13:28
Цитата(Cleric @ 22.12.2005, 11:54)
что то я попробовал и мне не понравилось

Значит ты что-то не то делаешь. Приведи код, посмотрим.

Автор: Cleric 22.12.2005, 15:00
есть у меня саб PaintGraph, который значения из массива на указаном пикчуребоксе рисует

код на событие paint вешаю такой:

Код

Private Sub pbGraph_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles pbGraph.Paint
        PaintGraph(pbgraph, Y, ...)
End Sub


где pbgraph - picturebox
Y - массив Double, которые рисуются на боксе...

Автор: arilou 22.12.2005, 15:03
Цитата(Cleric @ 22.12.2005, 15:00)
PaintGraph(pbgraph, Y, ...)

А этот метод по-подробнее?

Автор: Cleric 22.12.2005, 15:11
ну что то типа:

(когда висит на кнопке, то все нормально рисует)

Код

Public Sub PaintGraph(ByVal PBOX As PictureBox, ByVal X(,) As Double, ByVal C As Drawing.Color, ByVal MaxVal As Double, ByVal TStart As Integer, ByVal TAdd As Integer)
        ' x(t,0) - рисуется первый столбец
        If X Is Nothing Then Exit Sub
        Dim maxT As Integer = X.GetUpperBound(0) + TStart + TAdd, mX As Double = MaxVal

        Dim gW As Integer = PBOX.Width - 10
        Dim gH As Integer = PBOX.Height - 10

        Dim t As Integer, P As New Drawing.Pen(C, 2), Pblack As New Drawing.Pen(Color.Black, 1), PGray As New Drawing.Pen(Color.Gray, 1)
        PGray.DashStyle = Drawing2D.DashStyle.Dash


        Dim dx As Double = gW / maxT
        Dim ky As Double = gH / mX
  
        Dim pX As Single, pX2 As Single
        Dim pY As Single, pY2 As Single

        For t = TStart To maxT - TAdd
            If t >= TStart And t <= maxT - TAdd Then
                pX = Convert.ToSingle(5 + t * dx)
                pY = gH + 5 - Convert.ToSingle(Int(X(t - TStart, 0) + 0.5) * ky)
                pX2 = Convert.ToSingle(5 + (t + 1) * dx)
                If t < maxT - TAdd Then pY2 = gH + 5 - Convert.ToSingle(Int(X(t - TStart + 1, 0) + 0.5) * ky)


                If t < maxT - TAdd Then PBOX.CreateGraphics.DrawLine(P, pX, pY, pX2, pY2)
                PBOX.CreateGraphics.DrawLine(PGray, pX, pY, pX, gH + 5)
                PBOX.CreateGraphics.DrawEllipse(P, pX - 2, pY - 2, 4, 4)
                ' label value:
                PBOX.CreateGraphics.DrawString(Int(X(t - TStart, 0) + 0.5), Font1, Brushes.Black, pX + 2, pY - 5)
            End If
        Next

        ' Drawing axies and so on:
        PBOX.CreateGraphics.DrawLine(Pblack, 5, 5, 5, gH + 5)
        PBOX.CreateGraphics.DrawLine(Pblack, 5, gH + 5, gW + 5, gH + 5)
        PBOX.CreateGraphics.DrawString(mX, Font1, Brushes.Black, 5, 5)
End Sub



то есть он и потом нормально рисует, но могут оставаться белые пятна, если утащить окно с экрана а потом обратно вытаскивать

Автор: arilou 22.12.2005, 15:24
Цитата(Cleric @ 22.12.2005, 15:11)
PBOX.CreateGraphics.DrawLine(PGray, pX, pY, pX, gH + 5)

Соооовсем не так smile Надо передавать в метод PaintGraph объект Graphics, и рисовать используя его.

Например:

Код

Private Sub pbGraph_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles pbGraph.Paint
        PaintGraph(pbgraph, Y, ..., e.Graphics)
End Sub

Public Sub PaintGraph(ByVal PBOX As PictureBox, ByVal X(,) As Double, ByVal C As Drawing.Color, ByVal MaxVal As Double, ByVal TStart As Integer, ByVal TAdd As Integer, g As Graphics)
        ' x(t,0) - рисуется первый столбец
        If X Is Nothing Then Exit Sub
        Dim maxT As Integer = X.GetUpperBound(0) + TStart + TAdd, mX As Double = MaxVal

        Dim gW As Integer = PBOX.Width - 10
        Dim gH As Integer = PBOX.Height - 10

        Dim t As Integer, P As New Drawing.Pen(C, 2), Pblack As New Drawing.Pen(Color.Black, 1), PGray As New Drawing.Pen(Color.Gray, 1)
        PGray.DashStyle = Drawing2D.DashStyle.Dash


        Dim dx As Double = gW / maxT
        Dim ky As Double = gH / mX
  
        Dim pX As Single, pX2 As Single
        Dim pY As Single, pY2 As Single

        For t = TStart To maxT - TAdd
            If t >= TStart And t <= maxT - TAdd Then
                pX = Convert.ToSingle(5 + t * dx)
                pY = gH + 5 - Convert.ToSingle(Int(X(t - TStart, 0) + 0.5) * ky)
                pX2 = Convert.ToSingle(5 + (t + 1) * dx)
                If t < maxT - TAdd Then pY2 = gH + 5 - Convert.ToSingle(Int(X(t - TStart + 1, 0) + 0.5) * ky)


                If t < maxT - TAdd Then g.DrawLine(P, pX, pY, pX2, pY2)

                g.DrawLine(PGray, pX, pY, pX, gH + 5)
                g.DrawEllipse(P, pX - 2, pY - 2, 4, 4)
                ' label value:
                g.DrawString(Int(X(t - TStart, 0) + 0.5), Font1, Brushes.Black, pX + 2, pY - 5)
            End If
        Next

        ' Drawing axies and so on:
        g.DrawLine(Pblack, 5, 5, 5, gH + 5)
        g.DrawLine(Pblack, 5, gH + 5, gW + 5, gH + 5)
        g.DrawString(mX, Font1, Brushes.Black, 5, 5)
End Sub

Автор: Cleric 22.12.2005, 16:08
да. спасибо... smile

Автор: arilou 22.12.2005, 16:12
Cleric
smile

Автор: Cleric 22.12.2005, 16:40
только на resize плохо работает...

Автор: arilou 22.12.2005, 16:49
Цитата(Cleric @ 22.12.2005, 16:40)
только на resize плохо работает...

Тут надо хитро поступить smile Есть два варианта:

1) *красивый*. Наследовать свой класс от PictureBox, и в конструкторе после InitalizeComponent написать:
Код

SetStyle(ControlStyles.DoubleBuffer, True)
SetStyle(ControlStyles.AllPaintingInWmPaint, True)
ResizeRedraw = False

Вместо PictureBox'а везде использовать свой класс.

2) *хакерский smile ГЫ. Как раз сегодня использовал* Где-нить в конструкторе формы написать:

Код

Dim mi as MethodInfo = PBOX.GetType().GetMethod("SetStyle", BindingFlags.NonPublic Or BindingFlags.Instance)
mi.Invoke(PBOX, new object(){ControlStyles.DoubleBuffer, true})
mi.Invoke(PBOX, new object(){ControlStyles.AllPaintingInWmPaint, true})

Dim pi As PropertyInfo = PBOX.GetType().GetProperty("ResizeRedraw", BindingFlags.NonPublic Or BindingFlags.Instance)
pi.SetValue(PBOX, true, Nothing)


Да, для второго способа подключить namespace System.Reflection

Автор: Cleric 22.12.2005, 17:02
э... ну там вроде и на SizeChanged можно повесить что бы перересовывалось (как аргумент Graphics отправлять creategraphics пикчуребокса) все помоему нормально работать начинает...

но за хитрые методы отдельное спасибо

Автор: arilou 22.12.2005, 17:13
Цитата(Cleric @ 22.12.2005, 17:02)
ну там вроде и на SizeChanged можно повесить что бы перересовывалось

А, ты имеешь ввиду, что не перерисовывается на Resize? Мой вариант мерцание отключает...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)