Link to home
Start Free TrialLog in
Avatar of Hans J.Hau
Hans J.Hau

asked on

Slow page loading when there are 40 pie charts, how to speed up loading?

My web page has the function to create 40 different pie charts for 40 different machines and their activity and display them after loading. However, I noticed that by doing so the page loading is much longer, takes about 30 seconds to finish loading.

At first I thought it was my SQL to get the data for 40 machines was the cause. But after copying it from the code and testing it, that was not true. Also, the page loads faster when I set my page to create a single pie chart, so I'm likely to assume that the large sum of pie charts to create is the cause for the slowdown.

 Sub draw_chart1() 'All Machines

        Dim check1, check2, fi, cnt

        Dim sql
        Dim myConnectionString As String = "Provider=SQLOLEDB;" & SQLDB_pp.ConnectionString
        fi = 0
        cnt = 0

        PlaceHolder1.Dispose()
        PlaceHolder2.Dispose()
        'Get all model
        Dim query1 As String = String.Format("SELECT DISTINCT A.MacID FROM dbo.tblMachine A LEFT JOIN  dbo.tblDataHdr b on a.MacID = b.MacID where DayID between '" & TextBox1.Text & "' AND '" & TextBox3.Text & "' ORDER BY A.MACID")
        Dim dt1 As DataTable = GetData(query1)
        For Q As Integer = 0 To dt1.Rows.Count - 1
            'For Q As Integer = 0 To 1
            check1 = dt1.Rows(Q)(0).ToString()

            Dim query As String = String.Format("SELECT Z.MacID, Z.EventName, ISNULL(DIFF,0) AS DIFF FROM (select distinct MacID, EventName from dbo.tblMachine a  join (SELECT DISTINCT EVENTNAME FROM dbo.tblEvtDur where EventName <> 'ON'  ) b on b.EventName <> ''  and MacID in ('" & check1 & "') ) Z LEFT JOIN (SELECT A.MacID, A.EventName, SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) as diff,round(SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) / cast(aVG(Tdiff) as decimal(30,8)),4) * 100 AS PER FROM dbo.tblEvtDur  A LEFT JOIN ( SELECT MacID, SUM(DATEDIFF(SECOND, STARTdt, eNDdt)) as Tdiff FROM  dbo.tblEvtDur  WHERE DayID between '" & TextBox1.Text & "' and '" & TextBox3.Text & "'  GROUP BY MacID ) B ON  A.MacID = B.MacID WHERE DayID between '" & TextBox1.Text & "' and '" & TextBox3.Text & "'  AND A.MacID in ('" & check1 & "') group by A.MacID, A.EventName) a ON A.EVENTNAME = Z.EVENTNAME  and Z.MacID  = a.MacID order by Z.MacID, Z.EventName")

            Dim mychart As Chart = New Chart
            ' Dim myplace As PlaceHolder = New PlaceHolder
            Dim ChartArea1 As ChartArea = New ChartArea
            Dim Legend1 As Legend = New Legend

            Dim dt As DataTable = GetData(query)
            Dim x As String() = New String(dt.Rows.Count - 1) {}
            Dim y As Integer() = New Integer(dt.Rows.Count - 1) {}
            For i As Integer = 0 To dt.Rows.Count - 1

                x(i) = dt.Rows(i)(1).ToString()
                ' y(i) = dt.Rows(i)(2).ToString()
                y(i) = Convert.ToInt32(dt.Rows(i)(2))
            Next

            'Dim myConnection As New OleDbConnection(myConnectionString)
            'Dim myCommand As New OleDbCommand(sql, myConnection)
            'mychart.Width = Unit.Pixel(Session("sw") - 100)
            'mychart.Height = Unit.Pixel((Session("sh") / 2) - 88)

            mychart.Width = 600
            mychart.Height = 400

            mychart.ChartAreas.Clear()
            mychart.ChartAreas.Add("ChartArea1")

            mychart.Series.Clear()
            mychart.Series.Add(0)
            mychart.Series(0).Points.DataBindXY(x, y)

            mychart.Titles.Clear()
            mychart.Titles.Add("[" & Q + 1 & "] " & check1.ToString.ToUpper)
            mychart.Titles(0).Font = New System.Drawing.Font("Tahoma", 12, System.Drawing.FontStyle.Bold)
            mychart.Titles(0).BackColor = Color.PaleTurquoise
            mychart.Titles(0).ForeColor = Color.Black

            mychart.Series(0).ChartType = SeriesChartType.Pie
            '  mychart.Series(0).Points.DataBindXY(x, y)
            mychart.Series(0).LegendText = "#VALX"
            mychart.Series(0)("BarLabelStyle") = "Center"
            mychart.Series(0)("pointWidth") = "1"
            mychart.Series(0).BorderDashStyle = ChartDashStyle.Solid
            mychart.Series(0).BorderWidth = 2
            mychart.Series(0).Label = "#PERCENT"
            mychart.Series(0).ShadowColor = Color.Gray
            mychart.Series(0).ShadowOffset = 10

            mychart.Series(0).LabelBackColor = Drawing.Color.Cornsilk
            mychart.Series(0).Font = New Font("Tahoma", 9, FontStyle.Bold)

            'Chart1.Series(0).LabelToolTip = "#LABEL Percent: #PERCENT"
            mychart.Series(0).LegendToolTip = "#VALX - #PERCENT"
            mychart.Series(0).ToolTip = "#VALX - #PERCENT"

            mychart.ChartAreas("ChartArea1").Area3DStyle.Enable3D = True

            mychart.Series(0).CustomProperties = "DrawingStyle=LightToDark"
            'new
            Chart1.Series(0).CustomProperties = "PieLabelStyle=Outside"
           
            mychart.ChartAreas("ChartArea1").BorderDashStyle = BorderStyle.Solid
            mychart.Palette = ChartColorPalette.None
            mychart.Series(0).BorderDashStyle = ChartDashStyle.Solid
            mychart.Series(0).BorderWidth = 2
            mychart.Series(0).BorderColor = Color.Black

            mychart.PaletteCustomColors = {Drawing.Color.Black, Drawing.Color.LightGray, Drawing.Color.Blue, Drawing.Color.Yellow, Drawing.Color.Red, Drawing.Color.Orange, Drawing.Color.Green}

            mychart.Legends.Clear()
            mychart.Legends.Add(0)
            'Chart1.Legends(0).Enabled = True
            ''Chart1.Legends(0).BackColor = Drawing.Color.LightGreenplace
            mychart.Legends(0).Font = New Font("Tahoma", 10, FontStyle.Bold)
            mychart.Legends(0).Docking = System.Web.UI.DataVisualization.Charting.Docking.Bottom
            'Chart1.Legends(0).Alignment = Drawing.StringAlignment.Center
            'Chart1.Legends(0).BackColor = System.Drawing.Color.Transparent

            mychart.DataBind()

            'myplace.Visible = True
            If (Q + 1) Mod 2 <> 0 Then
                PlaceHolder1.Controls.Add(mychart)
                ' Dim spacer As LiteralControl = New LiteralControl("<p />")
                ' PlaceHolder1.Controls.Add(spacer)
            End If
            'Exit For
            If (Q + 1) Mod 2 = 0 Then

                PlaceHolder2.Controls.Add(mychart)
                'Dim spacer As LiteralControl = New LiteralControl("<p />")
                ' PlaceHolder2.Controls.Add(spacer)

            End If

        Next
    End Sub

Open in new window


This is what I use to create 40 pie charts in VB net. From my understanding of how the code works, it uses the 1st SQL statement to look up the list of machines operational for the date range specified and keeps the data in a DataTable, Then using the data in the DataTable, the 2nd SQL will get the necessary data to create the pie chart for the 1st machine in the DataTable. After that is complete, the code loops back to the 2nd SQL to repeat for the remaining machines.

I believe that is the main cause for the slowdown but I'm not sure on how to speed it up.
Avatar of Dr. Klahn
Dr. Klahn

I would personally think, and this is purely an opinion, that 30 seconds for 40 charts generated via SQL is pretty good response time.  That is 0.75 seconds per chart, and I would venture that this is about what is required to produce just one chart.  But while 0.75 seconds is not noticeable for one chart, 30 seconds for 40 charts certainly is.

Excel is "the standard" but I doubt that anyone would say that it is efficient in terms of CPU or memory use.  When doing 40 charts the inefficiency is multiplied by 40 plus the overhead involved in scaling and relocating each one to fit.  Combine that with SQL overhead and this is a recipe for significant slowdowns.

You might try:  See if the machine is paging during this operation, and if so, double the memory.  Memory is cheap but programmer time is not.
Avatar of Hans J.Hau

ASKER

Wait, do you mean double the memory of my PC? Cuz that is highly unlikely to do for every PC in my company who wants to use it...

Is there a more efficient method than what I have now?
Like for example, is it possible to have my web page load in first without any pie charts, then load a pie chart and repeat one by one until they're finished?

Sure it may not necessary be reducing slowdown, but at least users get to see some data while the others are still processing.
Any other leads? I've done some research on my end but still found no leads to this issue...

Plus my boss expects me to solve this as soon as possible.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.