locked
Line Chart - need some help RRS feed

  • Question

  • User-755734930 posted

    I found a code that draw a line char based in some values

    I have a problem when range between min and max value is too short, for example

    If I want to plot 20 values between 100 and 1000 works very well, but if I want to plot 20 values between 100 and 101, doesn’t work, I think that the problem is in the radio adjustment, but I can’t see the solution, I had been trying but nothing works for me, this is the code.

    Any help is very welcome!!..

    <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p> </o:p>

    Thanks

    Code here:

     

    Imports System.Drawing

    Imports System.Drawing.Drawing2D

    Imports System.Drawing.Imaging

    Imports System.Drawing.Text

    Partial Class test

    Inherits System.Web.UI.Page

    Private gfx As Graphics

    Private bmp As Bitmap

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    bmp = New Bitmap(640, 480)

    gfx = Graphics.FromImage(bmp)

    gfx.Clear(Color.White)

    gfx.SmoothingMode = SmoothingMode.AntiAlias

    Dim p As Double() = generateRandomValues()Dim k As Double() = New Double(p.Length - 1) {}

    Array.Copy(p, k, p.Length)

    Array.Sort(k)

    DrawChart(p, k(k.Length - 1), k(0))

    End Sub

    Private Sub DrawChart(ByVal points As Double(), ByVal maxValue As Double, ByVal minValue As Double)

    Dim adjustVerticalRatio As Double = 0

    Dim adjustHorizontalRatio As Double = 0

    'Offset (Margin) Values

    Dim bottomOffset As Integer = 50

    Dim topOffset As Integer = 50

    Dim leftOffset As Integer = 50Dim rightOffset As Integer = 50

     

    ' Taking care of some bookwork (declaring/initializing variables)

    Dim maxDataPoints As Integer = points.Length

    Dim chartHeight As Integer = bmp.Height - bottomOffset

    Dim chartWidth As Integer = bmp.Width - rightOffset

    'Draw Border Lines

    Dim borderLine As New Pen(Color.DarkGray, 2)

    'Left Border

    gfx.DrawLine(borderLine, New Point(leftOffset, chartHeight), New Point(leftOffset, topOffset))

    'Bottom Border

    gfx.DrawLine(borderLine, New Point(leftOffset, chartHeight), New Point(chartWidth, chartHeight))

    'Right Border

    gfx.DrawLine(borderLine, New Point(chartWidth, chartHeight), New Point(chartWidth, topOffset))

    'Top Border

    gfx.DrawLine(borderLine, New Point(leftOffset, topOffset), New Point(chartWidth, topOffset))

     

     

    ' Adjustable Values

    Dim adjustedMax As Double = ((maxValue - minValue) * 0.01) + maxValueDim adjustedMin As Double = minValue - ((maxValue - minValue) * 0.01)

    adjustHorizontalRatio = ((chartWidth - leftOffset) / (maxDataPoints - 1))

    If maxValue - minValue >= chartHeight Then

    adjustVerticalRatio = (chartHeight - topOffset) / adjustedMax

    Else

    'adjustVerticalRatio = ((chartHeight - topOffset) / adjustedMax)

    adjustVerticalRatio = (chartHeight - topOffset) / adjustedMax

    End If

    Dim chartPen As New Pen(Color.Orange, 3)

    Dim gridLine As New Pen(Color.LightGray, 1)

    Dim minYpos As Integer = chartHeight - topOffset

    Dim maxYpos As Integer = 10

    For i As Integer = 0 To maxDataPoints - 2

    ' Drawing the Lines

    Dim xPos As Single = Convert.ToSingle(i * adjustHorizontalRatio) + leftOffset

    Dim xPos2 As Single = Convert.ToSingle((i + 1) * adjustHorizontalRatio) + leftOffset

    Dim yPos As Single

    Dim yPos2 As Single

    If maxValue - minValue >= chartHeight Then

    yPos = Convert.ToSingle(chartHeight - adjustVerticalRatio * points(i))

    yPos2 = Convert.ToSingle(chartHeight - adjustVerticalRatio * points(i + 1))

    Else

    yPos = Convert.ToSingle(chartHeight - adjustVerticalRatio * points(i))

    yPos2 = Convert.ToSingle(chartHeight - adjustVerticalRatio * points(i + 1))

    End If

    If points(i) = minValue Then

    minYpos = yPos

    End If

    If points(i) = maxValue Then

    maxYpos = yPos

    End If

    gfx.DrawLine(gridLine, xPos2, topOffset, xPos2, chartHeight)

    gfx.DrawLine(chartPen, xPos, yPos, xPos2, yPos2)

    gfx.DrawString(i.ToString(),
    New Font("Arial", 8), New SolidBrush(Color.Gray), New Point(xPos - 4, chartHeight + 10))

    Next

    'Drawing Vertical Min/Max Values

    gfx.DrawString(maxValue.ToString(), New Font("Arial", 8), New SolidBrush(Color.Gray), New Point(leftOffset - 25, maxYpos))

    gfx.DrawString(minValue.ToString(), New Font("Arial", 8), New SolidBrush(Color.Gray), New Point(leftOffset - 25, minYpos))

    gfx.DrawLine(gridLine, New Point(leftOffset - 25, minYpos), New Point(chartWidth, minYpos))

    gfx.DrawLine(gridLine, New Point(leftOffset - 25, maxYpos), New Point(chartWidth, maxYpos))

    ' Title

    gfx.DrawString("[ Plotting Random Numbers ]", New Font("Arial", 10, FontStyle.Bold), New SolidBrush(Color.FromArgb(0, 102, 204)), New Point(leftOffset + 60, topOffset - 30))

    'Finalizing and Cleaning Up

    Response.ContentType = "image/jpeg"

    bmp.Save(Response.OutputStream, ImageFormat.Jpeg)

    bmp.Dispose()

    gfx.Dispose()

    Response.[End]()

    End Sub

    Private Function generateRandomValues() As Double()

    Dim rand As New Random()

    Dim numValues As Integer = 22

    Dim newArray As Double() = New Double(numValues - 1) {}

    For i As Integer = 0 To numValues - 1

    newArray(i) = rand.[Next](100, 101) + rand.NextDouble

    Next

    Return newArray

    End Function

    End Class

    Monday, August 18, 2008 3:21 PM

All replies

  • User117812838 posted

    You cannot achieve this kind of transform using multiplication only. The solution in my opinion would be:<o:p></o:p>

    <o:p> </o:p>

    Given the following parameters:<o:p></o:p>

    minView, maxView, minData, maxData,<o:p></o:p>

    where min / max view are the minimum / maximum coordinate in view<o:p></o:p>

    min / max Data are the minimum / maximum values you’re about to plot. <o:p></o:p>

    Value – an arbitrary value between minData and maxData:<o:p></o:p>

    <o:p> </o:p>

    Define a function that linearly maps in the range [minData, maxData] to [minView, maxView]<o:p></o:p>

     <o:p></o:p>

    Solution:<o:p></o:p>

    ViewRange = (maxView – minView);
    DataRange = (maxData – minData);
    Ratio = ViewRange / DataRange;<o:p></o:p>

    <o:p> </o:p>

    Coordinate = minView + ((value – minData) * Ratio;

    Verification:<o:p></o:p>

    For value = minData:<o:p></o:p>

    Coordinate = minView + (minData – minData) * (maxView – minView) / (maxData – minData) = minView;<o:p></o:p>

    <o:p> </o:p>

    For value = maxData;<o:p></o:p>

    minView + (maxData – minData) * (maxView – minView) / (maxData – minData) = <o:p></o:p>

    minView + (maxView – minView) =  maxView;

    <o:p></o:p>

    Checkout Nevron for a commercially available charting solution and save months of development.

     

    2D Line Chart  3D Line Chart

     

    Best regards,

    Anton Bahchevanov

    Nevron Software Team

     

    Monday, September 1, 2008 6:28 AM