Node border color updates late

Hi All, 

in a diagram, I click on a node and want its bordercolor to be red. 

1. Why can't I say @Model.DiagramNetwork.updateNode() ?

2. This does not do anything, why:

function diagramNetwork_Click(event) {
var diagram = @Model.DiagramNetwork;
var nodeName = event.element.name;
diagram.updateNode(nodeName, { borderColor: 'Tomato' });

3. This does change the color, but only at  the second click:
function diagramNetwork_Click(event) {
event.element.borderColor = 'Tomato';

I am a bit lost. Thanks!




13 Replies

SG Shyam G Syncfusion Team June 13, 2018 05:30 AM UTC

Hi Gyorgy Gorog, 

Query 
Response 
1. Why can't I say @Model.DiagramNetwork.updateNode() ? 
 
You need to take diagram instance as shown below not as @Model.DiagramNetwork 
 
Code example: 
var diagram = $("#DiagramContent").ejDiagram("instance"); 
2. This does not do anything, why: 
 
function diagramNetwork_Click(event) { 
var diagram = @Model.DiagramNetwork; 
var nodeName = event.element.name; 
diagram.updateNode(nodeName, { borderColor: 'Tomato' }); 
 
3. This does change the color, but only at  the second click: 
function diagramNetwork_Click(event) { 
event.element.borderColor = 'Tomato'; 
 
  • You have created incorrect diagram instance in your code example. So only the updateNode method doesn’t works.
  • We have created a sample in which we have updated the node borderColor using  diagram client side updateNode method in the click event. Please refer to the modified code example below.
 
Code example: 
 
//define click event 
Diagram.Click = "diagramNetwork_Click"; 
 
function diagramNetwork_Click(args) { 
        if (args.element && args.elementType === "node") { 
            var diagram = $("#DiagramContent").ejDiagram("instance"); 
            diagram.updateNode(args.element.name, { borderColor: "Tomato" }); 
        } 
    } 
 
Here is the sample for your reference 
 
 

Regards, 
Shyam G 



GG Gyorgy Gorog June 13, 2018 07:02 AM UTC

Shyam, thanks for reply. 

But if I render the diagram in View as:

@<div id ="DiagramContent">
    @Model.DiagramNetwork
</div>

then what shall I do? Thanks.


SG Shyam G Syncfusion Team June 14, 2018 06:57 AM UTC

Hi Gyorgy Gorog, 
 
  • By default, to render a diagram in MVC we define diagram in view file as shown in below code example
 
Code example: 
@Html.EJ().Diagram("DiagramContent", ViewData["DiagramModel"] as Syncfusion.JavaScript.DataVisualization.Models.DiagramProperties) 
 
  • In the above code example, DiagramContent is an diagram id. So, to access an client side methods, we will take diagram instance with diagram id as shown in below code example
 
Code example: 
var diagram = $("#DiagramContent").ejDiagram("instance"); 
 
  • In the above code example, DiagramContent is an diagram id.
  • In your code example, you have defined it as  @Model.DiagramNetwork and please let us know what the DiagramNetwork returns and if it is an JSON, you can share it to us.
  • Also, we suspect that you may have an DiagramId in @Model.DiagramNetwork  and you use that id to get an diagram instance as shown in below code example.
 
Code example: 
var diagram = $(#DiagramId).ejDiagram("instance"); 
 
please let us know if any concerns. 
 
Regards, 
Shyam G 



GG Gyorgy Gorog June 18, 2018 06:02 AM UTC

Shyam, my simplest version is:

View:
@model JustNet.Models.NetworkDiagramPageModel
@<div id="DiagramContent">
    @Model.DiagramNetwork
</div> and that's all!

Controller:
public ViewResult NetworkDiagram( string id)
        {
            NetworkDiagramPageModel model = new NetworkDiagramPageModel();
            DrawNetwork(model, celex); // here I add nodes, connector, layout
            return View(model);
        }

Model:
public class NetworkDiagramPageModel
    {
        public Diagram DiagramNetwork { get; set; }
        public Overview DiagramNetworkOverview { get; set; }
public NetworkDiagramPageModel()
        {
// Diagram
            DiagramNetwork = new Diagram
            { ID = "diagramNetwork",
                DiagramModel = new DiagramProperties
                {
                    Height = "700px",
                    Width = "700px",
                    Click = "diagramNetwork_Click",
                    DefaultSettings = new SfDiagram.DefaultSettings.....

So the diagram is passed together with the View. In this case, I don't use ViewData.
I think this way is much simpler for C# fans/JS non-fans like me. Basicly the view is just a series of placeholders for the controls. Also you can pass data as objects (see next reply).
I may have 1-2 hours a day to elaborate this if you find this approach useful for others too.




GG Gyorgy Gorog June 18, 2018 06:04 AM UTC

Hi, the original question has lead me to a more general one. 

I try to keep the Razor side as simple as I can, so I render the controls like @Model.MyDiagram, or @Model.MyTabs etc. after having defined everything in Model.
Another advantage is that I can pass a data object with my model, like Model.Doc, that has e.g. Model.Doc.Title and Model.Doc.Date etc. and than again I just say <div>@Model.Doc.Title</div> and that's all.

Now I see that some controls, in my case so far Splitter and Tab, cannot be referenced this way as I get a nullReference error. So I had to implement Tab by DataView["MyTab"]. This is discouraged by the company style sheet and I can insert the Doc data only one-by-one like DataView["DocTitle"] = Doc.Title which is much uglier than Model.Doc.Title, and

Html.EJ().Tab("mainTab", (Syncfusion.JavaScript.Models.TabProperties)ViewData["MainTab"]).Render();
is much uglier (for me, I know xou like it) than the simplest 

@Model.MainTab 
 
Do you know which controls can be referred to as @Model.MyControl and which cannot? Is there any rational reason behind these differences? Can I implement a uniform interface w/os ViewData?

Again, I am willing to collaborate. 

Thanks.


SG Shyam G Syncfusion Team June 19, 2018 12:10 PM UTC

Hi Gyorgy Gorog, 
 
Query 
Response 
So the diagram is passed together with the View. In this case, I don't use ViewData. 
I think this way is much simpler for C# fans/JS non-fans like me. Basicly the view is just a series of placeholders for the controls. Also you can pass data as objects (see next reply). 
I may have 1-2 hours a day to elaborate this if you find this approach useful for others too. 
Yes, we can use the Model to pass the diagram properties from controller to keep the code to minimum instead of ViewData. We have modified your code example and provided below. 
 
Code example: 
 
Controller: 
public ActionResult Index() 
        { 
            NetworkDiagramPageModel model = new NetworkDiagramPageModel(); 
            BasicShape node = new BasicShape() { Name = "node1", Width = 100, Height = 100, OffsetX = 200, OffsetY = 200 }; 
            model.DiagramNetwork.DiagramModel.Nodes.Add(node); 
            return View(model); 
        } 
 
index.cshtml 
 
<div class="diagram_section"> 
            @Html.EJ().Diagram("DiagramContent", Model.DiagramNetwork.DiagramModel)             
        </div> 
 
Here is code example for click event 
 
   function diagramNetwork_Click(args) { 
            if (args.element && args.elementType === "node") {                  
                var diagram = $("#DiagramContent").ejDiagram("instance"); 
                diagram.updateNode(args.element.name, { borderColor: "Tomato" }); 
            } 
        } 
 
Note: DiagramContent is an diagram id. 
 
Please refer to the sample below for your reference. 
 
 
 

I try to keep the Razor side as simple as I can, so I render the controls like @Model.MyDiagram, or @Model.MyTabs etc. after having defined everything in Model.
 
Another advantage is that I can pass a data object with my model, like Model.Doc, that has e.g. Model.Doc.Title and Model.Doc.Date etc. and than again I just say <div>@Model.Doc.Title</div> and that's all. 
 
Now I see that some controls, in my case so far Splitter and Tab, cannot be referenced this way as I get a nullReference error. So I had to implement Tab by DataView["MyTab"]. This is discouraged by the company style sheet and I can insert the Doc data only one-by-one like DataView["DocTitle"] = Doc.Title which is much uglier than Model.Doc.Title, and 
 
Html.EJ().Tab("mainTab", (Syncfusion.JavaScript.Models.TabProperties)ViewData["MainTab"]).Render(); 
is much uglier (for me, I know xou like it) than the simplest  
 
@Model.MainTab  
  
Do you know which controls can be referred to as @Model.MyControl and which cannot? Is there any rational reason behind these differences? Can I implement a uniform interface w/os ViewData? 
Similarly, for an tab control use the Model to pass the TabProperties from the controller to keep the code to minimum instead of using the ViewData. Kindly refer to the following code.  
 
[Controller]  
public ActionResult Index()  
{  
    ModelData modeldata = new ModelData();  
    TabProperties tab = new TabProperties();  
    tab.Items.Add(new TabBaseItem() { ID = "javaScript", Text = "JavaScript", ContentTemplate = new MvcTemplate<TabBaseItem> { RazorViewTemplate = (data) => { return "JavaScript (JS) is an interpreted computer programming language"; } } });  
    tab.Items.Add(new TabBaseItem() { ID = "cSharp", Text = "C Sharp", ContentTemplate = new MvcTemplate<TabBaseItem> { RazorViewTemplate = (data) => { return " C# is intended to be a simple, modern, general-purpose, object-oriented programming language."; } } });  
    tab.Items.Add(new TabBaseItem() { ID = "vb", Text = "VB.Net", ContentTemplate = new MvcTemplate<TabBaseItem> { RazorViewTemplate = (data) => { return  The command-line compiler, VBC.EXE, is installed as part of the Freeware .NET Framework SDK."; } } });  
    modeldata.tab = tab;  
    return View(modeldata);  
}  
 
[View]  
@model TabSampleEJ1.Controllers.ModelData  
  
@Html.EJ().Tab("Tab", Model.tab)  
 
Yes, you can achieve uniform interface either with ViewData or with Model.  
 
Sample  
 
 
 
Regards, 
Shyam G 



GG Gyorgy Gorog June 21, 2018 07:39 AM UTC

Thanks, Shyam, this is what I needed to enlighten my dark mind. 


SG Shyam G Syncfusion Team June 22, 2018 05:13 AM UTC

Hi Gyorgy Gorog, 
We are happy to hear that your problem is resolved. 
Regards, 
Shyam G 



GG Gyorgy Gorog June 25, 2018 11:18 AM UTC

Shyam, this is just to aknowledge that the mode bordercolor works the way you implemented. 

So it seems it's better to create the controls in View even if some controls let themselves to be created in Model.

Thanks. 


SG Shyam G Syncfusion Team June 26, 2018 10:54 AM UTC

Hi Gyorgy Gorog, 
 
Query 
Response 
So it seems it's better to create the controls in View even if some controls let themselves to be created in Model. 
  Could you please confirm whether you need tab and other syncfusion controls to be rendered in view similar to our diagram like @Model.DiagramNetwork?, then mention the controls, so that we can forward this query to respective product team. 
   If we misunderstood your requirement, please let me know how you expect an syncfusion controls to be rendered in view other than normal way as shown below. 
  @Html.EJ().Diagram("DiagramContent", ViewData["DiagramModel"] as Syncfusion.JavaScript.DataVisualization.Models.DiagramProperties)  
   
 
Regards, 
Shyam G 



GG Gyorgy Gorog June 26, 2018 12:23 PM UTC

Shyam, I think it's OK as it is. Either you make all controls constructable from model, or it's better to render all of them from View. 
Thanks for your efforts anyway.


SG Shyam G Syncfusion Team June 27, 2018 12:51 PM UTC

Hi Gyorgy Gorog, 

The tab and splitter control should work similar to diagram control rendering in view @Model.DiagramNetwork. We will update you once we get a response from that team. 

Regards, 
Shyam G 



KR Keerthana Rajendran Syncfusion Team June 28, 2018 11:49 AM UTC

Hi Gyorgy Gorog,  
 
We checked the possibility to construct the component in model end and pass the component model to view to render it. This works fine with non – content templated component but for content templated component, we don’t get the context of the page where to render the child element generated html to text writer. Hence forth, component like Tab, splitter won’t support on this behavior. So, we should pass the instance of component model to view and render it via razor mark up.  
 
Regards, 
Keerthana. 


Loader.
Up arrow icon