Render Maps component inside other components

10 May 202224 minutes to read

The Maps can be rendered within components such as the Dashboard Layout, Tabs, Dialog, and others. In general, the Maps component renders before other components, so a boolean variable ((i.e. boolean flag) is used to determine when to begin rendering the Maps component.

Maps component inside Dashboard Layout

When the Maps component renders within a panel of the Dashboard Layout component, its rendering begins concurrently with the Dashboard Layout component’s rendering. As a result, the size of the Maps component will not be proper. To properly render the Maps component, a boolean variable (i.e. IsInitialRender) must be created and it is used to determine the Maps component’s rendering. The boolean variable is set to false by default, so the Maps component will not be rendered initially. When the Dashboard Layout component is rendered, its Created event is fired, and the boolean variable (i.e. IsInitialRender) in this event must be changed to true to initiate the render of the Maps component.

When you drag and resize the Dashboard Layout’s panel, the Maps component is not notified, so the Maps are not properly rendered within the panel. To avoid this scenario, the Maps component’s Refresh method must be called in the Dashboard Layout’s Resizing and OnResizeStop events. Because the panel size of the Dashboard Layout is determined after a delay, a 500 millisecond delay must be provided before refreshing the Maps component.

On window resizing, the Maps component is not notified, so the Maps is not properly rendered within the panel. To avoid this scenario, the Dashboard Layout component’s RefreshAsync and the Maps component’s RefreshAsync method must be called in the Dashboard Layout’s OnWindowResize events.

@using Syncfusion.Blazor.Maps
@using Syncfusion.Blazor.Layouts

<SfDashboardLayout ID="DashBoard" @ref="DashboardLayout" AllowResizing="true"  AllowFloating="true" CellSpacing="@CellSpacing" Columns="20">
<DashboardLayoutEvents Created="Created" OnResizeStop="@ResizingHandler" OnWindowResize="@ResizingWindow" Resizing="ResizingHandler"></DashboardLayoutEvents>
    <DashboardLayoutPanels>
        <DashboardLayoutPanel Id="LayoutOne" Row="0" Col="5" SizeX="5" SizeY="7">
            <HeaderTemplate><div>Maps</div></HeaderTemplate>
            <ContentTemplate>
                @if (IsInitialRender)
                {
                     <SfMaps ID="Maps" @ref="MapsOne" Height="100%">
                        <MapsLayers>
                            <MapsLayer ShapeData='new {dataOptions= "https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                            </MapsLayer>
                        </MapsLayers>
                      </SfMaps> 
                }
            </ContentTemplate>
        </DashboardLayoutPanel> 
        <DashboardLayoutPanel Id="LayoutTwo" Row="1" Col="5" SizeX="5" SizeY="7">
            <HeaderTemplate><div>Maps - OSM</div></HeaderTemplate>
            <ContentTemplate>
                @if (IsInitialRender)
                {
                    <SfMaps ID="OSM" @ref="MapsTwo" Height="100%">
                           <MapsLayers>
                               <MapsLayer UrlTemplate="https://tile.openstreetmap.org/level/tileX/tileY.png" TValue="string"></MapsLayer>
                           </MapsLayers>
                       </SfMaps>
                }
            </ContentTemplate>
        </DashboardLayoutPanel> 
        <DashboardLayoutPanel Id="LayoutThree" Row="2" Col="5" SizeX="5" SizeY="7">
            <HeaderTemplate><div>Maps - SubLayer</div></HeaderTemplate>
            <ContentTemplate>
                @if (IsInitialRender)
                {
                    <SfMaps ID="SubLayer" @ref="MapsThree" Height="100%">
                        <MapsLayers>
                            <MapsLayer ShapeData='new {dataOptions ="https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                                <MapsShapeSettings Fill="#E5E5E5">
                                    <MapsShapeBorder Color="black" Width="0.1"></MapsShapeBorder>
                                </MapsShapeSettings>
                            </MapsLayer>
                            <MapsLayer ShapeData='new {dataOptions = "https://cdn.syncfusion.com/maps/map-data/africa.json"}'
	                    	        Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string">
                                <MapsShapeSettings Fill="rgba(141, 206, 255, 0.6)">
                                    <MapsShapeBorder Color="#1a9cff" Width="0.25"></MapsShapeBorder>
                                </MapsShapeSettings>
                            </MapsLayer>
                        </MapsLayers>
                    </SfMaps> 
                }
            </ContentTemplate>
        </DashboardLayoutPanel> 
    </DashboardLayoutPanels>
</SfDashboardLayout>

@code {
    SfMaps MapsOne;
    SfMaps MapsTwo;
    SfMaps MapsThree;
    SfDashboardLayout DashboardLayout;

    public double[] CellSpacing = { 10, 10 };
    public bool IsInitialRender { get; set; }

    public async void Created(Object args)
    {
        IsInitialRender = true;
    }

    public async Task ResizingWindow(ResizeArgs args)
    {
        await DashboardLayout.RefreshAsync();
        MapsOne.Refresh();
        MapsTwo.Refresh();
        MapsThree.Refresh();
    }
    
    public async void ResizingHandler(ResizeArgs args)
    {
        if(args.Id == "LayoutOne")
        {
            await Task.Delay(500);
            MapsOne.Refresh();
        } else if (args.Id == "LayoutTwo")
        {
            await Task.Delay(500);
            MapsTwo.Refresh();
        } else if(args.Id == "LayoutThree")
        {
            await Task.Delay(500);
            MapsThree.Refresh();
        }
    }
}

Blazor Maps inside Dashboard Layout component

Maps component inside Tab

When the Maps component renders within the Tab component, its rendering begins concurrently with the Tab component’s rendering. As a result, the size of the Maps component will not be proper. To properly render the Maps component, a boolean variable (i.e. IsInitialRender) must be created and it is used to determine the Maps component’s rendering. The boolean variable is set to false by default, so the Maps component will not be rendered initially. When the Tab component is rendered, its Created event is fired, and the boolean variable (i.e. IsInitialRender) in this event must be changed to true to initiate the render of the Maps component.

@using Syncfusion.Blazor.Navigations
@using Syncfusion.Blazor.Maps

    <SfTab CssClass="default-tab">
        <TabEvents Created="Created"></TabEvents>
        <TabItems>
            <TabItem>
                <ChildContent>
                    <TabHeader Text="Maps"></TabHeader>
                </ChildContent>
                <ContentTemplate>
                 @if (IsInitialRender)
                 {
                    <SfMaps ID="Maps" Width="100%">
                        <MapsLayers>
                            <MapsLayer ShapeData='new {dataOptions= "https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                            </MapsLayer>
                        </MapsLayers>
                    </SfMaps>                      
                 }   
                 </ContentTemplate>
            </TabItem>
            <TabItem>
                <ChildContent>
                    <TabHeader Text="Maps - OSM"></TabHeader>
                </ChildContent>
                 <ContentTemplate>
                 @if (IsInitialRender)
                 { 
                    <SfMaps ID="OSM" Width="100%">
                        <MapsLayers>
                            <MapsLayer UrlTemplate="https://tile.openstreetmap.org/level/tileX/tileY.png" TValue="string"></MapsLayer>
                        </MapsLayers>
                    </SfMaps> 
                 }   
                 </ContentTemplate>
            </TabItem>
            <TabItem>
                <ChildContent>
                    <TabHeader Text="Maps - SubLayer"></TabHeader>
                </ChildContent>
                 <ContentTemplate>
                 @if (IsInitialRender)
                 {
                    <SfMaps ID="SubLayer" Width="100%">
                        <MapsLayers>
                            <MapsLayer ShapeData='new {dataOptions ="https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                                <MapsShapeSettings Fill="#E5E5E5">
                                    <MapsShapeBorder Color="black" Width="0.1"></MapsShapeBorder>
                                </MapsShapeSettings>
                            </MapsLayer>
                            <MapsLayer ShapeData='new {dataOptions = "https://cdn.syncfusion.com/maps/map-data/africa.json"}'
	                    	        Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string">
                                <MapsShapeSettings Fill="rgba(141, 206, 255, 0.6)">
                                    <MapsShapeBorder Color="#1a9cff" Width="0.25"></MapsShapeBorder>
                                </MapsShapeSettings>
                            </MapsLayer>
                        </MapsLayers>
                    </SfMaps> 
                 }   
                 </ContentTemplate>
            </TabItem>
        </TabItems>
    </SfTab>

@code{
    public bool IsInitialRender { get; set; }
    public void Created()
    {
        IsInitialRender = true;
    }
}

Blazor Maps inside Tab component

Maps component inside Dialog

When the Maps component renders within the Dialog component, its rendering begins concurrently with the Dialog component’s rendering. As a result, the size of the Maps component will not be proper. To properly render the Maps component, a boolean variable (i.e. IsInitialRender) must be created and it is used to determine the Maps component’s rendering. The boolean variable is set to false by default, so the Maps component will not be rendered initially. When the Dialog component is being opened, its OnOpen event is fired, and the boolean variable (i.e. IsInitialRender) in this event must be changed to true to initiate the render of the Maps component. When the Dialog component is closed, its Closed event is fired, and the boolean variable (i.e. IsInitialRender) in this event must be changed to false.

When you drag and resize the Dialog component, the Maps component is not notified, so the Maps are not properly rendered within the Dialog. To avoid this scenario, the Maps component’s Refresh method must be called in the Dialog’s Resizing and OnResizeStop events. Because the size of the Dialog is determined after a delay, a 500 millisecond delay must be provided before refreshing the Maps component.

@using Syncfusion.Blazor.Popups
@using Syncfusion.Blazor.Maps

<div class="col-lg-12 control-section" id="target">
    <div>
        @if (this.ShowButton)
        {
            <button class="e-btn" @onclick="@OnClicked">Open</button>
        }
    </div>
    <SfDialog ResizeHandles="@DialogResizeDirections" AllowDragging="true" Height="400px" Width="400px" EnableResize="true" ShowCloseIcon="true" @bind-Visible="Visibility">
        <DialogEvents OnResizeStop="@OnResizeStopHandler" Resizing="OnResizeStopHandler" OnOpen="@DialogOpen" Closed="@DialogClose"></DialogEvents>
        <DialogTemplates>
            <Header>Maps</Header>
            <Content> 
                @if(IsInitialRender)
                {
                    <SfMaps ID="Maps" @ref="Maps" Height="100%">
                        <MapsLayers>
                            <MapsLayer ShapeData='new {dataOptions= "https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                            </MapsLayer>
                        </MapsLayers>
                    </SfMaps> 
                }
            </Content>
        </DialogTemplates>
    </SfDialog>
</div>
<style>
    #target {
        min-height: 400px;
    }
   
</style>
@code {
    SfMaps Maps;
    public bool IsInitialRender { get; set; }
    public bool Visibility { get; set; } = true;
    public bool ShowButton { get; set; } = false;
    public ResizeDirection[] DialogResizeDirections { get; set; } = new ResizeDirection[] { ResizeDirection.All };

    public async Task OnResizeStopHandler(Microsoft.AspNetCore.Components.Web.MouseEventArgs args)
    {
        await Task.Delay(500);
        Maps.Refresh();
    }

    private void DialogOpen(Object args)
    {
        this.ShowButton = false;
        IsInitialRender = true;
    }
    private void DialogClose(Object args)
    {
        this.ShowButton = true;
        IsInitialRender = false;
    }
    private void OnClicked()
    {
        this.Visibility = true;
    }
}

Blazor Maps inside Dialog component

Maps component inside Accordion

When the Maps component renders within the Accordion component, its rendering begins concurrently with the Accordion component’s rendering. As a result, the size of the Maps component will not be proper. To properly render the Maps component, a boolean variable (i.e. IsInitialRender) must be created and it is used to determine the Maps component’s rendering. The boolean variable is set to false by default, so the Maps component will not be rendered initially. When the Accordion component is rendered, its Created event is fired, and the boolean variable (i.e. IsInitialRender) in this event must be changed to true to initiate the render of the Maps component.

When you expand the Accordion component, the Maps component is not notified, so the Maps are not properly rendered within the Accordion. To avoid this scenario, the Maps component’s Refresh method must be called in the Accordion’s Expanded event.

@using Syncfusion.Blazor.Maps
@using Syncfusion.Blazor.Navigations

<div class="control-section accordion-control-section">
    <SfAccordion>
        <AccordionEvents Created="Created" Expanded="Expand"></AccordionEvents>
        <AccordionItems>
            <AccordionItem Expanded="true">
                <HeaderTemplate>Maps</HeaderTemplate>
                <ContentTemplate>
                 @if (IsInitialRender)
                 {
                     <SfMaps ID="Maps" @ref="MapsOne">
                        <MapsLayers>
                            <MapsLayer ShapeData='new {dataOptions= "https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                            </MapsLayer>
                        </MapsLayers>
                     </SfMaps> 
                 }
                </ContentTemplate>
            </AccordionItem>
            <AccordionItem>
                <HeaderTemplate>Maps - OSM</HeaderTemplate>
                <ContentTemplate>
                    @if (IsInitialRender)
                    {
                        <SfMaps ID="OSM" @ref="MapsTwo">
                           <MapsLayers>
                               <MapsLayer UrlTemplate="https://tile.openstreetmap.org/level/tileX/tileY.png" TValue="string"></MapsLayer>
                           </MapsLayers>
                        </SfMaps>
                    }      
                </ContentTemplate>
            </AccordionItem>
            <AccordionItem>
                <HeaderTemplate>Maps - SubLayer</HeaderTemplate>
                <ContentTemplate>
                     @if (IsInitialRender)
                     {
                        <SfMaps ID="SubLayer" @ref="MapsThree">
                            <MapsLayers>
                                <MapsLayer ShapeData='new {dataOptions ="https://cdn.syncfusion.com/maps/map-data/world-map.json"}' TValue="string">
                                    <MapsShapeSettings Fill="#E5E5E5">
                                        <MapsShapeBorder Color="black" Width="0.1"></MapsShapeBorder>
                                    </MapsShapeSettings>
                                </MapsLayer>
                                <MapsLayer ShapeData='new {dataOptions = "https://cdn.syncfusion.com/maps/map-data/africa.json"}'
	                        	        Type="Syncfusion.Blazor.Maps.Type.SubLayer" TValue="string">
                                    <MapsShapeSettings Fill="rgba(141, 206, 255, 0.6)">
                                        <MapsShapeBorder Color="#1a9cff" Width="0.25"></MapsShapeBorder>
                                    </MapsShapeSettings>
                                </MapsLayer>
                            </MapsLayers>
                        </SfMaps>   
                     }   
                </ContentTemplate>
            </AccordionItem>
        </AccordionItems>
    </SfAccordion>
</div>
<style>
    @@-moz-document url-prefix() {
        .e-accordion .e-content table {
            border-collapse: initial;
        }
    }
    .e-accordion table {
        width: 100%;
    }
    #nested-accordion.e-accordion {
        padding: 4px;
    }
    .e-accordion table th,
    .e-accordion table td {
        padding: 5px;
        border: 1px solid #ddd;
    }
    .accordion-control-section {
        margin: 0 10% 0 10%;
        padding-bottom: 25px;
    }
    .source-link {
        padding-bottom: 25px;
    }
    .annotationText {
        font-size: 35px;
        width: 120px;
        text-align: center;
        margin-top: -30px;
        margin-left: -55px
    }
</style>

@code{
    SfMaps MapsOne;
    SfMaps MapsTwo;
    SfMaps MapsThree;
    public bool IsInitialRender { get; set; }
    
    public void Created()
    {
        IsInitialRender = true;
    }

    public void Expand(ExpandedEventArgs args)
    {
        if(args.Index == 0)
        {
            MapsOne.Refresh();

        } else if (args.Index == 1)
        {
            MapsTwo.Refresh();

        } else if(args.Index == 2)
        {
            MapsThree.Refresh();
        } 
    }
}

Blazor Maps inside Accordion component