search envelope-o feed check
Home Unanswered Active Tags New Question
user comment-o

Scheduler export date range problems

Asked by Ed
1 month ago.

Hi,

Using Web forms scheduler and I have it set up to advance or retreat +- 3 months using the “Previous/Next” examples found throughout the forums. The +- navigation works as expected; my timeline advances or retracts by 3 months. I also have Day/Week views using similarly found examples…working fine as well. I’ve now added export to PDF but if I do scale by week or move the timeline via Previous/Next the export still only shows the date current date range.

For example, my scale by week option shows a year’s worth of events (ex. Mar2024-Mar2025) but when I export I only get Dec2024-Feb6 which matches my default date range. In the sub that calls the export I am setting start date and days (using visible start and visible end…not certain that’s how it works - image attached) but still only get the default date range. The same thing occurs when I’m scaling in day mode and use “Previous/Next”.

What am I doing wrong? Thanks….

Answer posted by Dan Letecky [DayPilot]
1 month ago.

By default, the exportAs() method includes the current viewport in the exported image.

You can use the area property of the options parameter to include the full timeline (area: "full") or a manually-specified date range (area: "range").

This lets you export the Scheduler grid as multiple images (for paged PDF export). See also the following tutorials:

Comment posted by Ed
1 month ago.

Copy and thanks for the feedback. In looking at your example it seems to be client-side based - how would it translate to server-side exporting? Please review the following code, partially derived from one of the examples: 

Private Sub ExportToPdf2()

        Dim doc As PdfDocument = New PdfDocument()

        Dim bitmap As Bitmap = Dps_Scv.ExportBitmap()

        ' add the image to the PDF page

        Dim img As XImage = XImage.FromGdiPlusImage(bitmap)

 

       'these numbers are guesswork but for an 11x17 landscape format get the closest thing to a good output.

        Dim captureHeight As Double = 760

        Dim captureWidth As Double = 2510

        Dim totalHeight As Double = img.PixelHeight / 1.5

        Dim totalWidth As Double = img.PixelWidth

 

        Dim page As PdfPage = Nothing

        Dim i = 0

        Dim saveHeight As Double = 0

        While saveHeight < totalHeight

            page = New PdfPage()

            page.Size = PdfSharp.PageSize.Tabloid

            page.Orientation = PdfSharp.PageOrientation.Landscape

            doc.Pages.Add(page)

 

            Dim xgr As XGraphics = XGraphics.FromPdfPage(doc.Pages(i))

            xgr.DrawImage(img, 0, -i * captureHeight, captureWidth, totalHeight)

            saveHeight += captureHeight

            i += 1

        End While

        ' save the PDF file to MemoryStream

        Dim mem As New MemoryStream()

        doc.Save(mem, False)

 

  ' send the output stream to the browser

        Response.Clear()

        Response.ContentType = "application/pdf"

        Response.AddHeader("content-disposition", "attachment;filename=staffview.pdf")

        mem.WriteTo(Response.OutputStream)

        Response.End()

    End Sub

 

In the example (which again is a combo of DayPilot example code and kludges that I found on a PDF Sharp forum for multiple page printing of an exported image), the scheduler is being captured as a bitmap and then various pdf sharp methods are being used to format the output, ultimately being streamed to the browser as a pdf. It works, but not without issues, etc. and I don’t think it will scale well.

Can the “ExportAs” functionality be adapted to a server-side model? If so, are there any examples in the docs? On a whim, I tried using ExportAs in my code-behind but I’m getting a VS error about ExportAs not being a member of DayPilotScheduler (screenshot attached).

So guessing that it can’t be directly leveraged from server-side code – any suggestions?

Thanks again - Ed

Comment posted by Dan Letecky [DayPilot]
1 month ago.

On the server side, it is necessary to use Export() or ExportBitmap() methods (see Server-Side Image Export in the documentation).

To limit the exported range, you can set StartDate, Days and Resources properties as needed before calling Export().

Comment posted by Ed
1 month ago.

OK thanks Dan, I’m bit by bit getting there - as far as “Resources” are concerned, is that property available for ExportBitmap() and if so, could you provide an example of how that would be implemented server-side?

Thanks again, loving the product!

Comment posted by Dan Letecky [DayPilot]
1 month ago.

The server-side export methods export the current state of the Scheduler. That means you don’t specify parameters of the Export() method but you simply set the properties of DayPilotScheduler object before exporting.

Also, you don’t have to use the same DayPilotScheduler object that you use for the web page. You can create a special ad-hoc instance for the purpose of the export.

Comment posted by Ed
1 month ago.

OK, so guess that is what I’m asking…. how to set the resource property when using server-side code?

For example, say I have a scheduler with 100 rows over a time range of 90 days (this is close to accurate for one of my views in this project). In my code-behind print function (vb.net protected sub…) I’m capturing the start date and the days for what I want to print (this works). Now, if I’m using the default example from the support docs and I let this run I get a very compressed, can’t really read it single-page pdf which I’d expect based on the amount of data I’m trying to squeeze onto that single page.

Using the hybrid code that I sent in my earlier post I get a 4-page pdf that splits on a resource row. It isn’t really professional looking…I get split rows and duplicates, but it works. The problem is, it doesn’t scale well based on the kludge that the hybrid code uses (captureHeight, captureWidth); changes to the date range for printing eventually produce a less-than-optimal output.

In your html5 example, you are demonstrating a “paged” approach where you limit the number of resource rows and the date range to what I’m assuming fits reliably onto an 8.5x11 printed page. So, going back to my server-side code, how does one tell the code “hey, just do the export for 20 rows please”? If that can be done (server-side), then I can (I assume) capture the total # of rows and use that value in a loop to process exportBitmap() into usable chunks for import into a pdf.

Thanks

Comment posted by Dan Letecky [DayPilot]
1 month ago.

You probably have a method that you use to assign the resources to DayPilotScheduler.Resources, e.g. LoadResources():

DayPilotScheduler1.Resources = LoadResources()

You can simply create a loop and include a subset of the result before exporting every image, like this:

' Load all resources
Dim allResources As List(Of Resource) = LoadResources()

' Define the number of resources per export page
Dim pageSize As Integer = 10

' Calculate total number of pages
Dim totalResources As Integer = allResources.Count
Dim totalPages As Integer = CInt(Math.Ceiling(totalResources / CDbl(pageSize)))

' Initialize a list to hold the exported Bitmaps
Dim bitmapList As New List(Of Bitmap)()

' Loop through each page
For pageIndex As Integer = 0 To totalPages - 1
    ' Determine the range of resources for the current page
    Dim startIndex As Integer = pageIndex * pageSize
    Dim currentPageSize As Integer = Math.Min(pageSize, totalResources - startIndex)

    ' Get the subset of resources for the current page
    Dim subsetResources As List(Of Resource) = allResources.GetRange(startIndex, currentPageSize)

    ' Assign the subset to the scheduler's Resources
    DayPilotScheduler1.Resources = subsetResources

    ' Optionally, adjust the scheduler's visible range or other properties here

    ' Perform the export to Bitmap
    Dim exportedBitmap As Bitmap = DayPilotScheduler1.ExportBitmap()

    ' Add the exported Bitmap to the list
    bitmapList.Add(exportedBitmap)
Next
Comment posted by Ed
1 month ago.

' Define the number of resources per export page

Dim pageSize As Integer = 10

' Initialize a list to hold the exported Bitmaps

Dim bitmapList As New List(Of Bitmap)()

' Get the subset of resources for the current page

Dim subsetResources As List(Of Resource) = allResources.GetRange(startIndex, currentPageSize)

That’s what I was looking for - thanks!

Comment posted by Dan Letecky [DayPilot]
1 month ago.

Good, thanks for the update!

Just a correction, the Resources property accepts ResourceCollection which doesn’t support GetRange() so the subset must be created manually:

' Load all resources
Dim allResources As ResourceCollection = LoadResources()

' Define the number of resources per export page
Dim pageSize As Integer = 10

' Calculate total number of pages
Dim totalResources As Integer = allResources.Count
Dim totalPages As Integer = CInt(Math.Ceiling(totalResources / CDbl(pageSize)))

' Initialize a list to hold the exported Bitmaps
Dim bitmapList As New List(Of Bitmap)()

' Loop through each page
For pageIndex As Integer = 0 To totalPages - 1
    ' Determine the starting index for the current page
    Dim startIndex As Integer = pageIndex * pageSize
    ' Calculate the number of resources on the current page
    Dim currentPageSize As Integer = Math.Min(pageSize, totalResources - startIndex)

    ' Create a new ResourceCollection for the current subset
    Dim subsetResources As New ResourceCollection()

    ' Manually add the subset of resources to subsetResources
    For i As Integer = 0 To currentPageSize - 1
        ' Ensure we don't exceed the total number of resources
        If (startIndex + i) < totalResources Then
            subsetResources.Add(allResources(startIndex + i))
        End If
    Next

    ' Assign the subset to the scheduler's Resources
    DayPilotScheduler1.Resources = subsetResources

    ' Optionally, adjust the scheduler's visible range or other properties here

    ' Perform the export to Bitmap
    Dim exportedBitmap As Bitmap = DayPilotScheduler1.ExportBitmap()

    ' Add the exported Bitmap to the list
    bitmapList.Add(exportedBitmap)
Next
Comment posted by Ed
26 days ago.

Hi Dan, Happy New Year! Just getting back to this and not having a lot of luck - I’m getting an “Expression does not produce a value” error from Intellisense (Visual Studio 2019) when I try to assign my version of “LoadResources()” - please see the attached images.

The sub that loads up the resource column scheduler is LoadAircraft() and everything is called via “LoadAircraftAndEvents()” - both generate the same error when I try them in the line:

Dim allResources As ResourceCollection = LoadResources()

Code for the subs that populate the scheduler:

Private Sub LoadAircraft()

Dim todaysDate As Date = Now()

dps_acv.Resources.Clear()

Dim sSQL As String = "select a.id,tnum,sn,type,a.oconus,location=(select location from t_aircraft_location where a.id=aircraft_id and returnDate > '" & todaysDate & "') "

sSQL = sSQL & "from t_aircraft a where inactive='false' and NOT RIGHT(tnum, 3) = 'SIM' order by oconus,location,type"

Dim da As New SqlDataAdapter(sSQL, ConfigurationManager.ConnectionStrings("DeimosDev.My.MySettings.db_conn").ConnectionString)

Dim dt As New DataTable()

da.Fill(dt)

For Each r As DataRow In dt.Rows

Dim name As String = DirectCast(r("tnum"), String)

Dim sn As String = DirectCast(r("sn"), String)

Dim id_Renamed As String = Convert.ToString(r("id"))

Dim oconus As String = Convert.ToString(r("oconus"))

Dim stroconus As String = "HomeBase"

If Not IsDBNull(r("location")) Then

stroconus = DirectCast(r("location"), String)

End If

Dim strStatus As String = "FMC"

Dim res As New Resource(name, id_Renamed)

res.DataItem = r

res.Columns.Add(New ResourceColumn(sn))

res.Columns.Add(New ResourceColumn(stroconus))

res.Columns.Add(New ResourceColumn(strStatus))

dps_acv.Resources.Add(res)

Next r

End Sub

Private Sub LoadAircraftAndEvents()

LoadAircraft()

dps_acv.DataSource = DbGetEvents(dps_acv.VisibleStart, dps_acv.VisibleEnd)

dps_acv.DataBind()

dps_acv.Update()

End Sub

I’m assuming that I’m doing something fundamentally wrong - any insight? Thanks…

Comment posted by Ed
25 days ago.

OK, for the “Expression does not produce a value error“ I think I’ve come to understand that loadResources() has to be a function vs. a sub, etc. - it’s got to be able to return a value. When I duplicated my “loadAircraft()” code into a private function I don’t get the Intellisense error anymore. However, now I’m getting an “Unable to cast object of type 'System.Data.DataTable' to type 'DayPilot.Web.Ui.ResourceCollection” - guess that is to be expected since the return value from the function is a data table and not a resource collection or anything that can be cast as such.

No change on the read-only issue with resources, regardless of what is referenced for “allResources”.

The code partially works if I do this:

Dim allResources As ResourceCollection = dps_acv.Resources()

However, the print output is incorrect; I get the total resource count * the number of pages that the resources were supposed to be spread over. So, in this example I have a scheduler with 16 rows total. If I set pageSize = 10 I get a 2-page pdf with 16 rows instead of a two-page pdf with 10 rows on the 1st page and the remaining 6 rows on the 2nd. If I set pageSize = 5 then I get a 4-page pdf with 16 rows, etc.

I’m guessing that this means some of the code is working (totalResources, totalPages) but since I can’t apply the “subsetResources” value to the DPS.Resources that it’s just exporting the same bitmap into the bitmap list and when I iterate through the list all it has are duplicate images to add into the pdf.

Comment posted by Dan Letecky [DayPilot]
24 days ago.

Your loadAircraft() loads the resources directly to the Resources property of the DayPilotScheduler object. You can do it this way and then load the allResources value from there:

Dim allResources As ResourceCollection = dps_acv.Resources()

If all exported pages display all resources, you should check this line:

DayPilotScheduler1.Resources = subsetResources

Make sure that it loads the subset and not all resources. Also, you can place a breakpoint there and check if the subsetResources variable contains the expected resources.

Comment posted by Ed
24 days ago.

Hi Dan,

Thanks, that’s the way I have it configured but still getting the “Property ‘Resources” is ReadOnly” message from VS. Please see the uploaded image; it is the current sub that does the printing.

If I uncomment the “dps_acv.Resources =subsetResources” I get the above error in VS. If I comment it out the line the sub produces a print job like I described in my previous post.

Thanks

Comment posted by Dan Letecky [DayPilot]
24 days ago.

Oh, sorry. You are right, the Resources property is read-only.

You need to replace this:

DayPilotScheduler1.Resources = subsetResources

With this:

DayPilotScheduler1.Resources.Clear()
For Each resource In subsetResources
    DayPilotScheduler1.Resources.Add(resource)
Next
Comment posted by Ed
24 days ago.

Thanks for the quick reply - getting an “Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index”
on the line “subsetResources.add(allResources(startIndex +i))”

If I comment out the .resources.clear() line then it prints but does lots of duplicate loop. Does the “for each resource…” need to be inside of the “for i as integer…” loop or the “for pageIndex…” loop (that’s where I currently have it)?

Updated image attached, thanks.

Comment posted by Dan Letecky [DayPilot]
24 days ago.

This version operates on the same ResourceCollection instance. It is necessary to create a copy:

Instead of this:

Dim allResources As ResourceCollection = dps_acv.Resources()

Use this:

Dim allResources As New ResourceCollection()

For Each res As Resource In dps_acv.Resources()
    allResources.Add(res)
Next
Comment posted by Ed
24 days ago.

Winner! That got it!

What’s the mechanism there…. why didn’t the “Dim allResources As ResourceCollection = dps_acv.Resources()” work but putting it into a loop fix the issue?

Again, huge thanks…this was the last big thing that I had to deal with on this project :)

Comment posted by Dan Letecky [DayPilot]
24 days ago.

Great, thanks for the update!

Without making a copy, the allResources variable contains the same object as DayPilotScheduler1.Resources.

Calling DayPilotScheduler1.Resources.Clear() emptied the allResources as well. But allResources needed to contain all original resources in the subsequent page loop cycles.

Making a copy detaches allResources from DayPilotScheduler1.Resources.

Comment posted by Ed
24 days ago.

Oh ok, I’ve run into a sort of similar issue in other parts of this project when string building…makes sense now.

Thanks again!

This question is more than 1 months old and has been closed. Please create a new question if you have anything to add.