Author Topic: Stylizing the basicTrendChart  (Read 5587 times)

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Stylizing the basicTrendChart
« on: February 11, 2015, 05:22:00 AM »
UGH

So I've been using the trend chart and found myself to be hating it's default look...
All I want to do is change the background colour and the line colour however I can't find the setting to change the line colour and the backColour doesn't make a difference...

Is it even possible? Maybe I should have a deeper look at its coding...

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #1 on: February 11, 2015, 06:39:33 AM »
The BasicTrendChart is truly just a Basic chart.If you want a Chart with more capabilities, you can use the Chart found on the Data group of the Toolbox along with the DataSubscriber. Here a couple threads discussing it's use:

http://advancedhmi.com/forum/index.php?topic=226.msg775#msg775

http://advancedhmi.com/forum/index.php?topic=606.msg2701#msg2701

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #2 on: February 11, 2015, 07:14:34 AM »
Here is another forum thread discussing the use of Chart:

http://sourceforge.net/p/advancedhmi/discussion/875091/thread/a2bce815/

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #3 on: February 11, 2015, 06:35:55 PM »
Maybe is it possible to modify your BasicTrendChart?
Since it inherits the basicchart... (mind you I really am a rookie at VB and could be completely wrong)
is there somewhere in the code of the component that specifies the look that it has been given?
I know that I've tried creating charts before, with a bit of success but they caused the program to lag horribly... I recently lost that project file to corruption and am in the process of rebuilding it with your new version... many new features are very helpful. :)

so since it is just a branch off of the basic chart is it possible to modify how it looks when it is ported through?
Thanks for helping

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #4 on: February 11, 2015, 07:57:30 PM »
Yes, you can extend the BasicTrendChart by inheriting it into a new class then overriding the Paint event. This does require a bit of knowledge of GDI+ and creating classes. Here is the framework to help get started on modifying the BasicTrendChart:

Public Class BasicTrendChartEx
    Inherits BasicTrendChart

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
        '* Fill in the background color
        e.Graphics.FillRectangle(New SolidBrush(Color.White), 0, 0, Me.Width, Me.Height)


        Dim MaxValue As Int16
        '* Draw the line connecting the points
        If Points.Count > 1 Then
            Dim index As Integer = 0
            While index < (Points.Count - 1)
                Try
                    '* Keep traclk of the maximum value for the Y Axis value draw at the end
                    If Points(index) > MaxValue Then
                        MaxValue = Points(index)
                    End If
                    '* calculate the x and y coordinates based on the Points collection
                    Dim StartPixel As New Point(x1, y1)
                    Dim EndPixel As New Point(x2, y2)
                    e.Graphics.DrawLine(System.Drawing.Pens.Blue, StartPixel, EndPixel)
                Catch ex As Exception
                    Dim dbg = 0
                End Try
                index += 1
            End While
        End If

        '* Draw the Axis
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, 0, 0, Me.Height)
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, Me.Height - 1, Me.Width, Me.Height - 1)
        e.Graphics.DrawString(MaxValue.ToString, New Drawing.Font("Arial", 10.0!), System.Drawing.Brushes.White, 0.0!, 0.0!)
        e.Graphics.DrawString(YMinimum.ToString, New Drawing.Font("Arial", 10), System.Drawing.Brushes.White, 0, Me.Height - 16)
    End Sub
End Class

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #5 on: February 11, 2015, 08:24:55 PM »
Hate to continue bothering you, however (your coding ability is excellent btw) it tells me that the points x1,x2,y1,y2 variables haven't been declared in the collection. the error sates that they may be inaccessible due to its protection level
As a result, I tried just initializing the variables however they aren't being populated and thus no line appears. it does however recognize the value and assigns the max y to it.
 :(

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #6 on: February 11, 2015, 10:18:48 PM »
That code is not complete, but more of a starting point. You would need to replace the x1, y1, x2, and y2 with calculations to go from the values in the Points collection to the pixel position on the chart. So let's make this a little easier and make the Y Axis max a fixed value by creating a property:

Private m_YAxisMaximum as integer
Public Propety YAxisMaximum as Integer
Get
    Return m_YAxisMaximum
End Get
Set (value as integer)
  m_YAxisMaximum =value
end Set
End Property


So now create variables and calculate their values

Dim x1,y1 as Integer
Dim x2, y2 as integer

x1=convert.ToInt32((Me.width/Points.Count) * index)
y1=Convert.ToInt32(Me.Height/m_YaxisMaximum)*Points(index))

x2=convert.ToInt32((Me.width/Points.Count) * index+1)
y1=Convert.ToInt32(Me.Height/m_YaxisMaximum)*Points(index+1))


Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #7 on: February 11, 2015, 10:21:16 PM »
So putting that all together:

Public Class BasicTrendChartEx
    Inherits BasicTrendChart

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
        '* Fill in the background color
        e.Graphics.FillRectangle(New SolidBrush(Color.White), 0, 0, Me.Width, Me.Height)

        Dim x1,y1 as Integer
        Dim x2, y2 as integer

        '* Draw the line connecting the points
        If Points.Count > 1 Then
            Dim index As Integer = 0
            While index < (Points.Count - 2)
                Try
                 '* calculate the x and y coordinates based on the Points collection
                  x1=convert.ToInt32((Me.width/Points.Count) * index)
                  y1=Convert.ToInt32(Me.Height/m_YaxisMaximum)*Points(index))

                  x2=convert.ToInt32((Me.width/Points.Count) * index+1)
                  y1=Convert.ToInt32(Me.Height/m_YaxisMaximum)*Points(index+1))

                    Dim StartPixel As New Point(x1, y1)
                    Dim EndPixel As New Point(x2, y2)
                    e.Graphics.DrawLine(System.Drawing.Pens.Blue, StartPixel, EndPixel)
                Catch ex As Exception
                    Dim dbg = 0
                End Try
                index += 1
            End While
        End If

        '* Draw the Axis
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, 0, 0, Me.Height)
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, Me.Height - 1, Me.Width, Me.Height - 1)
        e.Graphics.DrawString(MaxValue.ToString, New Drawing.Font("Arial", 10.0!), System.Drawing.Brushes.White, 0.0!, 0.0!)
        e.Graphics.DrawString(YMinimum.ToString, New Drawing.Font("Arial", 10), System.Drawing.Brushes.White, 0, Me.Height - 16)
    End Sub
End Class

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #8 on: February 12, 2015, 03:24:28 AM »
hmm, the graph shows and I've made a few tweaks to make it work :P
however the line is only appearing at the top of the chart, appearing as a line that gradually fills from left to right...
I'm truly stumped, no idea why this is happening.
This is my code:
Code: [Select]
Public Class BasicTrendChartEx
    Inherits BasicTrendChart

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
        '* Fill in the background color
        e.Graphics.FillRectangle(New SolidBrush(BackColour), 0, 0, Me.Width, Me.Height)

        Dim x1, y1 As Integer
        Dim x2, y2 As Integer

        '* Draw the line connecting the points
        If Points.Count > 1 Then
            Dim index As Integer = 0
            While index < (Points.Count - 2)
                Try
                    '* calculate the x and y coordinates based on the Points collection
                    x1 = convert.ToInt32((Me.width / Points.Count) * index)
                    y1 = Convert.ToInt32(Me.Height / m_YAxisMaximum) * Points(index)

                    x2 = Convert.ToInt32((Me.Width / Points.Count) * (index + 1))
                    y2 = Convert.ToInt32(Me.Height / m_YAxisMaximum) * Points(index + 1)
                    '*^ this was y1
                    Dim StartPixel As New Point(x1, y1)
                    Dim EndPixel As New Point(x2, y2)
                    e.Graphics.DrawLine(System.Drawing.Pens.Yellow, StartPixel, EndPixel)

                Catch ex As Exception
                    Dim dbg = 0
                End Try
                index += 1
            End While
        End If

        '* Draw the Axis
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, 0, 0, Me.Height)
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, Me.Height - 1, Me.Width, Me.Height - 1)
        e.Graphics.DrawString(m_YAxisMaximum.ToString, New Drawing.Font("Arial", 10.0!), System.Drawing.Brushes.White, 0.0!, 0.0!)
        '*                    ^^^^^^^^^^^^^^^ this was MaxValue
        e.Graphics.DrawString(YMinimum.ToString, New Drawing.Font("Arial", 10), System.Drawing.Brushes.White, 0, Me.Height - 16)
    End Sub
    Private m_YAxisMaximum As Integer
    Public Property YAxisMaximum As Integer
        Get
            Return m_YAxisMaximum
        End Get
        Set(value As Integer)
            m_YAxisMaximum = value
        End Set
    End Property
    Private _BackColour As Drawing.Color = Drawing.Color.Green
    Public Property BackColour() As Drawing.Color
        Get
            Return _BackColour
        End Get
        Set(ByVal value As Drawing.Color)
            _BackColour = value
        End Set
    End Property
End Class

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #9 on: February 12, 2015, 04:08:55 AM »
Be sure your maximum Y value has something other than 0:

 Private m_YAxisMaximum As Integer=32767

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #10 on: February 12, 2015, 04:36:18 AM »
well I'd set the max y value to 1700
my PLC is giving ~1250 (seen in a digital panel meter)

same PLCAddressValue... weird results :/

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #11 on: February 12, 2015, 05:42:41 AM »
Just thought I might post a pic of the problem:
The left is the one utilizing the new code and the one on the right is the default trendchart

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Stylizing the basicTrendChart
« Reply #12 on: February 12, 2015, 07:16:27 AM »
I think the problem is here:

y1 = Convert.ToInt32(Me.Height / m_YAxisMaximum) * Points(index)

This should be

y1 = Convert.ToInt32((Me.Height / m_YAxisMaximum) * Points(index))

The same with y2

andyandy26

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #13 on: February 12, 2015, 07:45:38 AM »
Yhippee! after a bit more help (thanks) and some tinkering, it now works!
Thanks Archie for your help, not only for helping to make it work but also expanding my ability.

Now I know how to add my own properties and such :)

now just to wrap my head around classes and their methods interaction... maybe one day I may be as talented as you! :P

For any peeps who may want it, here is the final code:

Code: [Select]
Public Class BasicTrendChartEx
    Inherits BasicTrendChart

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
        '* Fill in the background color
        e.Graphics.FillRectangle(New SolidBrush(BackColour), 0, 0, Me.Width, Me.Height)

        Dim x1, y1 As Integer
        Dim x2, y2 As Integer

        '* Draw the line connecting the points
        If Points.Count > 1 Then
            Dim index As Integer = 0
            While index < (Points.Count - 2)
                Try
                    '* calculate the x and y coordinates based on the Points collection
                    x1 = Me.Width - Convert.ToInt32((Me.Width / MaxPoints) * index)
                    y1 = Me.Height - Convert.ToInt32((Me.Height / (YMaximum - YMinimum)) * (Points(index) - YMinimum))

                    x2 = Me.Width - Convert.ToInt32((Me.Width / MaxPoints) * (index + 1))
                    y2 = Me.Height - Convert.ToInt32((Me.Height / (YMaximum - YMinimum)) * (Points(index + 1) - YMinimum))
                    '*^ this was y1
                    Dim StartPixel As New Point(x1, y1)
                    Dim EndPixel As New Point(x2, y2)
                    'e.Graphics.DrawLine(System.Drawing.Pens.Yellow, StartPixel, EndPixel)
                    e.Graphics.DrawLine(System.Drawing.Pens.Yellow, x1, y1, x2, y2)
                Catch ex As Exception
                    Dim dbg = 0
                End Try
                index += 1
            End While
        End If

        '* Draw the Axis
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, 0, 0, Me.Height)
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, Me.Height - 1, Me.Width, Me.Height - 1)
        e.Graphics.DrawString(YMaximum.ToString, New Drawing.Font("Arial", 10.0!), System.Drawing.Brushes.White, 0.0!, 0.0!)
        '*                    ^^^^^^^^^^^^^^^ this was MaxValue
        e.Graphics.DrawString(YMinimum.ToString, New Drawing.Font("Arial", 10), System.Drawing.Brushes.White, 0, Me.Height - 16)
    End Sub
    Private _BackColour As Drawing.Color = Drawing.Color.Green
    Public Property BackColour() As Drawing.Color
        Get
            Return _BackColour
        End Get
        Set(ByVal value As Drawing.Color)
            _BackColour = value
        End Set
    End Property
End Class

Enjoy!

Noe

  • Full Member
  • ***
  • Posts: 205
    • View Profile
Re: Stylizing the basicTrendChart
« Reply #14 on: February 12, 2015, 05:47:43 PM »
Thanks for sharing!!

Yhippee! after a bit more help (thanks) and some tinkering, it now works!
Thanks Archie for your help, not only for helping to make it work but also expanding my ability.

Now I know how to add my own properties and such :)

now just to wrap my head around classes and their methods interaction... maybe one day I may be as talented as you! :P

For any peeps who may want it, here is the final code:

Code: [Select]
Public Class BasicTrendChartEx
    Inherits BasicTrendChart

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
        '* Fill in the background color
        e.Graphics.FillRectangle(New SolidBrush(BackColour), 0, 0, Me.Width, Me.Height)

        Dim x1, y1 As Integer
        Dim x2, y2 As Integer

        '* Draw the line connecting the points
        If Points.Count > 1 Then
            Dim index As Integer = 0
            While index < (Points.Count - 2)
                Try
                    '* calculate the x and y coordinates based on the Points collection
                    x1 = Me.Width - Convert.ToInt32((Me.Width / MaxPoints) * index)
                    y1 = Me.Height - Convert.ToInt32((Me.Height / (YMaximum - YMinimum)) * (Points(index) - YMinimum))

                    x2 = Me.Width - Convert.ToInt32((Me.Width / MaxPoints) * (index + 1))
                    y2 = Me.Height - Convert.ToInt32((Me.Height / (YMaximum - YMinimum)) * (Points(index + 1) - YMinimum))
                    '*^ this was y1
                    Dim StartPixel As New Point(x1, y1)
                    Dim EndPixel As New Point(x2, y2)
                    'e.Graphics.DrawLine(System.Drawing.Pens.Yellow, StartPixel, EndPixel)
                    e.Graphics.DrawLine(System.Drawing.Pens.Yellow, x1, y1, x2, y2)
                Catch ex As Exception
                    Dim dbg = 0
                End Try
                index += 1
            End While
        End If

        '* Draw the Axis
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, 0, 0, Me.Height)
        e.Graphics.DrawLine(System.Drawing.Pens.White, 0, Me.Height - 1, Me.Width, Me.Height - 1)
        e.Graphics.DrawString(YMaximum.ToString, New Drawing.Font("Arial", 10.0!), System.Drawing.Brushes.White, 0.0!, 0.0!)
        '*                    ^^^^^^^^^^^^^^^ this was MaxValue
        e.Graphics.DrawString(YMinimum.ToString, New Drawing.Font("Arial", 10), System.Drawing.Brushes.White, 0, Me.Height - 16)
    End Sub
    Private _BackColour As Drawing.Color = Drawing.Color.Green
    Public Property BackColour() As Drawing.Color
        Get
            Return _BackColour
        End Get
        Set(ByVal value As Drawing.Color)
            _BackColour = value
        End Set
    End Property
End Class

Enjoy!