Current limitation: The Diagram component only allows pan through mouse interactions (Ctrl+drag). There are no methods to programmatically control the viewport.
Requested feature: Add programmatic viewport control API:
Use case:
Programmatic navigation: After adding a new shape, auto-scroll to show it; on search result, navigate to found shape
===
Forked from https://feedback.telerik.com/blazor/1708938
Current limitation: The Diagram component does not provide native context menu integration. There are no events like OnShapeContextMenu or OnConnectionContextMenu that fire on right-click. Developers cannot show contextual actions (edit, delete, copy, connect) when user right-clicks on diagram elements.
Requested feature: Add context menu support for Diagram elements:
Use case:
In workflow/process diagram editors, context menu is essential for:
Currently, there is no way to detect right-click on specific diagram elements. The only workaround is complex JavaScript interop to attach event listeners to SVG elements, which is fragile and breaks on re-render.
Example of desired API:
<TelerikDiagram @ref="@DiagramRef"
OnShapeContextMenu="@OnShapeRightClick"
OnConnectionContextMenu="@OnConnectionRightClick"
OnCanvasContextMenu="@OnCanvasRightClick">
<DiagramShapes>
@foreach (var shape in Shapes)
{
<DiagramShape Id="@shape.Id">
<DiagramShapeContent Text="@shape.Name" />
</DiagramShape>
}
</DiagramShapes>
</TelerikDiagram>
<TelerikContextMenu @ref="@ShapeContextMenu"
Data="@ShapeMenuItems"
OnClick="@OnShapeMenuClick">
<ItemTemplate Context="item">
<TelerikFontIcon Icon="@item.Icon" />
<span>@item.Text</span>
</ItemTemplate>
</TelerikContextMenu>
@code {
private TelerikContextMenu<MenuItem>? ShapeContextMenu;
private string? ClickedShapeId;
private async Task OnShapeRightClick(DiagramShapeContextMenuEventArgs args)
{
ClickedShapeId = args.ShapeId;
await ShapeContextMenu.ShowAsync(args.ClientX, args.ClientY);
}
private async Task OnShapeMenuClick(MenuItem item)
{
switch (item.Action)
{
case "edit":
await OpenShapeEditor(ClickedShapeId);
break;
case "delete":
await DeleteShape(ClickedShapeId);
break;
case "duplicate":
await DuplicateShape(ClickedShapeId);
break;
}
}
}Alternative minimal implementation:
Current limitation: The Diagram component only allows zoom through mouse interactions (scroll wheel). The Zoom parameter sets only the initial zoom level and cannot be changed at runtime. There are no methods to programmatically control the viewport.
Requested feature: Add programmatic viewport control API:
Use case:
In enterprise workflow/process editors, users need navigation controls beyond mouse wheel:
Accessibility: Users with trackpads, touch screens, or motor impairments cannot easily use scroll wheel zoom
Toolbar buttons: Standard diagram tools (Visio, Draw.io, Lucidchart) provide +/−/100%/Fit buttons
Programmatic navigation: After adding a new shape, auto-scroll to show it; on search result, navigate to found shape
Keyboard shortcuts: Implement Ctrl+Plus/Minus for zoom without native support
<TelerikDiagram @ref="@DiagramRef"
@bind-Zoom="@CurrentZoom"
ZoomChanged="@OnZoomChanged">
...
</TelerikDiagram>
<TelerikButton OnClick="@(() => DiagramRef.ZoomInAsync())">+</TelerikButton>
<TelerikButton OnClick="@(() => DiagramRef.ZoomOutAsync())">−</TelerikButton>
<TelerikButton OnClick="@(() => DiagramRef.SetZoomAsync(1.0))">100%</TelerikButton>
<TelerikButton OnClick="@(() => DiagramRef.FitToScreenAsync())">Fit</TelerikButton>
@code {
private TelerikDiagram? DiagramRef;
private double CurrentZoom = 1.0;
private async Task NavigateToShape(string shapeId)
{
await DiagramRef.BringIntoViewAsync(new[] { shapeId });
}
}
When there is no predefined Diagram layout, and a shape parameter value changes at runtime:
Possible workarounds:
To reproduce:
<label class="lbl">
Width: <TelerikNumericTextBox @bind-Value="@SelectedShapeWidth" Width="120px" />
</label>
<label class="lbl">
Height: <TelerikNumericTextBox @bind-Value="@SelectedShapeHeight" Width="120px" />
</label>
<label class="lbl">
X: <TelerikNumericTextBox @bind-Value="@SelectedShapeX" Width="120px" />
</label>
<label class="lbl">
Y: <TelerikNumericTextBox @bind-Value="@SelectedShapeY" Width="120px" />
</label>
<label class="lbl">
Angle: <TelerikNumericTextBox @bind-Value="@SelectedShapeAngle" Width="120px" />
</label>
<style>
.lbl {
display: block;
margin: 0 0 1em;
}
</style>
<TelerikButton OnClick="@OnButtonClick">Apply</TelerikButton>
@if (RenderDiagram)
{
<TelerikDiagram Height="300px" Zoom="0.8">
<DiagramShapes>
<DiagramShape
Id="shape1"
Width="100"
Height="100"
X="200"
Y="50">
<DiagramShapeContent Text="Shape 1" />
<DiagramShapeRotation Angle="0" />
</DiagramShape>
<DiagramShape
Id="@SelectedShapeId"
Width="@SelectedShapeWidth"
Height="@SelectedShapeHeight"
X="@SelectedShapeX"
Y="@SelectedShapeY">
<DiagramShapeContent Text="Shape 2" />
<DiagramShapeRotation Angle="@SelectedShapeAngle" />
</DiagramShape>
</DiagramShapes>
</TelerikDiagram>
<TelerikDiagram Height="300px" Zoom="0.8">
<DiagramShapes>
<DiagramShape
Id="shape1"
Width="100"
Height="100"
X="200"
Y="50">
<DiagramShapeContent Text="Shape 1" />
<DiagramShapeRotation Angle="0" />
</DiagramShape>
<DiagramShape
Id="@SelectedShapeId"
Width="@SelectedShapeWidth"
Height="@SelectedShapeHeight"
X="@SelectedShapeX"
Y="@SelectedShapeY">
<DiagramShapeContent Text="Shape 2" />
<DiagramShapeRotation Angle="@SelectedShapeAngle" />
</DiagramShape>
</DiagramShapes>
<DiagramConnections>
<DiagramConnection FromId="shape1" ToId="shape2" />
</DiagramConnections>
</TelerikDiagram>
}
@code {
#nullable enable
private List<ShapeDescriptor> DiagramShapeList { get; set; } = new();
private string SelectedShapeId { get; set; } = "shape2";
private double? SelectedShapeAngle { get; set; } = 0;
private double? SelectedShapeWidth { get; set; } = 100;
private double? SelectedShapeHeight { get; set; } = 100;
private double? SelectedShapeX { get; set; } = 300;
private double? SelectedShapeY { get; set; } = 200;
private bool RenderDiagram { get; set; } = true;
private async Task OnButtonClick()
{
if (string.IsNullOrEmpty(SelectedShapeId))
{
return;
}
RenderDiagram = false;
await Task.Delay(1);
RenderDiagram = true;
}
public class ShapeDescriptor
{
public string Id { get; set; } = string.Empty;
public string ParentId { get; set; } = string.Empty;
public DiagramShapeType Type { get; set; } = DiagramShapeType.Image;
public string Text { get; set; } = string.Empty;
public string Source { get; set; } = string.Empty;
public double? Width { get; set; } = 100;
public double? Height { get; set; } = 100;
public double? X { get; set; }
public double? Y { get; set; }
public double? Angle { get; set; }
}
}
Expose an OnShapeDrop event for the Diagram. It should provide information about the shape's current X and Y coordinates.
This would allow the user to save the diagram (e.g., as json) and load it later.
Current limitation: When DiagramShapeDefaultsEditable.Connect="true",
users can draw connections between shapes, but there is no event fired
when a new connection is created by the user.
Requested feature: Add OnConnectionCreated event that:
Use case: We need to capture user-created connections to persist them to database, validate business rules (e.g., prevent circular dependencies), and set connection properties (type, label, color) based on context.
Current limitation:
DiagramConnectionType only supports Cascading (orthogonal) and Polyline
types. There is no curved or Bezier option.
Requested feature: Add a new connection type such as DiagramConnectionType.Bezier or DiagramConnectionType.Curved that:
Use case: For workflow diagrams with many crossing connections, curved lines improve visual clarity and reduce cognitive load compared to sharp 90° angles.
Current limitation: The Diagram component only provides OnShapeClick event. There is no native double-click event for shapes.
Requested feature: Add OnShapeDoubleClick event that:
Use case: In workflow editors, single-click should select a shape, while double-click should open an editor dialog. Currently, we have to implement manual timing-based detection which is unreliable and doesn't match native OS double-click behavior.
We would like to use built-in tooltips for Shapes an Connections in the Diagram component to show some additional information of the different items and their relation.
Would it be possible to add this functionality similar to the MapLayerMarkerSettingsTooltip of the Map component?