New to Kendo UI for jQuery? Download free 30-day trial

Implement Local Data Editing in the Diagram

Environment

Product Progress® Kendo UI® Diagram for jQuery
Operating System Windows 10 64bit
Visual Studio Version Visual Studio 2017
Preferred Language JavaScript

Description

How can I render local data in the Kendo UI for jQuery Diagram?

Solution

The following example demonstrates how to implement the editing functionality with local data by using custom functions for the dataSource transport operations.

You need this functionality because assigning a non-default id value for the new items is required in order for the item to be accepted as existing by the dataSource and the new shapes to be displayed by the Diagram.


    <script>

      function localDataSource(options) {
        var id =  options.schema.model.id;
        var data = options.data;
        var newId = -1;
        var created, updated, deleted;

        var dataSource = new kendo.data.DataSource($.extend(true, {
          transport: {
            read: function(e) {
              created = {};
              updated = {};
              deleted = {};

              e.success(data || []);
            },

            update: function(e) {
              var item = e.data;
              if (!created[item[id]]) {
                updated[item[id]] = item;
              }
              e.success();
            },

            destroy: function(e) {
              var idValue = e.data[id];
              if (!created[idValue]) {
                deleted[idValue] = e.data;
              } else {
                delete created[idValue];
              }
              e.success();
            },
            create: function(e) {
              var item = e.data;
              item[id] = newId--;
              created[item[id]] = $.extend(true, {}, item);

              e.success(item);
            }
          },
        }, options));

        dataSource.getChanges = function () {
          return {
            deleted: toArray(deleted),
            created: toArray(created),
            updated: toArray(updated)
          }
        };

        return dataSource;
      }

      function toArray(changes) {
        var result = [];
        for (var id in changes) {
          result.push(changes[id]);
        }
        return result;
      }

      function createDiagram() {
        var shapesDataSource = localDataSource({
          data: [{
            "Id": 1,
            "JobTitle": "President"
          }, {
            "Id": 2,
            "JobTitle": "VP Finance",
            "Color": "#3399cc"
          }, {
            "Id": 3,
            "JobTitle": "VP Customer Relations",
            "Color": "#3399cc"
          }, {
            "Id": 4,
            "JobTitle": "VP Human Resources",
            "Color": "#3399cc"
          }],
          schema: {
            model: {
              id: "Id",
              fields: {
                Id: { type: "number", editable: false },
                JobTitle: { type: "string" },
                Color: { type: "string" }
              }
            }
          }
        });

        var connectionsDataSource = localDataSource({
          data:  [{
            "Id": 1,
            "FromShapeId": 1,
            "ToShapeId": 2
          }, {
            "Id": 2,
            "FromShapeId": 1,
            "ToShapeId": 3
          }, {
            "Id": 3,
            "FromShapeId": 1,
            "ToShapeId": 4
          }],
          schema: {
            model: {
              id: "Id",
              fields: {
                Id: { type: "number", editable: false },
                from: { from: "FromShapeId", type: "number" },
                to: { from: "ToShapeId", type: "number" },
                fromX: { from: "FromPointX", type: "number" },
                fromY: { from: "FromPointY", type: "number" },
                toX: { from: "ToPointX", type: "number" },
                toY: { from: "ToPointY", type: "number" }
              }
            }
          }
        });

        var changesViewModel = kendo.observable({
          showChanges: function () {
            var diagram = $("#diagram").data("kendoDiagram");
            this.set("shapes", diagram.dataSource.getChanges());
            this.set("connections", diagram.connectionsDataSource.getChanges());
            this.set("visible", true);
          },
          shapes: {
            deleted: [],
            created: [],
            updated: []
          },
          connections: {
            deleted: [],
            created: [],
            updated: []
          }
        });

        kendo.bind($("#changes"), changesViewModel);

        $("#diagram").kendoDiagram({
          dataSource: shapesDataSource,
          connectionsDataSource: connectionsDataSource,
          layout: {
            type: "tree",
            subtype: "tipover",
            underneathHorizontalOffset: 140
          },
          shapeDefaults: {
            visual: visualTemplate,
            content: {
              template: "#= dataItem.JobTitle #",
              fontSize: 17
            }
          },
          connectionDefaults: {
            stroke: {
              color: "#586477",
              width: 2
            }
          },
          dataBound: onDataBound
        });
      }

      $(document).ready(createDiagram);

      function visualTemplate(options) {
        var dataviz = kendo.dataviz;
        var g = new dataviz.diagram.Group();
        var dataItem = options.dataItem;

        if (dataItem.JobTitle === "President") {
          g.append(new dataviz.diagram.Circle({
            radius: 60,
            stroke: {
              width: 2,
              color: dataItem.Color || "#586477"
            },
            fill: "#e8eff7"
          }));
        } else {
          g.append(new dataviz.diagram.Rectangle({
            width: 240,
            height: 67,
            stroke: {
              width: 0
            },
            fill: "#e8eff7"
          }));

          g.append(new dataviz.diagram.Rectangle({
            width: 8,
            height: 67,
            fill: dataItem.Color,
            stroke: {
              width: 0
            }
          }));
        }

        return g;
      }

      function onDataBound(e) {
        this.bringIntoView(this.shapes);
      }
    </script>

    <div id="diagram"></div>
    <div id="changes">
      <button type="button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base" data-bind="click:showChanges"><span class="k-button-text">Show changes</span></button>
      <div data-bind="visible:visible">
        Deleted Shapes:
        <div data-bind="source: shapes.deleted" data-template="shapeItemTemplate">
        </div>
        <hr />
        Created Shapes:
        <div data-bind="source: shapes.created" data-template="shapeItemTemplate">
        </div>
        <hr />
        Updated Shapes:
        <div data-bind="source: shapes.updated" data-template="shapeItemTemplate">
        </div>
        <hr />
        Deleted Connections:
        <div data-bind="source: connections.deleted" data-template="connectionItemTemplate">
        </div>
        <hr />
        Created Connections:
        <div data-bind="source: connections.created" data-template="connectionItemTemplate">
        </div>
        <hr />
        Updated Connections:
        <div data-bind="source: connections.updated" data-template="connectionItemTemplate">
        </div>
      </div>
    </div>

    <script type="text/kendo" id="shapeItemTemplate">
            <div>
                JodTitle: #:JobTitle#
      </div>
    </script>

    <script type="text/kendo" id="connectionItemTemplate">
            <div>
                #console.log(data)#
                #:FromShapeId# - #:ToShapeId#
      </div>
    </script>

See Also

In this article