Revealing RadzenChart upon printing causes layout to be corrupted

I have an application that has several different Charts. User only sees 1 chart at a time, the user uses buttons to switch which chart is being viewed.

I have a print button, when user clicks it i want all the charts to be on the pages that is going to be printed.

To do this i put this in CSS:

@media print {
    .no-print, .no-print * {
        display: none !important;
    }
}

@media screen {
    .no-screen, .no-screen * {
        display: none !important;
    }
}

then in razor elements i just do: class="no-print" or class="no-screen" on the elements that i want to hide on print/screen. Basically, i have two core "divs", one for "no-print" and one for "no-screen". So when viewing the program in browser only "no-print" is shown and when printing only "no-screen" is printed. I then use "window.Print()" from js.

This works, however, if i dont show a chart on screen then it will be corrupted on print:

The chart flips upside down and width+height is wrong. Its impossible to read.

Is this a problem with RadzenChart? Or am i doing something wrong? Is there another method i could use to print all the charts in my program while not having them displayed when in browser mode?

You can try specifying the width of the chart during printing. Something like that:

@media print {
    .rz-chart {
        width: 500px !important;
        height: 500px !important;
    }
}

did not change anything. Tried putting that code in #media screen instead and that worked, so i dont think i did anything wrong.

I think the problem is something about the graph not being loaded/initialized because its not in view? Maybe if the graphs are shown for a splitsecond then hidden, then shown again when printing it will be fine? Or maybe if i show the graphs for a splitsecond before opening the print page?

You can also try setting the size of RadzenChart in pixels:

<RadzenChart style="width: 500px; height: 500px">

I was already doing that. Here is some of the html:

<RadzenContent Container="main">
    <ChildContent>
        <div class="row no-print">
                   //everything i dont want to print
        </div>
        <div class="row no-screen">
            <div class="row">
                <RadzenChart Style="height: 500px">
                    <RadzenLineSeries Stroke="rgb(0,153,65)" Smooth="true" Data="@nfoGraph" CategoryProperty="Frequency" Title="NFO" ValueProperty="Power">
                        <RadzenMarkers MarkerType="MarkerType.None" />
                    </RadzenLineSeries>

                    <RadzenLineSeries Stroke="rgb(153,15,0)" Smooth="true" Data="@pwmGraph" CategoryProperty="Frequency" LineType="LineType.Dashed" Title="PWM" ValueProperty="Power">
                        <RadzenMarkers MarkerType="MarkerType.None" />
                    </RadzenLineSeries>

                    <RadzenValueAxis Min="0" Max="@maxTest">
                        <RadzenGridLines Visible="true" />
                        <RadzenAxisTitle Text="Power (W)"/>
                    </RadzenValueAxis>

                    <RadzenCategoryAxis Min="5" Step="5" Max="@Fnom.Value">
                        <RadzenGridLines Visible="true" />
                        <RadzenAxisTitle Text="Frequency (Hz)" />
                    </RadzenCategoryAxis>
                </RadzenChart>

                //A few more charts that are almost identical to the one above.     
            </div>
        </div>
    </ChildContent>
</RadzenContent>

I dont know if its relevant, but in the no-print place i have a button:

                <div class="row">
                    <button class="btn btn-primary m-2" style="width: 100px" @onclick="JsPrint">Print</button>
                </div>

the function it calls:

    private async Task JsPrint()
    {
        await Js.InvokeVoidAsync("printDiv");
    }

the js function that calls:

function printDiv() {
    window.print();
}

I'm starting to think i have to flash the graphs before printing in order for them be correct. Is there a way for me to "wait" for the graphs to have been initialized? Or should i just hard code in a few millisecond delay? That might cause issues on slower computers though.

Try setting width as well.

yeah, i tried that before writing be previous comment. Yes, tried width and height at the same time too.

It worked perfectly to flash the charts for 10 ms before printing. The layout and sizes are all correct if i do that. Cause then the browser/program has time to lay out the layout. It's not layed out if its not shown, its not until the frame its being shown that the layout is built to the correct way.

However, hidding the divs after print is done seems more difficult. I tried just doing it after print was called:

  private async Task JsPrint()
    {
        printBeginTimer.Stop();
        await Js.InvokeVoidAsync("printDiv");
        showPrint = false;
    }

However, this did not work. So i tried with a 10 ms delay with a timer:

  private async Task JsPrint()
    {
        printBeginTimer.Stop();
        await Js.InvokeVoidAsync("printDiv");
        printEndTimer.Elapsed += EndPrintTimer_Tick;
        printEndTimer.Interval = 10;
        printEndTimer.Enabled = true;
        printEndTimer.Start();
    }

    private void EndPrintTimer_Tick(Object? source, ElapsedEventArgs e)
    {
        printEndTimer.Stop();
        showPrint = false;
    }

But that did not work either, tried many different intervals, it did not work.
The bool is being set correctly to false, the "controls"/"widgets"/view does not receive an alert that the bool was changed though. The change does not propagate.
When i change the bool with another button (showPrint = !showPrint ) it works fine.

So all i need to make my program work is a way to turn off the printable charts after print is done. Can i detect that print has been done or canceled?

Is there a way to force the view/design-area/widgets/controls to "update"/"refresh"?
The showPrint bool is set to false. As soon as i touch any button (that isnt even related to the charts or the bool) the view is updated and the charts disappear.

So if i could just force the view to update through code instead of the user having to click something, then i could hide the charts as i intended. Is there a way to "update"/"refresh" the view?

You can try with the StateHasChanged() method. But use it with InvokeAsync:

    private void EndPrintTimer_Tick(Object? source, ElapsedEventArgs e)
    {
        printEndTimer.Stop();
        showPrint = false;
        InvokeAsync(StateHasChanged);
    }

Awesome that worked, thanks for the help!